001 /*
002 * $Id: FrameDirectory.java,v 1.11 2012/02/19 17:35:44 davep 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;
032
033 import edu.wisc.ssec.mcidas.AREAnav;
034 import edu.wisc.ssec.mcidas.McIDASUtil;
035
036 import java.io.*;
037 import java.util.Date;
038
039 /**
040 * Class FrameDirectory holds information obtained
041 * from frame directory files, FRAMEn.p, from McIdas-X
042 */
043 public 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 }