001/* 002 * $Id: SwathAdapter.java,v 1.20 2011/03/24 16:06:33 davep Exp $ 003 * 004 * This file is part of McIDAS-V 005 * 006 * Copyright 2007-2011 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 031package edu.wisc.ssec.mcidasv.data.hydra; 032 033import java.util.HashMap; 034 035import visad.CoordinateSystem; 036import visad.FunctionType; 037import visad.Linear2DSet; 038import visad.RealTupleType; 039import visad.RealType; 040import visad.Set; 041import visad.Unit; 042 043public class SwathAdapter extends MultiDimensionAdapter { 044 045 String nav_type = "Interp"; 046 boolean lon_lat_trusted = true; 047 048 private int TrackLen; 049 private int XTrackLen; 050 051 static String longitude_name = "Longitude"; 052 static String latitude_name = "Latitude"; 053 static String track_name = "Track"; 054 static String xtrack_name = "XTrack"; 055 static String geo_track_name = "geo_Track"; 056 static String geo_xtrack_name = "geo_XTrack"; 057 static String array_name = "array_name"; 058 static String array_dimension_names = "array_dimension_names"; 059 static String lon_array_name = "lon_array_name"; 060 static String lat_array_name = "lat_array_name"; 061 static String lon_array_dimension_names = "lon_array_dimension_names"; 062 static String lat_array_dimension_names = "lat_array_dimension_names"; 063 static String range_name = "range_name"; 064 static String product_name = "product_name"; 065 static String scale_name = "scale_name"; 066 static String offset_name = "offset_name"; 067 static String fill_value_name = "fill_value_name"; 068 static String geo_track_offset_name = "geoTrack_offset"; 069 static String geo_xtrack_offset_name = "geoXTrack_offset"; 070 static String geo_track_skip_name = "geoTrack_skip"; 071 static String geo_xtrack_skip_name = "geoXTrack_skip"; 072 073 String[] rangeName_s = null; 074 Class[] arrayType_s = null; 075 Unit[] rangeUnit_s = new Unit[] {null}; 076 077 String rangeName = null; 078 079 RealType track = RealType.getRealType(track_name); 080 RealType xtrack = RealType.getRealType(xtrack_name); 081 RealType[] domainRealTypes = new RealType[2]; 082 083 int track_idx = -1; 084 int xtrack_idx = -1; 085 int lon_track_idx = -1; 086 int lon_xtrack_idx = -1; 087 int lat_track_idx = -1; 088 int lat_xtrack_idx = -1; 089 int range_rank = -1; 090 091 int geo_track_offset = 0; 092 int geo_track_skip = 1; 093 int geo_xtrack_offset = 0; 094 int geo_xtrack_skip = 1; 095 096 int track_tup_idx; 097 int xtrack_tup_idx; 098 099 private SwathNavigation navigation; 100 101 private Linear2DSet swathDomain; 102 private Linear2DSet domainSet_save; 103 104 private Object last_subset; 105 106 int default_stride = 1; 107 108 public static HashMap getEmptySubset() { 109 HashMap<String, double[]> subset = new HashMap<String, double[]>(); 110 subset.put(track_name, new double[3]); 111 subset.put(xtrack_name, new double[3]); 112 return subset; 113 } 114 115 public static HashMap<String, Object> getEmptyMetadataTable() { 116 HashMap<String, Object> metadata = new HashMap<String, Object>(); 117 metadata.put(array_name, null); 118 metadata.put(array_dimension_names, null); 119 metadata.put(track_name, null); 120 metadata.put(xtrack_name, null); 121 metadata.put(geo_track_name, null); 122 metadata.put(geo_xtrack_name, null); 123 metadata.put(lon_array_name, null); 124 metadata.put(lat_array_name, null); 125 metadata.put(lon_array_dimension_names, null); 126 metadata.put(lat_array_dimension_names, null); 127 metadata.put(scale_name, null); 128 metadata.put(offset_name, null); 129 metadata.put(fill_value_name, null); 130 metadata.put(range_name, null); 131 metadata.put(product_name, null); 132 metadata.put(geo_track_offset_name, null); 133 metadata.put(geo_xtrack_offset_name, null); 134 metadata.put(geo_track_skip_name, null); 135 metadata.put(geo_xtrack_skip_name, null); 136 return metadata; 137 } 138 139 public SwathAdapter() { 140 141 } 142 143 public SwathAdapter(MultiDimensionReader reader, HashMap metadata) { 144 super(reader, metadata); 145 this.init(); 146 } 147 148 private void init() { 149 for (int k=0; k<array_rank;k++) { 150 if ( ((String)metadata.get(track_name)).equals(array_dim_names[k]) ) { 151 track_idx = k; 152 } 153 if ( ((String)metadata.get(xtrack_name)).equals(array_dim_names[k]) ) { 154 xtrack_idx = k; 155 } 156 } 157 158 int[] lengths = new int[2]; 159 160 if (track_idx < xtrack_idx) { 161 domainRealTypes[0] = xtrack; 162 domainRealTypes[1] = track; 163 lengths[0] = array_dim_lengths[xtrack_idx]; 164 lengths[1] = array_dim_lengths[track_idx]; 165 track_tup_idx = 1; 166 xtrack_tup_idx = 0; 167 } 168 else { 169 domainRealTypes[0] = track; 170 domainRealTypes[1] = xtrack; 171 lengths[0] = array_dim_lengths[track_idx]; 172 lengths[1] = array_dim_lengths[xtrack_idx]; 173 track_tup_idx = 0; 174 xtrack_tup_idx = 1; 175 } 176 177 TrackLen = array_dim_lengths[track_idx]; 178 XTrackLen = array_dim_lengths[xtrack_idx]; 179 180 setLengths(); 181 182 lengths[track_tup_idx] = TrackLen; 183 lengths[xtrack_tup_idx] = XTrackLen; 184 185 if (metadata.get(range_name) != null) { 186 rangeName = (String)metadata.get(range_name); 187 } 188 else { 189 rangeName = (String)metadata.get(array_name); 190 } 191 192 rangeType = RealType.getRealType(rangeName, rangeUnit_s[0]); 193 194 /** TODO could be a mis-match between supplied unit, and default 195 unit of an existing RealType with same name. */ 196 if (rangeType == null) { 197 rangeType = RealType.getRealType(rangeName); 198 } 199 200 try { 201 RangeProcessor rangeProcessor = RangeProcessor.createRangeProcessor(reader, metadata); 202 if ( !(reader instanceof GranuleAggregation) ) { 203 setRangeProcessor(rangeProcessor); 204 } 205 } 206 catch (Exception e) { 207 System.out.println("RangeProcessor failed to create"); 208 e.printStackTrace(); 209 } 210 211 try { 212 navigation = SwathNavigation.createNavigation(this); 213 RealTupleType domainTupType = new RealTupleType(domainRealTypes[0], domainRealTypes[1]); 214 swathDomain = new Linear2DSet(domainTupType, 0, lengths[0]-1, lengths[0], 0, lengths[1]-1, lengths[1]); 215 } 216 catch (Exception e) { 217 System.out.println("Navigation failed to create"); 218 e.printStackTrace(); 219 } 220 221 if (XTrackLen <= 256) { 222 default_stride = 1; 223 } 224 else { 225 default_stride = (int) XTrackLen/256; 226 } 227 228 /* force default stride even */ 229 if (default_stride > 1) { 230 default_stride = (default_stride/2)*2; 231 } 232 233 } 234 235 protected void setLengths() { 236 } 237 238 public int getTrackLength() { 239 return TrackLen; 240 } 241 242 public int getXTrackLength() { 243 return XTrackLen; 244 } 245 246 public SwathNavigation getNavigation() { 247 return navigation; 248 } 249 250 protected void setTrackLength(int len) { 251 TrackLen = len; 252 } 253 254 protected void setXTrackLength(int len) { 255 XTrackLen = len; 256 } 257 258 public Set makeDomain(Object subset) throws Exception { 259 if (last_subset != null) { 260 if (spatialEquals(last_subset, subset)) return domainSet_save; 261 } 262 last_subset = subset; 263 264 double[] first = new double[2]; 265 double[] last = new double[2]; 266 int[] length = new int[2]; 267 268 HashMap<String, double[]> domainSubset = new HashMap<String, double[]>(); 269 domainSubset.put(track_name, (double[]) ((HashMap)subset).get(track_name)); 270 domainSubset.put(xtrack_name, (double[]) ((HashMap)subset).get(xtrack_name)); 271 272 domainSubset.put(track_name, new double[] {0,0,0}); 273 domainSubset.put(xtrack_name, new double[] {0,0,0}); 274 275 // compute coordinates for the Linear2D domainSet 276 for (int kk=0; kk<2; kk++) { 277 RealType rtype = domainRealTypes[kk]; 278 String name = rtype.getName(); 279 double[] coords = (double[]) ((HashMap)subset).get(name); 280 first[kk] = coords[0]; 281 last[kk] = coords[1]; 282 length[kk] = (int) ((last[kk] - first[kk])/coords[2] + 1); 283 last[kk] = first[kk] + (length[kk]-1)*coords[2]; 284 285 double[] new_coords = domainSubset.get(name); 286 new_coords[0] = first[kk]; 287 new_coords[1] = last[kk]; 288 new_coords[2] = coords[2]; 289 } 290 291 Linear2DSet domainSet = new Linear2DSet(first[0], last[0], length[0], first[1], last[1], length[1]); 292 //CoordinateSystem cs = navigation.getVisADCoordinateSystem(domainSet, domainSubset); 293 CoordinateSystem cs = navigation.getVisADCoordinateSystem(domainSet, subset); 294 295 RealTupleType domainTupType = new RealTupleType(domainRealTypes[0], domainRealTypes[1], cs, null); 296 domainSet_save = new Linear2DSet(domainTupType, first[0], last[0], length[0], first[1], last[1], length[1]); 297 298 return domainSet_save; 299 } 300 301 public String getArrayName() { 302 return rangeName; 303 } 304 305 public FunctionType getMathType() { 306 return null; 307 } 308 309 public RealType[] getDomainRealTypes() { 310 return domainRealTypes; 311 } 312 313 public Linear2DSet getSwathDomain() { 314 return swathDomain; 315 } 316 317 public boolean spatialEquals(Object last_subset, Object subset) { 318 double[] last_coords = (double[]) ((HashMap)last_subset).get(track_name); 319 double[] coords = (double[]) ((HashMap)subset).get(track_name); 320 321 for (int k=0; k<coords.length; k++) { 322 if (coords[k] != last_coords[k]) { 323 return false; 324 } 325 } 326 327 last_coords = (double[]) ((HashMap)last_subset).get(xtrack_name); 328 coords = (double[]) ((HashMap)subset).get(xtrack_name); 329 330 for (int k=0; k<coords.length; k++) { 331 if (coords[k] != last_coords[k]) { 332 return false; 333 } 334 } 335 336 return true; 337 } 338 339 public void setDefaultStride(int stride) { 340 default_stride = stride; 341 } 342 343 public HashMap getDefaultSubset() { 344 HashMap subset = SwathAdapter.getEmptySubset(); 345 346 double[] coords = (double[])subset.get("Track"); 347 coords[0] = 0.0; 348 coords[1] = TrackLen - 1; 349 coords[2] = (double)default_stride; 350 subset.put("Track", coords); 351 352 coords = (double[])subset.get("XTrack"); 353 coords[0] = 0.0; 354 coords[1] = XTrackLen - 1 ; 355 coords[2] = (double)default_stride; 356 subset.put("XTrack", coords); 357 return subset; 358 } 359}