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 */
028
029package edu.wisc.ssec.mcidasv.adt;
030
031import java.lang.Math;
032
033class IRRingData {
034   double distance;
035   double angle;
036   double temperature;
037}
038
039public class Data {
040
041   private static double KtoC_Value=273.16;
042   private static double OUTER_RADIUS=136.0;
043   private static double INNER_RADIUS=24.0;
044   private static double RING_WIDTH=4.0;
045   private static double EYE_SEARCH_RADIUS=24.0;
046   private static int MAXSECTOR = 24;
047   private static int MAXSECTORA = 10000;
048   private static int TEMPBINS = 64;
049   private static int RINGSLICESIZE = 15;
050   private static int RingDataArrayNumber;
051   private static int CWRing_Distance;
052   private static double Eye_Temperature;
053   private static double CWCloud_Temperature;
054   private static double Cloud_Temperature;
055   private static double Cloud2_Temperature;
056   private static double Cloud_Symmetry;
057   private static double Eye_STDV;
058   private static int Eye_FFTValue;
059   private static int Cloud_FFTValue;
060
061   private static IRRingData RingArray[] = new IRRingData[40000];
062   private static double MaxTempRingArray[] = new double[50];
063
064   public static int IRData_NumberRows;
065   public static int IRData_NumberColumns;
066   public static int IRData_JulianDate;
067   public static int IRData_HHMMSSTime;
068   public static double IRData_CenterLatitude;
069   public static double IRData_CenterLongitude;
070   public static double IRData_ImageResolution;
071   public static float[][] IRData_Latitude = new float[200][200];
072   public static float[][] IRData_Longitude = new float[200][200];
073   public static float[][] IRData_Temperature = new float[200][200];
074
075   public Data() {
076     Eye_Temperature=-999.9;
077     CWCloud_Temperature=-999.9;
078     Cloud_Temperature=-999.9;
079     Cloud2_Temperature=-999.9;
080     Cloud_Symmetry=-999.9;
081     Eye_STDV=-999.9;
082     CWRing_Distance=999;
083   }
084
085   private static void LoadRingData(double CenterLatitude,double CenterLongitude) 
086   {
087      double LatVal,LonVal,TempVal;
088      
089      RingDataArrayNumber = 0;
090      /* System.out.printf("CenterLat=%f CenterLon=%f\n",CenterLatitude,CenterLongitude); */
091      /* System.out.printf("numberRows=%d numberColumns=%d\n",IRData_NumberRows,IRData_NumberColumns); */
092      for (int j = 0; j < IRData_NumberRows; j++ ) {
093         for (int i = 0; i < IRData_NumberColumns; i++ ) {
094            LatVal = IRData_Latitude[j][i];
095            LonVal = IRData_Longitude[j][i];
096            TempVal = IRData_Temperature[j][i];
097            double LocalValue[] = Functions.distance_angle(LatVal,LonVal,
098                                  CenterLatitude,CenterLongitude,1);
099
100            if(LocalValue[0]<=(OUTER_RADIUS+80.0)) {
101               /* System.out.printf("j=%d i=%d  lat=%f lon=%f temp=%f ",j,i,LatVal,LonVal,TempVal); */
102               /* System.out.printf("  Distance=%f Angle=%f  ringarraynumber=%d \n",LocalValue[0],LocalValue[1],RingDataArrayNumber); */
103               RingArray[RingDataArrayNumber] = new IRRingData();
104
105               RingArray[RingDataArrayNumber].distance = LocalValue[0];
106               RingArray[RingDataArrayNumber].angle = LocalValue[1];
107               RingArray[RingDataArrayNumber].temperature = TempVal;
108               RingDataArrayNumber++;
109            }
110         }
111      }
112 
113   }
114
115   private static int RingDataNumberOfPoints() {
116      return RingDataArrayNumber;
117   }
118
119   private static double CalcEyeTemperature() {
120      double EyeMaxTemp=-99.0;
121
122      int RingDataCount = Data.RingDataNumberOfPoints();
123      /* System.out.printf("number of points in RingData=%d\n",RingDataCount); */
124
125      for (int i = 0; i < RingDataCount; i++ ) {
126         if(RingArray[i].distance<=EYE_SEARCH_RADIUS) {
127            /* System.out.printf("i=%d distance=%f temp=%f MAX=%f\n",i,RingArray[i].distance,RingArray[i].temperature,EyeMaxTemp); */
128            if(RingArray[i].temperature>EyeMaxTemp) {
129               EyeMaxTemp=RingArray[i].temperature;
130            }
131         }
132      }
133
134      return EyeMaxTemp; 
135   }
136
137   private static double[] CalcCWCloudInfo() {
138      double CWCloudTemp=10000.0;
139      double CWRingDist=0;
140      double DistVal;
141      double TempVal;
142      int CurrentRing;
143      int IntVal;
144      int i,j;
145
146      int RingDataCount = Data.RingDataNumberOfPoints();
147
148      int MaxNumberRings = (int)((OUTER_RADIUS-INNER_RADIUS)/RING_WIDTH);
149      /* System.out.printf("maxNumberRings=%d\n",MaxNumberRings); */
150      for (j = 0; j < MaxNumberRings; j++ ) {
151         MaxTempRingArray[j] = -999.0;
152      }
153
154      for (i = 0; i < RingDataCount; i++ ) {
155         DistVal = RingArray[i].distance;
156         TempVal = RingArray[i].temperature;
157         if((DistVal>=INNER_RADIUS)&&(DistVal<OUTER_RADIUS)) {
158            IntVal = (int)(DistVal-INNER_RADIUS);
159            CurrentRing = IntVal/((int)RING_WIDTH);
160            if(TempVal>MaxTempRingArray[CurrentRing]) {
161               MaxTempRingArray[CurrentRing] = TempVal;
162            }
163         }
164      }
165
166      for (j = 0; j < MaxNumberRings; j++ ) {
167         if((MaxTempRingArray[j]<CWCloudTemp)&&
168            (MaxTempRingArray[j]>160.0)) {
169            CWCloudTemp=MaxTempRingArray[j];
170            CWRingDist=(((double)j)*RING_WIDTH)+INNER_RADIUS;
171         }
172         /* System.out.printf("ring=%d MaxTempRing=%f CWCloudTemp=%f CWRingDist=%f\n",j,MaxTempRingArray[j],CWCloudTemp,CWRingDist); */
173      }
174
175      return new double[] {CWCloudTemp, CWRingDist }; 
176
177   }
178
179   private static double[] CalcSkew(double[] InputArray,int Counter) {
180
181      int i;
182      double ArraySum=0.0;
183      double DifferenceValue=0.0;
184      double ArrayValuesSumSquared=0.0;
185      double STDVValue;
186
187      for (i = 0; i < Counter ; i++ ) {
188         ArraySum = ArraySum + InputArray[i];
189      }
190      double AverageValue = ArraySum/(double)Counter;
191
192      for (i = 0; i < Counter ; i++ ) {
193         DifferenceValue = InputArray[i] - AverageValue;
194         ArrayValuesSumSquared = ArrayValuesSumSquared +
195                                 (DifferenceValue*DifferenceValue);
196      }
197
198      if(Counter<=1) {
199         STDVValue = 0.0;
200      } else {
201         STDVValue = Math.sqrt((1.0/((double)Counter-1.0))*ArrayValuesSumSquared);
202      }
203
204      /* System.out.printf("average value=%f  stdv=%f\n",AverageValue, STDVValue); */
205
206      return new double[] { AverageValue, STDVValue }; 
207   }
208
209
210   private static double[] CalcEyeCloudInfo() {
211
212      int i,j;
213      double InnerRadiusDistance;
214      double OuterRadiusDistance;
215      double DistVal,AngleVal,TempVal;
216      int SectorCountArray[] = new int[MAXSECTORA];
217      double TemperatureHistArray[] = new double[TEMPBINS];
218      double TemperatureHistArrayCounter[] = new double[TEMPBINS];
219      double TemperatureArray[] = new double[TEMPBINS];
220      double SectorDataArray[][] = new double[MAXSECTOR][MAXSECTORA];
221      double EyeDataArray[] = new double[MAXSECTORA];
222      double SectorAverageArray[] = new double[MAXSECTOR];
223      double SectorStdvArray[] = new double[MAXSECTOR];
224 
225      int RingDataCount = Data.RingDataNumberOfPoints();
226
227      for (i = 0; i < TEMPBINS; i++ ) {
228         TemperatureHistArray[i] = KtoC_Value + 26.0 - ((double)i)*2.0;
229      }
230 
231      /* determine FFT values for Eye and Cloud regions */
232      for (int SceneIDFlag = 0; SceneIDFlag <=1 ; SceneIDFlag++ ) {
233         for (i = 0; i < TEMPBINS; i++ ) {
234            TemperatureHistArrayCounter[i] = 0.0;
235            TemperatureArray[i] = 0.0;
236         }
237 
238         if(SceneIDFlag==0) {
239            /* CLOUD TOP REGION */
240            InnerRadiusDistance = (double)INNER_RADIUS;
241            OuterRadiusDistance = (double)OUTER_RADIUS;
242         }
243         else {
244            /* EYE REGION */
245            InnerRadiusDistance = (double)0;
246            OuterRadiusDistance = (double)INNER_RADIUS;
247         }
248 
249         for (i = 0; i < RingDataCount; i++ ) {
250            DistVal = RingArray[i].distance;
251            if((DistVal>=InnerRadiusDistance)&&(DistVal<=OuterRadiusDistance)) {
252               TempVal = RingArray[i].temperature;
253               for (j = 0; j < (TEMPBINS-1); j++ ) {
254                  if((TempVal<=TemperatureHistArray[j])&&(TempVal>TemperatureHistArray[j+1])) {
255                     TemperatureHistArrayCounter[j] = TemperatureHistArrayCounter[j] + 1.0;
256                     TemperatureArray[j] = TemperatureArray[j] + TempVal;
257                  }
258               }
259            }
260         }
261
262         int FFT_ReturnValue = FFT.calculateFFT(TemperatureHistArrayCounter);
263         
264         /* System.out.printf("sceneID=%d  harmonic=%d\n",SceneIDFlag,FFT_ReturnValue); */
265
266         if(SceneIDFlag==0) {
267           Cloud_FFTValue = FFT_ReturnValue;
268         } else {
269           Eye_FFTValue = FFT_ReturnValue;
270         }
271      }
272
273      History.IRCurrentRecord.eyefft = Eye_FFTValue;
274      History.IRCurrentRecord.cloudfft = Cloud_FFTValue;
275
276      /* determine various Eye and Cloud region parameters */
277      for (i = 0; i < MAXSECTOR; i++ ) {
278         SectorCountArray[i] = 0;
279      }
280
281      int EyeCount = 0;
282      InnerRadiusDistance = (double)INNER_RADIUS;
283      OuterRadiusDistance = (double)OUTER_RADIUS;
284
285      for (i = 0; i < RingDataCount; i++ ) {
286         DistVal = RingArray[i].distance;
287         AngleVal = RingArray[i].angle;
288         TempVal = RingArray[i].temperature;
289         if(AngleVal==360.0) AngleVal = 0.0;
290         int SectorVal = 0;
291
292         /* Check for Cloud region pixel */
293         if((DistVal>=InnerRadiusDistance)&&(DistVal<=OuterRadiusDistance)) {
294            while(SectorVal<MAXSECTOR) {
295               double SectorStartAngle = Math.max(0.0,(((double)SectorVal)*RINGSLICESIZE));
296               double SectorEndAngle = Math.min(360.0,(((double)SectorVal+1)*RINGSLICESIZE));
297               if((AngleVal>=SectorStartAngle)&&(AngleVal<SectorEndAngle)) {
298                  SectorDataArray[SectorVal][SectorCountArray[SectorVal]] = TempVal;
299                  SectorCountArray[SectorVal]++;
300                  SectorVal = MAXSECTOR;  /* exit while loop */
301               } else {
302                  SectorVal++;
303               }
304            }
305         }
306
307         /* Check for Eye region pixel */
308         if((DistVal>=0.0)&&(DistVal<InnerRadiusDistance)) {
309            EyeDataArray[EyeCount] = TempVal;
310            EyeCount++;
311         }
312      }
313
314      /* Calculate Cloud Region Annulus Temperature */
315      /* position annulus at CW max temp distance and
316       * determine mean temp w/in +/- 40km from this distance.  If dist
317       * is less than 68km from center, annulus will start at 28km */
318      int AnnulusTemperatureCount = 0;
319      double AnnulusTemperatureSum = 0.0;
320      double AnnulusDistance = History.IRCurrentRecord.cwring;
321      double AnnulusStartRadius = Math.max(28.0,AnnulusDistance-40.0);
322      double AnnulusEndRadius = Math.max(108.0,AnnulusDistance+40.0);
323      for (i = 0; i < RingDataCount; i++ ) {
324         DistVal = RingArray[i].distance;
325         AngleVal = RingArray[i].angle;
326         TempVal = RingArray[i].temperature;
327         if((DistVal>=AnnulusStartRadius)&&(DistVal<=AnnulusEndRadius)) {
328            AnnulusTemperatureSum = AnnulusTemperatureSum + TempVal;
329            AnnulusTemperatureCount++;
330         }
331      }
332
333      double CloudAnnulusAveTemp = AnnulusTemperatureSum/((double)AnnulusTemperatureCount);
334
335      /* calculate averages, standard deviations and skews for each sector */
336      double TempSectorArray[] = new double[MAXSECTORA];
337      for (i = 0; i < MAXSECTOR; i++ ) {
338         int SectorCounterValue = SectorCountArray[i];
339         for (j = 0; j < SectorCounterValue; j++ ) {
340            TempSectorArray[j] = SectorDataArray[i][j];
341         }
342         double ReturnValues[] = Data.CalcSkew(TempSectorArray,SectorCounterValue);
343         SectorAverageArray[i] = ReturnValues[0];
344         SectorStdvArray[i] = ReturnValues[1];
345      }
346      double ReturnValues2[] = Data.CalcSkew(SectorAverageArray,MAXSECTOR);
347      double SectorAverageAverageValue = ReturnValues2[0];   /* cloud2 value */
348
349      int HalfMaxSector = MAXSECTOR/2;
350      double SectorDifferenceArray[] = new double[HalfMaxSector];
351      for (i = 0; i < HalfMaxSector; i++ ) {
352         SectorDifferenceArray[i] = Math.abs(SectorAverageArray[i]-SectorAverageArray[i+HalfMaxSector]);
353      }
354      double ReturnValues3[] = Data.CalcSkew(SectorDifferenceArray,HalfMaxSector);
355      double SectorDiffAverageValue = ReturnValues3[0];    /* cloud symmetry value */
356
357      double ReturnValues4[] = Data.CalcSkew(EyeDataArray,EyeCount);
358      double EyeRegionSTDVValue = ReturnValues4[1];    /* eye stdv value */
359
360      return new double[] { CloudAnnulusAveTemp, SectorAverageAverageValue, SectorDiffAverageValue, EyeRegionSTDVValue };
361
362   }
363
364   public static void CalcEyeCloudTemps() {
365
366      int CenterXPos = IRData_NumberColumns/2;
367      int CenterYPos = IRData_NumberRows/2;
368
369      /* System.out.printf("CenterXPos=%d  CenterYPos=%d\n",CenterXPos,CenterYPos); */
370      double CenterLatValue = IRData_Latitude[CenterYPos][CenterXPos];
371      double CenterLonValue = IRData_Longitude[CenterYPos][CenterXPos];
372
373      /* System.out.printf("CenterLatVal=%f  CenterLonVal=%f\n",CenterLatValue,CenterLonValue); */
374
375      LoadRingData(CenterLatValue,CenterLonValue);
376
377      Eye_Temperature = Data.CalcEyeTemperature();
378      History.IRCurrentRecord.eyet = Eye_Temperature-KtoC_Value;
379      /* System.out.printf("eyeT=%f\n",Eye_Temperature); */
380
381      double LocalValue[] = Data.CalcCWCloudInfo();
382      CWCloud_Temperature = LocalValue[0];
383      CWRing_Distance = (int)LocalValue[1];
384      /* System.out.printf("cw cloudT=%f\n",CWCloud_Temperature); */
385      /* System.out.printf("cw Ring distance=%d\n",CWRing_Distance); */
386      History.IRCurrentRecord.cwcloudt = CWCloud_Temperature-KtoC_Value;
387      History.IRCurrentRecord.cwring = CWRing_Distance;
388
389      double LocalValue2[] = Data.CalcEyeCloudInfo();
390      Cloud_Temperature = LocalValue2[0];
391      Cloud2_Temperature = LocalValue2[1];
392      Cloud_Symmetry = LocalValue2[2];
393      Eye_STDV = LocalValue2[3];
394      /* System.out.printf("cloudt=%f\n",Cloud_Temperature); */
395      /* System.out.printf("cloud2t=%f\n",Cloud2_Temperature); */
396      /* System.out.printf("eyestdv=%f\n",Eye_STDV);   / double check these values */
397      /* System.out.printf("cloudsymave=%f\n",Cloud_Symmetry); */
398      History.IRCurrentRecord.cloudt = Cloud_Temperature-KtoC_Value;
399      History.IRCurrentRecord.cloudt2 = Cloud2_Temperature-KtoC_Value;
400      History.IRCurrentRecord.cloudsymave = Cloud_Symmetry;
401      History.IRCurrentRecord.eyestdv = Eye_STDV;
402
403   }
404
405   public static double[] CalcRMW() {
406
407      int CenterXPos = IRData_NumberColumns/2;
408      int CenterYPos = IRData_NumberRows/2;
409      double RadiusMaxWind = -99.5;
410      double EyeSizeRadius = -99.5;
411      double ThresholdWarmCloudTemperatureDegK = 223.0;
412      double CriticalTemperatureDegK = 228.0;
413
414      /* System.out.printf("CenterXPos=%d  CenterYPos=%d\n",CenterXPos,CenterYPos); */
415
416      double CloudTemperature = History.IRCurrentRecord.cloudt;
417      double EyeTemperature = History.IRCurrentRecord.eyet;
418
419      int XDirMaximum=Math.min(IRData_NumberColumns,CenterXPos+320);
420      int XDirMinimum=Math.max(0,CenterXPos-320);
421      int YDirMaximum=Math.min(IRData_NumberRows,CenterYPos+240);
422      int YDirMinimum=Math.max(0,CenterYPos-240);
423
424      if(CloudTemperature>=(ThresholdWarmCloudTemperatureDegK-KtoC_Value)) {
425         CriticalTemperatureDegK = KtoC_Value + ((EyeTemperature + (2.0*CloudTemperature))/3.0);
426      }
427      /* System.out.printf("thresholdT=%f\n",CriticalTemperatureDegK); */
428
429      /* Iterate five times */
430      int XInc,YInc;
431      int XDirIterationStoredMaximum = 0;
432      int XDirIterationStoredMinimum = 0;
433      int YDirIterationStoredMaximum = 0;
434      int YDirIterationStoredMinimum = 0;
435      for (int Iterations = 0; Iterations < 5; Iterations++ ) {
436      /* System.out.printf("Iteration=%d\n",Iterations); */
437         XInc=CenterXPos;
438         while(IRData_Temperature[CenterYPos][XInc]>CriticalTemperatureDegK) {
439            XInc=XInc-1;
440            if(XInc==XDirMinimum) {
441               /* Eyewall not found */
442               return new double[] { RadiusMaxWind, EyeSizeRadius };
443            }
444         }
445         XDirIterationStoredMinimum=XInc;
446         XInc=CenterXPos;
447         while(IRData_Temperature[CenterYPos][XInc]>CriticalTemperatureDegK) {
448            XInc=XInc+1;
449            if(XInc==XDirMaximum) {
450               /* Eyewall not found */
451               return new double[] { RadiusMaxWind, EyeSizeRadius };
452            }
453         }
454         XDirIterationStoredMaximum=XInc;
455         YInc=CenterYPos;
456         while(IRData_Temperature[YInc][CenterXPos]>CriticalTemperatureDegK) {
457            YInc=YInc-1;
458            if(YInc==YDirMinimum) {
459               /* Eyewall not found */
460               return new double[] { RadiusMaxWind, EyeSizeRadius };
461            }
462         }
463         YDirIterationStoredMinimum=YInc;
464         YInc=CenterYPos;
465         while(IRData_Temperature[YInc][CenterXPos]>CriticalTemperatureDegK) {
466            YInc=YInc+1;
467            if(YInc==YDirMaximum) {
468               /* Eyewall not found */
469               return new double[] { RadiusMaxWind, EyeSizeRadius };
470            }
471         }
472         YDirIterationStoredMaximum=YInc;
473         CenterXPos=(int)((((double)(XDirIterationStoredMinimum+
474                                         XDirIterationStoredMaximum))/2.0));
475         CenterYPos=(int)((((double)(YDirIterationStoredMinimum+
476                                         YDirIterationStoredMaximum))/2.0));
477      }
478
479      /* System.out.printf("x=%d  y=%d\n",CenterXPos,CenterYPos); */
480
481      double CenterPointLatitude,CenterPointLongitude;
482      double LatitudeValue,LongitudeValue;
483     
484      CenterPointLatitude = IRData_Latitude[CenterYPos][CenterXPos];
485      CenterPointLongitude = IRData_Longitude[CenterYPos][CenterXPos];
486
487      LatitudeValue = IRData_Latitude[CenterYPos][XDirIterationStoredMinimum];
488      LongitudeValue = IRData_Longitude[CenterYPos][XDirIterationStoredMinimum];
489      double LocalValue1[] = Functions.distance_angle(LatitudeValue,LongitudeValue,
490                                           CenterPointLatitude,CenterPointLongitude,1);
491      double DistanceValueX1 = LocalValue1[0];
492
493      LatitudeValue = IRData_Latitude[CenterYPos][XDirIterationStoredMaximum];
494      LongitudeValue = IRData_Longitude[CenterYPos][XDirIterationStoredMaximum];
495      double LocalValue2[] = Functions.distance_angle(LatitudeValue,LongitudeValue,
496                                           CenterPointLatitude,CenterPointLongitude,1);
497      double DistanceValueX2 = LocalValue2[0];
498
499      LatitudeValue = IRData_Latitude[YDirIterationStoredMinimum][CenterXPos];
500      LongitudeValue = IRData_Longitude[YDirIterationStoredMinimum][CenterXPos];
501      double LocalValue3[] = Functions.distance_angle(LatitudeValue,LongitudeValue,
502                                           CenterPointLatitude,CenterPointLongitude,1);
503      double DistanceValueY1 = LocalValue3[0];
504
505      LatitudeValue = IRData_Latitude[YDirIterationStoredMaximum][CenterXPos];
506      LongitudeValue = IRData_Longitude[YDirIterationStoredMaximum][CenterXPos];
507      double LocalValue4[] = Functions.distance_angle(LatitudeValue,LongitudeValue,
508                                           CenterPointLatitude,CenterPointLongitude,1);
509      double DistanceValueY2 = LocalValue4[0];
510
511      double AveragedDistance = (DistanceValueX1+DistanceValueX2+
512                                 DistanceValueY1+DistanceValueY2)/4.0;
513
514      if(AveragedDistance>0.0) {
515         RadiusMaxWind = 2.8068+(0.8361*AveragedDistance);
516         EyeSizeRadius = AveragedDistance;
517      } 
518
519      return new double[] { RadiusMaxWind, EyeSizeRadius };
520
521  }
522
523   public static float[][] GetCurrentImageLatitudeArray() {
524      return IRData_Latitude;
525   }
526   public static float[][] GetCurrentImageLongitudeArray() {
527      return IRData_Longitude;
528   }
529   public static float[][] GetCurrentImageTemperatureArray() {
530      return IRData_Temperature;
531   }
532   public static int GetCurrentImageJulianDate() {
533      return IRData_JulianDate;
534   }
535   public static int GetCurrentImageTime() {
536      return IRData_HHMMSSTime;
537   }
538   public static int GetCurrentImageXSize() {
539      return IRData_NumberColumns;
540   }
541   public static int GetCurrentImageYSize() {
542      return IRData_NumberRows;
543   }
544   public static double GetCurrentImageResolution() {
545      return IRData_ImageResolution;
546   }
547   public static double GetStormCenterLatitude() {
548      return IRData_CenterLatitude;
549   }
550   public static double GetStormCenterLongitude() {
551      return IRData_CenterLongitude;
552   }
553
554}