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