001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2025 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}