001 /*
002 * $Id: MultiSpectralDataSource.java,v 1.44 2012/04/10 18:13:17 rink Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2012
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 *
012 * All Rights Reserved
013 *
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.
016 *
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 *
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
025 * GNU Lesser Public License for more details.
026 *
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program. If not, see http://www.gnu.org/licenses.
029 */
030
031 package edu.wisc.ssec.mcidasv.data.hydra;
032
033 import java.awt.BorderLayout;
034 import java.awt.FlowLayout;
035 import java.awt.geom.Rectangle2D;
036
037 import java.io.File;
038
039 import java.rmi.RemoteException;
040
041 import java.util.ArrayList;
042 import java.util.Collections;
043 import java.util.Enumeration;
044 import java.util.HashMap;
045 import java.util.Hashtable;
046 import java.util.List;
047
048 import javax.swing.JComponent;
049 import javax.swing.JLabel;
050 import javax.swing.JPanel;
051 import javax.swing.JSplitPane;
052
053 import org.slf4j.Logger;
054 import org.slf4j.LoggerFactory;
055
056 import ucar.unidata.data.DataCategory;
057 import ucar.unidata.data.DataChoice;
058 import ucar.unidata.data.DataSelection;
059 import ucar.unidata.data.DataSelectionComponent;
060 import ucar.unidata.data.DataSourceDescriptor;
061 import ucar.unidata.data.DirectDataChoice;
062 import ucar.unidata.data.GeoLocationInfo;
063 import ucar.unidata.data.GeoSelection;
064 import ucar.unidata.util.Misc;
065
066 import visad.Data;
067 import visad.FlatField;
068 import visad.VisADException;
069 import visad.FunctionType;
070 import visad.RealType;
071 import visad.RealTupleType;
072 import visad.Linear2DSet;
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 else {
183 if (sources.size() > 1) {
184 for (int i = 0; i < sources.size(); i++) {
185 String s = (String) sources.get(i);
186 ncdfal.add(new NetCDFFile(s));
187 }
188 doAggregation = true;
189 } else {
190 reader = new NetCDFFile(filename);
191 }
192 }
193 }
194 catch (Exception e) {
195 e.printStackTrace();
196 System.out.println("cannot create NetCDF reader for file: "+filename);
197 }
198
199 Hashtable<String, String[]> properties = new Hashtable<String, String[]>();
200
201
202 multiSpectData_s.clear();
203
204 if ( name.startsWith("AIRS")) {
205 HashMap table = SpectrumAdapter.getEmptyMetadataTable();
206 table.put(SpectrumAdapter.array_name, "L1B_AIRS_Science/Data Fields/radiances");
207 table.put(SpectrumAdapter.range_name, "radiances");
208 table.put(SpectrumAdapter.channelIndex_name, "Channel");
209 table.put(SpectrumAdapter.ancillary_file_name, "/edu/wisc/ssec/mcidasv/data/hydra/resources/airs/L2.chan_prop.2003.11.19.v6.6.9.anc");
210 table.put(SpectrumAdapter.x_dim_name, "GeoXTrack");
211 table.put(SpectrumAdapter.y_dim_name, "GeoTrack");
212 spectrumAdapter = new AIRS_L1B_Spectrum(reader, table);
213
214 table = SwathAdapter.getEmptyMetadataTable();
215 table.put("array_name", "L1B_AIRS_Science/Data Fields/radiances");
216 table.put(SwathAdapter.range_name, "radiances");
217 table.put("lon_array_name", "L1B_AIRS_Science/Geolocation Fields/Longitude");
218 table.put("lat_array_name", "L1B_AIRS_Science/Geolocation Fields/Latitude");
219 table.put("XTrack", "GeoXTrack");
220 table.put("Track", "GeoTrack");
221 table.put("geo_Track", "GeoTrack");
222 table.put("geo_XTrack", "GeoXTrack");
223 table.put(SpectrumAdapter.channelIndex_name, "Channel"); //- think about this?
224
225 swathAdapter = new SwathAdapter(reader, table);
226 HashMap subset = swathAdapter.getDefaultSubset();
227 subset.put(SpectrumAdapter.channelIndex_name, new double[] {793,793,1});
228 defaultSubset = subset;
229 multiSpectData = new MultiSpectralData(swathAdapter, spectrumAdapter);
230 DataCategory.createCategory("MultiSpectral");
231 categories = DataCategory.parseCategories("MultiSpectral;MultiSpectral;IMAGE");
232 hasChannelSelect = true;
233 multiSpectData.init_wavenumber = 919.5f;
234 multiSpectData_s.add(multiSpectData);
235 }
236 else if ( name.startsWith("IASI_xxx_1C") && name.endsWith("h5")) {
237 HashMap table = SpectrumAdapter.getEmptyMetadataTable();
238 table.put(SpectrumAdapter.array_name, "U-MARF/EPS/IASI_xxx_1C/DATA/SPECT_DATA");
239 table.put(SpectrumAdapter.channelIndex_name, "dim2");
240 table.put(SpectrumAdapter.x_dim_name, "dim1");
241 table.put(SpectrumAdapter.y_dim_name, "dim0");
242 spectrumAdapter = new IASI_L1C_Spectrum(reader, table);
243
244 table = SwathAdapter.getEmptyMetadataTable();
245 table.put("array_name", "U-MARF/EPS/IASI_xxx_1C/DATA/SPECT_DATA");
246 table.put("lon_array_name", "U-MARF/EPS/IASI_xxx_1C/DATA/SPECT_LON_ARRAY");
247 table.put("lat_array_name", "U-MARF/EPS/IASI_xxx_1C/DATA/SPECT_LAT_ARRAY");
248 table.put("XTrack", "dim1");
249 table.put("Track", "dim0");
250 table.put("geo_XTrack", "dim1");
251 table.put("geo_Track", "dim0");
252 table.put("product_name", "IASI_L1C_xxx");
253 table.put(SpectrumAdapter.channelIndex_name, "dim2");
254 swathAdapter = new IASI_L1C_SwathAdapter(reader, table);
255 HashMap subset = swathAdapter.getDefaultSubset();
256 subset.put(SpectrumAdapter.channelIndex_name, new double[] {793,793,1});
257 defaultSubset = subset;
258 multiSpectData = new MultiSpectralData(swathAdapter, spectrumAdapter);
259 DataCategory.createCategory("MultiSpectral");
260 categories = DataCategory.parseCategories("MultiSpectral;MultiSpectral;");
261 multiSpectData.init_wavenumber = 919.5f;
262 hasChannelSelect = true;
263 multiSpectData_s.add(multiSpectData);
264 }
265 else if ( name.startsWith("IASI")) {
266 HashMap table = SpectrumAdapter.getEmptyMetadataTable();
267 table.put(SpectrumAdapter.array_name, "observations");
268 table.put(SpectrumAdapter.channelIndex_name, "obsChannelIndex");
269 table.put(SpectrumAdapter.x_dim_name, "obsElement");
270 table.put(SpectrumAdapter.y_dim_name, "obsLine");
271 table.put(SpectrumAdapter.channels_name, "observationChannels");
272 spectrumAdapter = new SpectrumAdapter(reader, table);
273
274 table = SwathAdapter.getEmptyMetadataTable();
275 table.put("array_name", "observations");
276 table.put("lon_array_name", "obsLongitude");
277 table.put("lat_array_name", "obsLatitude");
278 table.put("XTrack", "obsElement");
279 table.put("Track", "obsLine");
280 table.put("geo_XTrack", "obsElement");
281 table.put("geo_Track", "obsLine");
282 table.put(SpectrumAdapter.channelIndex_name, "obsChannelIndex"); //- think about this?
283 swathAdapter = new SwathAdapter(reader, table);
284 HashMap subset = swathAdapter.getDefaultSubset();
285 subset.put(SpectrumAdapter.channelIndex_name, new double[] {793,793,1});
286 defaultSubset = subset;
287 multiSpectData = new MultiSpectralData(swathAdapter, spectrumAdapter);
288 DataCategory.createCategory("MultiSpectral");
289 categories = DataCategory.parseCategories("MultiSpectral;MultiSpectral;");
290 multiSpectData.init_wavenumber = 919.5f;
291 multiSpectData_s.add(multiSpectData);
292 hasChannelSelect = true;
293 }
294 else if (name.startsWith("MOD021KM") || name.startsWith("MYD021KM") ||
295 (name.startsWith("a1") && (name.indexOf("1000m") > 0)) ||
296 (name.startsWith("t1") && (name.indexOf("1000m") > 0)) ) {
297 HashMap table = SwathAdapter.getEmptyMetadataTable();
298 table.put("array_name", "MODIS_SWATH_Type_L1B/Data Fields/EV_1KM_Emissive");
299 table.put("lon_array_name", "MODIS_SWATH_Type_L1B/Geolocation Fields/Longitude");
300 table.put("lat_array_name", "MODIS_SWATH_Type_L1B/Geolocation Fields/Latitude");
301 table.put("XTrack", "Max_EV_frames");
302 table.put("Track", "10*nscans");
303 table.put("geo_Track", "2*nscans");
304 table.put("geo_XTrack", "1KM_geo_dim");
305 table.put("scale_name", "radiance_scales");
306 table.put("offset_name", "radiance_offsets");
307 table.put("fill_value_name", "_FillValue");
308 table.put("range_name", "Emissive_Bands");
309 table.put(SpectrumAdapter.channelIndex_name, "Band_1KM_Emissive");
310 table.put(SwathAdapter.geo_track_offset_name, Double.toString(2.0));
311 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(2.0));
312 table.put(SwathAdapter.geo_track_skip_name, Double.toString(5.0));
313 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(5.0));
314 table.put(SwathAdapter.multiScaleDimensionIndex, Integer.toString(0));
315
316 // initialize the aggregation reader object
317 logger.debug("Trying to create MODIS 1K GranuleAggregation reader...");
318 if (doAggregation) {
319 try {
320 reader = new GranuleAggregation(ncdfal, 2030, "10*nscans", "Max_EV_frames");
321 } catch (Exception e) {
322 throw new VisADException("Unable to initialize aggregation reader");
323 }
324 }
325
326 swathAdapter = new SwathAdapter(reader, table);
327 swathAdapter.setDefaultStride(10);
328 logger.debug("Trying to create MODIS 1K SwathAdapter...");
329
330 HashMap subset = swathAdapter.getDefaultSubset();
331
332 table = SpectrumAdapter.getEmptyMetadataTable();
333 table.put(SpectrumAdapter.array_name, "MODIS_SWATH_Type_L1B/Data Fields/EV_1KM_Emissive");
334 table.put(SpectrumAdapter.channelIndex_name, "Band_1KM_Emissive");
335 table.put(SpectrumAdapter.x_dim_name, "Max_EV_frames");
336 table.put(SpectrumAdapter.y_dim_name, "10*nscans");
337 table.put(SpectrumAdapter.channelValues, new float[]
338 {3.799f,3.992f,3.968f,4.070f,4.476f,4.549f,6.784f,7.345f,8.503f,
339 9.700f,11.000f,12.005f,13.351f,13.717f,13.908f,14.205f});
340 table.put(SpectrumAdapter.bandNames, new String[]
341 {"20","21","22","23","24","25","27","28","29",
342 "30","31","32","33","34","35","36"});
343 table.put(SpectrumAdapter.channelType, "wavelength");
344 SpectrumAdapter spectrumAdapter = new SpectrumAdapter(reader, table);
345
346 multiSpectData = new MultiSpectralData(swathAdapter, spectrumAdapter, "MODIS", "Aqua");
347 multiSpectData.setInitialWavenumber(11.0f);
348 defaultSubset = multiSpectData.getDefaultSubset();
349
350 previewImage = multiSpectData.getImage(defaultSubset);
351 multiSpectData_s.add(multiSpectData);
352
353 //--- aggregate reflective bands
354 table = SwathAdapter.getEmptyMetadataTable();
355
356 table.put("array_name", "MODIS_SWATH_Type_L1B/Data Fields/EV_1KM_RefSB");
357 table.put("lon_array_name", "MODIS_SWATH_Type_L1B/Geolocation Fields/Longitude");
358 table.put("lat_array_name", "MODIS_SWATH_Type_L1B/Geolocation Fields/Latitude");
359 table.put("XTrack", "Max_EV_frames");
360 table.put("Track", "10*nscans");
361 table.put("geo_Track", "2*nscans");
362 table.put("geo_XTrack", "1KM_geo_dim");
363 table.put("scale_name", "reflectance_scales");
364 table.put("offset_name", "reflectance_offsets");
365 table.put("fill_value_name", "_FillValue");
366 table.put("range_name", "EV_1KM_RefSB");
367 table.put(SpectrumAdapter.channelIndex_name, "Band_1KM_RefSB");
368
369 table.put(SwathAdapter.geo_track_offset_name, Double.toString(2.0));
370 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(2.0));
371 table.put(SwathAdapter.geo_track_skip_name, Double.toString(5.0));
372 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(5.0));
373 table.put(SwathAdapter.multiScaleDimensionIndex, Integer.toString(0));
374
375 SwathAdapter sadapt0 = new SwathAdapter(reader, table);
376 sadapt0.setDefaultStride(10);
377
378 table = SpectrumAdapter.getEmptyMetadataTable();
379 table.put(SpectrumAdapter.array_name, "MODIS_SWATH_Type_L1B/Data Fields/EV_1KM_RefSB");
380 table.put(SpectrumAdapter.channelIndex_name, "Band_1KM_RefSB");
381 table.put(SpectrumAdapter.x_dim_name, "Max_EV_frames");
382 table.put(SpectrumAdapter.y_dim_name, "10*nscans");
383 table.put(SpectrumAdapter.channelValues, new float[]
384 {.412f,.450f,.487f,.531f,.551f,.666f,.668f,.677f,.679f,.748f,
385 .869f,.905f,.936f,.940f,1.375f});
386 table.put(SpectrumAdapter.bandNames, new String[]
387 {"8","9","10","11","12","13lo","13hi","14lo","14hi","15",
388 "16","17","18","19","26"});
389 table.put(SpectrumAdapter.channelType, "wavelength");
390 SpectrumAdapter specadap0 = new SpectrumAdapter(reader, table);
391 MultiSpectralData multispec0 = new MultiSpectralData(sadapt0, specadap0, "Reflectance", "Reflectance", "MODIS", "Aqua");
392
393 DataCategory.createCategory("MultiSpectral");
394 categories = DataCategory.parseCategories("MultiSpectral;MultiSpectral;IMAGE");
395 hasImagePreview = true;
396 hasChannelSelect = true;
397
398 table = SwathAdapter.getEmptyMetadataTable();
399
400 table.put("array_name", "MODIS_SWATH_Type_L1B/Data Fields/EV_250_Aggr1km_RefSB");
401 table.put("lon_array_name", "MODIS_SWATH_Type_L1B/Geolocation Fields/Longitude");
402 table.put("lat_array_name", "MODIS_SWATH_Type_L1B/Geolocation Fields/Latitude");
403 table.put("XTrack", "Max_EV_frames");
404 table.put("Track", "10*nscans");
405 table.put("geo_Track", "2*nscans");
406 table.put("geo_XTrack", "1KM_geo_dim");
407 table.put("scale_name", "reflectance_scales");
408 table.put("offset_name", "reflectance_offsets");
409 table.put("fill_value_name", "_FillValue");
410 table.put("range_name", "Reflective_Bands");
411 table.put(SpectrumAdapter.channelIndex_name, "Band_250M");
412
413 table.put(SwathAdapter.geo_track_offset_name, Double.toString(2.0));
414 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(2.0));
415 table.put(SwathAdapter.geo_track_skip_name, Double.toString(5.0));
416 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(5.0));
417 table.put(SwathAdapter.multiScaleDimensionIndex, Integer.toString(0));
418
419 SwathAdapter sadapt1 = new SwathAdapter(reader, table);
420
421 table = SpectrumAdapter.getEmptyMetadataTable();
422 table.put(SpectrumAdapter.array_name, "MODIS_SWATH_Type_L1B/Data Fields/EV_250_Aggr1km_RefSB");
423 table.put(SpectrumAdapter.channelIndex_name, "Band_250M");
424 table.put(SpectrumAdapter.x_dim_name, "Max_EV_frames");
425 table.put(SpectrumAdapter.y_dim_name, "10*nscans");
426 table.put(SpectrumAdapter.channelValues, new float[]
427 {.650f,.855f});
428 table.put(SpectrumAdapter.bandNames, new String[]
429 {"1","2"});
430 table.put(SpectrumAdapter.channelType, "wavelength");
431 SpectrumAdapter specadap1 = new SpectrumAdapter(reader, table);
432 MultiSpectralData multispec1 = new MultiSpectralData(sadapt1, specadap1, "Reflectance", "Reflectance", "MODIS", "Aqua");
433
434 table = SwathAdapter.getEmptyMetadataTable();
435
436 table.put("array_name", "MODIS_SWATH_Type_L1B/Data Fields/EV_500_Aggr1km_RefSB");
437 table.put("lon_array_name", "MODIS_SWATH_Type_L1B/Geolocation Fields/Longitude");
438 table.put("lat_array_name", "MODIS_SWATH_Type_L1B/Geolocation Fields/Latitude");
439 table.put("XTrack", "Max_EV_frames");
440 table.put("Track", "10*nscans");
441 table.put("geo_Track", "2*nscans");
442 table.put("geo_XTrack", "1KM_geo_dim");
443 table.put("scale_name", "reflectance_scales");
444 table.put("offset_name", "reflectance_offsets");
445 table.put("fill_value_name", "_FillValue");
446 table.put("range_name", "EV_500_Aggr1km_RefSB");
447 table.put(SpectrumAdapter.channelIndex_name, "Band_500M");
448 table.put(SwathAdapter.geo_track_offset_name, Double.toString(2.0));
449 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(2.0));
450 table.put(SwathAdapter.geo_track_skip_name, Double.toString(5.0));
451 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(5.0));
452 table.put(SwathAdapter.multiScaleDimensionIndex, Integer.toString(0));
453
454
455 SwathAdapter sadapt2 = new SwathAdapter(reader, table);
456
457
458 table = SpectrumAdapter.getEmptyMetadataTable();
459 table.put(SpectrumAdapter.array_name, "MODIS_SWATH_Type_L1B/Data Fields/EV_500_Aggr1km_RefSB");
460 table.put(SpectrumAdapter.channelIndex_name, "Band_500M");
461 table.put(SpectrumAdapter.x_dim_name, "Max_EV_frames");
462 table.put(SpectrumAdapter.y_dim_name, "10*nscans");
463 table.put(SpectrumAdapter.channelValues, new float[]
464 {.470f,.555f,1.240f,1.638f,2.130f});
465 table.put(SpectrumAdapter.bandNames, new String[]
466 {"3","4","5","6","7"});
467 table.put(SpectrumAdapter.channelType, "wavelength");
468 SpectrumAdapter specadap2 = new SpectrumAdapter(reader, table);
469 MultiSpectralData multispec2 = new MultiSpectralData(sadapt2, specadap2, "Reflectance", "Reflectance", "MODIS", "Aqua");
470
471 MultiSpectralAggr aggr = new MultiSpectralAggr(new MultiSpectralData[] {multispec1, multispec2, multispec0});
472 aggr.setInitialWavenumber(0.650f);
473 aggr.setDataRange(new float[] {0f, 0.8f});
474 multiSpectData_s.add(aggr);
475 }
476 else if (name.startsWith("MOD02QKM") || name.startsWith("MYD02QKM") ||
477 (name.startsWith("a1") && (name.indexOf("250m") > 0)) ||
478 (name.startsWith("t1") && (name.indexOf("250m") > 0)) ) {
479 HashMap table = SwathAdapter.getEmptyMetadataTable();
480 table.put("array_name", "MODIS_SWATH_Type_L1B/Data Fields/EV_250_RefSB");
481 table.put("lon_array_name", "MODIS_SWATH_Type_L1B/Geolocation Fields/Longitude");
482 table.put("lat_array_name", "MODIS_SWATH_Type_L1B/Geolocation Fields/Latitude");
483 table.put("XTrack", "4*Max_EV_frames");
484 table.put("Track", "40*nscans");
485 table.put("geo_Track", "10*nscans");
486 table.put("geo_XTrack", "Max_EV_frames");
487 table.put("scale_name", "reflectance_scales");
488 table.put("offset_name", "reflectance_offsets");
489 table.put("fill_value_name", "_FillValue");
490 table.put("range_name", "Reflective_Bands");
491 table.put(SpectrumAdapter.channelIndex_name, "Band_250M");
492 table.put(SwathAdapter.geo_track_offset_name, Double.toString(0.0));
493 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(0.0));
494 table.put(SwathAdapter.geo_track_skip_name, Double.toString(4.0));
495 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(4.0));
496 table.put(SwathAdapter.multiScaleDimensionIndex, Integer.toString(0));
497
498 swathAdapter = new SwathAdapter(reader, table);
499 swathAdapter.setDefaultStride(40);
500
501 table = SpectrumAdapter.getEmptyMetadataTable();
502 table.put(SpectrumAdapter.array_name, "MODIS_SWATH_Type_L1B/Data Fields/EV_250_RefSB");
503 table.put(SpectrumAdapter.channelIndex_name, "Band_250M");
504 table.put(SpectrumAdapter.x_dim_name, "4*Max_EV_frames");
505 table.put(SpectrumAdapter.y_dim_name, "40*nscans");
506 table.put(SpectrumAdapter.channelValues, new float[]
507 {.650f,.855f});
508 table.put(SpectrumAdapter.bandNames, new String[]
509 {"1","2"});
510 table.put(SpectrumAdapter.channelType, "wavelength");
511 SpectrumAdapter spectrumAdapter = new SpectrumAdapter(reader, table);
512
513 multiSpectData = new MultiSpectralData(swathAdapter, spectrumAdapter, "Reflectance", "Reflectance", "MODIS", "Aqua");
514 multiSpectData.setInitialWavenumber(0.650f);
515 multiSpectData.setDataRange(new float[] {0f, 0.8f});
516 defaultSubset = multiSpectData.getDefaultSubset();
517 previewImage = multiSpectData.getImage(defaultSubset);
518 multiSpectData_s.add(multiSpectData);
519
520 DataCategory.createCategory("MultiSpectral");
521 categories = DataCategory.parseCategories("MultiSpectral;MultiSpectral;IMAGE");
522 hasImagePreview = true;
523 hasChannelSelect = true;
524
525 multiSpectData_s.add(null);
526 }
527 else if (name.startsWith("MOD02HKM") || name.startsWith("MYD02HKM") ||
528 (name.startsWith("a1") && (name.indexOf("500m") > 0)) ||
529 (name.startsWith("t1") && (name.indexOf("500m") > 0)) ) {
530 HashMap table = SwathAdapter.getEmptyMetadataTable();
531 table.put("array_name", "MODIS_SWATH_Type_L1B/Data Fields/EV_250_Aggr500_RefSB");
532 table.put("lon_array_name", "MODIS_SWATH_Type_L1B/Geolocation Fields/Longitude");
533 table.put("lat_array_name", "MODIS_SWATH_Type_L1B/Geolocation Fields/Latitude");
534 table.put("XTrack", "2*Max_EV_frames");
535 table.put("Track", "20*nscans");
536 table.put("geo_Track", "10*nscans");
537 table.put("geo_XTrack", "Max_EV_frames");
538 table.put("scale_name", "reflectance_scales");
539 table.put("offset_name", "reflectance_offsets");
540 table.put("fill_value_name", "_FillValue");
541 table.put("range_name", "Reflective_Bands");
542 table.put(SpectrumAdapter.channelIndex_name, "Band_250M");
543 table.put(SwathAdapter.geo_track_offset_name, Double.toString(0.0));
544 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(0.0));
545 table.put(SwathAdapter.geo_track_skip_name, Double.toString(2.0));
546 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(2.0));
547 table.put(SwathAdapter.multiScaleDimensionIndex, Integer.toString(0));
548
549 SwathAdapter swathAdapter0 = new SwathAdapter(reader, table);
550 swathAdapter0.setDefaultStride(20);
551
552 table = SpectrumAdapter.getEmptyMetadataTable();
553 table.put(SpectrumAdapter.array_name, "MODIS_SWATH_Type_L1B/Data Fields/EV_250_Aggr500_RefSB");
554 table.put(SpectrumAdapter.channelIndex_name, "Band_250M");
555 table.put(SpectrumAdapter.x_dim_name, "2*Max_EV_frames");
556 table.put(SpectrumAdapter.y_dim_name, "20*nscans");
557 table.put(SpectrumAdapter.channelValues, new float[]
558 {.650f,.855f});
559 table.put(SpectrumAdapter.bandNames, new String[]
560 {"1","2"});
561 table.put(SpectrumAdapter.channelType, "wavelength");
562 SpectrumAdapter spectrumAdapter0 = new SpectrumAdapter(reader, table);
563
564 MultiSpectralData multiSpectData0 = new MultiSpectralData(swathAdapter0, spectrumAdapter0, "Reflectance", "Reflectance", "MODIS", "Aqua");
565
566 table = SwathAdapter.getEmptyMetadataTable();
567 table.put("array_name", "MODIS_SWATH_Type_L1B/Data Fields/EV_500_RefSB");
568 table.put("lon_array_name", "MODIS_SWATH_Type_L1B/Geolocation Fields/Longitude");
569 table.put("lat_array_name", "MODIS_SWATH_Type_L1B/Geolocation Fields/Latitude");
570 table.put("XTrack", "2*Max_EV_frames");
571 table.put("Track", "20*nscans");
572 table.put("geo_Track", "10*nscans");
573 table.put("geo_XTrack", "Max_EV_frames");
574 table.put("scale_name", "reflectance_scales");
575 table.put("offset_name", "reflectance_offsets");
576 table.put("fill_value_name", "_FillValue");
577 table.put("range_name", "Reflective_Bands");
578 table.put(SpectrumAdapter.channelIndex_name, "Band_500M");
579 table.put(SwathAdapter.geo_track_offset_name, Double.toString(0.0));
580 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(0.0));
581 table.put(SwathAdapter.geo_track_skip_name, Double.toString(2.0));
582 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(2.0));
583 table.put(SwathAdapter.multiScaleDimensionIndex, Integer.toString(0));
584
585 SwathAdapter swathAdapter1 = new SwathAdapter(reader, table);
586 swathAdapter1.setDefaultStride(20);
587
588 table = SpectrumAdapter.getEmptyMetadataTable();
589 table.put(SpectrumAdapter.array_name, "MODIS_SWATH_Type_L1B/Data Fields/EV_500_RefSB");
590 table.put(SpectrumAdapter.channelIndex_name, "Band_500M");
591 table.put(SpectrumAdapter.x_dim_name, "2*Max_EV_frames");
592 table.put(SpectrumAdapter.y_dim_name, "20*nscans");
593 table.put(SpectrumAdapter.channelValues, new float[]
594 {.470f,.555f,1.240f,1.638f,2.130f});
595 table.put(SpectrumAdapter.bandNames, new String[]
596 {"3","4","5","6","7"});
597 table.put(SpectrumAdapter.channelType, "wavelength");
598 SpectrumAdapter spectrumAdapter1 = new SpectrumAdapter(reader, table);
599
600 MultiSpectralData multiSpectData1 = new MultiSpectralData(swathAdapter1, spectrumAdapter1, "Reflectance", "Reflectance", "MODIS", "Aqua");
601
602 MultiSpectralAggr aggr =
603 new MultiSpectralAggr(new MultiSpectralData[] {multiSpectData0, multiSpectData1});
604 aggr.setInitialWavenumber(0.650f);
605 aggr.setDataRange(new float[] {0f, 0.8f});
606 multiSpectData_s.add(aggr);
607 multiSpectData = aggr;
608 defaultSubset = aggr.getDefaultSubset();
609 previewImage = aggr.getImage(defaultSubset);
610
611 DataCategory.createCategory("MultiSpectral");
612 categories = DataCategory.parseCategories("MultiSpectral;MultiSpectral;IMAGE");
613 hasImagePreview = true;
614 hasChannelSelect = true;
615
616 multiSpectData_s.add(null);
617 }
618 else if (name.startsWith("NSS")) {
619 HashMap swthTable = SwathAdapter.getEmptyMetadataTable();
620 swthTable.put("array_name", "ch3b_temperature");
621 swthTable.put("lon_array_name", "pixel_longitude");
622 swthTable.put("lat_array_name", "pixel_latitude");
623 swthTable.put("XTrack", "pixels_across_track");
624 swthTable.put("Track", "scan_lines_along_track");
625 swthTable.put("geo_Track", "scan_lines_along_track");
626 swthTable.put("geo_XTrack", "pixels_across_track");
627 swthTable.put("scale_name", "SCALE_FACTOR");
628 swthTable.put("offset_name", "ADD_OFFSET");
629 swthTable.put("fill_value_name", "_FILLVALUE");
630 swthTable.put("range_name", "Emmissive_Bands");
631 swthTable.put("unpack", "unpack");
632 swthTable.put("geo_scale_name", "SCALE_FACTOR");
633 swthTable.put("geo_offset_name", "ADD_OFFSET");
634 swthTable.put("geo_fillValue_name", "_FILLVALUE");
635
636
637 SwathAdapter swathAdapter0 = new SwathAdapter(reader, swthTable);
638 swathAdapter0.setDefaultStride(10);
639 HashMap subset = swathAdapter0.getDefaultSubset();
640 defaultSubset = subset;
641
642 HashMap specTable = SpectrumAdapter.getEmptyMetadataTable();
643 specTable.put(SpectrumAdapter.array_name, "ch3b_temperature");
644 specTable.put(SpectrumAdapter.x_dim_name, "pixels_across_track");
645 specTable.put(SpectrumAdapter.y_dim_name, "scan_lines_along_track");
646 specTable.put(SpectrumAdapter.channelValues, new float[] {3.740f});
647 specTable.put(SpectrumAdapter.bandNames, new String[] {"ch3b"});
648 specTable.put(SpectrumAdapter.channelType, "wavelength");
649 SpectrumAdapter spectrumAdapter0 = new SpectrumAdapter(reader, specTable);
650
651 MultiSpectralData multiSpectData0 = new MultiSpectralData(swathAdapter0, spectrumAdapter0, "BrightnessTemp", "BrightnessTemp", null, null);
652
653 HashMap table = SwathAdapter.getEmptyMetadataTable();
654 table.put("array_name", "ch4_temperature");
655 table.put("lon_array_name", "pixel_longitude");
656 table.put("lat_array_name", "pixel_latitude");
657 table.put("XTrack", "pixels_across_track");
658 table.put("Track", "scan_lines_along_track");
659 table.put("geo_Track", "scan_lines_along_track");
660 table.put("geo_XTrack", "pixels_across_track");
661 table.put("scale_name", "SCALE_FACTOR");
662 table.put("offset_name", "ADD_OFFSET");
663 table.put("fill_value_name", "_FILLVALUE");
664 table.put("range_name", "Emmissive_Bands");
665 table.put("unpack", "unpack");
666 swthTable.put("geo_scale_name", "SCALE_FACTOR");
667 swthTable.put("geo_offset_name", "ADD_OFFSET");
668 swthTable.put("geo_fillValue_name", "_FILLVALUE");
669
670
671 SwathAdapter swathAdapter1 = new SwathAdapter(reader, table);
672 swathAdapter1.setDefaultStride(10);
673
674 table = SpectrumAdapter.getEmptyMetadataTable();
675 table.put(SpectrumAdapter.array_name, "ch4_temperature");
676 table.put(SpectrumAdapter.x_dim_name, "pixels_across_track");
677 table.put(SpectrumAdapter.y_dim_name, "scan_lines_along_track");
678 table.put(SpectrumAdapter.channelValues, new float[] {10.80f});
679 table.put(SpectrumAdapter.bandNames, new String[] {"ch4"});
680 table.put(SpectrumAdapter.channelType, "wavelength");
681 SpectrumAdapter spectrumAdapter1 = new SpectrumAdapter(reader, table);
682
683 MultiSpectralData multiSpectData1 = new MultiSpectralData(swathAdapter1, spectrumAdapter1, "BrightnessTemp", "BrightnessTemp", null, null);
684
685 table = SwathAdapter.getEmptyMetadataTable();
686 table.put("array_name", "ch5_temperature");
687 table.put("lon_array_name", "pixel_longitude");
688 table.put("lat_array_name", "pixel_latitude");
689 table.put("XTrack", "pixels_across_track");
690 table.put("Track", "scan_lines_along_track");
691 table.put("geo_Track", "scan_lines_along_track");
692 table.put("geo_XTrack", "pixels_across_track");
693 table.put("scale_name", "SCALE_FACTOR");
694 table.put("offset_name", "ADD_OFFSET");
695 table.put("fill_value_name", "_FILLVALUE");
696 table.put("range_name", "Emmissive_Bands");
697 table.put("unpack", "unpack");
698 swthTable.put("geo_scale_name", "SCALE_FACTOR");
699 swthTable.put("geo_offset_name", "ADD_OFFSET");
700 swthTable.put("geo_fillValue_name", "_FILLVALUE");
701
702
703 SwathAdapter swathAdapter2 = new SwathAdapter(reader, table);
704 swathAdapter2.setDefaultStride(10);
705
706 table = SpectrumAdapter.getEmptyMetadataTable();
707 table.put(SpectrumAdapter.array_name, "ch5_temperature");
708 table.put(SpectrumAdapter.x_dim_name, "pixels_across_track");
709 table.put(SpectrumAdapter.y_dim_name, "scan_lines_along_track");
710 table.put(SpectrumAdapter.channelValues, new float[] {12.00f});
711 table.put(SpectrumAdapter.bandNames, new String[] {"ch5"});
712 table.put(SpectrumAdapter.channelType, "wavelength");
713 SpectrumAdapter spectrumAdapter2 = new SpectrumAdapter(reader, table);
714
715 MultiSpectralData multiSpectData2 = new MultiSpectralData(swathAdapter2, spectrumAdapter2, "BrightnessTemp", "BrightnessTemp", null, null);
716
717
718 MultiSpectralAggr aggr = new MultiSpectralAggr(new MultiSpectralData[] {multiSpectData0, multiSpectData1, multiSpectData2});
719 aggr.setInitialWavenumber(3.740f);
720 aggr.setDataRange(new float[] {180f, 340f});
721 multiSpectData = aggr;
722 multiSpectData_s.add(aggr);
723 defaultSubset = aggr.getDefaultSubset();
724 previewImage = aggr.getImage(defaultSubset);
725
726 //- now do the reflective bands
727 swthTable.put("array_name", "ch1_reflectance");
728 swthTable.put("range_name", "Reflective_Bands");
729
730 swathAdapter0 = new SwathAdapter(reader, swthTable);
731 swathAdapter0.setDefaultStride(10);
732
733 specTable.put(SpectrumAdapter.array_name, "ch1_reflectance");
734 specTable.put(SpectrumAdapter.channelValues, new float[] {0.630f});
735 specTable.put(SpectrumAdapter.bandNames, new String[] {"ch1"});
736 spectrumAdapter0 = new SpectrumAdapter(reader, specTable);
737
738 multiSpectData0 = new MultiSpectralData(swathAdapter0, spectrumAdapter0, "Reflectance", "Reflectance", null, null);
739
740 swthTable.put("array_name", "ch2_reflectance");
741 swthTable.put("range_name", "Reflective_Bands");
742
743 swathAdapter1 = new SwathAdapter(reader, swthTable);
744 swathAdapter1.setDefaultStride(10);
745
746 specTable.put(SpectrumAdapter.array_name, "ch2_reflectance");
747 specTable.put(SpectrumAdapter.channelValues, new float[] {0.862f});
748 specTable.put(SpectrumAdapter.bandNames, new String[] {"ch2"});
749 spectrumAdapter1 = new SpectrumAdapter(reader, specTable);
750
751 multiSpectData1 = new MultiSpectralData(swathAdapter1, spectrumAdapter1, "Reflectance", "Reflectance", null, null);
752
753 swthTable.put("array_name", "ch3ab_reflectance");
754 swthTable.put("range_name", "Reflective_Bands");
755
756 swathAdapter2 = new SwathAdapter(reader, swthTable);
757 swathAdapter2.setDefaultStride(10);
758 subset = swathAdapter2.getDefaultSubset();
759 defaultSubset = subset;
760
761 specTable.put(SpectrumAdapter.array_name, "ch3ab_reflectance");
762 specTable.put(SpectrumAdapter.channelValues, new float[] {1.610f});
763 specTable.put(SpectrumAdapter.bandNames, new String[] {"ch3ab"});
764 spectrumAdapter2 = new SpectrumAdapter(reader, specTable);
765
766 multiSpectData2 = new MultiSpectralData(swathAdapter2, spectrumAdapter2, "Reflectance", "Reflectance", null, null);
767
768 aggr = new MultiSpectralAggr(new MultiSpectralData[] {multiSpectData0, multiSpectData1, multiSpectData2});
769 aggr.setInitialWavenumber(0.630f);
770 aggr.setDataRange(new float[] {0f, 100f});
771 multiSpectData_s.add(aggr);
772
773 categories = DataCategory.parseCategories("MultiSpectral;MultiSpectral;IMAGE");
774
775 hasImagePreview = true;
776 hasChannelSelect = true;
777 }
778 else {
779 HashMap table = SwathAdapter.getEmptyMetadataTable();
780 table.put("array_name", "MODIS_SWATH_Type_L1B/Data Fields/EV_1KM_Emissive");
781 table.put("lon_array_name", "pixel_longitude");
782 table.put("lat_array_name", "pixel_latitude");
783 table.put("XTrack", "elements");
784 table.put("Track", "lines");
785 table.put("geo_Track", "lines");
786 table.put("geo_XTrack", "elements");
787 table.put("scale_name", "scale_factor");
788 table.put("offset_name", "add_offset");
789 table.put("fill_value_name", "_FillValue");
790 swathAdapter = new SwathAdapter(reader, table);
791 categories = DataCategory.parseCategories("2D grid;GRID-2D;");
792 defaultSubset = swathAdapter.getDefaultSubset();
793 }
794 setProperties(properties);
795 }
796
797 public void initAfterUnpersistence() {
798 try {
799 setup();
800 }
801 catch (Exception e) {
802 }
803 }
804
805 /**
806 * Make and insert the <code>DataChoice</code>-s for this
807 * <code>DataSource</code>.
808 */
809 public void doMakeDataChoices() {
810 try {
811 for (int k=0; k<multiSpectData_s.size(); k++) {
812 MultiSpectralData adapter = multiSpectData_s.get(k);
813 DataChoice choice = doMakeDataChoice(k, adapter);
814 adapterMap.put(choice.getName(), adapter);
815 addDataChoice(choice);
816 }
817 }
818 catch(Exception e) {
819 e.printStackTrace();
820 }
821 }
822
823 public void addChoice(String name, Data data) {
824 ComboDataChoice combo = new ComboDataChoice(name + hashCode(), name, new Hashtable(), data);
825 addDataChoice(combo);
826 getDataContext().dataSourceChanged(this);
827 }
828
829 private DataChoice doMakeDataChoice(int idx, MultiSpectralData adapter) throws Exception {
830 String name = "_ ";
831 DataSelection dataSel = new MultiDimensionSubset();
832 if (adapter != null) {
833 name = adapter.getName();
834 dataSel = new MultiDimensionSubset(defaultSubset);
835 }
836
837 Hashtable subset = new Hashtable();
838 subset.put(MultiDimensionSubset.key, dataSel);
839 if (adapter != null) {
840 subset.put(MultiSpectralDataSource.paramKey, adapter.getParameter());
841 }
842
843 DirectDataChoice ddc = new DirectDataChoice(this, new Integer(idx), name, name, categories, subset);
844 ddc.setProperties(subset);
845 return ddc;
846 }
847
848 /**
849 * Check to see if this <code>HDFHydraDataSource</code> is equal to the object
850 * in question.
851 * @param o object in question
852 * @return true if they are the same or equivalent objects
853 */
854 public boolean equals(Object o) {
855 if ( !(o instanceof MultiSpectralDataSource)) {
856 return false;
857 }
858 return (this == (MultiSpectralDataSource) o);
859 }
860
861 public MultiSpectralData getMultiSpectralData() {
862 return multiSpectData;
863 }
864
865 public MultiSpectralData getMultiSpectralData(DataChoice choice) {
866 return adapterMap.get(choice.getName());
867 }
868
869 public MultiSpectralData getMultiSpectralData(String name) {
870 return adapterMap.get(name);
871 }
872
873 public MultiSpectralData getMultiSpectralData(int idx) {
874 return multiSpectData_s.get(idx);
875 }
876
877 public String getDatasetName() {
878 return filename;
879 }
880
881 public void setDatasetName(String name) {
882 filename = name;
883 }
884
885 public ComboDataChoice getComboDataChoice() {
886 return comboChoice;
887 }
888
889 /**
890 * Called by the IDV's persistence manager in an effort to collect all of
891 * the files that should be included in a zipped bundle.
892 *
893 * @return Singleton list containing the file that this data source came from.
894 */
895 @Override public List getDataPaths() {
896 return Collections.singletonList(filename);
897 }
898
899 /**
900 public HashMap getSubsetFromLonLatRect(MultiDimensionSubset select, GeoSelection geoSelection) {
901 GeoLocationInfo ginfo = geoSelection.getBoundingBox();
902 return adapters[0].getSubsetFromLonLatRect(select.getSubset(), ginfo.getMinLat(), ginfo.getMaxLat(),
903 ginfo.getMinLon(), ginfo.getMaxLon());
904 }
905 */
906
907 public synchronized Data getData(String name, HashMap subset) throws VisADException, RemoteException {
908 MultiSpectralData msd = getMultiSpectralData(name);
909 Data data = null;
910 try {
911 data = msd.getImage(subset);
912 } catch (Exception e) {
913 e.printStackTrace();
914 }
915 return data;
916 }
917
918
919 public synchronized Data getData(DataChoice dataChoice, DataCategory category,
920 DataSelection dataSelection, Hashtable requestProperties)
921 throws VisADException, RemoteException {
922 return this.getDataInner(dataChoice, category, dataSelection, requestProperties);
923
924 }
925
926 protected Data getDataInner(DataChoice dataChoice, DataCategory category,
927 DataSelection dataSelection, Hashtable requestProperties)
928 throws VisADException, RemoteException {
929
930 //- this hack keeps the HydraImageProbe from doing a getData()
931 //- TODO: need to use categories?
932 if (requestProperties != null) {
933 if ((requestProperties.toString()).contains("ReadoutProbe")) {
934 return null;
935 }
936 }
937
938 GeoLocationInfo ginfo = null;
939 GeoSelection geoSelection = null;
940
941 if ((dataSelection != null) && (dataSelection.getGeoSelection() != null)) {
942 if (dataSelection.getGeoSelection().getBoundingBox() != null) {
943 geoSelection = dataSelection.getGeoSelection();
944 }
945 else if (dataChoice.getDataSelection() != null) {
946 geoSelection = dataChoice.getDataSelection().getGeoSelection();
947 }
948 }
949
950 if (geoSelection != null) {
951 ginfo = geoSelection.getBoundingBox();
952 }
953
954 Data data = null;
955
956 try {
957 HashMap subset = null;
958 if (ginfo != null) {
959 subset = swathAdapter.getSubsetFromLonLatRect(ginfo.getMinLat(), ginfo.getMaxLat(),
960 ginfo.getMinLon(), ginfo.getMaxLon());
961 }
962 else {
963 MultiDimensionSubset select = null;
964 Hashtable table = dataChoice.getProperties();
965 Enumeration keys = table.keys();
966 while (keys.hasMoreElements()) {
967 Object key = keys.nextElement();
968 if (key instanceof MultiDimensionSubset) {
969 select = (MultiDimensionSubset) table.get(key);
970 }
971 }
972 if (select != null) {
973 subset = select.getSubset();
974 }
975
976 if (dataSelection != null) {
977 Hashtable props = dataSelection.getProperties();
978 if (props != null) {
979 if (props.containsKey(MultiDimensionSubset.key)) {
980 subset = (HashMap)((MultiDimensionSubset)props.get(MultiDimensionSubset.key)).getSubset();
981 }
982 else {
983 subset = defaultSubset;
984 }
985 if (props.containsKey(SpectrumAdapter.channelIndex_name)) {
986 int idx = ((Integer) props.get(SpectrumAdapter.channelIndex_name)).intValue();
987 double[] coords = (double[]) subset.get(SpectrumAdapter.channelIndex_name);
988 if (coords == null) {
989 coords = new double[] {(double)idx, (double)idx, (double)1};
990 subset.put(SpectrumAdapter.channelIndex_name, coords);
991 }
992 else {
993 coords[0] = (double)idx;
994 coords[1] = (double)idx;
995 coords[2] = (double)1;
996 }
997 }
998 }
999 }
1000 }
1001
1002 if (subset != null) {
1003 MultiSpectralData multiSpectData = getMultiSpectralData(dataChoice);
1004 if (multiSpectData != null) {
1005 data = multiSpectData.getImage(subset);
1006 data = applyProperties(data, requestProperties, subset);
1007 }
1008 }
1009 } catch (Exception e) {
1010 e.printStackTrace();
1011 System.out.println("getData exception e=" + e);
1012 }
1013 return data;
1014 }
1015
1016 public MapProjection getDataProjection(HashMap subset) {
1017 MapProjection mp = null;
1018 try {
1019 Rectangle2D rect = multiSpectData.getLonLatBoundingBox(subset);
1020 mp = new LambertAEA(rect);
1021 }
1022 catch (Exception e) {
1023 logException("MultiSpectralDataSource.getDataProjection", e);
1024 }
1025 return mp;
1026 }
1027
1028 protected Data applyProperties(Data data, Hashtable requestProperties, HashMap subset)
1029 throws VisADException, RemoteException {
1030 Data new_data = data;
1031
1032 if (requestProperties == null) {
1033 new_data = data;
1034 return new_data;
1035 }
1036 return new_data;
1037 }
1038
1039 protected void initDataSelectionComponents(
1040 List<DataSelectionComponent> components,
1041 final DataChoice dataChoice) {
1042
1043 if (System.getProperty("os.name").equals("Mac OS X") && hasImagePreview && hasChannelSelect) {
1044 try {
1045 components.add(new ImageChannelSelection(new PreviewSelection(dataChoice, previewImage, null), new ChannelSelection(dataChoice)));
1046 } catch (Exception e) {
1047 e.printStackTrace();
1048 }
1049 }
1050 else {
1051 if (hasImagePreview) {
1052 try {
1053 previewSelection = new PreviewSelection(dataChoice, previewImage, null);
1054 components.add(previewSelection);
1055 } catch (Exception e) {
1056 System.out.println("Can't make PreviewSelection: "+e);
1057 e.printStackTrace();
1058 }
1059 }
1060 if (hasChannelSelect) {
1061 try {
1062 components.add(new ChannelSelection(dataChoice));
1063 }
1064 catch (Exception e) {
1065 e.printStackTrace();
1066 }
1067 }
1068 }
1069 }
1070
1071
1072
1073 public static MapProjection getDataProjection(FlatField fltField) throws Exception {
1074 Rectangle2D rect = MultiSpectralData.getLonLatBoundingBox(fltField);
1075 MapProjection mp = new LambertAEA(rect, false);
1076 return mp;
1077 }
1078
1079 public static Linear2DSet makeGrid(MapProjection mp, double res) throws Exception {
1080 Rectangle2D rect = mp.getDefaultMapArea();
1081
1082 int xLen = (int) (rect.getWidth()/res);
1083 int yLen = (int) (rect.getHeight()/res);
1084
1085 RealType xmap = RealType.getRealType("xmap", CommonUnit.meter);
1086 RealType ymap = RealType.getRealType("ymap", CommonUnit.meter);
1087
1088 RealTupleType rtt = new visad.RealTupleType(xmap, ymap, mp, null);
1089
1090 Linear2DSet grid = new Linear2DSet(rtt, rect.getX(), (xLen-1)*res, xLen,
1091 rect.getY(), (yLen-1)*res, yLen);
1092 return grid;
1093 }
1094
1095 public static FlatField swathToGrid(Linear2DSet grid, FlatField swath) throws Exception {
1096 return swathToGrid(grid, swath, 0.0);
1097 }
1098
1099 private static int count = 0;
1100
1101 public static FlatField swathToGrid(Linear2DSet grid, FlatField[] swaths, double mode) throws Exception {
1102 FunctionType ftype = (FunctionType) swaths[0].getType();
1103 visad.Set domSet = swaths[0].getDomainSet();
1104
1105 FlatField swath = new FlatField(new FunctionType(ftype.getDomain(),
1106 new RealTupleType(new RealType[] {RealType.getRealType("redimage_"+count), RealType.getRealType("greenimage_"+count), RealType.getRealType("blueimage_"+count)})), domSet);
1107
1108 swath.setSamples(new float[][]
1109 {swaths[0].getFloats(false)[0], swaths[1].getFloats(false)[0], swaths[2].getFloats(false)[0]});
1110
1111 count++;
1112
1113 return swathToGrid(grid, swath, mode);
1114 }
1115
1116 public static FlatField swathToGrid(Linear2DSet grid, FlatField swath, double mode) throws Exception {
1117 FunctionType ftype = (FunctionType) swath.getType();
1118 Linear2DSet swathDomain = (Linear2DSet) swath.getDomainSet();
1119 int[] lens = swathDomain.getLengths();
1120 float[][] swathRange = swath.getFloats(false);
1121 int trackLen = lens[1];
1122 int xtrackLen = lens[0];
1123 int gridLen = grid.getLength();
1124 lens = grid.getLengths();
1125 int gridXLen = lens[0];
1126 int gridYLen = lens[1];
1127
1128 CoordinateSystem swathCoordSys = swathDomain.getCoordinateSystem();
1129 CoordinateSystem gridCoordSys = grid.getCoordinateSystem();
1130
1131 RealTupleType rtt = ((SetType)grid.getType()).getDomain();
1132 FlatField grdFF = new FlatField(new FunctionType(rtt, ftype.getRange()), grid);
1133 float[][] gridRange = grdFF.getFloats(false);
1134 int rngTupDim = gridRange.length;
1135
1136 float[][] swathGridCoord = new float[2][gridLen];
1137 java.util.Arrays.fill(swathGridCoord[0], Float.NaN);
1138
1139 int[] swathIndexAtGrid = null;
1140 if (true) {
1141 swathIndexAtGrid = new int[gridLen];
1142 }
1143
1144 for (int j=0; j < trackLen; j++) {
1145 for (int i=0; i < xtrackLen; i++) {
1146 int swathIdx = j*xtrackLen + i;
1147 float val = swathRange[0][swathIdx];
1148
1149 float[][] swathCoord = swathDomain.indexToValue(new int[] {swathIdx});
1150 float[][] swathEarthCoord = swathCoordSys.toReference(swathCoord);
1151
1152 float[][] gridValue = gridCoordSys.fromReference(swathEarthCoord);
1153 int grdIdx = (grid.valueToIndex(gridValue))[0];
1154 float[][] gridCoord = grid.valueToGrid(gridValue);
1155
1156 int m=0;
1157 int n=0;
1158 int k = grdIdx + (m + n*gridXLen);
1159
1160 if ( !(Float.isNaN(val)) && ((k >=0) && (k < gridXLen*gridYLen)) ) { // val or val[rngTupDim] ?
1161 float grdVal = gridRange[0][k];
1162
1163 if (Float.isNaN(grdVal)) {
1164 for (int t=0; t<rngTupDim; t++) {
1165 gridRange[t][k] = swathRange[t][swathIdx];
1166 }
1167 swathGridCoord[0][k] = gridCoord[0][0];
1168 swathGridCoord[1][k] = gridCoord[1][0];
1169 swathIndexAtGrid[k] = swathIdx;
1170 }
1171 else {
1172 /**
1173 // compare current to last distance
1174 float[][] gridLoc = grid.indexToValue(new int[] {k});
1175 gridLoc = grid.valueToGrid(gridLoc);
1176
1177 float del_0 = swathGridCoord[0][k] - gridLoc[0][0];
1178 float del_1 = swathGridCoord[1][k] - gridLoc[1][0];
1179 float last_dst_sqrd = del_0*del_0 + del_1*del_1;
1180
1181 del_0 = gridCoord[0][0] - gridLoc[0][0];
1182 del_1 = gridCoord[1][0] - gridLoc[1][0];
1183 float dst_sqrd = del_0*del_0 + del_1*del_1;
1184
1185 if (dst_sqrd < last_dst_sqrd) {
1186 for (int t=0; t<rngTupDim; t++) {
1187 gridRange[t][k] = val;
1188 }
1189 swathGridCoord[0][k] = gridCoord[0][0];
1190 swathGridCoord[1][k] = gridCoord[1][0];
1191 swathIndexAtGrid[k] = swathIdx;
1192 }
1193 **/
1194 }
1195
1196 }
1197 }
1198 }
1199
1200
1201 // 2nd pass weighted average
1202 float[][] gCoord = new float[2][1];
1203 if (mode > 0.0) {
1204 float weight = 1f;
1205 float[] sumValue = new float[rngTupDim];
1206 for (int j=2; j<gridYLen-2; j++) {
1207 for (int i=2; i<gridXLen-2; i++) {
1208 int grdIdx = i + j*gridXLen;
1209
1210 // dont to weighted average if a nearest neigbhor existed for the grid point
1211 if (mode == 2.0) {
1212 if (!Float.isNaN(gridRange[0][grdIdx])) {
1213 continue;
1214 }
1215 }
1216
1217 gCoord[0][0] = swathGridCoord[0][grdIdx];
1218 gCoord[1][0] = swathGridCoord[1][grdIdx];
1219 float del_0 = gCoord[0][0] - (float) i;
1220 float del_1 = gCoord[1][0] - (float) j;
1221 float dst_sqrd = del_0*del_0 + del_1*del_1;
1222
1223 int num = 0;
1224 float sumWeights = 0f;
1225 for (int t=0; t<rngTupDim; t++) sumValue[t] = 0f;
1226 for (int n = -1; n < 2; n++) {
1227 for (int m = -1; m < 2; m++) {
1228 int k = grdIdx + (m + n*gridXLen);
1229
1230 if ( !Float.isNaN(swathGridCoord[0][k]) ) {
1231
1232 gCoord[0][0] = swathGridCoord[0][k];
1233 gCoord[1][0] = swathGridCoord[1][k];
1234 del_0 = gCoord[0][0] - (float) i;
1235 del_1 = gCoord[1][0] - (float) j;
1236 dst_sqrd = del_0*del_0 + del_1*del_1;
1237 weight = (float) (1.0/Math.exp((double)(dst_sqrd)*2.75f));
1238
1239 for (int t=0; t<rngTupDim; t++) sumValue[t] += swathRange[t][swathIndexAtGrid[k]]*weight;
1240 sumWeights += weight;
1241 num++;
1242 }
1243 }
1244 }
1245 for (int t=0; t<rngTupDim; t++) {
1246 gridRange[t][grdIdx] = sumValue[t]/sumWeights;
1247 }
1248 }
1249 }
1250 }
1251
1252 grdFF.setSamples(gridRange);
1253
1254 return grdFF;
1255 }
1256
1257
1258 }
1259
1260
1261 class ChannelSelection extends DataSelectionComponent {
1262
1263 DataChoice dataChoice;
1264 MultiSpectralDisplay display;
1265
1266 ChannelSelection(DataChoice dataChoice) throws Exception {
1267 super("Channels");
1268 this.dataChoice = dataChoice;
1269 display = new MultiSpectralDisplay((DirectDataChoice)dataChoice);
1270 display.showChannelSelector();
1271 }
1272
1273 protected JComponent doMakeContents() {
1274 try {
1275 JPanel panel = new JPanel(new BorderLayout());
1276 panel.add("Center", display.getDisplayComponent());
1277 if (display.getBandSelectComboBox() != null) {
1278 JPanel bandPanel = new JPanel(new FlowLayout());
1279 bandPanel.add(new JLabel("Band: "));
1280 bandPanel.add(display.getBandSelectComboBox());
1281 panel.add("South", bandPanel);
1282 }
1283 return panel;
1284 }
1285 catch (Exception e) {
1286 System.out.println(e);
1287 }
1288 return null;
1289 }
1290
1291 public void applyToDataSelection(DataSelection dataSelection) {
1292 try {
1293 dataSelection.putProperty(Constants.PROP_CHAN, display.getWaveNumber());
1294 dataSelection.putProperty(SpectrumAdapter.channelIndex_name, display.getChannelIndex());
1295 } catch (Exception e) {
1296 e.printStackTrace();
1297 }
1298 }
1299 }
1300
1301 class ImageChannelSelection extends DataSelectionComponent {
1302 PreviewSelection previewSelection;
1303 ChannelSelection channelSelection;
1304
1305 ImageChannelSelection(PreviewSelection previewSelection, ChannelSelection channelSelection) {
1306 super("MultiSpectral");
1307 this.previewSelection = previewSelection;
1308 this.channelSelection = channelSelection;
1309 }
1310
1311 protected JComponent doMakeContents() {
1312 JSplitPane splitpane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
1313 splitpane.add(previewSelection.doMakeContents());
1314 splitpane.add(channelSelection.doMakeContents());
1315 splitpane.setContinuousLayout(true);
1316 splitpane.setOneTouchExpandable(true);
1317 splitpane.setResizeWeight(1);
1318 splitpane.setDividerSize(12);
1319 return splitpane;
1320 }
1321
1322 public void applyToDataSelection(DataSelection dataSelection) {
1323 previewSelection.applyToDataSelection(dataSelection);
1324 channelSelection.applyToDataSelection(dataSelection);
1325 }
1326
1327
1328 }