001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2017 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 */ 028package edu.wisc.ssec.mcidasv.data.hydra; 029 030import java.io.File; 031import java.rmi.RemoteException; 032import java.util.Enumeration; 033import java.util.HashMap; 034import java.util.Hashtable; 035import java.util.List; 036import java.util.Map; 037 038import javax.swing.JOptionPane; 039 040import org.slf4j.Logger; 041import org.slf4j.LoggerFactory; 042 043import ucar.nc2.NetcdfFile; 044import ucar.nc2.Variable; 045import ucar.unidata.data.DataCategory; 046import ucar.unidata.data.DataChoice; 047import ucar.unidata.data.DataSelection; 048import ucar.unidata.data.DataSelectionComponent; 049import ucar.unidata.data.DataSourceDescriptor; 050import ucar.unidata.data.DirectDataChoice; 051import ucar.unidata.data.GeoLocationInfo; 052import ucar.unidata.data.GeoSelection; 053import ucar.unidata.util.Misc; 054 055import visad.Data; 056import visad.FlatField; 057import visad.GriddedSet; 058import visad.VisADException; 059 060import edu.wisc.ssec.mcidasv.data.HydraDataSource; 061import edu.wisc.ssec.mcidasv.data.PreviewSelection; 062 063/** 064 * A data source for Multi Dimension Data 065 */ 066 067public class MultiDimensionDataSource extends HydraDataSource { 068 069 private static final Logger logger = LoggerFactory.getLogger(MultiDimensionDataSource.class); 070 071 /** Sources file */ 072 protected String filename; 073 074 protected MultiDimensionReader reader; 075 076 protected MultiDimensionAdapter[] adapters = null; 077 protected Map[] defaultSubsets = null; 078 private Map<String, MultiDimensionAdapter> adapterMap = new HashMap<>(); 079 protected Hashtable[] propsArray = null; 080 protected List[] categoriesArray = null; 081 082 protected SpectrumAdapter spectrumAdapter; 083 084 private static final String DATA_DESCRIPTION = "Multi Dimension Data"; 085 086 private Map<String, double[]> defaultSubset; 087 public TrackAdapter track_adapter; 088 private MultiSpectralData multiSpectData; 089 090 private List categories; 091 private boolean hasImagePreview = false; 092 private boolean hasTrackPreview = false; 093 094 private TrackSelection trackSelection = null; 095 096 /** 097 * Zero-argument constructor for construction via unpersistence. 098 */ 099 public MultiDimensionDataSource() {} 100 101 /** 102 * Construct a new HYDRA hdf data source. 103 * @param descriptor descriptor for this {@code DataSource} 104 * @param fileName name of the hdf file to read 105 * @param properties hashtable of properties 106 * 107 * @throws VisADException problem creating data 108 */ 109 public MultiDimensionDataSource(DataSourceDescriptor descriptor, 110 String fileName, Hashtable properties) 111 throws VisADException { 112 this(descriptor, Misc.newList(fileName), properties); 113 } 114 115 /** 116 * Construct a new HYDRA hdf data source. 117 * @param descriptor descriptor for this {@code DataSource} 118 * @param newSources List of filenames 119 * @param properties hashtable of properties 120 * 121 * @throws VisADException problem creating data 122 */ 123 public MultiDimensionDataSource(DataSourceDescriptor descriptor, 124 List newSources, Hashtable properties) 125 throws VisADException { 126 super(descriptor, newSources, DATA_DESCRIPTION, properties); 127 128 this.filename = (String) sources.get(0); 129 130 try { 131 setup(); 132 } catch (Exception e) { 133 throw new VisADException("could not set up MultiDimensionDataSource", e); 134 } 135 } 136 137 public void setup() throws Exception { 138 139 try { 140 if (filename.contains("MYD02SSH")) { // get file union 141 String other = (String) sources.get(1); 142 if (filename.endsWith("nav.hdf")) { 143 String tmp = filename; 144 filename = other; 145 other = tmp; 146 } 147 reader = NetCDFFile.makeUnion(filename, other); 148 } 149 else { 150 reader = new NetCDFFile(filename); 151 } 152 } catch (Exception e) { 153 logger.error("Cannot create NetCDF reader for file: " + filename, e); 154 } 155 156 adapters = new MultiDimensionAdapter[2]; 157 defaultSubsets = new HashMap[2]; 158 Hashtable<String, String[]> properties = new Hashtable<>(); 159 160 String name = (new File(filename)).getName(); 161 162 if (name.startsWith("MOD04") || name.startsWith("MYD04")) { 163 Map<String, Object> table = SwathAdapter.getEmptyMetadataTable(); 164 table.put("array_name", "mod04/Data_Fields/Optical_Depth_Land_And_Ocean"); 165 table.put("lon_array_name", "mod04/Geolocation_Fields/Longitude"); 166 table.put("lat_array_name", "mod04/Geolocation_Fields/Latitude"); 167 table.put("XTrack", "Cell_Across_Swath"); 168 table.put("Track", "Cell_Along_Swath"); 169 table.put("geo_Track", "Cell_Along_Swath"); 170 table.put("geo_XTrack", "Cell_Across_Swath"); 171 table.put("scale_name", "scale_factor"); 172 table.put("offset_name", "add_offset"); 173 table.put("fill_value_name", "_FillValue"); 174 table.put("range_name", "Optical_Depth_Land_And_Ocean"); 175 adapters[0] = new SwathAdapter(reader, table); 176 categories = DataCategory.parseCategories("2D grid;GRID-2D;"); 177 defaultSubset = adapters[0].getDefaultSubset(); 178 defaultSubsets[0] = defaultSubset; 179 hasImagePreview = true; 180 } 181 else if (name.startsWith("MOD06") || name.startsWith("MYD06")) { 182 hasImagePreview = true; 183 String path = "mod06/Data_Fields/"; 184 String[] arrayNames = new String[] {"Cloud_Optical_Thickness", "Cloud_Effective_Radius", "Cloud_Water_Path"}; 185 String[] arrayNames_5km = new String[] {"Cloud_Top_Pressure", "Cloud_Top_Temperature", "Cloud_Fraction"}; 186 187 adapters = new MultiDimensionAdapter[arrayNames.length+arrayNames_5km.length]; 188 defaultSubsets = new HashMap[arrayNames.length+arrayNames_5km.length]; 189 categoriesArray = new List[adapters.length]; 190 191 192 for (int k=0; k<arrayNames.length; k++) { 193 Map<String, Object> table = SwathAdapter.getEmptyMetadataTable(); 194 table.put("array_name", path.concat(arrayNames[k])); 195 table.put("lon_array_name", "mod06/Geolocation_Fields/Longitude"); 196 table.put("lat_array_name", "mod06/Geolocation_Fields/Latitude"); 197 table.put("XTrack", "Cell_Across_Swath_1km"); 198 table.put("Track", "Cell_Along_Swath_1km"); 199 table.put("geo_Track", "Cell_Along_Swath_5km"); 200 table.put("geo_XTrack", "Cell_Across_Swath_5km"); 201 table.put("scale_name", "scale_factor"); 202 table.put("offset_name", "add_offset"); 203 table.put("fill_value_name", "_FillValue"); 204 table.put("range_name", arrayNames[k]); 205 206 table.put(SwathAdapter.geo_track_offset_name, Double.toString(2.0)); 207 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(2.0)); 208 table.put(SwathAdapter.geo_track_skip_name, Double.toString(5.0)); 209 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(5.0148148148)); 210 211 SwathAdapter swathAdapter = new SwathAdapter(reader, table); 212 swathAdapter.setDefaultStride(10); 213 defaultSubset = swathAdapter.getDefaultSubset(); 214 adapters[k] = swathAdapter; 215 defaultSubsets[k] = defaultSubset; 216 categoriesArray[k] = DataCategory.parseCategories("1km swath;GRID-2D;"); 217 } 218 219 for (int k=0; k<arrayNames_5km.length; k++) { 220 Map<String, Object> table = SwathAdapter.getEmptyMetadataTable(); 221 table.put("array_name", path.concat(arrayNames_5km[k])); 222 table.put("lon_array_name", "mod06/Geolocation_Fields/Longitude"); 223 table.put("lat_array_name", "mod06/Geolocation_Fields/Latitude"); 224 table.put("XTrack", "Cell_Across_Swath_5km"); 225 table.put("Track", "Cell_Along_Swath_5km"); 226 table.put("geo_Track", "Cell_Along_Swath_5km"); 227 table.put("geo_XTrack", "Cell_Across_Swath_5km"); 228 table.put("scale_name", "scale_factor"); 229 table.put("offset_name", "add_offset"); 230 table.put("fill_value_name", "_FillValue"); 231 table.put("range_name", arrayNames_5km[k]); 232 233 SwathAdapter swathAdapter = new SwathAdapter(reader, table); 234 defaultSubset = swathAdapter.getDefaultSubset(); 235 adapters[arrayNames.length+k] = swathAdapter; 236 defaultSubsets[arrayNames.length+k] = defaultSubset; 237 categoriesArray[arrayNames.length+k] = DataCategory.parseCategories("5km swath;GRID-2D;"); 238 } 239 } 240 else if (name.startsWith("a1") && name.contains("mod06")) { 241 hasImagePreview = true; 242 String[] arrayNames = new String[] {"Cloud_Optical_Thickness", "Cloud_Effective_Radius", "Cloud_Water_Path"}; 243 String[] arrayNames_5km = new String[] {"Cloud_Top_Pressure", "Cloud_Top_Temperature", "Cloud_Fraction"}; 244 245 adapters = new MultiDimensionAdapter[arrayNames.length+arrayNames_5km.length]; 246 defaultSubsets = new HashMap[arrayNames.length+arrayNames_5km.length]; 247 categoriesArray = new List[adapters.length]; 248 249 250 for (int k=0; k<arrayNames.length; k++) { 251 Map<String, Object> table = SwathAdapter.getEmptyMetadataTable(); 252 table.put("array_name", arrayNames[k]); 253 table.put("lon_array_name", "Longitude"); 254 table.put("lat_array_name", "Latitude"); 255 table.put("array_dimension_names", new String[] {"Cell_Along_Swath_1km", "Cell_Across_Swath_1km"}); 256 table.put("lon_array_dimension_names", new String[] {"Cell_Along_Swath_1km", "Cell_Across_Swath_1km"}); 257 table.put("lat_array_dimension_names", new String[] {"Cell_Along_Swath_1km", "Cell_Across_Swath_1km"}); 258 table.put("XTrack", "Cell_Across_Swath_1km"); 259 table.put("Track", "Cell_Along_Swath_1km"); 260 table.put("geo_Track", "Cell_Along_Swath_5km"); 261 table.put("geo_XTrack", "Cell_Across_Swath_5km"); 262 table.put("scale_name", "scale_factor"); 263 table.put("offset_name", "add_offset"); 264 table.put("fill_value_name", "_FillValue"); 265 table.put("range_name", arrayNames[k]); 266 267 table.put(SwathAdapter.geo_track_offset_name, Double.toString(2.0)); 268 table.put(SwathAdapter.geo_xtrack_offset_name, Double.toString(2.0)); 269 table.put(SwathAdapter.geo_track_skip_name, Double.toString(5.0)); 270 table.put(SwathAdapter.geo_xtrack_skip_name, Double.toString(5.0148148148)); 271 272 SwathAdapter swathAdapter = new SwathAdapter(reader, table); 273 swathAdapter.setDefaultStride(10); 274 defaultSubset = swathAdapter.getDefaultSubset(); 275 adapters[k] = swathAdapter; 276 defaultSubsets[k] = defaultSubset; 277 categoriesArray[k] = DataCategory.parseCategories("1km swath;GRID-2D;"); 278 } 279 280 for (int k=0; k<arrayNames_5km.length; k++) { 281 Map<String, Object> table = SwathAdapter.getEmptyMetadataTable(); 282 table.put("array_name", arrayNames_5km[k]); 283 table.put("lon_array_name", "Longitude"); 284 table.put("lat_array_name", "Latitude"); 285 table.put("array_dimension_names", new String[] {"Cell_Along_Swath_5km", "Cell_Across_Swath_5km"}); 286 table.put("lon_array_dimension_names", new String[] {"Cell_Along_Swath_5km", "Cell_Across_Swath_5km"}); 287 table.put("lat_array_dimension_names", new String[] {"Cell_Along_Swath_5km", "Cell_Across_Swath_5km"}); 288 table.put("XTrack", "Cell_Across_Swath_5km"); 289 table.put("Track", "Cell_Along_Swath_5km"); 290 table.put("geo_Track", "Cell_Along_Swath_5km"); 291 table.put("geo_XTrack", "Cell_Across_Swath_5km"); 292 table.put("scale_name", "scale_factor"); 293 table.put("offset_name", "add_offset"); 294 table.put("fill_value_name", "_FillValue"); 295 table.put("range_name", arrayNames_5km[k]); 296 297 SwathAdapter swathAdapter = new SwathAdapter(reader, table); 298 defaultSubset = swathAdapter.getDefaultSubset(); 299 adapters[arrayNames.length+k] = swathAdapter; 300 defaultSubsets[arrayNames.length+k] = defaultSubset; 301 categoriesArray[arrayNames.length+k] = DataCategory.parseCategories("5km swath;GRID-2D;"); 302 } 303 } 304 else if (name.contains("HSRL2_B200") && name.endsWith(".h5")) { 305 Map<String, Object> table; 306 adapters = new MultiDimensionAdapter[5]; 307 defaultSubsets = new HashMap[5]; 308 propsArray = new Hashtable[5]; 309 310 String dataPath = "DataProducts/"; 311 String[] arrayNames = new String[] {"532_total_attn_bsc", "1064_total_attn_bsc", "355_total_attn_bsc"}; 312 String[] rangeNames = new String[] {"Total_Attenuated_Backscatter_532", "Total_Attenuated_Backscatter_1064", "Total_Attenuated_Backscatter_355"}; 313 314 String[] arrayNameAOT = new String[] {"532_AOT_hi_col", "355_AOT_hi_col"}; 315 String[] rangeNamesAOT = new String[] {}; 316 317 318 for (int k=0; k<arrayNames.length; k++) { 319 table = ProfileAlongTrack.getEmptyMetadataTable(); 320 table.put(ProfileAlongTrack.array_name, dataPath+arrayNames[k]); 321 table.put(ProfileAlongTrack.range_name, rangeNames[k]); 322 table.put(ProfileAlongTrack.trackDim_name, "dim0"); 323 table.put(ProfileAlongTrack.vertDim_name, "dim1"); 324 table.put(ProfileAlongTrack.profileTime_name, "ApplanixIMU/gps_time"); 325 table.put(ProfileAlongTrack.longitude_name, "ApplanixIMU/gps_lon"); 326 table.put(ProfileAlongTrack.latitude_name, "ApplanixIMU/gps_lat"); 327 table.put("array_dimension_names", new String[] {"dim0", "dim1"}); 328 ProfileAlongTrack adapter = new HSRL2D(reader, table); 329 ProfileAlongTrack3D adapter3D = new ProfileAlongTrack3D(adapter); 330 Map<String, double[]> subset = adapter.getDefaultSubset(); 331 adapters[k] = adapter3D; 332 defaultSubset = subset; 333 defaultSubsets[k] = defaultSubset; 334 335 properties.put("medianFilter", new String[] {Integer.toString(adapter.getMedianFilterWindowHeight()), Integer.toString(adapter.getMedianFilterWindowWidth())}); 336 properties.put("setBelowSfcMissing", new String[] {"true"}); 337 propsArray[k] = properties; 338 } 339 340 DataCategory.createCategory("ProfileAlongTrack"); 341 categories = DataCategory.parseCategories("ProfileAlongTrack;ProfileAlongTrack;"); 342 343 hasTrackPreview = true; 344 345 ArrayAdapter[] adapter_s = new ArrayAdapter[3]; 346 table = ProfileAlongTrack.getEmptyMetadataTable(); 347 table.put(ProfileAlongTrack.array_name, "ApplanixIMU/gps_lat"); 348 table.put(ProfileAlongTrack.trackDim_name, "dim0"); 349 table.put(ProfileAlongTrack.vertDim_name, "dim1"); 350 table.put("array_dimension_names", new String[] {"dim0", "dim1"}); 351 adapter_s[0] = new ArrayAdapter(reader, table); 352 353 table = ProfileAlongTrack.getEmptyMetadataTable(); 354 table.put(ProfileAlongTrack.array_name, "UserInput/DEM_altitude"); 355 table.put(ProfileAlongTrack.trackDim_name, "dim0"); 356 table.put(ProfileAlongTrack.vertDim_name, "dim1"); 357 table.put("array_dimension_names", new String[] {"dim0", "dim1"}); 358 adapter_s[1] = new ArrayAdapter(reader, table); 359 /* 360 adapter_s[1].setRangeProcessor(new RangeProcessor() { // Eventually handle unit conversions better. 361 public float[] processRange(float[] fvals, Map<String, double[]> subset) { 362 for (int i=0; i<fvals.length; i++) { 363 fvals[i] *= 1000; //km -> m 364 } 365 return fvals; 366 } 367 }); 368 */ 369 370 table = ProfileAlongTrack.getEmptyMetadataTable(); 371 table.put(ProfileAlongTrack.array_name, "ApplanixIMU/gps_lon"); 372 table.put(ProfileAlongTrack.trackDim_name, "dim0"); 373 table.put(ProfileAlongTrack.vertDim_name, "dim1"); 374 table.put("array_dimension_names", new String[] {"dim0", "dim1"}); 375 adapter_s[2] = new ArrayAdapter(reader, table); 376 377 TrackDomain track_domain = new TrackDomain(adapter_s[2], adapter_s[0], adapter_s[1]); 378 track_adapter = new TrackAdapter(track_domain, adapter_s[1]); 379 380 TrackAdapter trkAdapter = new TrackAdapter(new TrackDomain(adapter_s[2], adapter_s[0], adapter_s[1]), adapter_s[1]); 381 trkAdapter.setName("Track3D"); 382 383 trkAdapter = new TrackAdapter(new TrackDomain(adapter_s[2], adapter_s[0]), adapter_s[1]); 384 trkAdapter.setName("Track2D"); 385 } 386 else if (name.startsWith("CAL_LID_L1")) { 387 388 // Make sure the variables we need are present. If not, this is not a valid 389 // L1 CALIPSO file McV can work with. 390 391 if (! ((hasVariable("Latitude")) && 392 (hasVariable("Longitude")) && 393 (hasVariable("Surface_Elevation")) && 394 (hasVariable("Tropopause_Height")) && 395 (hasVariable("Total_Attenuated_Backscatter_532"))) 396 ) { 397 // Pop up a dialog letting user know we can't work wit this data 398 String msg = "McIDAS-V is unable to read this Level 1 CALIPSO file.\n" + 399 "If you believe this is a valid file which should be supported,\n" + 400 "please contact the MUG or post a message on the MUG Forum."; 401 Object[] params = { msg }; 402 JOptionPane.showMessageDialog(null, params, "Data Validity Test Failure", JOptionPane.OK_OPTION); 403 throw new Exception("Unable to load CALIPSO data"); 404 } 405 406 adapters = new MultiDimensionAdapter[4]; 407 defaultSubsets = new HashMap[4]; 408 propsArray = new Hashtable[4]; 409 410 Map<String, Object> table = ProfileAlongTrack.getEmptyMetadataTable(); 411 table.put(ProfileAlongTrack.array_name, "Total_Attenuated_Backscatter_532"); 412 table.put(ProfileAlongTrack.ancillary_file_name, "/edu/wisc/ssec/mcidasv/data/hydra/resources/calipso/altitude"); 413 table.put(ProfileAlongTrack.trackDim_name, "dim0"); 414 table.put(ProfileAlongTrack.vertDim_name, "dim1"); 415 table.put(ProfileAlongTrack.profileTime_name, "Profile_Time"); 416 table.put(ProfileAlongTrack.longitude_name, "Longitude"); 417 table.put(ProfileAlongTrack.latitude_name, "Latitude"); 418 table.put("array_dimension_names", new String[] {"dim0", "dim1"}); 419 ProfileAlongTrack adapter = new Calipso2D(reader, table); 420 ProfileAlongTrack3D adapter3D = new ProfileAlongTrack3D(adapter); 421 Map<String, double[]> subset = adapter.getDefaultSubset(); 422 adapters[0] = adapter3D; 423 defaultSubset = subset; 424 defaultSubsets[0] = defaultSubset; 425 DataCategory.createCategory("ProfileAlongTrack"); 426 categories = DataCategory.parseCategories("ProfileAlongTrack;ProfileAlongTrack;"); 427 428 properties.put("medianFilter", new String[] {Integer.toString(adapter.getMedianFilterWindowHeight()), Integer.toString(adapter.getMedianFilterWindowWidth())}); 429 properties.put("setBelowSfcMissing", new String[] {"true"}); 430 propsArray[0] = properties; 431 432 ArrayAdapter[] adapter_s = new ArrayAdapter[3]; 433 table = ProfileAlongTrack.getEmptyMetadataTable(); 434 table.put(ProfileAlongTrack.array_name, "Latitude"); 435 table.put(ProfileAlongTrack.trackDim_name, "dim0"); 436 table.put(ProfileAlongTrack.vertDim_name, "dim1"); 437 table.put("array_dimension_names", new String[] {"dim0", "dim1"}); 438 adapter_s[0] = new ArrayAdapter(reader, table); 439 440 table = ProfileAlongTrack.getEmptyMetadataTable(); 441 table.put(ProfileAlongTrack.array_name, "Surface_Elevation"); 442 table.put(ProfileAlongTrack.trackDim_name, "dim0"); 443 table.put(ProfileAlongTrack.vertDim_name, "dim1"); 444 table.put("array_dimension_names", new String[] {"dim0", "dim1"}); 445 adapter_s[1] = new ArrayAdapter(reader, table); 446 adapter_s[1].setRangeProcessor(new RangeProcessor() { // Eventually handle unit conversions better. 447 public float[] processRange(float[] fvals, Map<String, double[]> subset) { 448 for (int i=0; i<fvals.length; i++) { 449 fvals[i] *= 1000; //km -> m 450 } 451 return fvals; 452 } 453 }); 454 455 table = ProfileAlongTrack.getEmptyMetadataTable(); 456 table.put(ProfileAlongTrack.array_name, "Longitude"); 457 table.put(ProfileAlongTrack.trackDim_name, "dim0"); 458 table.put(ProfileAlongTrack.vertDim_name, "dim1"); 459 table.put("array_dimension_names", new String[] {"dim0", "dim1"}); 460 adapter_s[2] = new ArrayAdapter(reader, table); 461 462 TrackDomain track_domain = new TrackDomain(adapter_s[2], adapter_s[0], adapter_s[1]); 463 track_adapter = new TrackAdapter(track_domain, adapter_s[1]); 464 465 table = ProfileAlongTrack.getEmptyMetadataTable(); 466 table.put(ProfileAlongTrack.array_name, "Tropopause_Height"); 467 table.put(ProfileAlongTrack.trackDim_name, "dim0"); 468 table.put(ProfileAlongTrack.vertDim_name, "dim1"); 469 table.put("array_dimension_names", new String[] {"dim0", "dim1"}); 470 ArrayAdapter trop_height = new ArrayAdapter(reader, table); 471 track_domain = new TrackDomain(adapter_s[2], adapter_s[0], trop_height); 472 adapters[1] = new TrackAdapter(track_domain, trop_height); 473 defaultSubsets[1] = adapters[1].getDefaultSubset(); 474 475 adapters[2] = new TrackAdapter(new TrackDomain(adapter_s[2], adapter_s[0], adapter_s[1]), adapter_s[1]); 476 ((TrackAdapter)adapters[2]).setName("Track3D"); 477 defaultSubsets[2] = adapters[2].getDefaultSubset(); 478 479 adapters[3] = new TrackAdapter(new TrackDomain(adapter_s[2], adapter_s[0]), adapter_s[1]); 480 ((TrackAdapter)adapters[3]).setName("Track2D"); 481 defaultSubsets[3] = adapters[3].getDefaultSubset(); 482 483 484 hasTrackPreview = true; 485 } 486 else if (name.startsWith("CAL_LID_L2")) { 487 488 // Make sure the variables we need are present. If not, this is not a valid 489 // L2 CALIPSO file McV can work with. 490 491 if (! ((hasVariable("Latitude")) && 492 (hasVariable("Longitude")) && 493 (hasVariable("DEM_Surface_Elevation")) && 494 (hasVariable("Layer_Top_Altitude"))) 495 ) { 496 // Pop up a dialog letting user know we can't work wit this data 497 String msg = "McIDAS-V is unable to read this Level 2 CALIPSO file.\n" + 498 "If you believe this is a valid file which should be supported,\n" + 499 "please contact the MUG or post a message on the MUG Forum."; 500 Object[] params = { msg }; 501 JOptionPane.showMessageDialog(null, params, "Data Validity Test Failure", JOptionPane.OK_OPTION); 502 throw new Exception("Unable to load CALIPSO data"); 503 } 504 505 adapters = new MultiDimensionAdapter[4]; 506 defaultSubsets = new HashMap[4]; 507 propsArray = new Hashtable[4]; 508 509 ArrayAdapter[] adapter_s = new ArrayAdapter[3]; 510 511 adapter_s[0] = createTrackVertArrayAdapter("Longitude"); 512 adapter_s[1] = createTrackVertArrayAdapter("Latitude"); 513 adapter_s[2] = createTrackVertArrayAdapter("DEM_Surface_Elevation"); 514 515 TrackDomain track_domain = new TrackDomain(adapter_s[0], adapter_s[1], adapter_s[2]); 516 track_adapter = new TrackAdapter(track_domain, adapter_s[2]); 517 adapters[1] = track_adapter; 518 defaultSubsets[1] = track_adapter.getDefaultSubset(); 519 520 ArrayAdapter layer_top_altitude = createTrackVertArrayAdapter("Layer_Top_Altitude"); 521 522 RangeProcessor rngProcessor = 523 new RangeProcessor(1.0f, 0.0f, -Float.MAX_VALUE, Float.MAX_VALUE, -9999.0f); 524 layer_top_altitude.setRangeProcessor(rngProcessor); 525 526 track_domain = new TrackDomain(adapter_s[0], adapter_s[1], layer_top_altitude); 527 adapters[0] = new TrackAdapter(track_domain, layer_top_altitude); 528 defaultSubsets[0] = adapters[0].getDefaultSubset(); 529 530 /** another layer, how to show all? 531 adapters[2] = new TrackAdapter(track_domain, layer_top_altitude); 532 ((TrackAdapter)adapters[2]).setListIndex(1); 533 defaultSubsets[2] = adapters[2].getDefaultSubset(); 534 */ 535 536 adapters[2] = new TrackAdapter(new TrackDomain(adapter_s[0], adapter_s[1]), adapter_s[2]); 537 ((TrackAdapter)adapters[2]).setName("Track2D"); 538 defaultSubsets[2] = adapters[2].getDefaultSubset(); 539 540 adapters[3] = new TrackAdapter(new TrackDomain(adapter_s[0], adapter_s[1], adapter_s[2]), adapter_s[2]); 541 ((TrackAdapter)adapters[3]).setName("Track3D"); 542 defaultSubsets[3] = adapters[3].getDefaultSubset(); 543 544 DataCategory.createCategory("ProfileAlongTrack"); 545 categories = DataCategory.parseCategories("ProfileAlongTrack;ProfileAlongTrack;"); 546 547 hasTrackPreview = true; 548 } 549 else if (name.indexOf("2B-GEOPROF") > 0) { 550 adapters = new MultiDimensionAdapter[4]; 551 defaultSubsets = new HashMap[4]; 552 propsArray = new Hashtable[4]; 553 554 Map<String, Object> table = ProfileAlongTrack.getEmptyMetadataTable(); 555 table.put(ProfileAlongTrack.array_name, "2B-GEOPROF/Data_Fields/Radar_Reflectivity"); 556 table.put(ProfileAlongTrack.range_name, "2B-GEOPROF_RadarReflectivity"); 557 table.put(ProfileAlongTrack.scale_name, "factor"); 558 table.put(ProfileAlongTrack.offset_name, "offset"); 559 table.put(ProfileAlongTrack.fill_value_name, "_FillValue"); 560 table.put(ProfileAlongTrack.valid_range, "valid_range"); 561 table.put(ProfileAlongTrack.ancillary_file_name, "/edu/wisc/ssec/mcidasv/data/hydra/resources/cloudsat/altitude"); 562 table.put(ProfileAlongTrack.trackDim_name, "nray"); 563 table.put(ProfileAlongTrack.vertDim_name, "nbin"); 564 table.put(ProfileAlongTrack.profileTime_name, "2B-GEOPROF/Geolocation_Fields/Profile_Time"); 565 table.put(ProfileAlongTrack.longitude_name, "2B-GEOPROF/Geolocation_Fields/Longitude"); 566 table.put(ProfileAlongTrack.latitude_name, "2B-GEOPROF/Geolocation_Fields/Latitude"); 567 table.put(ProfileAlongTrack.product_name, "2B-GEOPROF"); 568 ProfileAlongTrack adapter = new CloudSat2D(reader, table); 569 ProfileAlongTrack3D adapter3D = new ProfileAlongTrack3D(adapter); 570 Map<String, double[]> subset = adapter.getDefaultSubset(); 571 adapters[0] = adapter3D; 572 defaultSubset = subset; 573 defaultSubsets[0] = defaultSubset; 574 DataCategory.createCategory("ProfileAlongTrack"); 575 categories = DataCategory.parseCategories("ProfileAlongTrack;ProfileAlongTrack;"); 576 577 ArrayAdapter[] adapter_s = new ArrayAdapter[3]; 578 table = ProfileAlongTrack.getEmptyMetadataTable(); 579 table.put(ProfileAlongTrack.array_name, "2B-GEOPROF/Geolocation_Fields/Latitude"); 580 table.put(ProfileAlongTrack.range_name, "Latitude"); 581 table.put(ProfileAlongTrack.trackDim_name, "nray"); 582 adapter_s[0] = new ArrayAdapter(reader, table); 583 584 table = ProfileAlongTrack.getEmptyMetadataTable(); 585 table.put(ProfileAlongTrack.array_name, "2B-GEOPROF/Geolocation_Fields/DEM_elevation"); 586 table.put(ProfileAlongTrack.range_name, "DEM_elevation"); 587 table.put(ProfileAlongTrack.trackDim_name, "nray"); 588 adapter_s[1] = new ArrayAdapter(reader, table); 589 adapter_s[1].setRangeProcessor(new RangeProcessor() { // need this because we don't want -9999 mapped to NaN 590 public float[] processRange(short[] svals, Map<String, double[]> subset) { 591 float[] fvals = new float[svals.length]; 592 for (int i=0; i<svals.length; i++) { 593 short sval = svals[i]; 594 if (sval == -9999) { 595 fvals[i] = 0f; 596 } 597 else { 598 fvals[i] = sval; 599 } 600 } 601 return fvals; 602 } 603 }); 604 605 table = ProfileAlongTrack.getEmptyMetadataTable(); 606 table.put(ProfileAlongTrack.array_name, "2B-GEOPROF/Geolocation_Fields/Longitude"); 607 table.put(ProfileAlongTrack.range_name, "Longitude"); 608 table.put(ProfileAlongTrack.trackDim_name, "nray"); 609 adapter_s[2] = new ArrayAdapter(reader, table); 610 611 TrackDomain track_domain = new TrackDomain(adapter_s[2], adapter_s[0], adapter_s[1]); 612 track_adapter = new TrackAdapter(track_domain, adapter_s[1]); 613 614 adapters[2] = new TrackAdapter(new TrackDomain(adapter_s[2], adapter_s[0], adapter_s[1]), adapter_s[1]); 615 ((TrackAdapter)adapters[2]).setName("Track3D"); 616 defaultSubsets[2] = adapters[2].getDefaultSubset(); 617 618 adapters[1] = new TrackAdapter(new TrackDomain(adapter_s[2], adapter_s[0]), adapter_s[1]); 619 ((TrackAdapter)adapters[1]).setName("Track2D"); 620 defaultSubsets[1] = adapters[1].getDefaultSubset(); 621 622 623 properties.put("medianFilter", new String[] {Integer.toString(adapter.getMedianFilterWindowHeight()), Integer.toString(adapter.getMedianFilterWindowWidth())}); 624 properties.put("setBelowSfcMissing", new String[] {"true"}); 625 propsArray[0] = properties; 626 hasTrackPreview = true; 627 } 628 else if ( name.startsWith("MHSx_xxx_1B") && name.endsWith("h5")) { 629 Map<String, Object> table = SwathAdapter.getEmptyMetadataTable(); 630 table.put("array_name", "U-MARF/EPS/MHSx_xxx_1B/DATA/Channel1"); 631 table.put("lon_array_name", "U-MARF/EPS/IASI_xxx_1C/DATA/IMAGE_LON_ARRAY"); 632 table.put("lat_array_name", "U-MARF/EPS/IASI_xxx_1C/DATA/IMAGE_LAT_ARRAY"); 633 table.put("XTrack", "dim1"); 634 table.put("Track", "dim0"); 635 table.put("geo_XTrack", "dim1"); 636 table.put("geo_Track", "dim0"); 637 table.put("product_name", "MHSx_xxx_1B"); 638 SwathAdapter swathAdapter = new SwathAdapter(reader, table); 639 adapters[0] = swathAdapter; 640 Map<String, double[]> subset = swathAdapter.getDefaultSubset(); 641 defaultSubset = subset; 642 defaultSubsets[0] = defaultSubset; 643 categories = DataCategory.parseCategories("2D grid;GRID-2D;"); 644 } 645 else if ( name.startsWith("MYD02SSH") ) { 646 String[] arrayNames = null; 647 648 if (name.endsWith("level2.hdf")) { 649 arrayNames = new String[] {"cld_press_acha", "cld_temp_acha", "cld_height_acha", "cloud_type", 650 "cloud_albedo_0_65um_nom", "cloud_transmission_0_65um_nom", "cloud_fraction"}; 651 } 652 else if (name.endsWith("obs.hdf")) { 653 arrayNames = new String[] {"refl_0_65um_nom", "refl_0_86um_nom", "refl_3_75um_nom", "refl_1_60um_nom", "refl_1_38um_nom", 654 "temp_3_75um_nom", "temp_11_0um_nom", "temp_12_0um_nom", "temp_6_7um_nom", 655 "temp_8_5um_nom", "temp_13_3um_nom"}; 656 } 657 658 adapters = new MultiDimensionAdapter[arrayNames.length]; 659 defaultSubsets = new HashMap[arrayNames.length]; 660 propsArray = new Hashtable[arrayNames.length]; 661 662 for (int k=0; k<arrayNames.length; k++) { 663 Map<String, Object> swthTable = SwathAdapter.getEmptyMetadataTable(); 664 swthTable.put("array_name", arrayNames[k]); 665 swthTable.put("lon_array_name", "pixel_longitude"); 666 swthTable.put("lat_array_name", "pixel_latitude"); 667 swthTable.put("XTrack", "pixel_elements_along_scan_direction"); 668 swthTable.put("Track", "scan_lines_along_track_direction"); 669 swthTable.put("geo_Track", "scan_lines_along_track_direction"); 670 swthTable.put("geo_XTrack", "pixel_elements_along_scan_direction"); 671 swthTable.put("scale_name", "SCALE_FACTOR"); 672 swthTable.put("offset_name", "ADD_OFFSET"); 673 swthTable.put("fill_value_name", "_FILLVALUE"); 674 swthTable.put("geo_scale_name", "SCALE_FACTOR"); 675 swthTable.put("geo_offset_name", "ADD_OFFSET"); 676 swthTable.put("geo_fillValue_name", "_FILLVALUE"); 677 swthTable.put("range_name", arrayNames[k]); 678 swthTable.put("unpack", "unpack"); 679 680 SwathAdapter swathAdapter0 = new SwathAdapter(reader, swthTable); 681 Map<String, double[]> subset = swathAdapter0.getDefaultSubset(); 682 defaultSubset = subset; 683 adapters[k] = swathAdapter0; 684 defaultSubsets[k] = defaultSubset; 685 } 686 categories = DataCategory.parseCategories("2D grid;GRID-2D;"); 687 hasImagePreview = true; 688 } 689 else if (name.contains("AWG_OZONE") ) { 690 String[] arrayNames = new String[] {"ColumnOzone"}; 691 692 adapters = new MultiDimensionAdapter[arrayNames.length]; 693 defaultSubsets = new HashMap[arrayNames.length]; 694 propsArray = new Hashtable[arrayNames.length]; 695 696 for (int k=0; k<arrayNames.length; k++) { 697 Map<String, Object> swthTable = SwathAdapter.getEmptyMetadataTable(); 698 swthTable.put("array_name", arrayNames[k]); 699 swthTable.put("lon_array_name", "Longitude"); 700 swthTable.put("lat_array_name", "Latitude"); 701 swthTable.put("XTrack", "Columns"); 702 swthTable.put("Track", "Rows"); 703 swthTable.put("fill_value_name", "_FillValue"); 704 swthTable.put("geo_Track", "Rows"); 705 swthTable.put("geo_XTrack", "Columns"); 706 swthTable.put("geo_fillValue_name", "_FillValue"); 707 swthTable.put("range_name", arrayNames[k]); 708 709 SwathAdapter swathAdapter0 = new SwathAdapter(reader, swthTable); 710 swathAdapter0.setDefaultStride(5); 711 Map<String, double[]> subset = swathAdapter0.getDefaultSubset(); 712 defaultSubset = subset; 713 adapters[k] = swathAdapter0; 714 defaultSubsets[k] = defaultSubset; 715 } 716 717 categories = DataCategory.parseCategories("2D grid;GRID-2D;"); 718 hasImagePreview = true; 719 } 720 else if (name.contains("AWG_CLOUD_MASK") ) { 721 String[] arrayNames = new String[] {"CloudMask"}; 722 723 adapters = new MultiDimensionAdapter[arrayNames.length]; 724 defaultSubsets = new HashMap[arrayNames.length]; 725 propsArray = new Hashtable[arrayNames.length]; 726 727 for (int k=0; k<arrayNames.length; k++) { 728 Map<String, Object> swthTable = SwathAdapter.getEmptyMetadataTable(); 729 swthTable.put("array_name", arrayNames[k]); 730 swthTable.put("lon_array_name", "Longitude"); 731 swthTable.put("lat_array_name", "Latitude"); 732 swthTable.put("XTrack", "Columns"); 733 swthTable.put("Track", "Rows"); 734 swthTable.put("fill_value_name", "_FillValue"); 735 swthTable.put("geo_Track", "Rows"); 736 swthTable.put("geo_XTrack", "Columns"); 737 swthTable.put("geo_fillValue_name", "_FillValue"); 738 swthTable.put("range_name", arrayNames[k]); 739 740 SwathAdapter swathAdapter0 = new SwathAdapter(reader, swthTable); 741 swathAdapter0.setDefaultStride(5); 742 Map<String, double[]> subset = swathAdapter0.getDefaultSubset(); 743 defaultSubset = subset; 744 adapters[k] = swathAdapter0; 745 defaultSubsets[k] = defaultSubset; 746 } 747 748 categories = DataCategory.parseCategories("2D grid;GRID-2D;"); 749 hasImagePreview = true; 750 } 751 else if (name.contains("AWG_CLOUD_HEIGHT")) { 752 String[] arrayNames = new String[] {"CldTopTemp", "CldTopPres", "CldTopHght"}; 753 754 adapters = new MultiDimensionAdapter[arrayNames.length]; 755 defaultSubsets = new HashMap[arrayNames.length]; 756 propsArray = new Hashtable[arrayNames.length]; 757 758 for (int k=0; k<arrayNames.length; k++) { 759 Map<String, Object> swthTable = SwathAdapter.getEmptyMetadataTable(); 760 swthTable.put("array_name", arrayNames[k]); 761 swthTable.put("lon_array_name", "Longitude"); 762 swthTable.put("lat_array_name", "Latitude"); 763 swthTable.put("XTrack", "Columns"); 764 swthTable.put("Track", "Rows"); 765 swthTable.put("scale_name", "scale_factor"); 766 swthTable.put("offset_name", "add_offset"); 767 swthTable.put("fill_value_name", "_FillValue"); 768 swthTable.put("geo_Track", "Rows"); 769 swthTable.put("geo_XTrack", "Columns"); 770 swthTable.put("geo_scale_name", "scale_factor"); 771 swthTable.put("geo_offset_name", "add_offset"); 772 swthTable.put("geo_fillValue_name", "_FillValue"); 773 swthTable.put("range_name", arrayNames[k]); 774 swthTable.put("unpack", "unpack"); 775 776 SwathAdapter swathAdapter0 = new SwathAdapter(reader, swthTable); 777 swathAdapter0.setDefaultStride(5); 778 Map<String, double[]> subset = swathAdapter0.getDefaultSubset(); 779 defaultSubset = subset; 780 adapters[k] = swathAdapter0; 781 defaultSubsets[k] = defaultSubset; 782 } 783 categories = DataCategory.parseCategories("2D grid;GRID-2D;"); 784 hasImagePreview = true; 785 } 786 else if (name.startsWith("geocatL2") && name.endsWith("ci.hdf")) { 787 String[] arrayNames = new String[] {"box_average_11um_ctc", "box_average_11um_ctc_scaled", "conv_init", "cloud_type"}; 788 789 adapters = new MultiDimensionAdapter[arrayNames.length]; 790 defaultSubsets = new HashMap[arrayNames.length]; 791 propsArray = new Hashtable[arrayNames.length]; 792 793 for (int k=0; k<arrayNames.length; k++) { 794 Map<String, Object> swthTable = SwathAdapter.getEmptyMetadataTable(); 795 swthTable.put("array_name", arrayNames[k]); 796 swthTable.put("lon_array_name", "lon"); 797 swthTable.put("lat_array_name", "lat"); 798 swthTable.put("XTrack", "Elements"); 799 swthTable.put("Track", "Lines"); 800 swthTable.put("geo_Track", "Lines"); 801 swthTable.put("geo_XTrack", "Elements"); 802 swthTable.put("range_name", arrayNames[k]); 803 804 SwathAdapter swathAdapter0 = new SwathAdapter(reader, swthTable); 805 swathAdapter0.setDefaultStride(1); 806 Map<String, double[]> subset = swathAdapter0.getDefaultSubset(); 807 defaultSubset = subset; 808 adapters[k] = swathAdapter0; 809 defaultSubsets[k] = defaultSubset; 810 } 811 categories = DataCategory.parseCategories("2D grid;GRID-2D;"); 812 hasImagePreview = true; 813 } 814 else { 815 String[] arrayNames = new String[] {"baseline_cmask_seviri_cloud_mask", "baseline_ctype_seviri_cloud_type", 816 "baseline_ctype_seviri_cloud_phase", "baseline_cld_hght_seviri_cloud_top_pressure", 817 "baseline_cld_hght_seviri_cloud_top_height"}; 818 819 adapters = new MultiDimensionAdapter[arrayNames.length]; 820 defaultSubsets = new HashMap[arrayNames.length]; 821 propsArray = new Hashtable[arrayNames.length]; 822 823 for (int k=0; k<arrayNames.length; k++) { 824 Map<String, Object> swthTable = SwathAdapter.getEmptyMetadataTable(); 825 swthTable.put("array_name", arrayNames[k]); 826 swthTable.put("lon_array_name", "pixel_longitude"); 827 swthTable.put("lat_array_name", "pixel_latitude"); 828 swthTable.put("XTrack", "elements"); 829 swthTable.put("Track", "lines"); 830 swthTable.put("scale_name", "scale_factor"); 831 swthTable.put("offset_name", "add_offset"); 832 swthTable.put("fill_value_name", "_FillValue"); 833 swthTable.put("geo_Track", "lines"); 834 swthTable.put("geo_XTrack", "elements"); 835 swthTable.put("geo_scale_name", "scale_factor"); 836 swthTable.put("geo_offset_name", "add_offset"); 837 swthTable.put("geo_fillValue_name", "_FillValue"); 838 swthTable.put("range_name", arrayNames[k]); 839 swthTable.put("unpack", "unpack"); 840 841 SwathAdapter swathAdapter0 = new SwathAdapter(reader, swthTable); 842 swathAdapter0.setDefaultStride(2); 843 Map<String, double[]> subset = swathAdapter0.getDefaultSubset(); 844 defaultSubset = subset; 845 adapters[k] = swathAdapter0; 846 defaultSubsets[k] = defaultSubset; 847 } 848 categories = DataCategory.parseCategories("2D grid;GRID-2D;"); 849 hasImagePreview = true; 850 } 851 852 setProperties(properties); 853 } 854 855 public void initAfterUnpersistence() { 856 try { 857 setup(); 858 } catch (Exception e) { 859 logger.error("could not set up after unpersisting", e); 860 } 861 } 862 863 /** 864 * Make and insert the {@link DataChoice DataChoices} for this {@code DataSource}. 865 */ 866 public void doMakeDataChoices() { 867 DataChoice choice = null; 868 if (adapters != null) { 869 for (int idx=0; idx<adapters.length; idx++) { 870 try { 871 String arrayName = (adapters[idx] == null) ? "_ " : adapters[idx].getArrayName(); 872 choice = doMakeDataChoice(idx, arrayName); 873 adapterMap.put(choice.getName(), adapters[idx]); 874 } catch (Exception e) { 875 logger.error("error making data choices", e); 876 } 877 878 if (choice != null) { 879 addDataChoice(choice); 880 } 881 } 882 } 883 } 884 885 private DataChoice doMakeDataChoice(int idx, String var) throws Exception { 886 String name = var; 887 DataSelection dataSel = (defaultSubsets[idx] == null) ? new MultiDimensionSubset() : new MultiDimensionSubset(defaultSubsets[idx]); 888 Hashtable props = new Hashtable(); 889 props.put(new MultiDimensionSubset(), dataSel); 890 891 if (propsArray != null) { 892 if (propsArray[idx] != null) { 893 propsArray[idx].put(new MultiDimensionSubset(), dataSel); 894 props = propsArray[idx]; 895 } 896 } 897 DirectDataChoice ddc = null; 898 899 if (categories != null) { 900 ddc = new DirectDataChoice(this, idx, name, name, categories, props); 901 } 902 else { 903 ddc = new DirectDataChoice(this, idx, name, name, categoriesArray[idx], props); 904 } 905 906 return ddc; 907 } 908 909 /** 910 * Check to see if this {@code HDFHydraDataSource} is equal to the object 911 * in question. 912 * @param o object in question 913 * @return true if they are the same or equivalent objects 914 */ 915 public boolean equals(Object o) { 916 if ( !(o instanceof MultiDimensionDataSource)) { 917 return false; 918 } 919 return (this == (MultiDimensionDataSource) o); 920 } 921 922 public MultiSpectralData getMultiSpectralData() { 923 return multiSpectData; 924 } 925 926 public String getDatasetName() { 927 return filename; 928 } 929 930 public void setDatasetName(String name) { 931 filename = name; 932 } 933 934 public Map<String, double[]> getSubsetFromLonLatRect(MultiDimensionSubset select, GeoSelection geoSelection) { 935 GeoLocationInfo ginfo = geoSelection.getBoundingBox(); 936 logger.debug("ginfo0: " + ginfo); 937 return adapters[0].getSubsetFromLonLatRect(select.getSubset(), ginfo.getMinLat(), ginfo.getMaxLat(), 938 ginfo.getMinLon(), ginfo.getMaxLon()); 939 } 940 941 public synchronized Data getData(DataChoice dataChoice, DataCategory category, 942 DataSelection dataSelection, Hashtable requestProperties) 943 throws VisADException, RemoteException { 944 return this.getDataInner(dataChoice, category, dataSelection, requestProperties); 945 } 946 947 948 protected Data getDataInner(DataChoice dataChoice, DataCategory category, 949 DataSelection dataSelection, Hashtable requestProperties) 950 throws VisADException, RemoteException { 951 952 MultiDimensionAdapter adapter = null; 953 adapter = adapterMap.get(dataChoice.getName()); 954 955 Hashtable dataChoiceProps = dataChoice.getProperties(); 956 957 //- this hack keeps the HydraImageProbe from doing a getData() 958 //- TODO: need to use categories? 959 if (requestProperties != null) { 960 if ((requestProperties.toString()).equals("{prop.requester=MultiSpectral}")) { 961 return null; 962 } 963 } 964 965 GeoLocationInfo ginfo = null; 966 GeoSelection geoSelection = null; 967 968 if ((dataSelection != null) && (dataSelection.getGeoSelection() != null)) { 969 970 if (dataSelection.getGeoSelection().getBoundingBox() != null) { 971 geoSelection = dataSelection.getGeoSelection(); 972 } 973 else { // no bounding box in the incoming DataSelection. Check the dataChoice. 974 DataSelection datSelFromChoice = dataChoice.getDataSelection(); 975 if (datSelFromChoice != null) { 976 geoSelection = datSelFromChoice.getGeoSelection(); 977 } 978 } 979 } 980 981 if (geoSelection != null) { 982 ginfo = geoSelection.getBoundingBox(); 983 } 984 985 // Still no geo info so check for the lon/lat b.b. in this datasource (last set by DataSelectionComponent) 986 if (ginfo == null) { 987 DataSelection localDataSelection = getDataSelection(); 988 if (localDataSelection != null) { 989 geoSelection = localDataSelection.getGeoSelection(); 990 if (geoSelection != null) { 991 ginfo = geoSelection.getBoundingBox(); 992 } 993 } 994 } 995 996 Data data = null; 997 if (adapters == null) { 998 return data; 999 } 1000 1001 Map<String, double[]> subset = null; 1002 MultiDimensionSubset select = null; 1003 1004 Hashtable table = dataChoice.getProperties(); 1005 Enumeration keys = table.keys(); 1006 while (keys.hasMoreElements()) { 1007 Object key = keys.nextElement(); 1008 if (key instanceof MultiDimensionSubset) { 1009 select = (MultiDimensionSubset) table.get(key); 1010 } 1011 } 1012 1013 try { 1014 subset = null; 1015 if (ginfo != null) { 1016 if (trackSelection != null) { 1017 boolean trackStrideOk = trackSelection.setTrackStride(); 1018 boolean verticalStrideOk = trackSelection.setVerticalStride(); 1019 1020 if (trackStrideOk && verticalStrideOk) { 1021 subset = adapter.getSubsetFromLonLatRect(ginfo.getMinLat(), ginfo.getMaxLat(), 1022 ginfo.getMinLon(), ginfo.getMaxLon(), 1023 trackSelection.trackStride, 1024 trackSelection.verticalStride, 1025 geoSelection.getZStride()); 1026 } else { 1027 // one of the strides is not an integer, let user know 1028 String msg = "Either the Track or Vertical Stride is invalid.\n" + 1029 "Stride values must be positive integers.\n"; 1030 Object[] params = { msg }; 1031 JOptionPane.showMessageDialog(null, params, "Invalid Stride", JOptionPane.OK_OPTION); 1032 return null; 1033 } 1034 } else { 1035 subset = adapter.getSubsetFromLonLatRect(ginfo.getMinLat(), ginfo.getMaxLat(), 1036 ginfo.getMinLon(), ginfo.getMaxLon(), 1037 geoSelection.getXStride(), 1038 geoSelection.getYStride(), 1039 geoSelection.getZStride()); 1040 } 1041 if (subset == null && select != null) { 1042 subset = select.getSubset(); 1043 } 1044 } 1045 else { // no IDV incoming spatial selection info, so check for HYDRA specific via Properties 1046 if (select != null) { 1047 subset = select.getSubset(); 1048 } 1049 1050 if (dataSelection != null) { 1051 Hashtable props = dataSelection.getProperties(); 1052 } 1053 } 1054 1055 if (subset != null) { 1056 data = adapter.getData(subset); 1057 data = applyProperties(data, dataChoiceProps, subset); 1058 } 1059 } catch (Exception e) { 1060 logger.error("getData exception", e); 1061 } 1062 1063 return data; 1064 } 1065 1066 protected Data applyProperties(Data data, Hashtable requestProperties, Map<String, double[]> subset) 1067 throws VisADException, RemoteException, Exception { 1068 Data new_data = data; 1069 1070 if (requestProperties == null) { 1071 new_data = data; 1072 return new_data; 1073 } 1074 1075 if (requestProperties.containsKey("medianFilter")) { 1076 String[] items = (String[]) requestProperties.get("medianFilter"); 1077 int windowVertLen = Integer.parseInt(items[0]); 1078 int windowHorzLen = Integer.parseInt(items[1]); 1079 GriddedSet domainSet = (GriddedSet) ((FlatField)data).getDomainSet(); 1080 int[] lens = domainSet.getLengths(); 1081 float[] range_values = (((FlatField)data).getFloats())[0]; 1082 range_values = 1083 ProfileAlongTrack.medianFilter(range_values, lens[0], lens[1], windowHorzLen, windowVertLen); 1084 ((FlatField)new_data).setSamples(new float[][] {range_values}); 1085 } 1086 if (requestProperties.containsKey("setBelowSfcMissing")) { 1087 FlatField track = (FlatField) track_adapter.getData(subset); 1088 float[] sfcElev = (track.getFloats())[0]; 1089 FlatField field = (FlatField) new_data; 1090 GriddedSet gset = (GriddedSet) field.getDomainSet(); 1091 float[][] samples = gset.getSamples(false); 1092 int[] lens = gset.getLengths(); 1093 float[] range_values = (field.getFloats())[0]; 1094 1095 int trkIdx = ((ProfileAlongTrack3D)adapters[0]).adapter2D.getTrackTupIdx(); 1096 int vrtIdx = ((ProfileAlongTrack3D)adapters[0]).adapter2D.getVertTupIdx(); 1097 1098 int k = 0; 1099 for (int j=0; j<lens[trkIdx]; j++) { 1100 float val = sfcElev[j]; 1101 for (int i=0; i<lens[vrtIdx]; i++) { 1102 if (vrtIdx < trkIdx) k = i + j*lens[0]; 1103 if (trkIdx < vrtIdx) k = j + i*lens[0]; 1104 if (samples[2][k] <= val) { 1105 range_values[k] = Float.NaN; 1106 } 1107 } 1108 } 1109 field.setSamples(new float[][] {range_values}); 1110 } 1111 return new_data; 1112 } 1113 1114 protected void initDataSelectionComponents( 1115 List<DataSelectionComponent> components, 1116 final DataChoice dataChoice) { 1117 1118 if (hasImagePreview) { 1119 try { 1120 FlatField image = (FlatField) getDataInner(dataChoice, null, null, null); 1121 components.add(new PreviewSelection(dataChoice, image, null)); 1122 } catch (Exception e) { 1123 logger.error("cannot make preview selection", e); 1124 } 1125 } 1126 if (hasTrackPreview) { 1127 try { 1128 FlatField track = track_adapter.getData(track_adapter.getDefaultSubset()); 1129 Map defaultSubset = (adapterMap.get(dataChoice.getName())).getDefaultSubset(); 1130 trackSelection = new TrackSelection(dataChoice, track, defaultSubset); 1131 components.add(trackSelection); 1132 } catch (Exception e) { 1133 logger.error("cannot make preview selection", e); 1134 } 1135 } 1136 } 1137 1138 private String getTrackDimensionName(String variableName) { 1139 return getVariableDimensionName(variableName, 0); 1140 } 1141 1142 private String getVerticalDimensionName(String variableName) { 1143 return getVariableDimensionName(variableName, 1); 1144 } 1145 1146 private String getVariableDimensionName(String variableName, int dimension) { 1147 NetcdfFile ncfile = ((NetCDFFile)reader).getNetCDFFile(); 1148 Variable v = ncfile.findVariable(variableName); 1149 String name = null; 1150 if (v != null) { 1151 name = v.getDimension(dimension).getFullName(); 1152 } 1153 return name; 1154 } 1155 1156 private boolean hasVariable(String variableName) { 1157 NetcdfFile ncfile = ((NetCDFFile) reader).getNetCDFFile(); 1158 return ncfile.findVariable(variableName) != null; 1159 } 1160 1161 private ArrayAdapter createTrackVertArrayAdapter(String variableName) { 1162 Map<String, Object> table = SwathAdapter.getEmptyMetadataTable(); 1163 1164 String trackDimName = getTrackDimensionName(variableName); 1165 String vertDimName = getVerticalDimensionName(variableName); 1166 1167 table.put(ProfileAlongTrack.array_name, variableName); 1168 table.put(ProfileAlongTrack.trackDim_name, trackDimName); 1169 table.put(ProfileAlongTrack.vertDim_name, vertDimName); 1170 table.put("array_dimension_names", new String[] { trackDimName, vertDimName }); 1171 1172 return new ArrayAdapter(reader, table); 1173 } 1174}