001 /*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2013
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas
009 *
010 * All Rights Reserved
011 *
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.
014 *
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 *
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023 * GNU Lesser Public License for more details.
024 *
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program. If not, see http://www.gnu.org/licenses.
027 */
028
029 package edu.wisc.ssec.mcidasv.data.hydra;
030
031 import java.awt.BorderLayout;
032 import java.awt.FlowLayout;
033 import java.awt.geom.Rectangle2D;
034
035 import java.io.File;
036
037 import java.rmi.RemoteException;
038
039 import java.util.ArrayList;
040 import java.util.Collections;
041 import java.util.Enumeration;
042 import java.util.HashMap;
043 import java.util.Hashtable;
044 import java.util.LinkedHashSet;
045 import java.util.List;
046
047 import javax.swing.JComponent;
048 import javax.swing.JLabel;
049 import javax.swing.JPanel;
050 import javax.swing.JSplitPane;
051
052 import org.slf4j.Logger;
053 import org.slf4j.LoggerFactory;
054
055 import ucar.unidata.data.DataCategory;
056 import ucar.unidata.data.DataChoice;
057 import ucar.unidata.data.DataSelection;
058 import ucar.unidata.data.DataSelectionComponent;
059 import ucar.unidata.data.DataSourceDescriptor;
060 import ucar.unidata.data.DirectDataChoice;
061 import ucar.unidata.data.GeoLocationInfo;
062 import ucar.unidata.data.GeoSelection;
063 import ucar.unidata.util.Misc;
064
065 import visad.Data;
066 import visad.FlatField;
067 import visad.VisADException;
068 import visad.FunctionType;
069 import visad.RealType;
070 import visad.RealTupleType;
071 import visad.Linear2DSet;
072 import visad.Gridded2DSet;
073 import visad.CoordinateSystem;
074 import visad.CommonUnit;
075 import visad.SetType;
076 import visad.georef.MapProjection;
077
078 import edu.wisc.ssec.mcidasv.Constants;
079 import edu.wisc.ssec.mcidasv.control.LambertAEA;
080 import edu.wisc.ssec.mcidasv.data.ComboDataChoice;
081 import edu.wisc.ssec.mcidasv.data.HydraDataSource;
082 import edu.wisc.ssec.mcidasv.data.PreviewSelection;
083 import edu.wisc.ssec.mcidasv.display.hydra.MultiSpectralDisplay;
084
085 /**
086 * A data source for Multi Dimension Data
087 */
088
089 public class MultiSpectralDataSource extends HydraDataSource {
090
091 private static final Logger logger = LoggerFactory.getLogger(MultiSpectralDataSource.class);
092
093 /** Sources file */
094 protected String filename;
095
096 protected MultiDimensionReader reader;
097
098 protected MultiDimensionAdapter[] adapters = null;
099
100 private static final String DATA_DESCRIPTION = "Multi Dimension Data";
101
102
103 private HashMap defaultSubset;
104 private SwathAdapter swathAdapter;
105 private SpectrumAdapter spectrumAdapter;
106 private MultiSpectralData multiSpectData;
107
108 private ArrayList<MultiSpectralData> multiSpectData_s = new ArrayList<MultiSpectralData>();
109 private HashMap<String, MultiSpectralData> adapterMap = new HashMap<String, MultiSpectralData>();
110
111 private List categories;
112 private boolean hasImagePreview = false;
113 private boolean hasChannelSelect = false;
114
115 private boolean doAggregation = false;
116
117 private ComboDataChoice comboChoice;
118
119 private PreviewSelection previewSelection = null;
120 private FlatField previewImage = null;
121
122 public static final String paramKey = "paramKey";
123
124 /**
125 * Zero-argument constructor for construction via unpersistence.
126 */
127 public MultiSpectralDataSource() {}
128
129 public MultiSpectralDataSource(String fileName) throws VisADException {
130 this(null, Misc.newList(fileName), null);
131 }
132
133 /**
134 * Construct a new HYDRA hdf data source.
135 * @param descriptor descriptor for this <code>DataSource</code>
136 * @param fileName name of the hdf file to read
137 * @param properties hashtable of properties
138 *
139 * @throws VisADException problem creating data
140 */
141 public MultiSpectralDataSource(DataSourceDescriptor descriptor,
142 String fileName, Hashtable properties)
143 throws VisADException {
144 this(descriptor, Misc.newList(fileName), properties);
145 }
146
147 /**
148 * Construct a new HYDRA hdf data source.
149 * @param descriptor descriptor for this <code>DataSource</code>
150 * @param sources List of filenames
151 * @param properties hashtable of properties
152 *
153 * @throws VisADException problem creating data
154 */
155 public MultiSpectralDataSource(DataSourceDescriptor descriptor,
156 List newSources, Hashtable properties)
157 throws VisADException {
158 super(descriptor, newSources, DATA_DESCRIPTION, properties);
159
160 this.filename = (String)sources.get(0);
161
162 try {
163 setup();
164 }
165 catch (Exception e) {
166 e.printStackTrace();
167 throw new VisADException();
168 }
169 }
170
171 public void setup() throws Exception {
172 String name = (new File(filename)).getName();
173 // aggregations will use sets of NetCDFFile readers
174 ArrayList<NetCDFFile> ncdfal = new ArrayList<NetCDFFile>();
175
176 try {
177 if (name.startsWith("NSS.HRPT.NP") && name.endsWith("obs.hdf")) { // get file union
178 String other = new String(filename);
179 other = other.replace("obs", "nav");
180 reader = NetCDFFile.makeUnion(filename, other);
181 }
182 /**
183 else if (name.startsWith("MYD021KM")) { //hack test code
184 //reader = new NetCDFFileUnion(new String[] {filename, "/Users/rink/Downloads/MYD03.A2011331.0405.005.2011332200700.hdf"});
185 reader = new NetCDFFile(filename);
186 }
187 */
188 else {
189 if (sources.size() > 1) {
190 for (int i = 0; i < sources.size(); i++) {
191 String s = (String) sources.get(i);
192 ncdfal.add(new NetCDFFile(s));
193 }
194 doAggregation = true;
195 } else {
196 reader = new NetCDFFile(filename);
197 }
198 }
199 }
200 catch (Exception e) {
201 e.printStackTrace();
202 logger.error("Cannot create NetCDF reader for file: " + filename);
203 }
204
205 Hashtable<String, String[]> properties = new Hashtable<String, String[]>();
206
207 multiSpectData_s.clear();
208
209 if ( name.startsWith("AIRS")) {
210 HashMap table = SpectrumAdapter.getEmptyMetadataTable();
211 table.put(SpectrumAdapter.array_name, "L1B_AIRS_Science/Data_Fields/radiances");
212 table.put(SpectrumAdapter.range_name, "radiances");
213 table.put(SpectrumAdapter.channelIndex_name, "Channel");
214 table.put(SpectrumAdapter.ancillary_file_name, "/edu/wisc/ssec/mcidasv/data/hydra/resources/airs/L2.chan_prop.2003.11.19.v6.6.9.anc");
215 table.put(SpectrumAdapter.x_dim_name, "GeoXTrack");
216 table.put(SpectrumAdapter.y_dim_name, "GeoTrack");
217 spectrumAdapter = new AIRS_L1B_Spectrum(reader, table);
218
219 table = SwathAdapter.getEmptyMetadataTable();
220 table.put("array_name", "L1B_AIRS_Science/Data_Fields/radiances");
221 table.put(SwathAdapter.range_name, "radiances");
222 table.put("lon_array_name", "L1B_AIRS_Science/Geolocation_Fields/Longitude");
223 table.put("lat_array_name", "L1B_AIRS_Science/Geolocation_Fields/Latitude");
224 table.put("XTrack", "GeoXTrack");
225 table.put("Track", "GeoTrack");
226 table.put("geo_Track", "GeoTrack");
227 table.put("geo_XTrack", "GeoXTrack");
228 table.put(SpectrumAdapter.channelIndex_name, "Channel"); //- think about this?
229
230 swathAdapter = new SwathAdapter(reader, table);
231 HashMap subset = swathAdapter.getDefaultSubset();
232 subset.put(SpectrumAdapter.channelIndex_name, new double[] {793,793,1});
233 defaultSubset = subset;
234 multiSpectData = new MultiSpectralData(swathAdapter, spectrumAdapter);
235 DataCategory.createCategory("MultiSpectral");
236 categories = DataCategory.parseCategories("MultiSpectral;MultiSpectral;IMAGE");
237 hasChannelSelect = true;
238 multiSpectData.init_wavenumber = 919.5f;
239 multiSpectData_s.add(multiSpectData);
240 }
241 else if ( name.startsWith("IASI_xxx_1C") && name.endsWith("h5")) {
242 HashMap table = SpectrumAdapter.getEmptyMetadataTable();
243 table.put(SpectrumAdapter.array_name, "U-MARF/EPS/IASI_xxx_1C/DATA/SPECT_DATA");
244 table.put(SpectrumAdapter.channelIndex_name, "dim2");
245 table.put(SpectrumAdapter.x_dim_name, "dim1");
246 table.put(SpectrumAdapter.y_dim_name, "dim0");
247 spectrumAdapter = new IASI_L1C_Spectrum(reader, table);
248
249 table = SwathAdapter.getEmptyMetadataTable();
250 table.put("array_name", "U-MARF/EPS/IASI_xxx_1C/DATA/SPECT_DATA");
251 table.put("lon_array_name", "U-MARF/EPS/IASI_xxx_1C/DATA/SPECT_LON_ARRAY");
252 table.put("lat_array_name", "U-MARF/EPS/IASI_xxx_1C/DATA/SPECT_LAT_ARRAY");
253 table.put("XTrack", "dim1");
254 table.put("Track", "dim0");
255 table.put("geo_XTrack", "dim1");
256 table.put("geo_Track", "dim0");
257 table.put("product_name", "IASI_L1C_xxx");
258 table.put(SpectrumAdapter.channelIndex_name, "dim2");
259 swathAdapter = new IASI_L1C_SwathAdapter(reader, table);
260 HashMap subset = swathAdapter.getDefaultSubset();
261 subset.put(SpectrumAdapter.channelIndex_name, new double[] {793,793,1});
262 defaultSubset = subset;
263 multiSpectData = new MultiSpectralData(swathAdapter, spectrumAdapter);
264 DataCategory.createCategory("MultiSpectral");
265 categories = DataCategory.parseCategories("MultiSpectral;MultiSpectral;");
266 multiSpectData.init_wavenumber = 919.5f;
267 hasChannelSelect = true;
268 multiSpectData_s.add(multiSpectData);
269 }
270 else if ( name.startsWith("IASI")) {
271 HashMap table = SpectrumAdapter.getEmptyMetadataTable();
272 table.put(SpectrumAdapter.array_name, "observations");
273 table.put(SpectrumAdapter.channelIndex_name, "obsChannelIndex");
274 table.put(SpectrumAdapter.x_dim_name, "obsElement");
275 table.put(SpectrumAdapter.y_dim_name, "obsLine");
276 table.put(SpectrumAdapter.channels_name, "observationChannels");
277 spectrumAdapter = new SpectrumAdapter(reader, table);
278
279 table = SwathAdapter.getEmptyMetadataTable();
280 table.put("array_name", "observations");
281 table.put("lon_array_name", "obsLongitude");
282 table.put("lat_array_name", "obsLatitude");
283 table.put("XTrack", "obsElement");
284 table.put("Track", "obsLine");
285 table.put("geo_XTrack", "obsElement");
286 table.put("geo_Track", "obsLine");
287 table.put(SpectrumAdapter.channelIndex_name, "obsChannelIndex"); //- think about this?
288 swathAdapter = new SwathAdapter(reader, table);
289 HashMap subset = swathAdapter.getDefaultSubset();
290 subset.put(SpectrumAdapter.channelIndex_name, new double[] {793,793,1});
291 defaultSubset = subset;
292 multiSpectData = new MultiSpectralData(swathAdapter, spectrumAdapter);
293 DataCategory.createCategory("MultiSpectral");
294 categories = DataCategory.parseCategories("MultiSpectral;MultiSpectral;");
295 multiSpectData.init_wavenumber = 919.5f;
296 multiSpectData_s.add(multiSpectData);
297 hasChannelSelect = true;
298 }
299 else if (name.startsWith("MOD021KM") || name.startsWith("MYD021KM") ||
300 (name.startsWith("a1") && (name.indexOf("1000m") > 0)) ||
301 (name.startsWith("t1") && (name.indexOf("1000m") > 0)) ) {
302 HashMap table = SwathAdapter.getEmptyMetadataTable();
303 table.put("array_name", "MODIS_SWATH_Type_L1B/Data_Fields/EV_1KM_Emissive");
304 table.put("lon_array_name", "MODIS_SWATH_Type_L1B/Geolocation_Fields/Longitude");
305 table.put("lat_array_name", "MODIS_SWATH_Type_L1B/Geolocation_Fields/Latitude");
306 //table.put("lon_array_name", "MODIS_Swath_Type_GEO/Geolocation_Fields/Longitude");
307 //table.put("lat_array_name", "MODIS_Swath_Type_GEO/Geolocation_Fields/Latitude");
308 table.put("XTrack", "Max_EV_frames");
309 table.put("Track", "10*nscans");
310 table.put("geo_Track", "2*nscans");
311 table.put("geo_XTrack", "1KM_geo_dim");
312 //table.put("geo_Track", "nscans*10");
313 //table.put("geo_XTrack", "mframes");
314 table.put("scale_name", "radiance_scales");
315 table.put("offset_name", "radiance_offsets");
316 table.put("fill_value_name", "_FillValue");
317 table.put("range_name", "Emissive_Bands");
318 table.put(SpectrumAdapter.channelIndex_name, "Band_1KM_Emissive");
319 table.put(SwathAdapter.geo_track_offset_name, Double.toString(2.0));
320 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(2.0));
321 table.put(SwathAdapter.geo_track_skip_name, Double.toString(5.0));
322 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(5.0));
323 table.put(SwathAdapter.multiScaleDimensionIndex, Integer.toString(0));
324
325 // initialize the aggregation reader object
326 logger.debug("Trying to create MODIS 1K GranuleAggregation reader...");
327 LinkedHashSet<String> products = new LinkedHashSet<String>();
328 products.add((String) table.get("array_name"));
329 products.add("MODIS_SWATH_Type_L1B/Data_Fields/EV_1KM_RefSB");
330 products.add("MODIS_SWATH_Type_L1B/Data_Fields/EV_250_Aggr1km_RefSB");
331 products.add("MODIS_SWATH_Type_L1B/Data_Fields/EV_500_Aggr1km_RefSB");
332 products.add("MODIS_SWATH_Type_L1B/Data_Fields/EV_250_Aggr500_RefSB");
333 products.add("MODIS_SWATH_Type_L1B/Data_Fields/EV_250_RefSB");
334 products.add("MODIS_SWATH_Type_L1B/Data_Fields/EV_500_RefSB");
335 products.add((String) table.get("lon_array_name"));
336 products.add((String) table.get("lat_array_name"));
337 if (doAggregation) {
338 try {
339 reader = new GranuleAggregation(ncdfal, products, "10*nscans", "2*nscans", "Max_EV_frames");
340 } catch (Exception e) {
341 throw new VisADException("Unable to initialize aggregation reader");
342 }
343 }
344
345 swathAdapter = new SwathAdapter(reader, table);
346 swathAdapter.setDefaultStride(10);
347 logger.debug("Trying to create MODIS 1K SwathAdapter...");
348
349 HashMap subset = swathAdapter.getDefaultSubset();
350
351 table = SpectrumAdapter.getEmptyMetadataTable();
352 table.put(SpectrumAdapter.array_name, "MODIS_SWATH_Type_L1B/Data_Fields/EV_1KM_Emissive");
353 table.put(SpectrumAdapter.channelIndex_name, "Band_1KM_Emissive");
354 table.put(SpectrumAdapter.x_dim_name, "Max_EV_frames");
355 table.put(SpectrumAdapter.y_dim_name, "10*nscans");
356 table.put(SpectrumAdapter.channelValues, new float[]
357 {3.799f,3.992f,3.968f,4.070f,4.476f,4.549f,6.784f,7.345f,8.503f,
358 9.700f,11.000f,12.005f,13.351f,13.717f,13.908f,14.205f});
359 table.put(SpectrumAdapter.bandNames, new String[]
360 {"20","21","22","23","24","25","27","28","29",
361 "30","31","32","33","34","35","36"});
362 table.put(SpectrumAdapter.channelType, "wavelength");
363 SpectrumAdapter spectrumAdapter = new SpectrumAdapter(reader, table);
364
365 multiSpectData = new MultiSpectralData(swathAdapter, spectrumAdapter, "MODIS", "Aqua");
366 multiSpectData.setInitialWavenumber(11.0f);
367 defaultSubset = multiSpectData.getDefaultSubset();
368
369 previewImage = multiSpectData.getImage(defaultSubset);
370 multiSpectData_s.add(multiSpectData);
371
372 //--- aggregate reflective bands
373 table = SwathAdapter.getEmptyMetadataTable();
374
375 table.put("array_name", "MODIS_SWATH_Type_L1B/Data_Fields/EV_1KM_RefSB");
376 table.put("lon_array_name", "MODIS_SWATH_Type_L1B/Geolocation_Fields/Longitude");
377 table.put("lat_array_name", "MODIS_SWATH_Type_L1B/Geolocation_Fields/Latitude");
378 table.put("XTrack", "Max_EV_frames");
379 table.put("Track", "10*nscans");
380 table.put("geo_Track", "2*nscans");
381 table.put("geo_XTrack", "1KM_geo_dim");
382 table.put("scale_name", "reflectance_scales");
383 table.put("offset_name", "reflectance_offsets");
384 table.put("fill_value_name", "_FillValue");
385 table.put("range_name", "EV_1KM_RefSB");
386 table.put(SpectrumAdapter.channelIndex_name, "Band_1KM_RefSB");
387
388 table.put(SwathAdapter.geo_track_offset_name, Double.toString(2.0));
389 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(2.0));
390 table.put(SwathAdapter.geo_track_skip_name, Double.toString(5.0));
391 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(5.0));
392 table.put(SwathAdapter.multiScaleDimensionIndex, Integer.toString(0));
393
394 SwathAdapter sadapt0 = new SwathAdapter(reader, table);
395 sadapt0.setDefaultStride(10);
396
397 table = SpectrumAdapter.getEmptyMetadataTable();
398 table.put(SpectrumAdapter.array_name, "MODIS_SWATH_Type_L1B/Data_Fields/EV_1KM_RefSB");
399 table.put(SpectrumAdapter.channelIndex_name, "Band_1KM_RefSB");
400 table.put(SpectrumAdapter.x_dim_name, "Max_EV_frames");
401 table.put(SpectrumAdapter.y_dim_name, "10*nscans");
402 table.put(SpectrumAdapter.channelValues, new float[]
403 {.412f,.450f,.487f,.531f,.551f,.666f,.668f,.677f,.679f,.748f,
404 .869f,.905f,.936f,.940f,1.375f});
405 table.put(SpectrumAdapter.bandNames, new String[]
406 {"8","9","10","11","12","13lo","13hi","14lo","14hi","15",
407 "16","17","18","19","26"});
408 table.put(SpectrumAdapter.channelType, "wavelength");
409 SpectrumAdapter specadap0 = new SpectrumAdapter(reader, table);
410 MultiSpectralData multispec0 = new MultiSpectralData(sadapt0, specadap0, "Reflectance", "Reflectance", "MODIS", "Aqua");
411
412 DataCategory.createCategory("MultiSpectral");
413 categories = DataCategory.parseCategories("MultiSpectral;MultiSpectral;IMAGE");
414 hasImagePreview = true;
415 hasChannelSelect = true;
416
417 table = SwathAdapter.getEmptyMetadataTable();
418
419 table.put("array_name", "MODIS_SWATH_Type_L1B/Data_Fields/EV_250_Aggr1km_RefSB");
420 table.put("lon_array_name", "MODIS_SWATH_Type_L1B/Geolocation_Fields/Longitude");
421 table.put("lat_array_name", "MODIS_SWATH_Type_L1B/Geolocation_Fields/Latitude");
422 table.put("XTrack", "Max_EV_frames");
423 table.put("Track", "10*nscans");
424 table.put("geo_Track", "2*nscans");
425 table.put("geo_XTrack", "1KM_geo_dim");
426 table.put("scale_name", "reflectance_scales");
427 table.put("offset_name", "reflectance_offsets");
428 table.put("fill_value_name", "_FillValue");
429 table.put("range_name", "Reflective_Bands");
430 table.put(SpectrumAdapter.channelIndex_name, "Band_250M");
431
432 table.put(SwathAdapter.geo_track_offset_name, Double.toString(2.0));
433 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(2.0));
434 table.put(SwathAdapter.geo_track_skip_name, Double.toString(5.0));
435 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(5.0));
436 table.put(SwathAdapter.multiScaleDimensionIndex, Integer.toString(0));
437
438 SwathAdapter sadapt1 = new SwathAdapter(reader, table);
439
440 table = SpectrumAdapter.getEmptyMetadataTable();
441 table.put(SpectrumAdapter.array_name, "MODIS_SWATH_Type_L1B/Data_Fields/EV_250_Aggr1km_RefSB");
442 table.put(SpectrumAdapter.channelIndex_name, "Band_250M");
443 table.put(SpectrumAdapter.x_dim_name, "Max_EV_frames");
444 table.put(SpectrumAdapter.y_dim_name, "10*nscans");
445 table.put(SpectrumAdapter.channelValues, new float[]
446 {.650f,.855f});
447 table.put(SpectrumAdapter.bandNames, new String[]
448 {"1","2"});
449 table.put(SpectrumAdapter.channelType, "wavelength");
450 SpectrumAdapter specadap1 = new SpectrumAdapter(reader, table);
451 MultiSpectralData multispec1 = new MultiSpectralData(sadapt1, specadap1, "Reflectance", "Reflectance", "MODIS", "Aqua");
452
453 table = SwathAdapter.getEmptyMetadataTable();
454
455 table.put("array_name", "MODIS_SWATH_Type_L1B/Data_Fields/EV_500_Aggr1km_RefSB");
456 table.put("lon_array_name", "MODIS_SWATH_Type_L1B/Geolocation_Fields/Longitude");
457 table.put("lat_array_name", "MODIS_SWATH_Type_L1B/Geolocation_Fields/Latitude");
458 table.put("XTrack", "Max_EV_frames");
459 table.put("Track", "10*nscans");
460 table.put("geo_Track", "2*nscans");
461 table.put("geo_XTrack", "1KM_geo_dim");
462 table.put("scale_name", "reflectance_scales");
463 table.put("offset_name", "reflectance_offsets");
464 table.put("fill_value_name", "_FillValue");
465 table.put("range_name", "EV_500_Aggr1km_RefSB");
466 table.put(SpectrumAdapter.channelIndex_name, "Band_500M");
467 table.put(SwathAdapter.geo_track_offset_name, Double.toString(2.0));
468 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(2.0));
469 table.put(SwathAdapter.geo_track_skip_name, Double.toString(5.0));
470 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(5.0));
471 table.put(SwathAdapter.multiScaleDimensionIndex, Integer.toString(0));
472
473
474 SwathAdapter sadapt2 = new SwathAdapter(reader, table);
475
476
477 table = SpectrumAdapter.getEmptyMetadataTable();
478 table.put(SpectrumAdapter.array_name, "MODIS_SWATH_Type_L1B/Data_Fields/EV_500_Aggr1km_RefSB");
479 table.put(SpectrumAdapter.channelIndex_name, "Band_500M");
480 table.put(SpectrumAdapter.x_dim_name, "Max_EV_frames");
481 table.put(SpectrumAdapter.y_dim_name, "10*nscans");
482 table.put(SpectrumAdapter.channelValues, new float[]
483 {.470f,.555f,1.240f,1.638f,2.130f});
484 table.put(SpectrumAdapter.bandNames, new String[]
485 {"3","4","5","6","7"});
486 table.put(SpectrumAdapter.channelType, "wavelength");
487 SpectrumAdapter specadap2 = new SpectrumAdapter(reader, table);
488 MultiSpectralData multispec2 = new MultiSpectralData(sadapt2, specadap2, "Reflectance", "Reflectance", "MODIS", "Aqua");
489
490 MultiSpectralAggr aggr = new MultiSpectralAggr(new MultiSpectralData[] {multispec1, multispec2, multispec0});
491 aggr.setInitialWavenumber(0.650f);
492 aggr.setDataRange(new float[] {0f, 0.8f});
493 multiSpectData_s.add(aggr);
494 }
495 else if (name.startsWith("MOD02QKM") || name.startsWith("MYD02QKM") ||
496 (name.startsWith("a1") && (name.indexOf("250m") > 0)) ||
497 (name.startsWith("t1") && (name.indexOf("250m") > 0)) ) {
498 HashMap table = SwathAdapter.getEmptyMetadataTable();
499 table.put("array_name", "MODIS_SWATH_Type_L1B/Data_Fields/EV_250_RefSB");
500 table.put("lon_array_name", "MODIS_SWATH_Type_L1B/Geolocation_Fields/Longitude");
501 table.put("lat_array_name", "MODIS_SWATH_Type_L1B/Geolocation_Fields/Latitude");
502 table.put("XTrack", "4*Max_EV_frames");
503 table.put("Track", "40*nscans");
504 table.put("geo_Track", "10*nscans");
505 table.put("geo_XTrack", "Max_EV_frames");
506 table.put("scale_name", "reflectance_scales");
507 table.put("offset_name", "reflectance_offsets");
508 table.put("fill_value_name", "_FillValue");
509 table.put("range_name", "Reflective_Bands");
510 table.put(SpectrumAdapter.channelIndex_name, "Band_250M");
511 table.put(SwathAdapter.geo_track_offset_name, Double.toString(0.0));
512 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(0.0));
513 table.put(SwathAdapter.geo_track_skip_name, Double.toString(4.0));
514 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(4.0));
515 table.put(SwathAdapter.multiScaleDimensionIndex, Integer.toString(0));
516 // initialize the aggregation reader object
517 logger.debug("Trying to create MODIS 1K GranuleAggregation reader...");
518 LinkedHashSet<String> products = new LinkedHashSet<String>();
519 products.add((String) table.get("array_name"));
520 products.add("MODIS_SWATH_Type_L1B/Data_Fields/EV_250_RefSB");
521 products.add((String) table.get("lon_array_name"));
522 products.add((String) table.get("lat_array_name"));
523 if (doAggregation) {
524 try {
525 reader = new GranuleAggregation(ncdfal, products, "40*nscans", "10*nscans", "4*Max_EV_frames");
526 } catch (Exception e) {
527 throw new VisADException("Unable to initialize aggregation reader");
528 }
529 }
530 swathAdapter = new SwathAdapter(reader, table);
531 swathAdapter.setDefaultStride(40);
532
533 table = SpectrumAdapter.getEmptyMetadataTable();
534 table.put(SpectrumAdapter.array_name, "MODIS_SWATH_Type_L1B/Data_Fields/EV_250_RefSB");
535 table.put(SpectrumAdapter.channelIndex_name, "Band_250M");
536 table.put(SpectrumAdapter.x_dim_name, "4*Max_EV_frames");
537 table.put(SpectrumAdapter.y_dim_name, "40*nscans");
538 table.put(SpectrumAdapter.channelValues, new float[]
539 {.650f,.855f});
540 table.put(SpectrumAdapter.bandNames, new String[]
541 {"1","2"});
542 table.put(SpectrumAdapter.channelType, "wavelength");
543 SpectrumAdapter spectrumAdapter = new SpectrumAdapter(reader, table);
544
545 multiSpectData = new MultiSpectralData(swathAdapter, spectrumAdapter, "Reflectance", "Reflectance", "MODIS", "Aqua");
546 multiSpectData.setInitialWavenumber(0.650f);
547 multiSpectData.setDataRange(new float[] {0f, 0.8f});
548 defaultSubset = multiSpectData.getDefaultSubset();
549 previewImage = multiSpectData.getImage(defaultSubset);
550 multiSpectData_s.add(multiSpectData);
551
552 DataCategory.createCategory("MultiSpectral");
553 categories = DataCategory.parseCategories("MultiSpectral;MultiSpectral;IMAGE");
554 hasImagePreview = true;
555 hasChannelSelect = true;
556
557 multiSpectData_s.add(null);
558 }
559 else if (name.startsWith("MOD02HKM") || name.startsWith("MYD02HKM") ||
560 (name.startsWith("a1") && (name.indexOf("500m") > 0)) ||
561 (name.startsWith("t1") && (name.indexOf("500m") > 0)) ) {
562 HashMap table = SwathAdapter.getEmptyMetadataTable();
563 table.put("array_name", "MODIS_SWATH_Type_L1B/Data_Fields/EV_250_Aggr500_RefSB");
564 table.put("lon_array_name", "MODIS_SWATH_Type_L1B/Geolocation_Fields/Longitude");
565 table.put("lat_array_name", "MODIS_SWATH_Type_L1B/Geolocation_Fields/Latitude");
566 table.put("XTrack", "2*Max_EV_frames");
567 table.put("Track", "20*nscans");
568 table.put("geo_Track", "10*nscans");
569 table.put("geo_XTrack", "Max_EV_frames");
570 table.put("scale_name", "reflectance_scales");
571 table.put("offset_name", "reflectance_offsets");
572 table.put("fill_value_name", "_FillValue");
573 table.put("range_name", "Reflective_Bands");
574 table.put(SpectrumAdapter.channelIndex_name, "Band_250M");
575 table.put(SwathAdapter.geo_track_offset_name, Double.toString(0.0));
576 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(0.0));
577 table.put(SwathAdapter.geo_track_skip_name, Double.toString(2.0));
578 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(2.0));
579 table.put(SwathAdapter.multiScaleDimensionIndex, Integer.toString(0));
580
581 // initialize the aggregation reader object
582 logger.debug("Trying to create MODIS 1K GranuleAggregation reader...");
583 LinkedHashSet<String> products = new LinkedHashSet<String>();
584 products.add((String) table.get("array_name"));
585 products.add("MODIS_SWATH_Type_L1B/Data_Fields/EV_500_RefSB");
586 products.add("MODIS_SWATH_Type_L1B/Data_Fields/EV_250_Aggr500_RefSB");
587 products.add((String) table.get("lon_array_name"));
588 products.add((String) table.get("lat_array_name"));
589 if (doAggregation) {
590 try {
591 reader = new GranuleAggregation(ncdfal, products, "20*nscans", "10*nscans", "2*Max_EV_frames");
592 } catch (Exception e) {
593 throw new VisADException("Unable to initialize aggregation reader");
594 }
595 }
596
597 SwathAdapter swathAdapter0 = new SwathAdapter(reader, table);
598 swathAdapter0.setDefaultStride(20);
599
600 table = SpectrumAdapter.getEmptyMetadataTable();
601 table.put(SpectrumAdapter.array_name, "MODIS_SWATH_Type_L1B/Data_Fields/EV_250_Aggr500_RefSB");
602 table.put(SpectrumAdapter.channelIndex_name, "Band_250M");
603 table.put(SpectrumAdapter.x_dim_name, "2*Max_EV_frames");
604 table.put(SpectrumAdapter.y_dim_name, "20*nscans");
605 table.put(SpectrumAdapter.channelValues, new float[]
606 {.650f,.855f});
607 table.put(SpectrumAdapter.bandNames, new String[]
608 {"1","2"});
609 table.put(SpectrumAdapter.channelType, "wavelength");
610 SpectrumAdapter spectrumAdapter0 = new SpectrumAdapter(reader, table);
611
612 MultiSpectralData multiSpectData0 = new MultiSpectralData(swathAdapter0, spectrumAdapter0, "Reflectance", "Reflectance", "MODIS", "Aqua");
613
614 table = SwathAdapter.getEmptyMetadataTable();
615 table.put("array_name", "MODIS_SWATH_Type_L1B/Data_Fields/EV_500_RefSB");
616 table.put("lon_array_name", "MODIS_SWATH_Type_L1B/Geolocation_Fields/Longitude");
617 table.put("lat_array_name", "MODIS_SWATH_Type_L1B/Geolocation_Fields/Latitude");
618 table.put("XTrack", "2*Max_EV_frames");
619 table.put("Track", "20*nscans");
620 table.put("geo_Track", "10*nscans");
621 table.put("geo_XTrack", "Max_EV_frames");
622 table.put("scale_name", "reflectance_scales");
623 table.put("offset_name", "reflectance_offsets");
624 table.put("fill_value_name", "_FillValue");
625 table.put("range_name", "Reflective_Bands");
626 table.put(SpectrumAdapter.channelIndex_name, "Band_500M");
627 table.put(SwathAdapter.geo_track_offset_name, Double.toString(0.0));
628 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(0.0));
629 table.put(SwathAdapter.geo_track_skip_name, Double.toString(2.0));
630 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(2.0));
631 table.put(SwathAdapter.multiScaleDimensionIndex, Integer.toString(0));
632
633 SwathAdapter swathAdapter1 = new SwathAdapter(reader, table);
634 swathAdapter1.setDefaultStride(20);
635
636 table = SpectrumAdapter.getEmptyMetadataTable();
637 table.put(SpectrumAdapter.array_name, "MODIS_SWATH_Type_L1B/Data_Fields/EV_500_RefSB");
638 table.put(SpectrumAdapter.channelIndex_name, "Band_500M");
639 table.put(SpectrumAdapter.x_dim_name, "2*Max_EV_frames");
640 table.put(SpectrumAdapter.y_dim_name, "20*nscans");
641 table.put(SpectrumAdapter.channelValues, new float[]
642 {.470f,.555f,1.240f,1.638f,2.130f});
643 table.put(SpectrumAdapter.bandNames, new String[]
644 {"3","4","5","6","7"});
645 table.put(SpectrumAdapter.channelType, "wavelength");
646 SpectrumAdapter spectrumAdapter1 = new SpectrumAdapter(reader, table);
647
648 MultiSpectralData multiSpectData1 = new MultiSpectralData(swathAdapter1, spectrumAdapter1, "Reflectance", "Reflectance", "MODIS", "Aqua");
649
650 MultiSpectralAggr aggr =
651 new MultiSpectralAggr(new MultiSpectralData[] {multiSpectData0, multiSpectData1});
652 aggr.setInitialWavenumber(0.650f);
653 aggr.setDataRange(new float[] {0f, 0.8f});
654 multiSpectData_s.add(aggr);
655 multiSpectData = aggr;
656 defaultSubset = aggr.getDefaultSubset();
657 previewImage = aggr.getImage(defaultSubset);
658
659 DataCategory.createCategory("MultiSpectral");
660 categories = DataCategory.parseCategories("MultiSpectral;MultiSpectral;IMAGE");
661 hasImagePreview = true;
662 hasChannelSelect = true;
663
664 multiSpectData_s.add(null);
665 }
666 else if (name.startsWith("NSS.HRPT") && name.endsWith("level2.hdf")) {
667 HashMap swthTable = SwathAdapter.getEmptyMetadataTable();
668 swthTable.put("array_name", "temp_3_75um_nom");
669 swthTable.put("lon_array_name", "longitude");
670 swthTable.put("lat_array_name", "latitude");
671 swthTable.put("XTrack", "pixel_elements_along_scan_direction");
672 swthTable.put("Track", "scan_lines_along_track_direction");
673 swthTable.put("geo_Track", "scan_lines_along_track_direction");
674 swthTable.put("geo_XTrack", "pixel_elements_along_scan_direction");
675 swthTable.put("scale_name", "SCALE_FACTOR");
676 swthTable.put("offset_name", "ADD_OFFSET");
677 swthTable.put("fill_value_name", "_FILLVALUE");
678 swthTable.put("range_name", "Emmissive_Bands");
679 swthTable.put("unpack", "unpack");
680 swthTable.put("geo_scale_name", "SCALE_FACTOR");
681 swthTable.put("geo_offset_name", "ADD_OFFSET");
682 swthTable.put("geo_fillValue_name", "_FILLVALUE");
683
684
685 SwathAdapter swathAdapter0 = new SwathAdapter(reader, swthTable);
686 swathAdapter0.setDefaultStride(10);
687 HashMap subset = swathAdapter0.getDefaultSubset();
688 defaultSubset = subset;
689
690 HashMap specTable = SpectrumAdapter.getEmptyMetadataTable();
691 specTable.put(SpectrumAdapter.array_name, "temp_3_75um_nom");
692 specTable.put(SpectrumAdapter.x_dim_name, "pixel_elements_along_scan_direction");
693 specTable.put(SpectrumAdapter.y_dim_name, "scan_lines_along_track_direction");
694 specTable.put(SpectrumAdapter.channelValues, new float[] {3.740f});
695 specTable.put(SpectrumAdapter.bandNames, new String[] {"ch3b"});
696 specTable.put(SpectrumAdapter.channelType, "wavelength");
697 SpectrumAdapter spectrumAdapter0 = new SpectrumAdapter(reader, specTable);
698
699 MultiSpectralData multiSpectData0 = new MultiSpectralData(swathAdapter0, spectrumAdapter0, "BrightnessTemp", "BrightnessTemp", null, null);
700
701 HashMap table = SwathAdapter.getEmptyMetadataTable();
702 table.put("array_name", "temp_11_0um_nom");
703 table.put("lon_array_name", "longitude");
704 table.put("lat_array_name", "latitude");
705 table.put("XTrack", "pixel_elements_along_scan_direction");
706 table.put("Track", "scan_lines_along_track_direction");
707 table.put("geo_Track", "scan_lines_along_track_direction");
708 table.put("geo_XTrack", "pixel_elements_along_scan_direction");
709 table.put("scale_name", "SCALE_FACTOR");
710 table.put("offset_name", "ADD_OFFSET");
711 table.put("fill_value_name", "_FILLVALUE");
712 table.put("range_name", "Emmissive_Bands");
713 table.put("unpack", "unpack");
714 table.put("geo_scale_name", "SCALE_FACTOR");
715 table.put("geo_offset_name", "ADD_OFFSET");
716 table.put("geo_fillValue_name", "_FILLVALUE");
717
718
719 SwathAdapter swathAdapter1 = new SwathAdapter(reader, table);
720 swathAdapter1.setDefaultStride(10);
721
722 table = SpectrumAdapter.getEmptyMetadataTable();
723 table.put(SpectrumAdapter.array_name, "temp_11_0um_nom");
724 table.put(SpectrumAdapter.x_dim_name, "pixel_elements_along_scan_direction");
725 table.put(SpectrumAdapter.y_dim_name, "scan_lines_along_track_direction");
726 table.put(SpectrumAdapter.channelValues, new float[] {10.80f});
727 table.put(SpectrumAdapter.bandNames, new String[] {"ch4"});
728 table.put(SpectrumAdapter.channelType, "wavelength");
729 SpectrumAdapter spectrumAdapter1 = new SpectrumAdapter(reader, table);
730
731 MultiSpectralData multiSpectData1 = new MultiSpectralData(swathAdapter1, spectrumAdapter1, "BrightnessTemp", "BrightnessTemp", null, null);
732
733 table = SwathAdapter.getEmptyMetadataTable();
734 table.put("array_name", "temp_12_0um_nom");
735 table.put("lon_array_name", "longitude");
736 table.put("lat_array_name", "latitude");
737 table.put("XTrack", "pixel_elements_along_scan_direction");
738 table.put("Track", "scan_lines_along_track_direction");
739 table.put("geo_Track", "scan_lines_along_track_direction");
740 table.put("geo_XTrack", "pixel_elements_along_scan_direction");
741 table.put("scale_name", "SCALE_FACTOR");
742 table.put("offset_name", "ADD_OFFSET");
743 table.put("fill_value_name", "_FILLVALUE");
744 table.put("range_name", "Emmissive_Bands");
745 table.put("unpack", "unpack");
746 table.put("geo_scale_name", "SCALE_FACTOR");
747 table.put("geo_offset_name", "ADD_OFFSET");
748 table.put("geo_fillValue_name", "_FILLVALUE");
749
750
751 SwathAdapter swathAdapter2 = new SwathAdapter(reader, table);
752 swathAdapter2.setDefaultStride(10);
753
754 table = SpectrumAdapter.getEmptyMetadataTable();
755 table.put(SpectrumAdapter.array_name, "temp_12_0um_nom");
756 table.put(SpectrumAdapter.x_dim_name, "pixel_elements_along_scan_direction");
757 table.put(SpectrumAdapter.y_dim_name, "scan_lines_along_track_direction");
758 table.put(SpectrumAdapter.channelValues, new float[] {12.00f});
759 table.put(SpectrumAdapter.bandNames, new String[] {"ch5"});
760 table.put(SpectrumAdapter.channelType, "wavelength");
761 SpectrumAdapter spectrumAdapter2 = new SpectrumAdapter(reader, table);
762
763 MultiSpectralData multiSpectData2 = new MultiSpectralData(swathAdapter2, spectrumAdapter2, "BrightnessTemp", "BrightnessTemp", null, null);
764
765
766 MultiSpectralAggr aggr = new MultiSpectralAggr(new MultiSpectralData[] {multiSpectData0, multiSpectData1, multiSpectData2});
767 aggr.setInitialWavenumber(3.740f);
768 aggr.setDataRange(new float[] {180f, 340f});
769 multiSpectData = aggr;
770 multiSpectData_s.add(aggr);
771 defaultSubset = aggr.getDefaultSubset();
772 previewImage = aggr.getImage(defaultSubset);
773
774 //- now do the reflective bands
775 swthTable.put("array_name", "refl_0_65um_nom");
776 swthTable.put("range_name", "Reflective_Bands");
777
778 swathAdapter0 = new SwathAdapter(reader, swthTable);
779 swathAdapter0.setDefaultStride(10);
780
781 specTable.put(SpectrumAdapter.array_name, "refl_0_65um_nom");
782 specTable.put(SpectrumAdapter.channelValues, new float[] {0.630f});
783 specTable.put(SpectrumAdapter.bandNames, new String[] {"ch1"});
784 spectrumAdapter0 = new SpectrumAdapter(reader, specTable);
785
786 multiSpectData0 = new MultiSpectralData(swathAdapter0, spectrumAdapter0, "Reflectance", "Reflectance", null, null);
787
788 swthTable.put("array_name", "refl_0_86um_nom");
789 swthTable.put("range_name", "Reflective_Bands");
790
791 swathAdapter1 = new SwathAdapter(reader, swthTable);
792 swathAdapter1.setDefaultStride(10);
793
794 specTable.put(SpectrumAdapter.array_name, "refl_0_86um_nom");
795 specTable.put(SpectrumAdapter.channelValues, new float[] {0.862f});
796 specTable.put(SpectrumAdapter.bandNames, new String[] {"ch2"});
797 spectrumAdapter1 = new SpectrumAdapter(reader, specTable);
798
799 multiSpectData1 = new MultiSpectralData(swathAdapter1, spectrumAdapter1, "Reflectance", "Reflectance", null, null);
800
801 swthTable.put("array_name", "refl_1_60um_nom");
802 swthTable.put("range_name", "Reflective_Bands");
803
804 swathAdapter2 = new SwathAdapter(reader, swthTable);
805 swathAdapter2.setDefaultStride(10);
806 subset = swathAdapter2.getDefaultSubset();
807 defaultSubset = subset;
808
809 specTable.put(SpectrumAdapter.array_name, "refl_1_60um_nom");
810 specTable.put(SpectrumAdapter.channelValues, new float[] {1.610f});
811 specTable.put(SpectrumAdapter.bandNames, new String[] {"ch3ab"});
812 spectrumAdapter2 = new SpectrumAdapter(reader, specTable);
813
814 multiSpectData2 = new MultiSpectralData(swathAdapter2, spectrumAdapter2, "Reflectance", "Reflectance", null, null);
815
816 aggr = new MultiSpectralAggr(new MultiSpectralData[] {multiSpectData0, multiSpectData1, multiSpectData2});
817 aggr.setInitialWavenumber(0.630f);
818 aggr.setDataRange(new float[] {0f, 100f});
819 multiSpectData_s.add(aggr);
820
821 categories = DataCategory.parseCategories("MultiSpectral;MultiSpectral;IMAGE");
822
823 hasImagePreview = true;
824 hasChannelSelect = true;
825 }
826 else {
827 HashMap table = SwathAdapter.getEmptyMetadataTable();
828 table.put("array_name", "MODIS_SWATH_Type_L1B/Data_Fields/EV_1KM_Emissive");
829 table.put("lon_array_name", "pixel_longitude");
830 table.put("lat_array_name", "pixel_latitude");
831 table.put("XTrack", "elements");
832 table.put("Track", "lines");
833 table.put("geo_Track", "lines");
834 table.put("geo_XTrack", "elements");
835 table.put("scale_name", "scale_factor");
836 table.put("offset_name", "add_offset");
837 table.put("fill_value_name", "_FillValue");
838 swathAdapter = new SwathAdapter(reader, table);
839 categories = DataCategory.parseCategories("2D grid;GRID-2D;");
840 defaultSubset = swathAdapter.getDefaultSubset();
841 }
842 setProperties(properties);
843 }
844
845 public void initAfterUnpersistence() {
846 try {
847 setup();
848 }
849 catch (Exception e) {
850 }
851 }
852
853 /**
854 * Make and insert the <code>DataChoice</code>-s for this
855 * <code>DataSource</code>.
856 */
857 public void doMakeDataChoices() {
858 try {
859 for (int k=0; k<multiSpectData_s.size(); k++) {
860 MultiSpectralData adapter = multiSpectData_s.get(k);
861 DataChoice choice = doMakeDataChoice(k, adapter);
862 adapterMap.put(choice.getName(), adapter);
863 addDataChoice(choice);
864 }
865 }
866 catch(Exception e) {
867 e.printStackTrace();
868 }
869 }
870
871 public void addChoice(String name, Data data) {
872 ComboDataChoice combo = new ComboDataChoice(name + hashCode(), name, new Hashtable(), data);
873 addDataChoice(combo);
874 getDataContext().dataSourceChanged(this);
875 }
876
877 private DataChoice doMakeDataChoice(int idx, MultiSpectralData adapter) throws Exception {
878 String name = "_ ";
879 DataSelection dataSel = new MultiDimensionSubset();
880 if (adapter != null) {
881 name = adapter.getName();
882 //dataSel = new MultiDimensionSubset(defaultSubset);
883 dataSel = new MultiDimensionSubset(adapter.getDefaultSubset());
884 }
885
886 Hashtable subset = new Hashtable();
887 subset.put(MultiDimensionSubset.key, dataSel);
888 if (adapter != null) {
889 subset.put(MultiSpectralDataSource.paramKey, adapter.getParameter());
890 }
891
892 DirectDataChoice ddc = new DirectDataChoice(this, new Integer(idx), name, name, categories, subset);
893 ddc.setProperties(subset);
894 return ddc;
895 }
896
897 /**
898 * Check to see if this <code>HDFHydraDataSource</code> is equal to the object
899 * in question.
900 * @param o object in question
901 * @return true if they are the same or equivalent objects
902 */
903 public boolean equals(Object o) {
904 if ( !(o instanceof MultiSpectralDataSource)) {
905 return false;
906 }
907 return (this == (MultiSpectralDataSource) o);
908 }
909
910 public MultiSpectralData getMultiSpectralData() {
911 return multiSpectData;
912 }
913
914 public MultiSpectralData getMultiSpectralData(DataChoice choice) {
915 return adapterMap.get(choice.getName());
916 }
917
918 public MultiSpectralData getMultiSpectralData(String name) {
919 return adapterMap.get(name);
920 }
921
922 public MultiSpectralData getMultiSpectralData(int idx) {
923 return multiSpectData_s.get(idx);
924 }
925
926 public String getDatasetName() {
927 return filename;
928 }
929
930 public void setDatasetName(String name) {
931 filename = name;
932 }
933
934 public ComboDataChoice getComboDataChoice() {
935 return comboChoice;
936 }
937
938 /**
939 * Called by the IDV's persistence manager in an effort to collect all of
940 * the files that should be included in a zipped bundle.
941 *
942 * @return Singleton list containing the file that this data source came from.
943 */
944 @Override public List getDataPaths() {
945 return Collections.singletonList(filename);
946 }
947
948 /**
949 public HashMap getSubsetFromLonLatRect(MultiDimensionSubset select, GeoSelection geoSelection) {
950 GeoLocationInfo ginfo = geoSelection.getBoundingBox();
951 return adapters[0].getSubsetFromLonLatRect(select.getSubset(), ginfo.getMinLat(), ginfo.getMaxLat(),
952 ginfo.getMinLon(), ginfo.getMaxLon());
953 }
954 */
955
956 public synchronized Data getData(String name, HashMap subset) throws VisADException, RemoteException {
957 MultiSpectralData msd = getMultiSpectralData(name);
958 Data data = null;
959 try {
960 data = msd.getImage(subset);
961 } catch (Exception e) {
962 e.printStackTrace();
963 }
964 return data;
965 }
966
967
968 public synchronized Data getData(DataChoice dataChoice, DataCategory category,
969 DataSelection dataSelection, Hashtable requestProperties)
970 throws VisADException, RemoteException {
971 return this.getDataInner(dataChoice, category, dataSelection, requestProperties);
972
973 }
974
975 protected Data getDataInner(DataChoice dataChoice, DataCategory category,
976 DataSelection dataSelection, Hashtable requestProperties)
977 throws VisADException, RemoteException {
978
979 //- this hack keeps the HydraImageProbe from doing a getData()
980 //- TODO: need to use categories?
981 if (requestProperties != null) {
982 if ((requestProperties.toString()).contains("ReadoutProbe")) {
983 return null;
984 }
985 }
986
987 GeoLocationInfo ginfo = null;
988 GeoSelection geoSelection = null;
989
990 if ((dataSelection != null) && (dataSelection.getGeoSelection() != null)) {
991 if (dataSelection.getGeoSelection().getBoundingBox() != null) {
992 geoSelection = dataSelection.getGeoSelection();
993 }
994 else if (dataChoice.getDataSelection() != null) {
995 geoSelection = dataChoice.getDataSelection().getGeoSelection();
996 }
997 }
998
999 if (geoSelection != null) {
1000 ginfo = geoSelection.getBoundingBox();
1001 }
1002
1003 Data data = null;
1004
1005 try {
1006 HashMap subset = null;
1007 if (ginfo != null) {
1008 subset = swathAdapter.getSubsetFromLonLatRect(ginfo.getMinLat(), ginfo.getMaxLat(),
1009 ginfo.getMinLon(), ginfo.getMaxLon());
1010 }
1011 else {
1012 MultiDimensionSubset select = null;
1013 Hashtable table = dataChoice.getProperties();
1014 Enumeration keys = table.keys();
1015 while (keys.hasMoreElements()) {
1016 Object key = keys.nextElement();
1017 if (key instanceof MultiDimensionSubset) {
1018 select = (MultiDimensionSubset) table.get(key);
1019 }
1020 }
1021 if (select != null) {
1022 subset = select.getSubset();
1023 }
1024
1025 if (dataSelection != null) {
1026 Hashtable props = dataSelection.getProperties();
1027 if (props != null) {
1028 if (props.containsKey(MultiDimensionSubset.key)) {
1029 subset = (HashMap)((MultiDimensionSubset)props.get(MultiDimensionSubset.key)).getSubset();
1030 }
1031 else {
1032 subset = defaultSubset;
1033 }
1034 if (props.containsKey(SpectrumAdapter.channelIndex_name)) {
1035 int idx = ((Integer) props.get(SpectrumAdapter.channelIndex_name)).intValue();
1036 double[] coords = (double[]) subset.get(SpectrumAdapter.channelIndex_name);
1037 if (coords == null) {
1038 coords = new double[] {(double)idx, (double)idx, (double)1};
1039 subset.put(SpectrumAdapter.channelIndex_name, coords);
1040 }
1041 else {
1042 coords[0] = (double)idx;
1043 coords[1] = (double)idx;
1044 coords[2] = (double)1;
1045 }
1046 }
1047 }
1048 }
1049 }
1050
1051 if (subset != null) {
1052 MultiSpectralData multiSpectData = getMultiSpectralData(dataChoice);
1053 if (multiSpectData != null) {
1054 data = multiSpectData.getImage(subset);
1055 data = applyProperties(data, requestProperties, subset);
1056 }
1057 }
1058 } catch (Exception e) {
1059 e.printStackTrace();
1060 System.out.println("getData exception e=" + e);
1061 }
1062 return data;
1063 }
1064
1065 public MapProjection getDataProjection(HashMap subset) {
1066 MapProjection mp = null;
1067 try {
1068 Rectangle2D rect = multiSpectData.getLonLatBoundingBox(subset);
1069 mp = new LambertAEA(rect);
1070 }
1071 catch (Exception e) {
1072 logException("MultiSpectralDataSource.getDataProjection", e);
1073 }
1074 return mp;
1075 }
1076
1077 protected Data applyProperties(Data data, Hashtable requestProperties, HashMap subset)
1078 throws VisADException, RemoteException {
1079 Data new_data = data;
1080
1081 if (requestProperties == null) {
1082 new_data = data;
1083 return new_data;
1084 }
1085 return new_data;
1086 }
1087
1088 protected void initDataSelectionComponents(
1089 List<DataSelectionComponent> components,
1090 final DataChoice dataChoice) {
1091
1092 if (System.getProperty("os.name").equals("Mac OS X") && hasImagePreview && hasChannelSelect) {
1093 try {
1094 components.add(new ImageChannelSelection(new PreviewSelection(dataChoice, previewImage, null), new ChannelSelection(dataChoice)));
1095 } catch (Exception e) {
1096 e.printStackTrace();
1097 }
1098 }
1099 else {
1100 if (hasImagePreview) {
1101 try {
1102 previewSelection = new PreviewSelection(dataChoice, previewImage, null);
1103 components.add(previewSelection);
1104 } catch (Exception e) {
1105 System.out.println("Can't make PreviewSelection: "+e);
1106 e.printStackTrace();
1107 }
1108 }
1109 if (hasChannelSelect) {
1110 try {
1111 components.add(new ChannelSelection(dataChoice));
1112 }
1113 catch (Exception e) {
1114 e.printStackTrace();
1115 }
1116 }
1117 }
1118 }
1119
1120
1121 public static MapProjection getDataProjection(FlatField fltField) throws Exception {
1122 Rectangle2D rect = MultiSpectralData.getLonLatBoundingBox(fltField);
1123 MapProjection mp = new LambertAEA(rect, false);
1124 return mp;
1125 }
1126
1127 public static MapProjection getSwathProjection(FlatField image, float[][] corners) throws VisADException, RemoteException {
1128 MapProjection mp = null;
1129 FunctionType fnc_type = (FunctionType) image.getType();
1130 RealTupleType rtt = fnc_type.getDomain();
1131 CoordinateSystem cs = rtt.getCoordinateSystem();
1132 Gridded2DSet domainSet = (Gridded2DSet) image.getDomainSet();
1133
1134 if (cs instanceof visad.CachingCoordinateSystem) {
1135 cs = ((visad.CachingCoordinateSystem)cs).getCachedCoordinateSystem();
1136 }
1137
1138 if (cs instanceof LongitudeLatitudeCoordinateSystem) {
1139 try {
1140 mp = new LambertAEA(corners);
1141 } catch (Exception e) {
1142 System.out.println(" getDataProjection"+e);
1143 }
1144 return mp;
1145 }
1146 else {
1147 return null;
1148 }
1149 }
1150
1151
1152 public static Linear2DSet makeGrid(MapProjection mp, double res) throws Exception {
1153 Rectangle2D rect = mp.getDefaultMapArea();
1154
1155 int xLen = (int) (rect.getWidth()/res);
1156 int yLen = (int) (rect.getHeight()/res);
1157
1158 RealType xmap = RealType.getRealType("xmap", CommonUnit.meter);
1159 RealType ymap = RealType.getRealType("ymap", CommonUnit.meter);
1160
1161 RealTupleType rtt = new visad.RealTupleType(xmap, ymap, mp, null);
1162
1163 Linear2DSet grid = new Linear2DSet(rtt, rect.getX(), (xLen-1)*res, xLen,
1164 rect.getY(), (yLen-1)*res, yLen);
1165 return grid;
1166 }
1167
1168 public static Linear2DSet makeGrid(MapProjection mp, float[][] corners, float res) throws Exception {
1169 float[][] xy = mp.fromReference(corners);
1170
1171 float min_x = Float.MAX_VALUE;
1172 float min_y = Float.MAX_VALUE;
1173 float max_x = -Float.MAX_VALUE;
1174 float max_y = -Float.MAX_VALUE;
1175
1176 for (int k=0; k<xy[0].length;k++) {
1177 if (xy[0][k] < min_x) min_x = xy[0][k];
1178 if (xy[1][k] < min_y) min_y = xy[1][k];
1179 if (xy[0][k] > max_x) max_x = xy[0][k];
1180 if (xy[1][k] > max_y) max_y = xy[1][k];
1181 }
1182
1183 RealType xmap = RealType.getRealType("xmap", CommonUnit.meter);
1184 RealType ymap = RealType.getRealType("ymap", CommonUnit.meter);
1185
1186 RealTupleType rtt = new visad.RealTupleType(xmap, ymap, mp, null);
1187
1188 min_x = ((int) (min_x/res)) * res;
1189 max_x = ((int) (max_x/res)) * res;
1190 min_y = ((int) (min_y/res)) * res;
1191 max_y = ((int) (max_y/res)) * res;
1192
1193 float del_x = max_x - min_x;
1194 float del_y = max_y - min_y;
1195
1196 int xLen = (int) (del_x/res);
1197 int yLen = (int) (del_y/res);
1198
1199 Linear2DSet grid = new Linear2DSet(rtt, min_x, min_x + (xLen-1)*res, xLen,
1200 min_y, min_y + (yLen-1)*res, yLen);
1201
1202 return grid;
1203 }
1204
1205 public static FlatField swathToGridOld(Linear2DSet grid, FlatField swath) throws Exception {
1206 return swathToGridOld(grid, swath, 0.0);
1207 }
1208
1209 private static int count = 0;
1210
1211 public static FlatField swathToGridOld(Linear2DSet grid, FlatField[] swaths, double mode) throws Exception {
1212 FunctionType ftype = (FunctionType) swaths[0].getType();
1213 visad.Set domSet = swaths[0].getDomainSet();
1214
1215 FlatField swath = new FlatField(new FunctionType(ftype.getDomain(),
1216 new RealTupleType(new RealType[] {RealType.getRealType("redimage_"+count), RealType.getRealType("greenimage_"+count), RealType.getRealType("blueimage_"+count)})), domSet);
1217
1218 swath.setSamples(new float[][]
1219 {swaths[0].getFloats(false)[0], swaths[1].getFloats(false)[0], swaths[2].getFloats(false)[0]});
1220
1221 count++;
1222
1223 return swathToGridOld(grid, swath, mode);
1224 }
1225
1226 public static FlatField swathToGrid(Linear2DSet grid, FlatField[] swaths, double mode) throws Exception {
1227 FunctionType ftype = (FunctionType) swaths[0].getType();
1228 visad.Set domSet = swaths[0].getDomainSet();
1229
1230 FlatField swath = new FlatField(new FunctionType(ftype.getDomain(),
1231 new RealTupleType(new RealType[] {RealType.getRealType("redimage_"+count), RealType.getRealType("greenimage_"+count), RealType.getRealType("blueimage_"+count)})), domSet);
1232
1233 swath.setSamples(new float[][]
1234 {swaths[0].getFloats(false)[0], swaths[1].getFloats(false)[0], swaths[2].getFloats(false)[0]});
1235
1236 count++;
1237
1238 return swathToGrid(grid, swath, mode);
1239 }
1240
1241
1242 public static FlatField swathToGridOld(Linear2DSet grid, FlatField swath, double mode) throws Exception {
1243 FunctionType ftype = (FunctionType) swath.getType();
1244 Linear2DSet swathDomain = (Linear2DSet) swath.getDomainSet();
1245 int[] lens = swathDomain.getLengths();
1246 float[][] swathRange = swath.getFloats(false);
1247 int trackLen = lens[1];
1248 int xtrackLen = lens[0];
1249 int gridLen = grid.getLength();
1250 lens = grid.getLengths();
1251 int gridXLen = lens[0];
1252 int gridYLen = lens[1];
1253
1254 CoordinateSystem swathCoordSys = swathDomain.getCoordinateSystem();
1255 CoordinateSystem gridCoordSys = grid.getCoordinateSystem();
1256
1257 RealTupleType rtt = ((SetType)grid.getType()).getDomain();
1258 FlatField grdFF = new FlatField(new FunctionType(rtt, ftype.getRange()), grid);
1259 float[][] gridRange = grdFF.getFloats(false);
1260 int rngTupDim = gridRange.length;
1261
1262 float[][] swathGridCoord = new float[2][gridLen];
1263 java.util.Arrays.fill(swathGridCoord[0], Float.NaN);
1264
1265 int[] swathIndexAtGrid = null;
1266 if (true) {
1267 swathIndexAtGrid = new int[gridLen];
1268 }
1269
1270 for (int j=0; j < trackLen; j++) {
1271 for (int i=0; i < xtrackLen; i++) {
1272 int swathIdx = j*xtrackLen + i;
1273 float val = swathRange[0][swathIdx];
1274
1275 float[][] swathCoord = swathDomain.indexToValue(new int[] {swathIdx});
1276 float[][] swathEarthCoord = swathCoordSys.toReference(swathCoord);
1277
1278 float[][] gridValue = gridCoordSys.fromReference(swathEarthCoord);
1279 float[][] gridCoord = grid.valueToGrid(gridValue);
1280 float g0 = gridCoord[0][0];
1281 float g1 = gridCoord[1][0];
1282 int grdIdx = (g0 != g0 || g1 != g1) ? -1 : ((int) (g0 + 0.5)) + gridXLen * ((int) (g1 + 0.5));
1283
1284
1285 int m=0;
1286 int n=0;
1287 int k = grdIdx + (m + n*gridXLen);
1288
1289 if ( !(Float.isNaN(val)) && ((k >=0) && (k < gridXLen*gridYLen)) ) { // val or val[rngTupDim] ?
1290 float grdVal = gridRange[0][k];
1291
1292 if (Float.isNaN(grdVal)) {
1293 for (int t=0; t<rngTupDim; t++) {
1294 gridRange[t][k] = swathRange[t][swathIdx];
1295 }
1296 swathGridCoord[0][k] = gridCoord[0][0];
1297 swathGridCoord[1][k] = gridCoord[1][0];
1298 swathIndexAtGrid[k] = swathIdx;
1299 }
1300 else {
1301 /**
1302 // compare current to last distance
1303 float[][] gridLoc = grid.indexToValue(new int[] {k});
1304 gridLoc = grid.valueToGrid(gridLoc);
1305
1306 float del_0 = swathGridCoord[0][k] - gridLoc[0][0];
1307 float del_1 = swathGridCoord[1][k] - gridLoc[1][0];
1308 float last_dst_sqrd = del_0*del_0 + del_1*del_1;
1309
1310 del_0 = gridCoord[0][0] - gridLoc[0][0];
1311 del_1 = gridCoord[1][0] - gridLoc[1][0];
1312 float dst_sqrd = del_0*del_0 + del_1*del_1;
1313
1314 if (dst_sqrd < last_dst_sqrd) {
1315 for (int t=0; t<rngTupDim; t++) {
1316 gridRange[t][k] = val;
1317 }
1318 swathGridCoord[0][k] = gridCoord[0][0];
1319 swathGridCoord[1][k] = gridCoord[1][0];
1320 swathIndexAtGrid[k] = swathIdx;
1321 }
1322 **/
1323 }
1324
1325 }
1326 }
1327 }
1328
1329
1330 // 2nd pass weighted average
1331 float[][] gCoord = new float[2][1];
1332 if (mode > 0.0) {
1333 float weight = 1f;
1334 float[] sumValue = new float[rngTupDim];
1335 for (int j=2; j<gridYLen-2; j++) {
1336 for (int i=2; i<gridXLen-2; i++) {
1337 int grdIdx = i + j*gridXLen;
1338
1339 // dont do weighted average if a nearest neigbhor existed for the grid point
1340 if (mode == 2.0) {
1341 if (!Float.isNaN(gridRange[0][grdIdx])) {
1342 continue;
1343 }
1344 }
1345
1346 gCoord[0][0] = swathGridCoord[0][grdIdx];
1347 gCoord[1][0] = swathGridCoord[1][grdIdx];
1348 float del_0 = gCoord[0][0] - (float) i;
1349 float del_1 = gCoord[1][0] - (float) j;
1350 float dst_sqrd = del_0*del_0 + del_1*del_1;
1351
1352 int num = 0;
1353 float sumWeights = 0f;
1354 for (int t=0; t<rngTupDim; t++) sumValue[t] = 0f;
1355 for (int n = -1; n < 2; n++) {
1356 for (int m = -1; m < 2; m++) {
1357 int k = grdIdx + (m + n*gridXLen);
1358
1359 if ( !Float.isNaN(swathGridCoord[0][k]) ) {
1360
1361 gCoord[0][0] = swathGridCoord[0][k];
1362 gCoord[1][0] = swathGridCoord[1][k];
1363 del_0 = gCoord[0][0] - (float) i;
1364 del_1 = gCoord[1][0] - (float) j;
1365 dst_sqrd = del_0*del_0 + del_1*del_1;
1366 //weight = (float) (1.0/Math.exp((double)(dst_sqrd)*2.75f));
1367 weight = (float) (1.08/Math.exp((double)(dst_sqrd)*5.40f));
1368
1369 for (int t=0; t<rngTupDim; t++) sumValue[t] += swathRange[t][swathIndexAtGrid[k]]*weight;
1370 sumWeights += weight;
1371 num++;
1372 }
1373 }
1374 }
1375 for (int t=0; t<rngTupDim; t++) {
1376 gridRange[t][grdIdx] = sumValue[t]/sumWeights;
1377 }
1378 }
1379 }
1380 }
1381
1382 grdFF.setSamples(gridRange);
1383
1384 return grdFF;
1385 }
1386
1387 public static FlatField swathToGrid(Linear2DSet grid, FlatField swath, double mode) throws Exception {
1388 FunctionType ftype = (FunctionType) swath.getType();
1389 Linear2DSet swathDomain = (Linear2DSet) swath.getDomainSet();
1390 int[] lens = swathDomain.getLengths();
1391 float[][] swathRange = swath.getFloats(false);
1392 int trackLen = lens[1];
1393 int xtrackLen = lens[0];
1394 int gridLen = grid.getLength();
1395 lens = grid.getLengths();
1396 int gridXLen = lens[0];
1397 int gridYLen = lens[1];
1398
1399 CoordinateSystem swathCoordSys = swathDomain.getCoordinateSystem();
1400 CoordinateSystem gridCoordSys = grid.getCoordinateSystem();
1401
1402 RealTupleType rtt = ((SetType)grid.getType()).getDomain();
1403 FlatField grdFF = new FlatField(new FunctionType(rtt, ftype.getRange()), grid);
1404 float[][] gridRange = grdFF.getFloats(false);
1405 int rngTupDim = gridRange.length;
1406
1407 float[][] swathGridCoord = new float[2][gridLen];
1408 byte[] numSwathPoints = new byte[gridLen];
1409
1410 int[] swathIndexAtGrid = null;
1411 if (true) {
1412 swathIndexAtGrid = new int[gridLen];
1413 }
1414
1415 float[][] grdCrd = new float[2][1];
1416 float[][] firstGridRange = new float[rngTupDim][gridLen];
1417 float[] sumRange = new float[rngTupDim];
1418 for (int t=0; t<rngTupDim; t++) {
1419 java.util.Arrays.fill(firstGridRange[t], Float.NaN);
1420 java.util.Arrays.fill(gridRange[t], Float.NaN);
1421 }
1422
1423 float g0_last = Float.NaN;
1424 float g1_last = Float.NaN;
1425 float xt_dist = Float.NaN;
1426
1427 for (int j=0; j < trackLen; j++) {
1428 for (int i=0; i < xtrackLen; i++) {
1429 int swathIdx = j*xtrackLen + i;
1430 float val = swathRange[0][swathIdx];
1431
1432 float[][] swathCoord = swathDomain.indexToValue(new int[] {swathIdx});
1433 float[][] swathEarthCoord = swathCoordSys.toReference(swathCoord);
1434
1435 float[][] gridValue = gridCoordSys.fromReference(swathEarthCoord);
1436 float[][] gridCoord = grid.valueToGrid(gridValue);
1437 float g0 = gridCoord[0][0];
1438 float g1 = gridCoord[1][0];
1439 int grdIdx = (g0 != g0 || g1 != g1) ? -1 : ((int) (g0 + 0.5)) + gridXLen * ((int) (g1 + 0.5));
1440
1441
1442 // tooclose logic
1443 if (i >= 1) {
1444 float diff_0 = g0 - g0_last;
1445 float diff_1 = g1 - g1_last;
1446 xt_dist = (diff_0*diff_0) + (diff_1*diff_1);
1447 }
1448 g0_last = g0;
1449 g1_last = g1;
1450
1451 boolean tooclose = false;
1452 float closest = Float.MAX_VALUE;
1453 for (int n = -2; n < 3; n++) {
1454 for (int m = -2; m < 3; m++) {
1455 int k = grdIdx + (m + n*gridXLen);
1456 if (k >=0 && k < gridXLen*gridYLen) {
1457 if ( !Float.isNaN(swathGridCoord[0][k]) ) {
1458 float del_0 = g0 - swathGridCoord[0][k];
1459 float del_1 = g1 - swathGridCoord[1][k];
1460 float dst = del_0*del_0 + del_1*del_1;
1461 if (dst < closest) closest = dst;
1462 }
1463 }
1464 }
1465 }
1466 if (Math.sqrt((double)closest) < 0.86*Math.sqrt((double)xt_dist)) tooclose = true;
1467
1468
1469 int m=0;
1470 int n=0;
1471 int k = grdIdx + (m + n*gridXLen);
1472
1473 if ( !(Float.isNaN(val)) && ((k >=0) && (k < gridXLen*gridYLen)) && !tooclose) { // val or val[rngTupDim] ?
1474 float grdVal = firstGridRange[0][k];
1475
1476 if (Float.isNaN(grdVal)) {
1477 for (int t=0; t<rngTupDim; t++) {
1478 firstGridRange[t][k] = swathRange[t][swathIdx];
1479 }
1480 swathGridCoord[0][k] = g0;
1481 swathGridCoord[1][k] = g1;
1482 swathIndexAtGrid[k] = swathIdx;
1483 }
1484 }
1485
1486 }
1487 }
1488
1489 float[][] gCoord = new float[2][1];
1490 if (mode > 0.0) { // 2nd pass weighted average
1491 float sigma = 0.6f;
1492 float weight = 1f;
1493 float[] sumValue = new float[rngTupDim];
1494
1495 float[][] dst_sqrd = new float[5][5];
1496 for (int n=-2; n<3; n++) {
1497 for (int m=-2; m<3; m++) {
1498 float del_0 = m;
1499 float del_1 = n;
1500 dst_sqrd[n+2][m+2] = (float) Math.sqrt((double)(del_0*del_0 + del_1*del_1));
1501 }
1502 }
1503
1504
1505 for (int j=2; j<gridYLen-2; j++) {
1506 for (int i=2; i<gridXLen-2; i++) {
1507 int grdIdx = i + j*gridXLen;
1508
1509 // don't do weighted average if a nearest neigbhor existed for the grid point
1510 if (mode == 2.0) {
1511 if (!Float.isNaN(firstGridRange[0][grdIdx])) {
1512 for (int t=0; t<rngTupDim; t++) {
1513 gridRange[t][grdIdx] = firstGridRange[t][grdIdx];
1514 }
1515 continue;
1516 }
1517 }
1518
1519 int num = 0;
1520 float mag = 1f;
1521 float sumWeights = 0f;
1522 float[] dists = new float[25];
1523 float[][] values = new float[rngTupDim][25];
1524 for (int t=0; t<rngTupDim; t++) {
1525 sumValue[t] = 0f;
1526 }
1527
1528 for (int n = -1; n < 2; n++) {
1529 for (int m = -1; m < 2; m++) {
1530 int k = grdIdx + (m + n*gridXLen);
1531 if ( !Float.isNaN(firstGridRange[0][k]) ) {
1532 dists[num] = dst_sqrd[n+2][m+2];
1533 for (int t=0; t<rngTupDim; t++) {
1534 values[t][num] = firstGridRange[t][k];
1535 }
1536 num++;
1537 }
1538 }
1539 }
1540
1541 if (num < 5) {
1542
1543 for (int n = -2; n < 3; n++) {
1544 for (int m = -2; m < 3; m++) {
1545 if ( (n == -2 || n == 2) || ((n <= 1 && n >= -1) && (m==-2 || m==2)) ) { // don't repeat inner box
1546 int k = grdIdx + (m + n*gridXLen);
1547 if ( !Float.isNaN(firstGridRange[0][k]) ) {
1548 dists[num] = dst_sqrd[n+2][m+2];
1549 for (int t=0; t<rngTupDim; t++) {
1550 values[t][num] = firstGridRange[t][k];
1551 }
1552 num++;
1553 }
1554 }
1555 }
1556 }
1557
1558 if (num > 14 && num <= 21) sigma = 0.46f;
1559 if (num > 10 && num <= 14) sigma = 0.50f;
1560 if (num > 7 && num <= 10) sigma = 0.58f;
1561 if (num > 4 && num <= 7) sigma = 0.72f;
1562 if (num < 4) sigma = 1.44f;
1563 }
1564 else { // inner box only
1565 sigma = 0.40f;
1566 }
1567
1568 for (int q=0; q<num; q++) {
1569 float dstsqrd = dists[q];
1570 weight = (float) (mag/Math.exp((double)(dstsqrd/(sigma))));
1571 for (int t=0; t<rngTupDim; t++) {
1572 sumValue[t] += values[t][q]*weight;
1573 }
1574 sumWeights += weight;
1575 }
1576
1577 for (int t=0; t<rngTupDim; t++) {
1578 gridRange[t][grdIdx] = sumValue[t]/sumWeights;
1579 }
1580
1581 }
1582 }
1583 grdFF.setSamples(gridRange);
1584 }
1585 else { // no averaging
1586 grdFF.setSamples(firstGridRange);
1587 }
1588
1589 return grdFF;
1590 }
1591
1592 public static boolean validLonLat(float[][] lonlat) {
1593 float lon = lonlat[0][0];
1594 float lat = lonlat[1][0];
1595 return ((lon >= -180f && lon <= 360f) && (lat >= -90f && lat <= 90f));
1596 }
1597
1598 }
1599
1600
1601 class ChannelSelection extends DataSelectionComponent {
1602
1603 DataChoice dataChoice;
1604 MultiSpectralDisplay display;
1605
1606 ChannelSelection(DataChoice dataChoice) throws Exception {
1607 super("Channels");
1608 this.dataChoice = dataChoice;
1609 display = new MultiSpectralDisplay((DirectDataChoice)dataChoice);
1610 display.showChannelSelector();
1611 }
1612
1613 protected JComponent doMakeContents() {
1614 try {
1615 JPanel panel = new JPanel(new BorderLayout());
1616 panel.add("Center", display.getDisplayComponent());
1617 if (display.getBandSelectComboBox() != null) {
1618 JPanel bandPanel = new JPanel(new FlowLayout());
1619 bandPanel.add(new JLabel("Band: "));
1620 bandPanel.add(display.getBandSelectComboBox());
1621 panel.add("South", bandPanel);
1622 }
1623 return panel;
1624 }
1625 catch (Exception e) {
1626 System.out.println(e);
1627 }
1628 return null;
1629 }
1630
1631 public void applyToDataSelection(DataSelection dataSelection) {
1632 try {
1633 dataSelection.putProperty(Constants.PROP_CHAN, display.getWaveNumber());
1634 dataSelection.putProperty(SpectrumAdapter.channelIndex_name, display.getChannelIndex());
1635 } catch (Exception e) {
1636 e.printStackTrace();
1637 }
1638 }
1639 }
1640
1641 class ImageChannelSelection extends DataSelectionComponent {
1642 PreviewSelection previewSelection;
1643 ChannelSelection channelSelection;
1644
1645 ImageChannelSelection(PreviewSelection previewSelection, ChannelSelection channelSelection) {
1646 super("MultiSpectral");
1647 this.previewSelection = previewSelection;
1648 this.channelSelection = channelSelection;
1649 }
1650
1651 protected JComponent doMakeContents() {
1652 JSplitPane splitpane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
1653 splitpane.add(previewSelection.doMakeContents());
1654 splitpane.add(channelSelection.doMakeContents());
1655 splitpane.setContinuousLayout(true);
1656 splitpane.setOneTouchExpandable(true);
1657 splitpane.setResizeWeight(1);
1658 splitpane.setDividerSize(12);
1659 return splitpane;
1660 }
1661
1662 public void applyToDataSelection(DataSelection dataSelection) {
1663 previewSelection.applyToDataSelection(dataSelection);
1664 channelSelection.applyToDataSelection(dataSelection);
1665 }
1666
1667
1668 }