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 031public class Intensity { 032 033 private static int MWAnalysisFlag; 034 private static int Rule9StrengthFlag; 035 036 private static double[] BDCurve_Points = { 037 30.0, 9.0, -30.0, -42.0, -54.0, -64.0, -70.0, -76.0, -80.0, -84.0, 038 -100.0 039 }; 040 041 public Intensity() { 042 MWAnalysisFlag = 0; 043 Rule9StrengthFlag = 0; 044 } 045 046 /** 047 * Compute intensity values CI, Final T#, and Raw T#. 048 * 049 * @param RedoIntensityFlagValue Recalculate Intensity flag value. 050 * @param RunFullAnalysis Whether or not a full analysis should be 051 * performed. 052 * @param HistoryFileName Path to history file. 053 * 054 */ 055 public static void CalculateIntensity(int RedoIntensityFlagValue, 056 boolean RunFullAnalysis, 057 String HistoryFileName) 058 { 059 double TnoRaw=0.0; 060 double TnoFinal=0.0; 061 double CI=0.0; 062 double CIadjP=0.0; 063 064 boolean InitStrengthTF = Env.InitStrengthTF; 065 boolean LandFlagTF = Env.LandFlagTF; 066 067 int RecLand = History.IRCurrentRecord.land; 068 double Latitude = History.IRCurrentRecord.latitude; 069 double Longitude = History.IRCurrentRecord.longitude; 070 071 if((LandFlagTF)&&(RecLand==1)) { 072 /* Initialize Missing Record */ 073 /* throw exception ?? */ 074 } else { 075 double RetVal[] = adt_TnoRaw(RedoIntensityFlagValue,HistoryFileName); 076 TnoRaw = RetVal[0]; 077 MWAnalysisFlag = (int)RetVal[1]; 078 /* System.out.printf("RawT#Adj=%f MWAnalysisFlag=%d\n",TnoRaw,MWAnalysisFlag); */ 079 History.IRCurrentRecord.Traw = TnoRaw; 080 } 081 082 /* System.out.printf("RunFullAnalysis=%b\n",RunFullAnalysis); */ 083 if(!RunFullAnalysis) { 084 /* Perform Spot Analysis (only T#raw) */ 085 History.IRCurrentRecord.Tfinal = TnoRaw; 086 History.IRCurrentRecord.CI = TnoRaw; 087 //CIadjP = adt_latbias(InitStrengthTF,LandFlagTF,HistoryFileName,TnoRaw,Latitude,Longitude); 088 CIadjP = adt_latbias(InitStrengthTF,LandFlagTF,HistoryFileName,Latitude,Longitude); 089 History.IRCurrentRecord.CIadjp = CIadjP; 090 History.IRCurrentRecord.rule9 = 0; 091 } else { 092 int NumRecsHistory = History.HistoryNumberOfRecords(); 093 /* System.out.printf("numrecs=%d inistrength=%b historyfilename=%s*\n",NumRecsHistory,InitStrengthTF,HistoryFileName); */ 094 /* System.out.printf("MWanalysisflag=%d\n",MWAnalysisFlag); */ 095 if((((NumRecsHistory==0)&&(InitStrengthTF))&&(HistoryFileName!=null))||(MWAnalysisFlag==1)) { 096 System.out.printf("tnoraw=%f\n",TnoRaw); 097 History.IRCurrentRecord.Tfinal = TnoRaw; 098 History.IRCurrentRecord.CI = TnoRaw; 099 History.IRCurrentRecord.CIadjp = 0.0; 100 if(MWAnalysisFlag==1) { 101 double[] RetVals = adt_CIno(HistoryFileName); 102 CI = RetVals[0]; 103 Rule9StrengthFlag = (int)RetVals[1]; 104 History.IRCurrentRecord.CI = CI; 105 History.IRCurrentRecord.rule9 = Rule9StrengthFlag; 106 //CIadjP = adt_latbias(InitStrengthTF,LandFlagTF,HistoryFileName,TnoRaw,Latitude,Longitude); 107 CIadjP = adt_latbias(InitStrengthTF,LandFlagTF,HistoryFileName,Latitude,Longitude); 108 History.IRCurrentRecord.CIadjp = CIadjP; 109 } else { 110 History.IRCurrentRecord.CI = TnoRaw; 111 History.IRCurrentRecord.rule9 = 0; 112 } 113 } else { 114 /* System.out.printf("rawt=%f\n",History.IRCurrentRecord.Traw); */ 115 TnoFinal = adt_TnoFinal(1); 116 /* System.out.printf("FinalT#=%f\n",TnoFinal); */ 117 History.IRCurrentRecord.Tfinal = TnoFinal; 118 double[] RetVals2 = adt_CIno(HistoryFileName); 119 CI = RetVals2[0]; 120 Rule9StrengthFlag = (int)RetVals2[1]; 121 /* System.out.printf("CI#=%f Rule9StrengthFlag=%d \n",CI,Rule9StrengthFlag); */ 122 History.IRCurrentRecord.CI = CI; 123 History.IRCurrentRecord.rule9 = Rule9StrengthFlag; 124 } 125 } 126 } 127 128 /** 129 * Compute initial Raw T-Number value using original Dvorak rules 130 * 131 * @param RedoIntensityFlag Recalculate Intensity flag value. 132 * @param HistoryFileName Path to history file. 133 * 134 * @return Array of two doubles. First value represents 135 * intensity estimate, and the second is the analysis flag. 136 */ 137 public static double[] adt_TnoRaw(int RedoIntensityFlag, 138 String HistoryFileName) 139 { 140 int XInc; 141 int CloudBDCategory = 0; 142 int Rule8AdjCatValue = 0; 143 int PreviousHistoryRecPtr = 0; 144 double CloudTnoIntensity = -909.0; 145 double TnoRawValue=0.0; 146 double IntensityEstimateValue = 0.0; 147 double TnoInterpAdjValue = 0.0; 148 double FinalIntensityEstimateValue = 0.0; 149 double ShearInterpAdjValue = 0.0; 150 double CDOSizeRegressionAdjValue = 0.0; 151 double EyeCloudTempDifferenceAdjValue = 0.0; 152 double CDOSymmatryRegressionAdjValue = 0.0; 153 double PreviousHistoryCIValue = 0.0; 154 double CIValueAdjustmentFactorValue=0.0; 155 double HistoryRecTime = 0.0; 156 boolean First48HourShearTF = false; 157 boolean MWOFFTF = false; 158 boolean LandCheckTF = true; 159 160 /* EYE SCENE REGRESSION BASE VALUES */ 161 double[][] EyeRegressionBaseArray = 162 /* DG MG LG B W CMG CDG */ 163 {{1.00,2.00,3.25,4.00,4.75,5.25,5.75,6.50,7.25,7.75,8.25}, 164 {1.50,2.25,3.30,3.85,4.50,4.75,5.15,5.50,6.00,6.25,6.75}}; 165 /* CLOUD SCENE REGRESSION BASE VALUES */ 166 double[][] CloudRegressionBaseArray = 167 /* DG MG LG B W CMG CDG */ 168 {{2.00,2.40,3.25,3.50,3.75,4.00,4.10,4.20,4.30,4.40,4.70}, 169 {2.05,2.40,3.00,3.20,3.40,3.55,3.65,3.75,3.80,3.90,4.10}}; 170 /* Curved Band Scene Type Intensity Values (each 20% of wrap around center) */ 171 double[] CurvedBandIntensityArray = {1.5,1.5,2.0,2.5,3.0,3.5,4.0}; 172 /* Shear Scene Type Distance Threshold Values (distance in km) */ 173 double[] ShearDistanceArray = {0.0,35.0,50.0,80.0,110.0,140.0}; 174 /* Shear Scene Type Intensity Values */ 175 double[] ShearIntensityArray = {3.50,3.00,2.50,2.25,2.00,1.50}; 176 177 /* Rule 8 Adjustments 178 * Row 1 - Shear Scenes (original rule 8) 179 * Row 2 - Eye Scenes (original + 0.5) 180 * Row 3 - Other Scenes (original - 0.5) 181 */ 182 double[][] Rule8AdjArray = 183 /* 1hr 6hr 12hr 18hr 24hr */ 184 {{0.0,0.51,1.01,1.71,2.21,2.71,0.0,0.0,0.21,0.51}, 185 {0.0,0.51,1.01,2.71,3.21,3.71,1.31,0.0,0.21,0.51}, 186 {0.0,0.51,0.71,1.21,1.71,2.21,0.0,0.0,0.21,0.51}}; 187 /* Eye Regression Factor (Atlantic, Pacific) */ 188 double[] EyeCloudTempDifferenceRegressionFactorArrayEYE = { 0.011, 0.015 }; 189 /* Cloud Region Symmatry Regression Factor - Eye Scene (Atlantic, Pacific) */ 190 double[] CloudSymmatryRegressionFactorArrayEYE = { -0.015, -0.015 }; 191 /* CDO size (km - Dark Gray BD Curve) - Cloud Scene (Atlantic, Pacific) */ 192 double[] CDOSizeRegressionFactorArrayCLD = { 0.002 , 0.001 }; 193 /* Cloud Region Symmatry Regression Factor - Cloud Scene (Atlantic, Pacific) */ 194 double[] CloudSymmatryRegressionFactorArrayCLD = { -0.030, -0.015 }; 195 196 double CurrentTime = 1900001.0; 197 int ImageDate = 1900001; 198 int ImageTime = 000000;; 199 int RecDate = 1900001; 200 int RecTime = 000000; 201 int RecLand = 0; 202 boolean LandFlagTF = Env.LandFlagTF; 203 boolean InitStrengthTF = Env.InitStrengthTF; 204 double InitStrengthValue = Env.InitRawTValue; 205 int LandFlagCurrent = History.IRCurrentRecord.land; 206 double RecTnoRaw = 0.0; 207 208 int NumRecsHistory = History.HistoryNumberOfRecords(); 209 /* System.out.printf("numrecs=%d\n",NumRecsHistory); */ 210 if((NumRecsHistory==0)&&(HistoryFileName!=null)) { 211 /* 212 * History file does not exist and current analysis is 213 * first analysis for the storm 214 */ 215 if(InitStrengthTF) { 216 History.IRCurrentRecord.TrawO = InitStrengthValue; 217 return new double [] { InitStrengthValue, 0.0 }; /* EXIT */ 218 } 219 } else { 220 double LastValidRecordTime=1900001.0; 221 ImageDate = History.IRCurrentRecord.date; 222 ImageTime = History.IRCurrentRecord.time; 223 CurrentTime = Functions.calctime(ImageDate,ImageTime); 224 /* System.out.printf("CurrentTime=%f\n",CurrentTime); */ 225 double FirstHistoryRecTime = LastValidRecordTime; 226 if(NumRecsHistory!=0) { 227 RecDate = History.HistoryFile[0].date; 228 RecTime = History.HistoryFile[0].time; 229 FirstHistoryRecTime = Functions.calctime(RecDate,RecTime); 230 if((CurrentTime-FirstHistoryRecTime)<=2.0) { 231 First48HourShearTF = true; 232 } 233 } else { 234 FirstHistoryRecTime = LastValidRecordTime; 235 } 236 237 /* System.out.printf("FirstHistoryRecTime=%f\n",FirstHistoryRecTime); */ 238 XInc = 0; 239 while(XInc<NumRecsHistory) { 240 RecDate = History.HistoryFile[XInc].date; 241 RecTime = History.HistoryFile[XInc].time; 242 HistoryRecTime = Functions.calctime(RecDate,RecTime); 243 /* System.out.printf("XInc= %d HistoryRecTime%f\n",XInc,HistoryRecTime); */ 244 if(HistoryRecTime>CurrentTime) { 245 break; 246 } 247 RecLand = History.HistoryFile[XInc].land; 248 RecTnoRaw = History.HistoryFile[XInc].Traw; 249 LandCheckTF = true; 250 if(((LandFlagTF)&&(RecLand==1))||(RecTnoRaw<1.0)) { 251 LandCheckTF = false; 252 } 253 if(LandCheckTF) { 254 if((HistoryRecTime==CurrentTime)&&(XInc==0)&&(InitStrengthValue!=0.0)) { 255 /* 256 * Current analysis is at or before first record in 257 * existing history file - return global initial 258 * strength value 259 */ 260 System.out.printf("FIRST RECORD in NON-empty file\n"); 261 History.IRCurrentRecord.TrawO = InitStrengthValue; 262 /* InitStrengthValue = 0.0; */ 263 /* Env.InitRawTValue = 0.0; */ 264 return new double[] {InitStrengthValue, 0.0 }; /* EXIT */ 265 } 266 PreviousHistoryRecPtr = XInc; 267 LastValidRecordTime = HistoryRecTime; 268 } 269 XInc++; 270 } 271 if(HistoryFileName!=null) { 272 PreviousHistoryCIValue = History.HistoryFile[PreviousHistoryRecPtr].CI; 273 } else { 274 PreviousHistoryCIValue = 4.0; 275 } 276 277 /* System.out.printf("PreviousHistoryCIValue=%f\n",PreviousHistoryCIValue); */ 278 if(((CurrentTime-LastValidRecordTime)>1.0)&& (HistoryFileName!=null)) { 279 /* The history file either begins with all land scenes 280 * or there is a break in the history file of greater than 281 * 24 hours. Reinitialize the storm with the input 282 * Initial Classification value 283 */ 284 History.IRCurrentRecord.TrawO = InitStrengthValue; 285 Env.InitRawTValue = -1.0; 286 /* System.out.printf("returning...\n"); */ 287 return new double[] { InitStrengthValue, 0.0 }; /* EXIT */ 288 } 289 } 290 291 double CloudTemperatureCurrent = History.IRCurrentRecord.cloudt; 292 double EyeTemperatureCurrent = History.IRCurrentRecord.eyet; 293 294 /* System.out.printf("current cloudT=%f eyeT=%f\n",CloudTemperatureCurrent,EyeTemperatureCurrent); */ 295 for(XInc=0;XInc<10;XInc++) { 296 /* compute cloud category */ 297 if((CloudTemperatureCurrent<=BDCurve_Points[XInc])&& (CloudTemperatureCurrent>BDCurve_Points[XInc+1])) { 298 CloudBDCategory = XInc; 299 CloudTnoIntensity = (CloudTemperatureCurrent-BDCurve_Points[CloudBDCategory])/ 300 (BDCurve_Points[CloudBDCategory+1]- 301 BDCurve_Points[CloudBDCategory]); 302 } 303 /* compute eye category for eye adjustment */ 304 if((EyeTemperatureCurrent<=BDCurve_Points[XInc])&& (EyeTemperatureCurrent>BDCurve_Points[XInc+1])) { 305 } 306 } 307 308 /* System.out.printf("cloudBD=%d CloudTnoIntensity= %f eyeBD=%d \n",CloudBDCategory,CloudTnoIntensity,EyeBDCategory); */ 309 int EyeSceneCurrent = History.IRCurrentRecord.eyescene; 310 if(EyeSceneCurrent==1) { 311 /* this matches DT used at NHC (jack beven) */ 312 /* EyeTemperature=(9.0+EyeTemperature)/2.0; */ 313 /* Eye Temp is between +9C (beven) and measured eye temp (turk) */ 314 EyeTemperatureCurrent = (EyeTemperatureCurrent+9.0)/2.0; 315 History.IRCurrentRecord.eyet = EyeTemperatureCurrent; 316 } 317 318 /* System.out.printf("EyeCloudBDCategoryDifference=%f\n",EyeCloudBDCategoryDifference); */ 319 320 /* if scenetype is EYE */ 321 int CurvedBandBDAmountCurrent = History.IRCurrentRecord.ringcbval; 322 int CurvedBandBDCategoryCurrent = History.IRCurrentRecord.ringcb; 323 double MWScoreValueCurrent = History.IRCurrentRecord.mwscore; 324 /* System.out.printf("MWScoreValueCurrent=%f\n",MWScoreValueCurrent); */ 325 326 MWAnalysisFlag = 0; 327 if(RedoIntensityFlag==1) { 328 Env.MWJulianDate = History.IRCurrentRecord.mwdate; 329 Env.MWHHMMSSTime = History.IRCurrentRecord.mwtime; 330 System.out.printf("****REDO : MW DATE=%d Time=%d\n", Env.MWJulianDate, Env.MWHHMMSSTime); 331 } 332 333 int CloudScene = History.IRCurrentRecord.cloudscene; 334 int EyeScene = History.IRCurrentRecord.eyescene; 335 int DomainID = Env.DomainID; 336 double CloudSymAveCurrent = History.IRCurrentRecord.cloudsymave; 337 double EyeCDOSizeCurrent = History.IRCurrentRecord.eyecdosize; 338 /* System.out.printf("CloudScene=%d\n",CloudScene); */ 339 if(CloudScene==3) { 340 /* CURVED BAND */ 341 CurvedBandBDAmountCurrent = Math.min(30,CurvedBandBDAmountCurrent+1); 342 int CurvedBandBDPercentage = CurvedBandBDAmountCurrent/5; 343 double IncrementMultFactor = 0.1; 344 if(CurvedBandBDPercentage==1) { 345 IncrementMultFactor = 0.2; 346 } 347 IntensityEstimateValue=CurvedBandIntensityArray[CurvedBandBDPercentage]; 348 TnoInterpAdjValue = IncrementMultFactor* 349 ((double)(CurvedBandBDAmountCurrent-(CurvedBandBDPercentage*5))); 350 /* 351 * System.out.printf("CurvedBandBDAmount=%d CurvedBandBDPercentage=%d CurvedBandBDCategory=%d IntensityEstimateValue=%f TnoInterpAdjValue=%f\n", 352 * CurvedBandBDAmountCurrent,CurvedBandBDPercentage, CurvedBandBDCategoryCurrent,IntensityEstimateValue, TnoInterpAdjValue); 353 */ 354 IntensityEstimateValue = IntensityEstimateValue+TnoInterpAdjValue; 355 if(CurvedBandBDCategoryCurrent==5) { 356 IntensityEstimateValue = Math.min(4.0,IntensityEstimateValue+0.5); 357 } 358 if(CurvedBandBDCategoryCurrent==6) { 359 IntensityEstimateValue = Math.min(4.5,IntensityEstimateValue+1.0); 360 } 361 Rule8AdjCatValue=2; 362 } else if(CloudScene==4) { 363 /* POSSIBLE SHEAR -- new definition from NHC */ 364 XInc = 0; 365 IntensityEstimateValue = 1.5; 366 double ShearDistanceCurrent = History.IRCurrentRecord.eyecdosize; 367 while(XInc<5) { 368 if((ShearDistanceCurrent>=ShearDistanceArray[XInc])&& (ShearDistanceCurrent<ShearDistanceArray[XInc+1])) { 369 ShearInterpAdjValue = (ShearDistanceCurrent-ShearDistanceArray[XInc])/ 370 (ShearDistanceArray[XInc+1]- 371 ShearDistanceArray[XInc]); 372 TnoInterpAdjValue = (ShearInterpAdjValue* 373 (ShearIntensityArray[XInc+1]- 374 ShearIntensityArray[XInc])); 375 IntensityEstimateValue = ShearIntensityArray[XInc]+TnoInterpAdjValue; 376 XInc=5; 377 } else { 378 XInc++; 379 } 380 } 381 Rule8AdjCatValue = 0; 382 if(First48HourShearTF) { 383 IntensityEstimateValue=Math.min(2.5,IntensityEstimateValue); 384 if(Env.DEBUG==100) { 385 System.out.printf("Constraining SHEAR Intensity to 2.5 or less during first 48 hours\n"); 386 } 387 } 388 } else { 389 /* EYE or NO EYE */ 390 /* int DomainID_Local = Env.DomainID = DomainID; */ 391 if(EyeScene<=2) { 392 /* EYE */ 393 /* 394 * System.out.printf("EYE : EyeTemperature=%f CloudTemperature=%f\n", 395 * EyeTemperatureCurrent,CloudTemperatureCurrent); 396 * System.out.printf("EYE : CloudTnoIntensity=%f DomainID=%d CloudBDCategory=%d\n",CloudTnoIntensity,DomainID, 397 * CloudBDCategory); 398 */ 399 TnoInterpAdjValue = (CloudTnoIntensity* 400 (EyeRegressionBaseArray[DomainID][CloudBDCategory+1]- 401 EyeRegressionBaseArray[DomainID][CloudBDCategory])); 402 EyeCloudTempDifferenceAdjValue = 403 EyeCloudTempDifferenceRegressionFactorArrayEYE[DomainID]* 404 (EyeTemperatureCurrent-CloudTemperatureCurrent); 405 CDOSymmatryRegressionAdjValue = 406 CloudSymmatryRegressionFactorArrayEYE[DomainID]* 407 (CloudSymAveCurrent); 408 409 /* System.out.printf("EYE : cloudsymave=%f CDOSymmatryRegressionAdjValue=%f\n", 410 CloudSymAveCurrent,CDOSymmatryRegressionAdjValue); */ 411 412 IntensityEstimateValue = 413 EyeRegressionBaseArray[DomainID][CloudBDCategory]+ 414 TnoInterpAdjValue+ 415 EyeCloudTempDifferenceAdjValue+ 416 CDOSymmatryRegressionAdjValue; 417 418 /* System.out.printf("EYE :TnoInterpAdjValue=%f EyeCloudTempDifferenceAdjValue=%f CDOSymmatryRegressionAdjValue=%f IntensityEstimateValue=%f\n", 419 TnoInterpAdjValue,EyeCloudTempDifferenceAdjValue, CDOSymmatryRegressionAdjValue,IntensityEstimateValue); */ 420 421 IntensityEstimateValue = Math.min(IntensityEstimateValue,9.0); 422 /* System.out.printf("IntensityEstimateValue=%f\n",IntensityEstimateValue); */ 423 if(EyeScene==2) { 424 /* LARGE EYE adjustment */ 425 IntensityEstimateValue = Math.min(IntensityEstimateValue-0.5,6.5); 426 } 427 Rule8AdjCatValue = 1; 428 } else { 429 /* NO EYE */ 430 /* CDO */ 431 TnoInterpAdjValue = (CloudTnoIntensity* 432 (CloudRegressionBaseArray[DomainID][CloudBDCategory+1]- 433 CloudRegressionBaseArray[DomainID][CloudBDCategory])); 434 CDOSizeRegressionAdjValue = 435 CDOSizeRegressionFactorArrayCLD[DomainID]* 436 EyeCDOSizeCurrent; 437 438 /* System.out.printf("CDO : dgraysize=%f CDOSymmatryRegressionAdjValue=%f\n", 439 EyeCDOSizeCurrent,CDOSizeRegressionAdjValue); */ 440 441 CDOSymmatryRegressionAdjValue = 442 CloudSymmatryRegressionFactorArrayCLD[DomainID]* 443 (CloudSymAveCurrent); 444 445 /* System.out.printf("CDO : cloudsymave=%f CDOSymmatryRegressionAdjValue=%f\n", 446 CloudSymAveCurrent,CDOSymmatryRegressionAdjValue); */ 447 448 IntensityEstimateValue = 449 CloudRegressionBaseArray[DomainID][CloudBDCategory]+ 450 TnoInterpAdjValue+CDOSizeRegressionAdjValue+CDOSymmatryRegressionAdjValue; 451 IntensityEstimateValue = IntensityEstimateValue-0.1; /* bias adjustment */ 452 /* CDO adjustment for very weak or very strong CDOs */ 453 if(CloudScene==0) { 454 CIValueAdjustmentFactorValue=0.0; 455 if(PreviousHistoryCIValue>=4.5) { 456 CIValueAdjustmentFactorValue = Math.max(0.0,Math.min(1.0,PreviousHistoryCIValue-4.5)); 457 } 458 if(PreviousHistoryCIValue<=3.0) { 459 CIValueAdjustmentFactorValue = Math.min(0.0,Math.max(-1.0,PreviousHistoryCIValue-3.0)); 460 } 461 IntensityEstimateValue = IntensityEstimateValue+CIValueAdjustmentFactorValue; 462 } 463 464 /* System.out.printf("CDO : TnoInterpAdjValue=%f CDOSizeRegressionAdjValue=%f CDOSymmatryRegressionAdjValue=%f IntensityEstimateValue=%f\n", 465 TnoInterpAdjValue,CDOSizeRegressionAdjValue,CDOSymmatryRegressionAdjValue,IntensityEstimateValue); */ 466 467 CIValueAdjustmentFactorValue = 0.0; 468 /* EMBEDDED CENTER */ 469 if(CloudScene==1) { 470 CIValueAdjustmentFactorValue = Math.max(0.0,Math.min( 471 1.5,PreviousHistoryCIValue-4.0)); 472 473 /* System.out.printf("EMBC : PreviousHistoryCIValue=%f TnoInterpAdjValue=%f\n", 474 PreviousHistoryCIValue,CIValueAdjustmentFactorValue); */ 475 476 IntensityEstimateValue = IntensityEstimateValue+CIValueAdjustmentFactorValue; 477 } 478 /* IRREGULAR CDO (PT=3.5) */ 479 if(CloudScene==2) { 480 /* additional IrrCDO bias adjustment */ 481 IntensityEstimateValue = IntensityEstimateValue+0.3; 482 IntensityEstimateValue = Math.min(3.5,Math.max(2.5,IntensityEstimateValue)); 483 } 484 Rule8AdjCatValue = 2; 485 } 486 } 487 488 FinalIntensityEstimateValue = ((double)((int)((IntensityEstimateValue+0.01)*10.0)))/10.0; 489 History.IRCurrentRecord.TrawO = FinalIntensityEstimateValue; 490 491 /* System.out.printf("RawT#orig=%f\n",FinalIntensityEstimateValue); */ 492 493 /* NEW Microwave Eye Score logic */ 494 if(Env.DEBUG==100) { 495 System.out.printf("***IntensityEstimateValue=%f\n",IntensityEstimateValue); 496 } 497 498 /* moved MW analysis here to work with all scenes */ 499 500 double[] RetVals2 = MWAdj.adt_calcmwadjustment(MWScoreValueCurrent,FinalIntensityEstimateValue); 501 MWAnalysisFlag = (int)RetVals2[0]; 502 IntensityEstimateValue = RetVals2[1]; 503 504 if(Env.DEBUG==100) { 505 System.out.printf("MWAnalysisFlag=%d IntensityEstimateValue=%f\n", MWAnalysisFlag,IntensityEstimateValue); 506 } 507 FinalIntensityEstimateValue=(double)((int)((IntensityEstimateValue+0.01)*10.0))/10.0; 508 /* System.out.printf("FinalIntensityEstimateValue=%f\n",FinalIntensityEstimateValue); */ 509 510 int Rule8Current = History.IRCurrentRecord.rule8; 511 512 if(Rule8Current==34) MWOFFTF = true; 513 514 boolean SpecialPostMWRule8EYEFlag = false; 515 if((MWOFFTF)&&(Rule8AdjCatValue==1)) { 516 /* System.out.printf("USING NEW POST-MW EYE RULE 8 CONSTRAINTS!!!\n"); */ 517 SpecialPostMWRule8EYEFlag = true; 518 } 519 520 /* System.out.printf("MWAnalysisFlag=%d\n",MWAnalysisFlag); */ 521 if(MWAnalysisFlag==0) { 522 /* 523 * perform Dvorak EIR Rule 8 Constrants on Raw T# value 524 * "velden rule" (actually 86.4 minutes... 0.06 of a day) 525 * "additional velden rule", only over first 6 hours 526 * All cases : delT of 0.5 over 1 hour : rule8 = 9 "velden rule" 527 * delT of 0.1 over 1 hour : rule8 = 8 "additional" 528 * Raw T# < 4.0 : delT of 1.0 over 6 hours : rule8 = 2 529 * No threshold exceeded : rule8 = 0 530 * Raw T# >= 4.0 : delT of 1.0 over 6 hours : rule8 = 2 531 * delT of 1.5 over 12 hours : rule8 = 3 532 * delT of 2.0 over 18 hours : rule8 = 4 533 * delT of 2.5 over 24 hours : rule8 = 5 534 * No threshold exceeded : rule8 = 0 535 */ 536 double PreviousHistoryFinalTnoValue = FinalIntensityEstimateValue; 537 int EyeSceneCounter = 0; 538 int NonEyeSceneCounter = 0; 539 double TnoValueMinus1hr = FinalIntensityEstimateValue; 540 double TnoValueMinus6hr = FinalIntensityEstimateValue; 541 double TnoValueMinus12hr = FinalIntensityEstimateValue; 542 double TnoValueMinus18hr = FinalIntensityEstimateValue; 543 double TnoValueMinus24hr = FinalIntensityEstimateValue; 544 double RawTnoValueMinus6hrTime = CurrentTime; 545 double RawTnoValueMinus6hr = FinalIntensityEstimateValue; 546 double RawTnoValueMinus1hr = FinalIntensityEstimateValue; 547 boolean First6hrRecordTF = false; 548 if(NumRecsHistory!=0) { 549 /* 550 * 0.0416 is one hour... round to 0.05 to make sure I catch the 551 * hour previous report 552 */ 553 double CurrentTimeMinus1hr = CurrentTime-0.05; 554 double CurrentTimeMinus6hr = CurrentTime-0.26; 555 double CurrentTimeMinus12hr = CurrentTime-0.51; 556 double CurrentTimeMinus18hr = CurrentTime-0.76; 557 double CurrentTimeMinus24hr = CurrentTime-1.01; 558 double TnoDifferenceValueMinus1hr; 559 double TnoDifferenceValueMinus6hr; 560 double TnoDifferenceValueMinus12hr; 561 double TnoDifferenceValueMinus18hr; 562 double TnoDifferenceValueMinus24hr; 563 RecDate = History.HistoryFile[0].date; 564 RecTime = History.HistoryFile[0].time; 565 double FirstHistoryRecTime = Functions.calctime(RecDate,RecTime); 566 boolean FirstHistoryLandRecTF = true; 567 boolean CurrentTimeMinus24hrTF = false; 568 boolean CurrentTimeMinus18hrTF = false; 569 boolean CurrentTimeMinus12hrTF = false; 570 boolean CurrentTimeMinus6hrTF = false; 571 boolean CurrentTimeMinus1hrTF = false; 572 boolean HistoryVeldenRuleFlagTF = false; 573 boolean ApplyVeldenRuleTF = true; 574 double RecTFinal; 575 double RecTRaw; 576 int RecRule9; 577 int RecRapidDiss; 578 int RecEyeScene; 579 int Rule8Val = 0; 580 int PreviousHistoryRule9Value = 0; 581 int PreviousHistoryRapidDissIDValue = 0; 582 double Rule8TESTValue; 583 584 if(FirstHistoryRecTime>=CurrentTimeMinus6hr) { 585 First6hrRecordTF = true; 586 } 587 XInc = 0; 588 while(XInc<NumRecsHistory) { 589 RecDate = History.HistoryFile[XInc].date; 590 RecTime = History.HistoryFile[XInc].time; 591 RecLand = History.HistoryFile[XInc].land; 592 HistoryRecTime = Functions.calctime(RecDate,RecTime); 593 RecTFinal = History.HistoryFile[XInc].Tfinal; 594 RecTRaw = History.HistoryFile[XInc].Traw; 595 RecRule9 = History.HistoryFile[XInc].rule9; 596 RecRapidDiss = History.HistoryFile[XInc].rapiddiss; 597 RecEyeScene = History.HistoryFile[XInc].eyescene; 598 /* System.out.printf("currenttime=%f historyrectime=%f\n",CurrentTime,HistoryRecTime); */ 599 if(HistoryRecTime>=CurrentTime) { 600 /* System.out.printf("outta here\n"); */ 601 break; 602 } 603 LandCheckTF = true; 604 /* System.out.printf("**RecLand=%d\n",RecLand); */ 605 if(((LandFlagTF)&&(RecLand==1))||(RecTnoRaw<1.0)) { 606 LandCheckTF = false; 607 if (FirstHistoryLandRecTF) { 608 FirstHistoryLandRecTF = false; 609 } 610 } else { 611 FirstHistoryLandRecTF = true; 612 } 613 /* System.out.printf("**LandCheckTF=%b\n",LandCheckTF); */ 614 if((HistoryRecTime>=CurrentTimeMinus24hr)&& (HistoryRecTime<CurrentTime)&& (!CurrentTimeMinus24hrTF)&&(LandCheckTF)) { 615 CurrentTimeMinus24hrTF = true; 616 TnoValueMinus24hr = RecTFinal; 617 } 618 if((HistoryRecTime>=CurrentTimeMinus18hr)&& (HistoryRecTime<CurrentTime)&& (!CurrentTimeMinus18hrTF)&&(LandCheckTF)) { 619 CurrentTimeMinus18hrTF = true; 620 TnoValueMinus18hr = RecTFinal; 621 } 622 if((HistoryRecTime>=CurrentTimeMinus12hr)&& (HistoryRecTime<CurrentTime)&& (!CurrentTimeMinus12hrTF)&&(LandCheckTF)) { 623 CurrentTimeMinus12hrTF = true; 624 TnoValueMinus12hr = RecTFinal; 625 } 626 if((HistoryRecTime>=CurrentTimeMinus6hr)&& (HistoryRecTime<CurrentTime)&& (!CurrentTimeMinus6hrTF)&&(LandCheckTF)) { 627 CurrentTimeMinus6hrTF = true; 628 TnoValueMinus6hr = RecTFinal; 629 RawTnoValueMinus6hr = RecTRaw; 630 RawTnoValueMinus6hrTime = HistoryRecTime; 631 } 632 if((HistoryRecTime>=CurrentTimeMinus1hr)&& (HistoryRecTime<CurrentTime)&& (!CurrentTimeMinus1hrTF)&&(LandCheckTF)) { 633 CurrentTimeMinus1hrTF = true; 634 TnoValueMinus1hr = RecTFinal; 635 RawTnoValueMinus1hr = RecTRaw; 636 } 637 if((HistoryRecTime<CurrentTime)&&(LandCheckTF)) { 638 PreviousHistoryFinalTnoValue = RecTFinal; 639 PreviousHistoryRule9Value = RecRule9; 640 PreviousHistoryRapidDissIDValue = RecRapidDiss; 641 if(RecEyeScene<=2) { 642 EyeSceneCounter++; 643 NonEyeSceneCounter = 0; 644 if(EyeSceneCounter>=3||HistoryVeldenRuleFlagTF) { 645 ApplyVeldenRuleTF = false; 646 HistoryVeldenRuleFlagTF = true; 647 } 648 } else { 649 EyeSceneCounter = 0; 650 NonEyeSceneCounter++; 651 if(NonEyeSceneCounter>=3) { 652 ApplyVeldenRuleTF = true; 653 HistoryVeldenRuleFlagTF = false; 654 } 655 } 656 if(PreviousHistoryRapidDissIDValue>=2) { 657 ApplyVeldenRuleTF = false; 658 } 659 } 660 XInc++; 661 } 662 663 /* System.out.printf("LandFlagCurrent=%d\n",LandFlagCurrent); */ 664 /* added to correctly analyze current record (08/27/13)*/ 665 if(LandFlagCurrent==2) { 666 if(EyeScene<=2) { 667 if(EyeSceneCounter>=2||HistoryVeldenRuleFlagTF) { 668 ApplyVeldenRuleTF = false; 669 } 670 } else { 671 ApplyVeldenRuleTF = true; 672 } 673 } 674 /* System.out.printf("ApplyVeldenRuleTF=%b\n",ApplyVeldenRuleTF); */ 675 Rule8Val = (Rule8AdjCatValue*10)+0; 676 /* System.out.printf("Rule8AdjCatValue=%d Rule8Val=%d\n",Rule8AdjCatValue,Rule8Val); */ 677 History.IRCurrentRecord.rule8 = Rule8Val; 678 /* System.out.printf("PreviousHistoryFinalTnoValue=%f\n",PreviousHistoryFinalTnoValue); */ 679 /* System.out.printf("Rule8 value = %d\n",History.IRCurrentRecord.rule8); */ 680 if(PreviousHistoryFinalTnoValue<4.0) { 681 /* System.out.printf(" LESS THAN 4.0\n"); */ 682 /* Raw T# < 4.0 */ 683 /* System.out.printf("First6hrRecordTF=%b\n",First6hrRecordTF); */ 684 if(First6hrRecordTF) { 685 if(CurrentTimeMinus1hrTF) { 686 TnoDifferenceValueMinus1hr = Math.abs(RawTnoValueMinus1hr- 687 FinalIntensityEstimateValue); 688 if(TnoDifferenceValueMinus1hr> Rule8AdjArray[Rule8AdjCatValue][8]) { 689 FinalIntensityEstimateValue = Math.max((RawTnoValueMinus1hr- 690 Rule8AdjArray[Rule8AdjCatValue][8]), 691 Math.min((RawTnoValueMinus1hr+ 692 Rule8AdjArray[Rule8AdjCatValue][8]), 693 FinalIntensityEstimateValue)); 694 Rule8Val = (Rule8AdjCatValue*10)+8; 695 History.IRCurrentRecord.rule8 = Rule8Val; 696 } 697 } else { 698 /* 699 ** no value available within past hour... 700 ** must determine approx value 701 */ 702 TnoDifferenceValueMinus1hr = 0.1*(Math.abs(CurrentTime-RawTnoValueMinus6hrTime)/.0416); 703 double RawTnoMinimumValue = RawTnoValueMinus6hr - TnoDifferenceValueMinus1hr; 704 double RawTnoMaximumValue = RawTnoValueMinus6hr + TnoDifferenceValueMinus1hr; 705 if((FinalIntensityEstimateValue>RawTnoMaximumValue)|| (FinalIntensityEstimateValue<RawTnoMinimumValue)) { 706 FinalIntensityEstimateValue = Math.max(RawTnoMinimumValue, 707 Math.min(RawTnoMaximumValue, 708 FinalIntensityEstimateValue)); 709 Rule8Val = (Rule8AdjCatValue*10)+8; 710 History.IRCurrentRecord.rule8 = Rule8Val; 711 } 712 } 713 } else { 714 TnoDifferenceValueMinus1hr = Math.abs(TnoValueMinus1hr- 715 FinalIntensityEstimateValue); 716 /* System.out.printf("TnoDifferenceValueMinus1hr=%f\n",TnoDifferenceValueMinus1hr); */ 717 if((TnoDifferenceValueMinus1hr> Rule8AdjArray[Rule8AdjCatValue][9])&& (CurrentTimeMinus1hrTF)&&(ApplyVeldenRuleTF)) { 718 FinalIntensityEstimateValue = Math.max(TnoValueMinus1hr- 719 Rule8AdjArray[Rule8AdjCatValue][9], 720 Math.min(TnoValueMinus1hr+ 721 Rule8AdjArray[Rule8AdjCatValue][9], 722 FinalIntensityEstimateValue)); 723 Rule8Val = (Rule8AdjCatValue*10)+9; 724 History.IRCurrentRecord.rule8 = Rule8Val; 725 } 726 TnoDifferenceValueMinus6hr = Math.abs(TnoValueMinus6hr- 727 FinalIntensityEstimateValue); 728 /* System.out.printf("TnoDifferenceValueMinus6hr=%f\n",TnoDifferenceValueMinus6hr); */ 729 /* System.out.printf("PreviousHistoryRule9Value=%d\n",PreviousHistoryRule9Value); */ 730 if(PreviousHistoryRule9Value<2) { 731 if((TnoDifferenceValueMinus6hr> Rule8AdjArray[Rule8AdjCatValue][2])&& (CurrentTimeMinus6hrTF)) { 732 FinalIntensityEstimateValue = Math.max(TnoValueMinus6hr- 733 Rule8AdjArray[Rule8AdjCatValue][2], 734 Math.min(TnoValueMinus6hr+ 735 Rule8AdjArray[Rule8AdjCatValue][2], 736 FinalIntensityEstimateValue)); 737 Rule8Val = (Rule8AdjCatValue*10)+2; 738 History.IRCurrentRecord.rule8 = Rule8Val; 739 } 740 } else { 741 if((TnoDifferenceValueMinus6hr> Rule8AdjArray[Rule8AdjCatValue][1])&& (CurrentTimeMinus6hrTF)) { 742 FinalIntensityEstimateValue = Math.max(TnoValueMinus6hr- 743 Rule8AdjArray[Rule8AdjCatValue][1], 744 Math.min(TnoValueMinus6hr+ 745 Rule8AdjArray[Rule8AdjCatValue][1], 746 FinalIntensityEstimateValue)); 747 Rule8Val = (Rule8AdjCatValue*10)+1; 748 History.IRCurrentRecord.rule8 = Rule8Val; 749 } 750 } 751 } 752 } else { 753 /* System.out.printf(" GREATER THAN 4.0\n"); */ 754 /* Raw T# >= 4.0 */ 755 TnoDifferenceValueMinus1hr = Math.abs(TnoValueMinus1hr- 756 FinalIntensityEstimateValue); 757 /* System.out.printf("TnoDifferenceValueMinus1hr=%f\n",TnoDifferenceValueMinus1hr); */ 758 if((TnoDifferenceValueMinus1hr> Rule8AdjArray[Rule8AdjCatValue][9])&& (CurrentTimeMinus1hrTF)&&(ApplyVeldenRuleTF)) { 759 FinalIntensityEstimateValue = Math.max(TnoValueMinus1hr- 760 Rule8AdjArray[Rule8AdjCatValue][9], 761 Math.min(TnoValueMinus1hr+ 762 Rule8AdjArray[Rule8AdjCatValue][9], 763 FinalIntensityEstimateValue)); 764 Rule8Val = (Rule8AdjCatValue*10)+9; 765 History.IRCurrentRecord.rule8 = Rule8Val; 766 } 767 TnoDifferenceValueMinus6hr = Math.abs(TnoValueMinus6hr-FinalIntensityEstimateValue); 768 TnoDifferenceValueMinus12hr = Math.abs(TnoValueMinus12hr-FinalIntensityEstimateValue); 769 TnoDifferenceValueMinus18hr = Math.abs(TnoValueMinus18hr-FinalIntensityEstimateValue); 770 TnoDifferenceValueMinus24hr = Math.abs(TnoValueMinus24hr-FinalIntensityEstimateValue); 771 /* System.out.printf("Rule8AdjCatValue=%d\n",Rule8AdjCatValue); 772 /* System.out.printf("current6hrTF=%b TnoDifferenceValueMinus6hr=%f arrayval=%f \n", 773 CurrentTimeMinus6hrTF,TnoDifferenceValueMinus6hr,Rule8AdjArray[Rule8AdjCatValue][2]); */ 774 /* System.out.printf("current12hrTF=%b TnoDifferenceValueMinus12hr=%f arrayval=%f \n", 775 CurrentTimeMinus12hrTF,TnoDifferenceValueMinus12hr,Rule8AdjArray[Rule8AdjCatValue][3]); */ 776 /* System.out.printf("current18hrTF=%b TnoDifferenceValueMinus18hr=%f arrayval=%f \n", 777 CurrentTimeMinus18hrTF,TnoDifferenceValueMinus18hr,Rule8AdjArray[Rule8AdjCatValue][4]); */ 778 /* System.out.printf("current24hrTF=%b TnoDifferenceValueMinus24hr=%f arrayval=%f \n", 779 CurrentTimeMinus24hrTF,TnoDifferenceValueMinus24hr,Rule8AdjArray[Rule8AdjCatValue][5]); */ 780 781 /* NEW Rule 8 MW adjustment*/ 782 if(SpecialPostMWRule8EYEFlag) { 783 Rule8TESTValue=Rule8AdjArray[Rule8AdjCatValue][6]; 784 } else { 785 Rule8TESTValue=Rule8AdjArray[Rule8AdjCatValue][2]; 786 } 787 788 if((TnoDifferenceValueMinus6hr> Rule8TESTValue)&& (CurrentTimeMinus6hrTF)) { 789 /* System.out.printf("6 hr\n"); */ 790 FinalIntensityEstimateValue = Math.max(TnoValueMinus6hr- 791 Rule8TESTValue, 792 Math.min(TnoValueMinus6hr+ 793 Rule8TESTValue, 794 FinalIntensityEstimateValue)); 795 if(SpecialPostMWRule8EYEFlag) { 796 Rule8Val = (Rule8AdjCatValue*10)+6; 797 } else { 798 Rule8Val = (Rule8AdjCatValue*10)+2; 799 } 800 History.IRCurrentRecord.rule8 = Rule8Val; 801 } else if((TnoDifferenceValueMinus12hr> Rule8AdjArray[Rule8AdjCatValue][3])&& (CurrentTimeMinus12hrTF)) { 802 /* System.out.printf("12 hr\n"); */ 803 FinalIntensityEstimateValue = Math.max(TnoValueMinus12hr- 804 Rule8AdjArray[Rule8AdjCatValue][3], 805 Math.min(TnoValueMinus12hr+ 806 Rule8AdjArray[Rule8AdjCatValue][3], 807 FinalIntensityEstimateValue)); 808 Rule8Val = (Rule8AdjCatValue*10)+3; 809 History.IRCurrentRecord.rule8 = Rule8Val; 810 } else if((TnoDifferenceValueMinus18hr> Rule8AdjArray[Rule8AdjCatValue][4])&& (CurrentTimeMinus18hrTF)) { 811 /* System.out.printf("18 hr\n"); */ 812 FinalIntensityEstimateValue = Math.max(TnoValueMinus18hr- 813 Rule8AdjArray[Rule8AdjCatValue][4], 814 Math.min(TnoValueMinus18hr+ 815 Rule8AdjArray[Rule8AdjCatValue][4], 816 FinalIntensityEstimateValue)); 817 Rule8Val = (Rule8AdjCatValue*10)+4; 818 History.IRCurrentRecord.rule8 = Rule8Val; 819 } else if((TnoDifferenceValueMinus24hr> Rule8AdjArray[Rule8AdjCatValue][5])&& (CurrentTimeMinus24hrTF)) { 820 /* System.out.printf("24 hr\n"); */ 821 FinalIntensityEstimateValue = Math.max(TnoValueMinus24hr- 822 Rule8AdjArray[Rule8AdjCatValue][5], 823 Math.min(TnoValueMinus24hr+ 824 Rule8AdjArray[Rule8AdjCatValue][5], 825 FinalIntensityEstimateValue)); 826 Rule8Val = (Rule8AdjCatValue*10)+5; 827 History.IRCurrentRecord.rule8 = Rule8Val; 828 } else { 829 /* System.out.printf("default \n"); */ 830 History.IRCurrentRecord.rule8 = Rule8Val; 831 } 832 } 833 } 834 } 835 /* System.out.printf("Rule 8 value @ end of intensity calc=%d\n",History.IRCurrentRecord.rule8); */ 836 if(MWOFFTF) { 837 /* printf("holding Rule 8 flag to 34\n"); */ 838 History.IRCurrentRecord.rule8 = 34; 839 } 840 /* 841 ** NOTE : additional function return points above 842 ** - return Global Initial Strength Value if new history file or 843 ** inserting before first record in existing file 844 */ 845 846 if(Env.DEBUG==100) { 847 System.out.printf("FinalIntensityEstimateValue=%f\n",FinalIntensityEstimateValue); 848 } 849 850 TnoRawValue = FinalIntensityEstimateValue; 851 double ReturnMWAnalysisFlag = (double)MWAnalysisFlag; 852 853 return new double[] { TnoRawValue, ReturnMWAnalysisFlag }; 854 } 855 856 /** 857 * Compute time averaged T-Number value using previous and current 858 * intensity estimates. 859 * 860 * <p>Average using a time-weighted averaging scheme.</p> 861 * 862 * @param TimeAvgDurationID Time average duration flag. Use {@code 0} for 863 * 6 hour and {@code 1} for 3 hour. 864 * 865 * @return Final T# value. 866 */ 867 public static double adt_TnoFinal(int TimeAvgDurationID) { 868 /* double TnoFinalValue = 0.0; */ 869 870 double TnoFinalValue = History.IRCurrentRecord.Traw; 871 872 /* int TimeAvgDurationID = 0; */ 873 double OneHourInterval = 1.0/24.0; 874 double BaseTimeAvgValueHrs; 875 double FinalTnoValue; 876 double AverageValue = 0.0; 877 double AverageValueSum = 0.0; 878 double WeightValue = 0.0; 879 double WeightValueSum = 0.0; 880 boolean FoundValuesTF = false; 881 boolean LandCheckTF = false; 882 883 if(TimeAvgDurationID==1) { 884 BaseTimeAvgValueHrs=3.0; /* for NHC 3-hour time average value */ 885 } else if(TimeAvgDurationID==2) { 886 BaseTimeAvgValueHrs=12.0; /* for TIE Model time average value */ 887 } else { 888 BaseTimeAvgValueHrs=6.0; 889 } 890 891 int ImageDate = History.IRCurrentRecord.date; 892 int ImageTime = History.IRCurrentRecord.time; 893 double CurrentTime = Functions.calctime(ImageDate,ImageTime); 894 int NumRecsHistory = History.HistoryNumberOfRecords(); 895 boolean LandFlagTF = Env.LandFlagTF; 896 897 /* 898 * compute average with current value with any values 899 * from previous 6 hours 900 */ 901 double BeginningTime=CurrentTime-(BaseTimeAvgValueHrs/24.0); 902 903 int XInc = 0; 904 while(XInc<NumRecsHistory) { 905 int RecDate = History.HistoryFile[XInc].date; 906 int RecTime = History.HistoryFile[XInc].time; 907 double HistoryRecTime = Functions.calctime(RecDate,RecTime); 908 if((HistoryRecTime>=BeginningTime)&&(HistoryRecTime<CurrentTime)) { 909 LandCheckTF = true; 910 if(TimeAvgDurationID<=1) { 911 AverageValue = History.HistoryFile[XInc].Traw; 912 } else { 913 if(AverageValue<0.0) { 914 AverageValue = 0.0; 915 } 916 } 917 918 int RecLand = History.HistoryFile[XInc].land; 919 if(((LandFlagTF)&&(RecLand==1))||(AverageValue<1.0)) { 920 LandCheckTF = false; 921 } 922 if(LandCheckTF) { 923 double TimeDifference=CurrentTime-HistoryRecTime; 924 if(TimeAvgDurationID==0) { 925 /* time weighted average */ 926 WeightValue = (BaseTimeAvgValueHrs-(TimeDifference/OneHourInterval)); 927 } else { 928 /* straight average */ 929 WeightValue = BaseTimeAvgValueHrs; 930 } 931 AverageValueSum = AverageValueSum+(WeightValue*AverageValue); 932 WeightValueSum = WeightValueSum+WeightValue; 933 FoundValuesTF = true; 934 } 935 } else { 936 if(FoundValuesTF) { 937 break; 938 } 939 } 940 XInc++; 941 } 942 /* 943 * compute time-averaged T# value. 944 * if no previous records found, return Raw T# 945 */ 946 /* System.out.printf("TRAW=%f\n",History.IRCurrentRecord.Traw); */ 947 if(TimeAvgDurationID<=1) { 948 AverageValue = History.IRCurrentRecord.Traw; 949 } else { 950 if(AverageValue<=1.0) { 951 FoundValuesTF = false; 952 } 953 } 954 /* System.out.printf("foundvaluestf=%b averagevalue=%f\n",FoundValuesTF,AverageValue); */ 955 if(FoundValuesTF) { 956 AverageValueSum = AverageValueSum+(BaseTimeAvgValueHrs*AverageValue); 957 WeightValueSum = WeightValueSum+BaseTimeAvgValueHrs; 958 /* remove any value remainder past tenths */ 959 FinalTnoValue = (double)((int)(((AverageValueSum/WeightValueSum)+0.01)*10.0))/10.0; 960 } else { 961 FinalTnoValue = AverageValue; 962 } 963 /* System.out.printf("finaltnovalue=%f\n",FinalTnoValue); */ 964 965 TnoFinalValue = FinalTnoValue; 966 967 return TnoFinalValue; 968 } 969 970 /** 971 * Compute final CI-Number applying various Dvorak Rules, such 972 * as the now famous Rule 9. 973 * 974 * @param HistoryFileName Path to history file. 975 * 976 * @return Array of two doubles. First value represents current intensity, 977 * and the second represents the current strengthening/weakening flag. 978 */ 979 // TODO(jon): WHAT IS THIS FAMOUS RULE NUMBER 9!? 980 public static double[] adt_CIno(String HistoryFileName) { 981 int RapidDissIDValue = 0; 982 int CurrentStrengthIDValue; 983 int PreviousHistoryRule9Value = 0;; 984 int Rule9IDValue; 985 double PreviousHistoryFinalTnoValue; 986 double IntensityValue; 987 double TnoMinimumValue = 9.0; /* T# minimum value */ 988 double TnoMaximumValue = 0.0; /* T# maximum value */ 989 double Rule9AdditiveValue = 1.0; 990 double CIadjP; 991 boolean LandOnly12hrTF = true; /* land only during last 12hrs logical*/ 992 boolean LandCheckTF = true; 993 994 int ImageDate = History.IRCurrentRecord.date; 995 int ImageTime = History.IRCurrentRecord.time; 996 double CurrentTime = Functions.calctime(ImageDate,ImageTime); 997 double Latitude = History.IRCurrentRecord.latitude; 998 double Longitude = History.IRCurrentRecord.longitude; 999 boolean LandFlagTF = Env.LandFlagTF; 1000 double InitStrengthValue = Env.InitRawTValue; 1001 boolean InitStrengthTF = Env.InitStrengthTF; 1002 1003 int NumRecsHistory = History.HistoryNumberOfRecords(); 1004 if(NumRecsHistory==0) { 1005 /* no records in history file */ 1006 IntensityValue = History.IRCurrentRecord.Traw; 1007 CurrentStrengthIDValue = 0; 1008 /* this will trip the RULE 9 FLAG for an initial classification of >=6.0 */ 1009 if(InitStrengthValue>=6.0) { 1010 CurrentStrengthIDValue = 2; 1011 } 1012 /* Apply Latitude Bias Adjustment to CI value */ 1013 //CIadjP = adt_latbias(InitStrengthTF,LandFlagTF,HistoryFileName,IntensityValue,Latitude,Longitude); 1014 CIadjP = adt_latbias(InitStrengthTF,LandFlagTF,HistoryFileName,Latitude,Longitude); 1015 History.IRCurrentRecord.CIadjp = CIadjP; 1016 /* return Raw T# for CI# for initial analysis */ 1017 return new double[] { IntensityValue, (double)CurrentStrengthIDValue }; /* EXIT */ 1018 } 1019 /* MW Eye Score Adjustment being applied... let CI# = Final T# and return */ 1020 int Rule8Current = History.IRCurrentRecord.rule8; 1021 if((Rule8Current>=30)&&(Rule8Current<=33)) { 1022 IntensityValue = History.IRCurrentRecord.Tfinal; 1023 /* Apply Latitude Bias Adjustment to CI value */ 1024 //CIadjP = adt_latbias(InitStrengthTF,LandFlagTF,HistoryFileName,IntensityValue,Latitude,Longitude); 1025 CIadjP = adt_latbias(InitStrengthTF,LandFlagTF,HistoryFileName,Latitude,Longitude); 1026 History.IRCurrentRecord.CIadjp = CIadjP; 1027 CurrentStrengthIDValue = 0; 1028 return new double[] { IntensityValue, (double)CurrentStrengthIDValue }; /* EXIT */ 1029 } 1030 1031 /* determine various time threshold values */ 1032 double CurrentTimeMinus6Hrs = CurrentTime-0.25; 1033 double CurrentTimeMinus24Hrs = CurrentTime-1.0; 1034 1035 /* find record just prior to current record */ 1036 double PreviousHistoryTnoMaximumValue = 0.0; 1037 double PreviousHistoryTnoMaximum6hrValue = 0.0; 1038 double PreviousHistoryCIValue = 0.0; 1039 double PreviousHistoryRapidDissIDValue = 0; 1040 double PreviousHistoryRapidDissIDMinimumValue = 99; 1041 int XInc = 0; 1042 while(XInc<NumRecsHistory) { 1043 int RecDate = History.HistoryFile[XInc].date; 1044 int RecTime = History.HistoryFile[XInc].time; 1045 double HistoryRecTime = Functions.calctime(RecDate,RecTime); 1046 if(HistoryRecTime>=CurrentTime) { 1047 break; 1048 } 1049 int RecLand = History.HistoryFile[XInc].land; 1050 double Traw = History.HistoryFile[XInc].Traw; 1051 LandCheckTF = true; 1052 if(((LandFlagTF)&&(RecLand==1))||(Traw<1.0)) { 1053 LandCheckTF = false; 1054 } 1055 if(LandCheckTF) { 1056 PreviousHistoryFinalTnoValue = History.HistoryFile[XInc].Tfinal; 1057 PreviousHistoryCIValue = History.HistoryFile[XInc].CI; 1058 PreviousHistoryRule9Value = History.HistoryFile[XInc].rule9; 1059 PreviousHistoryRapidDissIDValue = History.HistoryFile[XInc].rapiddiss; 1060 /* check Rule 9 */ 1061 if(HistoryRecTime>=CurrentTimeMinus6Hrs) { 1062 /* find largest finalT# in last 6 hours prior to current record */ 1063 if(PreviousHistoryFinalTnoValue>PreviousHistoryTnoMaximumValue) { 1064 PreviousHistoryTnoMaximumValue = PreviousHistoryFinalTnoValue; 1065 } 1066 } 1067 if(HistoryRecTime>=CurrentTimeMinus6Hrs) { 1068 /* if storm is over land for SIX hours, turn off Rule 9 1069 (changed from 12 hours) */ 1070 LandOnly12hrTF = false; 1071 1072 /* rapid dissapation check */ 1073 if(PreviousHistoryRapidDissIDValue<PreviousHistoryRapidDissIDMinimumValue) { 1074 PreviousHistoryRapidDissIDMinimumValue = PreviousHistoryRapidDissIDValue; 1075 } 1076 if(PreviousHistoryFinalTnoValue>PreviousHistoryTnoMaximum6hrValue) { 1077 PreviousHistoryTnoMaximum6hrValue = PreviousHistoryFinalTnoValue; 1078 } 1079 } 1080 if(HistoryRecTime>=CurrentTimeMinus24Hrs) { 1081 /* find min and max finalT# in last 24 hours prior to current record */ 1082 if(PreviousHistoryFinalTnoValue<TnoMinimumValue) { 1083 TnoMinimumValue = PreviousHistoryFinalTnoValue; 1084 } 1085 if(PreviousHistoryFinalTnoValue>TnoMaximumValue) { 1086 TnoMaximumValue = PreviousHistoryFinalTnoValue; 1087 } 1088 } 1089 } 1090 XInc++; 1091 } 1092 1093 IntensityValue = History.IRCurrentRecord.Tfinal; 1094 1095 if(XInc==0) { 1096 /* current record is before first record in history file */ 1097 CurrentStrengthIDValue=0; 1098 /* Apply Latitude Bias Adjustment to CI value */ 1099 //CIadjP = adt_latbias(InitStrengthTF,LandFlagTF,HistoryFileName,IntensityValue,Latitude,Longitude); 1100 CIadjP = adt_latbias(InitStrengthTF,LandFlagTF,HistoryFileName,Latitude,Longitude); 1101 History.IRCurrentRecord.CIadjp = CIadjP; 1102 /* return Final T# for CI# for initial analysis */ 1103 return new double[] { IntensityValue, (double)CurrentStrengthIDValue }; /* EXIT */ 1104 } 1105 1106 Rule9IDValue = PreviousHistoryRule9Value; 1107 int[] ReturnValues3 = Functions.adt_oceanbasin(Latitude,Longitude); 1108 int BasinID_Local = ReturnValues3[0]; 1109 1110 /* rapid dissipation determination */ 1111 double Slope6hrValue = Functions.adt_slopecal(6.0,2); 1112 if(PreviousHistoryRapidDissIDValue<=1) { 1113 RapidDissIDValue = 0; 1114 /* if(Slope6hrValue>=2.0) { */ 1115 /* relax rapid weakening criteria for the East Pac */ 1116 if(((BasinID_Local!=2)&&(Slope6hrValue>=2.0))|| ((BasinID_Local==2)&&(Slope6hrValue>=1.5))) { 1117 /* 2.0/24 hours or 1.5/24 hours for East Pac */ 1118 RapidDissIDValue = 1; 1119 } 1120 if((PreviousHistoryRapidDissIDMinimumValue==1)&&(RapidDissIDValue==1)) { 1121 Rule9AdditiveValue = 0.5; 1122 RapidDissIDValue = 2; 1123 } 1124 } else { 1125 Rule9AdditiveValue = 0.5; 1126 RapidDissIDValue = 2; 1127 /* if(Slope6hrValue<1.5) { */ 1128 if(((BasinID_Local!=2)&&(Slope6hrValue<1.5))|| ((BasinID_Local==2)&&(Slope6hrValue<1.0))) { 1129 /* 1.5/24 hours or 1.0/24 hours for East Pac */ 1130 RapidDissIDValue = 3; 1131 } 1132 if((PreviousHistoryRapidDissIDMinimumValue==3)&&(RapidDissIDValue==3)) { 1133 Rule9AdditiveValue = 1.0; 1134 RapidDissIDValue = 0; 1135 } 1136 } 1137 1138 /* 1139 * strength flags : 0 - strengthening, but not significant 1140 * 1 - applying Max's 12 hour max Tno. rule 1141 */ 1142 /* determine CI# */ 1143 double CurrentTnoValue = IntensityValue; 1144 double CurrentTnoPlusRule9Value = IntensityValue+Rule9AdditiveValue; 1145 /* 1146 * We have once again returned to using the 6 hour Max T# value 1147 * for all basins for the Rule 9 check 1148 */ 1149 double CIValue = Math.min(CurrentTnoPlusRule9Value, 1150 Math.max(PreviousHistoryTnoMaximumValue,CurrentTnoValue)); 1151 1152 /* will utilize Max's Rule all of the time */ 1153 if(CIValue>CurrentTnoValue) { 1154 Rule9IDValue = 1; 1155 } 1156 if((PreviousHistoryRule9Value==1)&&(PreviousHistoryCIValue<=CurrentTnoValue)) { 1157 Rule9IDValue = 0; 1158 } 1159 1160 /* 1161 * check for land interaction 1162 * if undergoing interactation with land "turn off" Rule 9 1163 * application and return CI value to Adjusted Raw Tno value for >= 3 hours (was 12 hours) 1164 */ 1165 if(LandOnly12hrTF) { 1166 /* 1167 * if land flag is TRUE, 1168 * turn off Rule 9 and let CI value be equal to the 1169 * current Adjusted Raw T# value, and return (was Final T#) 1170 * current intensity flag to "insignificant value" until 1171 * another significant strengtheing cycle occurs 1172 */ 1173 Rule9IDValue = 0; 1174 CIValue = History.IRCurrentRecord.Traw; 1175 RapidDissIDValue = 0; 1176 } 1177 /* Apply Latitude Bias Adjustment to CI value */ 1178 //CIadjP = adt_latbias(InitStrengthTF,LandFlagTF,HistoryFileName,CIValue,Latitude,Longitude); 1179 CIadjP = adt_latbias(InitStrengthTF,LandFlagTF,HistoryFileName,Latitude,Longitude); 1180 /* System.out.printf("CIno: ciadjp=%f\n",CIadjP); */ 1181 History.IRCurrentRecord.CIadjp = CIadjP; 1182 History.IRCurrentRecord.rapiddiss = RapidDissIDValue; 1183 1184 CurrentStrengthIDValue = Rule9IDValue; 1185 1186 return new double[] { CIValue, (double)CurrentStrengthIDValue }; 1187 } 1188 1189 /** 1190 * Apply Latitude Bias Adjustment to CI value. 1191 * 1192 * @param InitStrengthTF 1193 * @param LandFlagTF Flag that represents land status. 1194 * @param HistoryFileName Path to history file. 1195 * @param InputLatitude Current latitude of storm. 1196 * @param InputLongitude Current longitude of storm. 1197 * 1198 * @return Adjusted MSLP value. 1199 */ 1200 public static double adt_latbias(boolean InitStrengthTF, 1201 boolean LandFlagTF, 1202 String HistoryFileName, 1203 double InputLatitude, 1204 double InputLongitude) 1205 { 1206 double ReturnCIPressureAdjValue = 0.0; 1207 boolean UseCKZTF = Env.UseCKZTF; 1208 if(!UseCKZTF) { 1209 double[] RetVals = adt_scenesearch(HistoryFileName,InitStrengthTF,LandFlagTF); 1210 int LatBiasAdjFlagID = (int)RetVals[0]; 1211 double AdjustmentMultFactor = RetVals[1]; 1212 History.IRCurrentRecord.LBflag = LatBiasAdjFlagID; 1213 /* System.out.printf("latbiasadjflagid=%d\n",LatBiasAdjFlagID); */ 1214 if(LatBiasAdjFlagID>=2) { 1215 /* EIR scene */ 1216 if((InputLatitude>=0.0)&&((InputLongitude>=-100.0)&& (InputLongitude<=-40.0))) { 1217 /* do not make adjustment in N Indian Ocean */ 1218 ReturnCIPressureAdjValue = 0.0; 1219 } else { 1220 /* apply bias adjustment to pressure */ 1221 ReturnCIPressureAdjValue = AdjustmentMultFactor* 1222 (7.325-(0.302*Math.abs(InputLatitude))); 1223 } 1224 } 1225 } 1226 return ReturnCIPressureAdjValue; 1227 } 1228 1229 /** 1230 * Search for valid scene range for Latitude Bias Adjustment application. 1231 * Inputs : None 1232 * Outputs : AdjustmentMultFactor_Return - multiplicative value for merging 1233 * Return : 0 - first record in new history file 1234 * 1 - non Enhanced Infrared scene or intermediate/merging application 1235 * 2 - entering/leaving valid adjustment time period. Also used for 1236 * non-history file intensity analysis (full adjustment) 1237 * 1238 * @param HistoryFileName Path to history file. 1239 * @param InitStrengthTF 1240 * @param LandFlagTF Over land? 1241 * 1242 * @return Array of two doubles. The first value represents latitude bias 1243 * adjustment, while the second value represents the adjustment's 1244 * multiplicative factor. 1245 */ 1246 public static double[] adt_scenesearch(String HistoryFileName, 1247 boolean InitStrengthTF, 1248 boolean LandFlagTF) 1249 { 1250 int LatBiasAdjFlagID = -1; 1251 double AdjustmentMultFactor = 0.0; 1252 1253 int NumRecsHistory = History.HistoryNumberOfRecords(); 1254 if(((NumRecsHistory==0)&&(InitStrengthTF))&&(HistoryFileName!=null)) { 1255 return new double[] { 0.0, -999.9 }; 1256 } 1257 if(HistoryFileName==null) { 1258 return new double[] { 2.0, 1.0 }; 1259 } 1260 1261 int HistoryRecLatBiasAdjFlagIDValue = 0; 1262 1263 int CloudScene = History.IRCurrentRecord.cloudscene; 1264 /* System.out.printf("cloudscene=%d\n",CloudScene); */ 1265 if((CloudScene>=2)&&(CloudScene<6)) LatBiasAdjFlagID = 0; 1266 1267 int ImageDate = History.IRCurrentRecord.date; 1268 int ImageTime = History.IRCurrentRecord.time; 1269 double CurrentTime = Functions.calctime(ImageDate,ImageTime); 1270 double CurrentTimeMinus6hr = CurrentTime - 0.26; 1271 double MergePeriodFirstTime = CurrentTime; 1272 1273 int RecDate,RecTime,RecLand; 1274 double HistoryRecTime; 1275 double RecTnoRaw; 1276 boolean LandCheckTF=true; 1277 boolean EIRSceneTypeTF=true; 1278 boolean FoundMergePeriodFirstRecordTF = false; 1279 double FirstHistoryRecTime = -99999.0; 1280 1281 int XInc=0; 1282 while(XInc<NumRecsHistory) { 1283 RecDate = History.HistoryFile[XInc].date; 1284 RecTime = History.HistoryFile[XInc].time; 1285 HistoryRecTime = Functions.calctime(RecDate,RecTime); 1286 RecLand = History.HistoryFile[XInc].land; 1287 RecTnoRaw = History.HistoryFile[XInc].Traw; 1288 if(((LandFlagTF)&&(RecLand==1))||(RecTnoRaw<1.0)) { 1289 LandCheckTF = false; 1290 } 1291 if((HistoryRecTime<CurrentTime)&&(LandCheckTF)) { 1292 HistoryRecLatBiasAdjFlagIDValue = History.HistoryFile[XInc].LBflag; 1293 /* System.out.printf("Historyrectime=%f Currtimem6=%f eirscenetypetf=%b\n",HistoryRecTime,CurrentTimeMinus6hr,EIRSceneTypeTF); */ 1294 if((HistoryRecTime>=CurrentTimeMinus6hr)&&(EIRSceneTypeTF)) { 1295 if(FirstHistoryRecTime<0.0) { 1296 FirstHistoryRecTime = HistoryRecTime; 1297 } 1298 /* System.out.printf("HistoryRecLatBiasAdjFlagIDValue=%d\n",HistoryRecLatBiasAdjFlagIDValue); */ 1299 if(HistoryRecLatBiasAdjFlagIDValue==0) { 1300 EIRSceneTypeTF = false; 1301 } 1302 if(HistoryRecLatBiasAdjFlagIDValue==2) { 1303 if(!FoundMergePeriodFirstRecordTF) { 1304 MergePeriodFirstTime = HistoryRecTime; 1305 FoundMergePeriodFirstRecordTF = true; 1306 } 1307 } 1308 } 1309 } 1310 XInc++; 1311 } 1312 1313 /* System.out.printf("scenesearch: FirstHistoryRecTime=%f\n",FirstHistoryRecTime); */ 1314 if(FirstHistoryRecTime<0.0) { 1315 /* there is a six hour gap in the data for some reason... 1316 I will use the last value available */ 1317 LatBiasAdjFlagID=HistoryRecLatBiasAdjFlagIDValue; 1318 if(HistoryRecLatBiasAdjFlagIDValue>=1) { 1319 LatBiasAdjFlagID = 2; 1320 } 1321 AdjustmentMultFactor = 1.0; 1322 } else { 1323 /* System.out.printf("scenesearch: eirscenetypetf=%b",EIRSceneTypeTF); */ 1324 if(EIRSceneTypeTF) { 1325 /* entering or in valid lat bias adjustment period */ 1326 LatBiasAdjFlagID = 2; 1327 /* return value from 0 to 1 */ 1328 AdjustmentMultFactor = (CurrentTime-MergePeriodFirstTime)/ 1329 (CurrentTime-FirstHistoryRecTime); 1330 } else { 1331 /* LatBiasAdjFlagID = LatBiasAdjFlagID; */ 1332 AdjustmentMultFactor = -999.0; 1333 } 1334 } 1335 return new double[] { (double)LatBiasAdjFlagID, AdjustmentMultFactor }; 1336 } 1337}