001/* 002 * $Id: FrameDirectory.java,v 1.10 2011/03/24 16:06:32 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; 032 033import edu.wisc.ssec.mcidas.AREAnav; 034import edu.wisc.ssec.mcidas.McIDASUtil; 035 036import java.io.*; 037import java.util.Date; 038 039/** 040 * Class FrameDirectory holds information obtained 041 * from frame directory files, FRAMEn.p, from McIdas-X 042 */ 043public class FrameDirectory { 044 045 /** time of data in frame */ 046 private Date nominalTime; 047 048 /** Sensor source name */ 049 private String sensorName; 050 051 /** Sensor source number */ 052 private int sensorNumber; 053 054 /** Year and Julian day, ccyyddd */ 055 private int cyd; 056 057 /** Time, hhmmss */ 058 private int hms; 059 060 /** Band number */ 061 private int band; 062 063 /** Upper-left corner satellite coordinates */ 064 private int uLLine; 065 private int uLEle; 066 067 /** Magnification factors */ 068 private int lineMag; 069 private int eleMag; 070 071 /** Resolution factors */ 072 private int lineRes; 073 private int eleRes; 074 075 /** Navigation block */ 076 private int[] nav; 077 078 /** Navigation block */ 079 private int[] aux; 080 081 /** GRAF navigation type */ 082 private int AREAnavGRAF = 1196572998; 083 084 /** 085 * Constructor 086 */ 087 public FrameDirectory() { } 088 089 /** 090 * Copy constructor 091 * 092 * @param that The FrameDirectory to copy 093 * 094 */ 095 public FrameDirectory(FrameDirectory that) { 096 this.sensorName = that.sensorName; 097 this.sensorNumber = that.sensorNumber; 098 this.cyd = that.cyd; 099 this.hms = that.hms; 100 this.nominalTime = new Date(1000*McIDASUtil.mcDayTimeToSecs(that.cyd,that.hms)); 101 this.band = that.band; 102 this.uLLine = that.uLLine; 103 this.uLEle = that.uLEle; 104 this.lineMag = that.lineMag; 105 this.eleMag = that.eleMag; 106 this.lineRes = that.lineRes; 107 this.eleRes = that.eleRes; 108 this.nav = that.nav; 109 this.aux = that.aux; 110 } 111 112 /** 113 * Constructor 114 * 115 * @param directory frame directory from McIdax-X 116 * 117 */ 118 public FrameDirectory(int[] directory) { 119 //System.out.println("FrameDirectory constructor:"); 120 this.sensorNumber = directory[0]; 121// if (this.sensorNumber != -1) 122// this.sensorName = getName(directory[0]); 123// else 124// this.sensorName = ""; 125 this.sensorName = ""; 126 this.cyd = directory[1]; 127 this.hms = directory[2]; 128 this.nominalTime = new Date(1000*McIDASUtil.mcDayTimeToSecs(cyd,hms)); 129 this.band = directory[3]; 130 this.uLLine = directory[4]; 131 this.uLEle = directory[5]; 132 this.lineRes = directory[10]; 133 this.eleRes = directory[11]; 134 this.lineMag = directory[19]; 135 this.eleMag = directory[20]; 136 137// if (this.lineMag < 0) this.lineMag = 1; 138// if (this.eleMag < 0) this.eleMag = 1; 139// this.lineMag=1; 140// this.eleMag=1; 141 142/* 143 System.out.println(" cyd=" + cyd); 144 System.out.println(" hms=" + hms); 145 System.out.println(" band=" + band); 146 System.out.println(" uLLine=" + uLLine); 147 System.out.println(" uLEle=" + uLEle); 148 System.out.println(" lineMag=" + lineMag); 149 System.out.println(" eleMag=" + eleMag); 150 System.out.println(" lineRes=" + lineRes); 151 System.out.println(" eleRes=" + eleRes); 152*/ 153// System.out.println("Navigation type " + directory[64] + ": " + navIntToString(directory[64])); 154 155 int navLength; 156 if (directory[64] == AREAnav.LALO) navLength = 128; 157 else navLength = 640; 158 this.nav = new int[navLength]; 159 System.arraycopy(directory, 64, this.nav, 0, navLength); 160 161 if (this.nav[0] == this.AREAnavGRAF) 162 this.nav = transformGRAFIntoRECT(this.nav); 163 164 int auxLength = 0; 165 int rows = 0; 166 int cols = 0; 167 int begLat = 0; 168 int begLon = 0; 169 if (this.nav[0] == AREAnav.LALO) { 170 rows = this.nav[65]; 171 cols = this.nav[66]; 172 begLat = this.nav[78]/4; 173 begLon = this.nav[79]/4; 174 auxLength = begLon + (rows*cols); 175 this.aux = new int[auxLength]; 176 } 177 else { 178 this.aux = new int[1]; 179 } 180 int numPoints = rows * cols; 181 System.arraycopy(directory, 64+navLength, this.aux, begLat, numPoints); 182 if (auxLength > 0) { 183 System.arraycopy(directory, 64+navLength+numPoints, this.aux, begLon, numPoints); 184 } 185// System.out.println("FrameDirectory navLength: " + navLength + ", auxLength: " + auxLength); 186 } 187 188 /* 189 * TODO: FrameDirectory.getName() is not used right now... keep the code here just in case. 190 * If you do decide you need it, read SATANNOT over the bridge, not locally... 191 */ 192/* 193 public String getName(int num) { 194 String name = ""; 195 FileInputStream fis; 196 //byte[] bline={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 197 byte[] bline = new byte[31]; 198 int off=0; 199 int ret = 0; 200 int sensor=0; 201 202 System.out.println("Fix this: SATANNOT should not be read locally"); 203 try { 204 fis = new FileInputStream("/home/mcidas/data/SATANNOT"); 205 } catch(Exception e) { 206 System.out.println("FrameDirectory: Can't find SATANNOT"); 207 return name; 208 } 209 int counter=0; 210 int sensor1=0; 211 int sensor2=0; 212 int sensor3=0; 213 while (ret != -1) { 214 try { 215 int ptr=0; 216 int next=0; 217 for (int i=0;i<19; i++) { 218 next = fis.read(); 219 bline[ptr] = (byte)next; 220 ptr++; 221 } 222 name = new String(bline, 0, ptr); 223 for (int i=20;i<30; i++) { 224 off = fis.read(); 225 } 226 sensor1 = fis.read()-48; 227 sensor2 = fis.read()-48; 228 sensor3 = fis.read()-48; 229 sensor = 0; 230 if (sensor1 >= 0) { 231 sensor = sensor1; 232 } 233 if (sensor2 >= 0) { 234 sensor *= 10; 235 sensor += sensor2; 236 } 237 if (sensor3 >= 0) { 238 sensor *= 10; 239 sensor += sensor3; 240 } 241 for (int i=32; i<80; i++) 242 off = fis.read(); 243 } catch(Exception e) { 244 System.out.println("FrameDirectory: Can't read SATANNOT"); 245 try { 246 fis.close(); 247 } catch (Exception ee) { 248 } 249 return name; 250 } 251 if (sensor == num) ret =-1; 252 counter++; 253 if (counter>200) ret=-1; 254 } 255 try { 256 fis.close(); 257 } catch (Exception e) { 258 } 259 return name; 260 } 261*/ 262 263 /** 264 * Get the nominalTime. 265 * 266 * @return The nominalTime. 267 */ 268 public Date getNominalTime() { 269 return this.nominalTime; 270 } 271 272 /** 273 * Get the sensorName. 274 * 275 * @return The sensorName. 276 */ 277 public String getSensorName() { 278 return this.sensorName; 279 } 280 281 /** 282 * Get the sensorNumber. 283 * 284 * @return The sensorNumber. 285 */ 286 public int getSensorNumber() { 287 return this.sensorNumber; 288 } 289 290 /** 291 * Get cyd. 292 * 293 * @return cyd. 294 */ 295 public int getCyd() { 296 return this.cyd; 297 } 298 299 /** 300 * Get hms. 301 * 302 * @return hms. 303 */ 304 public int getHms() { 305 return this.hms; 306 } 307 308 /** 309 * Get band. 310 * 311 * @return band. 312 */ 313 public int getBand() { 314 return this.band; 315 } 316 317 /** 318 * Set sensorName. 319 * 320 * @param newName The new vaue for sensorName. 321 */ 322 public void setSensorName(String newName) { 323 this.sensorName = newName; 324 } 325 326 /** 327 * Set cyd. 328 * 329 * @param newCyd The new vaue for cyd. 330 */ 331 public void setCyd(int newCyd) { 332 this.cyd = newCyd; 333 } 334 335 /** 336 * Set hms. 337 * 338 * @param newHms The new vaue for hms. 339 */ 340 public void setHms(int newHms) { 341 this.hms = newHms; 342 } 343 344 /** 345 * Set band. 346 * 347 * @param newBand The new vaue for band. 348 */ 349 public void setBand(int newBand) { 350 this.band = newBand; 351 } 352 353 /** 354 * Get a String representation of this object 355 * @return a string representation 356 */ 357 public String toString() { 358 StringBuffer buf = new StringBuffer(); 359 buf.append(this.sensorName + " "); 360 buf.append(this.sensorNumber + " "); 361 buf.append(this.cyd + " "); 362 buf.append(this.hms + " "); 363 buf.append(this.band); 364 return buf.toString(); 365 } 366 367 public int[] getFrameNav() { 368 return nav; 369 } 370 371 public int[] getFrameAux() { 372 return aux; 373 } 374 375 public int getLineRes() { 376 return lineRes; 377 } 378 379 public int getEleRes() { 380 return eleRes; 381 } 382 383 public int getULLine() { 384 return uLLine; 385 } 386 387 public int getULEle() { 388 return uLEle; 389 } 390 391 /** 392 * Print the nav type 393 */ 394 private String navIntToString(int navInt) { 395 int int1 = navInt/0x1000000&0xff; 396 int int2 = navInt/0x10000&0xff; 397 int int3 = navInt/0x100&0xff; 398 int int4 = navInt&0xff; 399 String char1 = new Character((char)int1).toString(); 400 String char2 = new Character((char)int2).toString(); 401 String char3 = new Character((char)int3).toString(); 402 String char4 = new Character((char)int4).toString(); 403 String returnString = char1 + char2 + char3 + char4; 404 return returnString; 405 } 406 407 /** 408 * Since GRAF is not a real data projection, try to munge it into RECT for VisAD 409 */ 410 private int[] transformGRAFIntoRECT(int[] nav) { 411 if (nav[0] != this.AREAnavGRAF) return nav; 412 int[] RECT = nav; 413 int minLat = RECT[21]; 414 int maxLat = RECT[22]; 415 int minLon = RECT[23]; 416 int maxLon = RECT[24]; 417 int minY = RECT[25]; 418 int maxY = RECT[26]; 419 int minX = RECT[27]; 420 int maxX = RECT[28]; 421 int centerLat = Math.round((maxLat - minLat) / 2) + minLat; 422 int centerLon = Math.round((maxLon - minLon) / 2) + minLon; 423 int rangeLat = maxLat - minLat; 424 int rangeLon = maxLon - minLon; 425 int centerY = Math.round((maxY - minY) / 2) + minY; 426 int centerX = Math.round((maxX - minX) / 2) + minX; 427 int rangeY = maxY - minY; 428 int rangeX = maxX - minX; 429 RECT[0] = AREAnav.RECT; 430 RECT[1] = centerY - minY; 431 RECT[2] = centerLat; 432 RECT[3] = centerX - minX; 433 RECT[4] = centerLon; 434 RECT[5] = Math.round(rangeLat / rangeY); 435 RECT[6] = Math.round(rangeLon / rangeX); 436 // Earth constants (eccentricity and radius) 437 RECT[7] = 6378388; 438 RECT[8] = 81992; 439 for (int i=9; i<24; i++) RECT[i] = 0; 440 return RECT; 441 } 442}