001 /* 002 * $Id: StormAODT.java,v 1.1 2012/01/04 20:39:39 tommyj Exp $ 003 * 004 * This file is part of McIDAS-V 005 * 006 * Copyright 2007-2012 007 * Space Science and Engineering Center (SSEC) 008 * University of Wisconsin - Madison 009 * 1225 W. Dayton Street, Madison, WI 53706, USA 010 * https://www.ssec.wisc.edu/mcidas 011 * 012 * All Rights Reserved 013 * 014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 015 * some McIDAS-V source code is based on IDV and VisAD source code. 016 * 017 * McIDAS-V is free software; you can redistribute it and/or modify 018 * it under the terms of the GNU Lesser Public License as published by 019 * the Free Software Foundation; either version 3 of the License, or 020 * (at your option) any later version. 021 * 022 * McIDAS-V is distributed in the hope that it will be useful, 023 * but WITHOUT ANY WARRANTY; without even the implied warranty of 024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 025 * GNU Lesser Public License for more details. 026 * 027 * You should have received a copy of the GNU Lesser Public License 028 * along with this program. If not, see http://www.gnu.org/licenses. 029 */ 030 031 package edu.wisc.ssec.mcidasv.control.cyclone; 032 033 import java.util.List; 034 035 /** 036 * Created by IntelliJ IDEA. User: yuanho Date: Feb 20, 2009 Time: 3:09:14 PM To 037 * change this template use File | Settings | File Templates. 038 */ 039 040 public class StormAODT { 041 042 /** _more_ */ 043 StormAODTInfo.IRData odtcurrent_v72IR; 044 045 /** _more_ */ 046 StormAODTInfo.DataGrid areadata_v72; 047 048 /** _more_ */ 049 boolean lauto = false; 050 051 /** _more_ */ 052 int idomain_v72, ixdomain_v72, ifixtype_v72, rmwsizeman_v72; 053 054 /** _more_ */ 055 int oland_v72; 056 057 /** _more_ */ 058 boolean osearch_v72; 059 060 /** _more_ */ 061 int ostartstr_v72; 062 063 /** _more_ */ 064 float osstr_v72; 065 066 /** 067 * _more_ 068 * 069 * @param curdate 070 * _more_ 071 * @param curtime 072 * _more_ 073 * @param cursat 074 * _more_ 075 * @param cenlat 076 * _more_ 077 * @param cenlon 078 * _more_ 079 * @param posm 080 * _more_ 081 * @param g_domain 082 * _more_ 083 * 084 * @return _more_ 085 */ 086 int aodtv72_drive(int curdate, int curtime, int cursat, float cenlat, 087 float cenlon, int posm, String g_domain) { 088 089 int idomain = 0; 090 091 /* 092 * Set miscoptions flags in AODT 093 */ 094 095 int eyeSize = -99; 096 oland_v72 = 0; /* allow AODT operation over land */ 097 osearch_v72 = false; /* search for maximum curved band position */ 098 rmwsizeman_v72 = eyeSize; /* eye size parameter */ 099 100 /* 101 * Set initial classification flag and value in AODT 102 */ 103 104 ostartstr_v72 = 0; /* user defined initial classification flag */ 105 osstr_v72 = 0.0f; /* starting initial classification value */ 106 107 /* 108 * Set image date/time info in AODT 109 */ 110 111 int iaodt = aodtv72_setIRimageinfo(curdate, curtime, cursat); 112 113 /* 114 * Get storm center lat/lon 115 */ 116 if (lauto == true) { 117 // aodtv72_runautomode( nauto, fauto, imagefile, &cenlat, &cenlon, 118 // &posm ); 119 } 120 121 /* 122 * Set center location in AODT 123 */ 124 iaodt = aodtv72_setlocation(cenlat, cenlon, posm); 125 126 /* 127 * Set domain FLAG in AODT 128 */ 129 if (g_domain.equalsIgnoreCase("AUTO")) { 130 idomain = 0; 131 } 132 if (g_domain.equalsIgnoreCase("ATL")) { 133 idomain = 1; 134 } 135 if (g_domain.equalsIgnoreCase("PAC")) { 136 idomain = 2; 137 } 138 if (g_domain.equalsIgnoreCase("IND")) { 139 idomain = 2; 140 } 141 142 iaodt = aodtv72_setdomain(idomain); 143 144 /* 145 * Retrieve temperatures from image. This to be done in IDV 146 */ 147 148 float[][] temps = null; 149 float[][] lons = null; 150 float[][] lats = null; 151 int numx = 0; 152 int numy = 0; 153 154 /* 155 * Load the IR imge information in AODT init areadata_v72 156 */ 157 158 iaodt = aodtv72_loadIRimage(temps, lats, lons, numx, numy); 159 160 /* 161 * Set eye and cloud temperature values in AODT, return position for IR 162 * image data read 163 */ 164 165 odtcurrent_v72IR = aodtv72_seteyecloudtemp(StormAODTInfo.keyerM_v72, 166 areadata_v72); 167 168 /* 169 * Determine scene type Set scene type 170 */ 171 172 float[] oscen = StormAODTSceneType.aodtv72_calcscene(odtcurrent_v72IR, 173 rmwsizeman_v72, areadata_v72, osstr_v72, osearch_v72); 174 175 odtcurrent_v72IR.eyescene = (int) oscen[0]; 176 odtcurrent_v72IR.cloudscene = (int) oscen[1]; 177 odtcurrent_v72IR.eyesceneold = -1; 178 odtcurrent_v72IR.cloudsceneold = -1; 179 odtcurrent_v72IR.eyecdosize = oscen[2]; 180 odtcurrent_v72IR.ringcb = (int) oscen[3]; 181 odtcurrent_v72IR.ringcbval = (int) oscen[4]; 182 odtcurrent_v72IR.ringcbvalmax = (int) oscen[5]; 183 odtcurrent_v72IR.ringcblatmax = oscen[6]; 184 odtcurrent_v72IR.ringcblonmax = oscen[7]; 185 odtcurrent_v72IR.rmw = oscen[8]; 186 odtcurrent_v72IR.cloudt = oscen[9]; 187 odtcurrent_v72IR.cloudt2 = oscen[10]; 188 odtcurrent_v72IR.eyestdv = oscen[11]; 189 odtcurrent_v72IR.cloudsymave = oscen[12]; 190 odtcurrent_v72IR.eyefft = (int) oscen[13]; 191 odtcurrent_v72IR.cloudfft = (int) oscen[14]; 192 193 /* 194 * Determine intensity 195 */ 196 197 iaodt = aodtv72_calcintensity(idomain_v72); 198 if (iaodt == 71) { 199 throw new IllegalStateException("center location is over land"); 200 } 201 202 /* 203 * Print out all diagnostic messages to screen 204 */ 205 List result = StormAODTUtil.aodtv72_textscreenoutput(odtcurrent_v72IR, 206 idomain_v72); 207 208 return 0; 209 210 } 211 212 /** 213 * Routine to search for, identify, and set the eye and cloud temperature 214 * values for the AODT library. Temperatures are set within AODT library. 215 * Inputs : none Outputs: none Return : -51 : eye, CWcloud, or warmest 216 * temperature <-100C or >+40C 0 : o.k. 217 * 218 * @param keyerM_v72 219 * _more_ 220 * @param areadata 221 * _more_ 222 * 223 * @return _more_ 224 */ 225 226 StormAODTInfo.IRData aodtv72_seteyecloudtemp(int keyerM_v72, 227 StormAODTInfo.DataGrid areadata) 228 229 { 230 StormAODTInfo.IRData ird = StormAODTSceneType.aodtv72_gettemps( 231 keyerM_v72, areadata); 232 if (ird == null) { 233 throw new IllegalStateException( 234 "eye, CWcloud, or warmest temperature <-100C or >+40C"); 235 } 236 237 return ird; 238 } 239 240 /** 241 * _more_ 242 * 243 * @param temps 244 * _more_ 245 * @param lats 246 * _more_ 247 * @param lons 248 * _more_ 249 * @param numx 250 * _more_ 251 * @param numy 252 * _more_ 253 * 254 * @return _more_ 255 */ 256 int aodtv72_loadIRimage(float[][] temps, float[][] lats, float[][] lons, 257 int numx, int numy) 258 /* 259 * Subroutine to load IR image data grid values (temperatures and positions) 260 * into data structure for AODT library Inputs : temperature, latitude, and 261 * longitude arrays centered on storm position location along with number of 262 * columns (x) and rows (y) in grid Outputs: none (areadata_v72 structure 263 * passed via global variable) Return : 0 : o.k. 264 */ 265 { 266 StormAODTInfo sinfo = new StormAODTInfo(); 267 /* allocate space for data */ 268 269 areadata_v72 = sinfo.new DataGrid(temps, lats, lons, numx, numy); 270 271 return 0; 272 } 273 274 /** 275 * _more_ 276 * 277 * @param indomain 278 * _more_ 279 * 280 * @return _more_ 281 */ 282 int aodtv72_setdomain(int indomain) 283 /* 284 * set current ocean domain variable within AODT library memory Inputs : 285 * domain flag value from input Outputs: none Return : -81 : error 286 * deterimining storm basin 287 */ 288 { 289 int domain; 290 float xlon; 291 292 /* obtain current storm center longitude */ 293 xlon = odtcurrent_v72IR.longitude; 294 if ((xlon < -180.0) || (xlon > 180.0)) { 295 return -81; 296 } 297 298 ixdomain_v72 = indomain; 299 /* determine oceanic domain */ 300 if (indomain == 0) { 301 /* automatically determined storm basin */ 302 if (xlon >= 0.0) { 303 domain = 0; /* atlantic and east pacific to 180W/dateline */ 304 } else { 305 domain = 1; /* west pacific and other regions */ 306 } 307 } else { 308 /* manually determined storm basin */ 309 domain = indomain - 1; 310 } 311 312 /* assign ocean domain flag value to AODT library variable */ 313 idomain_v72 = domain; 314 315 return 0; 316 } 317 318 /** 319 * _more_ 320 * 321 * @param ilat 322 * _more_ 323 * @param ilon 324 * _more_ 325 * @param ipos 326 * _more_ 327 * 328 * @return _more_ 329 */ 330 int aodtv72_setlocation(float ilat, float ilon, int ipos) 331 /* 332 * set current storm center location within from AODT library memory Inputs 333 * : AODT library current storm center latitude and longitude values and 334 * location positioning method : 1-forecast interpolation 2-laplacian 335 * technique 3-warm spot 4-extrapolation Outputs: none Return : -21 : 336 * invalid storm center position 21 : user selected storm center position 22 337 * : auto selected storm center position 338 */ 339 { 340 int iret; 341 342 /* assign current storm center latitude value to AODT library variable */ 343 odtcurrent_v72IR.latitude = ilat; 344 /* assign current storm center longitude value to AODT library variable */ 345 odtcurrent_v72IR.longitude = ilon; 346 /* assign current storm center positioning flag to AODT library variable */ 347 odtcurrent_v72IR.autopos = ipos; 348 if ((odtcurrent_v72IR.longitude < -180.) 349 || (odtcurrent_v72IR.longitude > 180.)) { 350 iret = -21; 351 } 352 if ((odtcurrent_v72IR.latitude < -90.) 353 || (odtcurrent_v72IR.latitude > 90.)) { 354 iret = -21; 355 } 356 357 iret = 21; /* user selected image location */ 358 if (ipos >= 1) { 359 iret = 22; 360 } 361 362 return iret; 363 } 364 365 /** 366 * _more_ 367 * 368 * @param date 369 * _more_ 370 * @param time 371 * _more_ 372 * @param sat 373 * _more_ 374 * 375 * @return _more_ 376 */ 377 int aodtv72_setIRimageinfo(int date, int time, int sat) 378 /* 379 * set IR image date/time within AODT library memory Inputs : AODT library 380 * IR image date/time/satellite information Outputs: none Return : 0 : o.k. 381 */ 382 { 383 /* assign IR image date to AODT library variable */ 384 odtcurrent_v72IR.date = date; 385 /* assign IR image time to AODT library variable */ 386 odtcurrent_v72IR.time = time; 387 /* assign IR image satellite type to AODT library variable */ 388 odtcurrent_v72IR.sattype = sat; 389 390 return 0; 391 } 392 393 /** 394 * _more_ 395 * 396 * @param idomain 397 * _more_ 398 * 399 * @return _more_ 400 */ 401 public int aodtv72_calcintensity(int idomain) 402 /* 403 * Compute intensity values CI, Final T#, and Raw T#. Inputs : global 404 * structure odtcurrent_v72 containing current analysis Outputs : none 405 * Return : 71 : storm is over land 0 : o.k. 406 */ 407 { 408 409 int iret; 410 int strength; 411 412 if ((odtcurrent_v72IR.land == 1)) { 413 aodtv72_initcurrent(true, odtcurrent_v72IR); 414 iret = 71; 415 } else { 416 /* calculate current Raw T# value */ 417 odtcurrent_v72IR.Traw = aodtv72_Tnoraw(odtcurrent_v72IR, idomain); 418 odtcurrent_v72IR.TrawO = odtcurrent_v72IR.Traw; 419 /* check for spot analysis or full analysis using history file */ 420 /* if(hfile_v72==(char *)NULL) { */ 421 if (true) { 422 /* perform spot analysis (only Traw) */ 423 odtcurrent_v72IR.Tfinal = odtcurrent_v72IR.Traw; 424 odtcurrent_v72IR.Tfinal3 = odtcurrent_v72IR.Traw; 425 odtcurrent_v72IR.CI = odtcurrent_v72IR.Traw; 426 odtcurrent_v72IR.CIadjp = aodtv72_latbias(odtcurrent_v72IR.CI, 427 odtcurrent_v72IR.latitude, odtcurrent_v72IR.longitude, 428 odtcurrent_v72IR); 429 /* 430 * printf("%f %f %f %f\n",odtcurrent_v72IR.CI,odtcurrent_v72IR. 431 * latitude 432 * ,odtcurrent_v72->IR.longitude,odtcurrent_v72->IR.CIadjp); 433 */ 434 odtcurrent_v72IR.rule9 = 0; 435 /* odtcurrent_v72->IR.TIEraw=aodtv72_TIEmodel(); */ 436 /* odtcurrent_v72->IR.TIEavg=odtcurrent_v72->IR.TIEraw; */ 437 /* odtcurrent_v72->IR.TIEflag=aodtv72_tieflag(); */ 438 } 439 440 iret = 0; 441 } 442 443 return iret; 444 } 445 446 /** 447 * _more_ 448 * 449 * @param initval 450 * _more_ 451 * @param latitude 452 * _more_ 453 * @param longitude 454 * _more_ 455 * @param odtcurrent_v72IR 456 * _more_ 457 * 458 * @return _more_ 459 */ 460 float aodtv72_latbias(float initval, float latitude, float longitude, 461 StormAODTInfo.IRData odtcurrent_v72IR) 462 /* 463 * Apply Latitude Bias Adjustment to CI value Inputs : initval - initial CI 464 * value latitude - current latitude of storm Outputs : adjusted MSLP value 465 * as return value 466 */ 467 { 468 float initvalp; 469 float value; /* lat bias adjustement amount (0.00-1.00) */ 470 int sceneflag; /* 471 * contains lat bias adjustment flag 0=no adjustment 472 * 1=intermediate adjustment (6 hours) 2=full adjustment 473 */ 474 475 sceneflag = aodtv72_scenesearch(0); /* 476 * 0 means search for EIR based 477 * parameters... cdo, etc 478 */ 479 value = 1.0f; /* this value should be return from scenesearch() */ 480 /* printf("sceneflag=%d value=%f\n",sceneflag,value); */ 481 odtcurrent_v72IR.LBflag = sceneflag; 482 /* initvalp=aodtv72_getpwval(0,initval); TLO */ 483 initvalp = 0.0f; 484 if (sceneflag >= 2) { 485 /* EIR scene */ 486 if ((latitude >= 0.0) 487 && ((longitude >= -100.0) && (longitude <= -40.0))) { 488 /* do not make adjustment in N Indian Ocean */ 489 return initvalp; 490 } 491 /* apply bias adjustment to pressure */ 492 /* initvalp=-1.0*value*(-20.60822+(0.88463*A_ABS(latitude))); */ 493 initvalp = value * (7.325f - (0.302f * Math.abs(latitude))); 494 } 495 496 return initvalp; 497 } 498 499 /** 500 * _more_ 501 * 502 * @param type 503 * _more_ 504 * 505 * @return _more_ 506 */ 507 int aodtv72_scenesearch(int type) { 508 int curflag = 1, flag, eirflag; 509 double curtime, xtime, curtimem6, mergetimefirst, mergetimelast, firsttime = -9999.0; 510 511 /* 512 * if(((odthistoryfirst_v72==0)&&(ostartstr_v72==TRUE))&&(hfile_v72!=(char 513 * *)NULL)) { 514 */ 515 516 if (true) { 517 flag = 2; 518 } 519 return flag; 520 } 521 522 /** 523 * _more_ 524 * 525 * @param redo 526 * _more_ 527 * @param odtcurrent_v72IR 528 * _more_ 529 * 530 * @return _more_ 531 */ 532 int aodtv72_initcurrent(boolean redo, StormAODTInfo.IRData odtcurrent_v72IR) 533 /* 534 * initialize odtcurrent_v72 array or reset values for land interaction 535 * situations 536 */ 537 { 538 539 if (!redo) { 540 // odtcurrent_v72=(struct odtdata *)malloc(sizeof(struct odtdata)); 541 odtcurrent_v72IR.latitude = 999.99f; 542 odtcurrent_v72IR.longitude = 999.99f; 543 odtcurrent_v72IR.land = 0; 544 odtcurrent_v72IR.autopos = 0; 545 // strcpy(odtcurrent_v72IR.comment,comm); 546 // diagnostics_v72=(char *)calloc((size_t)50000,sizeof(char)); 547 // hfile_v72=(char *)calloc((size_t)200,sizeof(char)); 548 // fixfile_v72=(char *)calloc((size_t)200,sizeof(char)); 549 550 // b=sizeof(float); 551 // bb=sizeof(double); 552 // fcstlat_v72=(float *)calloc((size_t)5,b); 553 // fcstlon_v72=(float *)calloc((size_t)5,b); 554 // fcsttime_v72=(double *)calloc((size_t)5,bb); 555 } 556 557 odtcurrent_v72IR.Traw = 0.0f; 558 odtcurrent_v72IR.TrawO = 0.0f; 559 odtcurrent_v72IR.Tfinal = 0.0f; 560 odtcurrent_v72IR.Tfinal3 = 0.0f; 561 odtcurrent_v72IR.CI = 0.0f; 562 odtcurrent_v72IR.eyet = 99.99f; 563 odtcurrent_v72IR.warmt = 99.99f; 564 odtcurrent_v72IR.cloudt = 99.99f; 565 odtcurrent_v72IR.cloudt2 = 99.99f; 566 odtcurrent_v72IR.cwcloudt = 99.99f; 567 odtcurrent_v72IR.warmlatitude = 999.99f; 568 odtcurrent_v72IR.warmlongitude = 999.99f; 569 odtcurrent_v72IR.eyecdosize = 0.0f; 570 odtcurrent_v72IR.eyestdv = 0.0f; 571 odtcurrent_v72IR.cloudsymave = 0.0f; 572 odtcurrent_v72IR.eyescene = 0; 573 odtcurrent_v72IR.cloudscene = 0; 574 odtcurrent_v72IR.eyesceneold = -1; 575 odtcurrent_v72IR.cloudsceneold = -1; 576 odtcurrent_v72IR.rule9 = 0; 577 odtcurrent_v72IR.rule8 = 0; 578 odtcurrent_v72IR.LBflag = 0; 579 odtcurrent_v72IR.rapiddiss = 0; 580 odtcurrent_v72IR.eyefft = 0; 581 odtcurrent_v72IR.cloudfft = 0; 582 odtcurrent_v72IR.cwring = 0; 583 odtcurrent_v72IR.ringcb = 0; 584 odtcurrent_v72IR.ringcbval = 0; 585 odtcurrent_v72IR.ringcbvalmax = 0; 586 odtcurrent_v72IR.CIadjp = 0.0f; 587 odtcurrent_v72IR.rmw = -99.9f; 588 /* odtcurrent_v72->IR.TIEflag=0; */ 589 /* odtcurrent_v72->IR.TIEraw=0.0; */ 590 /* odtcurrent_v72->IR.TIEavg=0.0; */ 591 /* odtcurrent_v72->IR.sst=-99.9; */ 592 // if(!redo) odtcurrent_v72->nextrec=NULL; /* added by CDB */ 593 594 return 0; 595 } 596 597 /** 598 * Compute initial Raw T-Number value using original Dvorak rules 599 * 600 * @param odtcurrent 601 * @param idomain_v72 602 * @return return value is Raw T# 603 */ 604 605 float aodtv72_Tnoraw(StormAODTInfo.IRData odtcurrent, int idomain_v72) 606 /* 607 * Compute initial Raw T-Number value using original Dvorak rules Inputs : 608 * global structure odtcurrent_v72 containing current analysis Outputs : 609 * return value is Raw T# 610 * 611 * ODT SCENE/TEMPERATURE TABLE BD | WMG OW DG MG LG B W CMG CDG | TEMP |30.0 612 * 0.0 -30.0 -42.0 -54.0 -64.0 -70.0 -76.0 -80.0+| 613 * ---------------------------------------------------------------| Atl EYE 614 * | 3.5 4.0 4.5 4.5 5.0 5.5 6.0 6.5 7.0 | EMBC | 3.5 3.5 4.0 4.0 4.5 4.5 615 * 5.0 5.0 5.0 | CDO | 3.0 3.0 3.5 4.0 4.5 4.5 4.5 5.0 5.0 | 616 * ---------------------------------------------------------------| Pac EYE 617 * | 4.0 4.0 4.0 4.5 4.5 5.0 5.5 6.0 6.5 | EMBC | 3.5 3.5 4.0 4.0 4.5 4.5 618 * 5.0 5.0 5.0 | CDO | 3.0 3.5 3.5 4.0 4.5 4.5 4.5 4.5 5.0 | 619 * ---------------------------------------------------------------| Cat diff 620 * | 0 1 2 3 4 5 6 7 8 | add | 0.0 0.0 0.0 0.0 0.0-->0.5 0.5-->1.0 1.5 | 621 * (old) add |-0.5 -0.5 0.0 0.0-->0.5 0.5 0.5-->1.0 1.0 | (new) 622 * ---------------------------------------------------------------| 623 */ 624 { 625 626 double eno[][] = { 627 { 1.00, 2.00, 3.25, 4.00, 4.75, 5.50, 5.90, 6.50, 7.00, 7.50, 628 8.00 }, /* original plus adjusted > CDG+ */ 629 { 1.50, 2.25, 3.30, 3.85, 4.50, 5.00, 5.40, 5.75, 6.25, 6.50, 630 7.00 } }; /* adjusted based */ 631 double cdo[][] = { 632 { 2.00, 2.40, 3.25, 3.50, 3.75, 4.00, 4.10, 4.20, 4.30, 4.40, 633 4.70 }, 634 { 2.05, 2.40, 3.00, 3.20, 3.40, 3.55, 3.65, 3.75, 3.80, 3.90, 635 4.10 } }; 636 double curbnd[] = { 1.0, 1.5, 2.5, 3.0, 3.5, 4.0, 4.5 }; 637 double shrdst[] = { 0.0, 35.0, 50.0, 80.0, 110.0, 140.0 }; 638 double shrcat[] = { 3.5, 3.0, 2.5, 2.25, 2.0, 1.5 }; 639 640 double diffchk[][] = { 641 { 0.0, 0.5, 1.2, 1.7, 2.2, 2.7, 0.0, 0.0, 0.1, 0.5 }, /* 642 * shear 643 * scene 644 * types... 645 * original 646 * Rule 8 647 * rules 648 */ 649 { 0.0, 0.5, 1.7, 2.2, 2.7, 3.2, 0.0, 0.0, 0.1, 0.5 }, /* 650 * eye scene 651 * types... 652 * add 0.5 653 * to Rule 8 654 * rules 655 */ 656 { 0.0, 0.5, 0.7, 1.2, 1.7, 2.2, 0.0, 0.0, 0.1, 0.5 } }; /* 657 * other 658 * scene 659 * types 660 * ... 661 * subtract 662 * 0.5 663 * from 664 * Rule 665 * 8 666 * rules 667 */ 668 double eyeadjfacEYE[] = { 0.011, 0.015 }; /* 669 * modified wpac value to be 670 * closer to atlantic 671 */ 672 double symadjfacEYE[] = { -0.015, -0.015 }; 673 double dgraysizefacCLD[] = { 0.002, 0.001 }; 674 double symadjfacCLD[] = { -0.030, -0.015 }; 675 676 int diffchkcat; 677 int ixx, cloudcat, eyecat, diffcat, rp, xrp, rb; 678 float incval, lastci, lasttno, lastr9, lastraw; 679 float xpart, xparteye, xaddtno, eyeadj, spart, ddvor, dvorchart, ciadj; 680 float sdist, cloudtemp, eyetemp, fftcloud; 681 float t1val, t6val, t12val, t18val, t24val, delt1, delt6, delt12, delt18, delt24; 682 float t1valraw, t1valrawx, txvalmin, txvalmax; 683 double curtime, xtime, firsttime, firstlandtime; 684 double ttime1, ttime6, ttime12, ttime18, ttime24, t1valrawxtime; 685 StormAODTInfo.IRData odthistory, prevrec; 686 boolean oceancheck, adjustshear, firstland; 687 boolean t1found = false, t6found = false, t12found = false, t18found = false, t24found = false; 688 boolean first6hrs = false; 689 float symadj, dgraysizeadj, deltaT; 690 691 cloudtemp = odtcurrent.cloudt; 692 eyetemp = odtcurrent.eyet; 693 cloudcat = 0; 694 eyecat = 0; 695 lastci = 4.0f; 696 xpart = 0.0f; 697 698 for (ixx = 0; ixx < 10; ixx++) { 699 /* compute cloud category */ 700 if ((cloudtemp <= StormAODTInfo.ebd_v72[ixx]) 701 && (cloudtemp > StormAODTInfo.ebd_v72[ixx + 1])) { 702 cloudcat = ixx; 703 xpart = (float) (cloudtemp - StormAODTInfo.ebd_v72[cloudcat]) 704 / (float) (StormAODTInfo.ebd_v72[cloudcat + 1] - StormAODTInfo.ebd_v72[cloudcat]); 705 } 706 /* compute eye category for eye adjustment */ 707 if ((eyetemp <= StormAODTInfo.ebd_v72[ixx]) 708 && (eyetemp > StormAODTInfo.ebd_v72[ixx + 1])) { 709 eyecat = ixx; 710 } 711 /* eyetemp=Math.min(0.0,eyetemp); */ 712 } 713 if (odtcurrent.eyescene == 1) { 714 /* for pinhole eye, determine what storm should be seeing */ 715 /* 716 * eyetemp=pinhole(odtcurrent_v72->IR.latitude,odtcurrent_v72->IR.longitude 717 * ,eyetemp); 718 */ 719 /* 720 * eyetemp=(9.0-eyetemp)/2.0; / this matches DT used at NHC (jack 721 * beven) 722 */ 723 eyetemp = (float) (eyetemp - 9.0) / 2.0f; /* 724 * between +9C (beven) and 725 * measured eye temp (turk) 726 */ 727 odtcurrent.eyet = eyetemp; 728 } 729 730 /* category difference between eye and cloud region */ 731 diffcat = Math.max(0, cloudcat - eyecat); 732 733 /* if scenetype is EYE */ 734 rp = odtcurrent.ringcbval; 735 rb = odtcurrent.ringcb; 736 fftcloud = odtcurrent.cloudfft; 737 738 if (odtcurrent.cloudscene == 3) { 739 /* CURVED BAND */ 740 rp = Math.min(30, rp + 1); /* added 1 for testing */ 741 xrp = rp / 5; 742 incval = 0.1f; 743 if (xrp == 1) { 744 incval = 0.2f; 745 } 746 ddvor = (float) curbnd[xrp]; 747 xaddtno = incval * (float) (rp - (xrp * 5)); 748 /* 749 * printf("rp=%d xrp=%d rb=%d ddvor=%f xaddtno=%f\n",rp,xrp,rb,ddvor 750 * ,xaddtno); 751 */ 752 ddvor = ddvor + xaddtno; 753 if (rb == 5) { 754 ddvor = Math.min(4.0f, ddvor + 0.5f); 755 } 756 if (rb == 6) { 757 ddvor = Math.min(4.5f, ddvor + 1.0f); 758 } 759 diffchkcat = 2; /* added for test - non-eye/shear cases */ 760 } else if (odtcurrent.cloudscene == 4) { 761 /* POSSIBLE SHEAR -- new definition from NHC */ 762 ixx = 0; 763 ddvor = 1.0f; 764 sdist = odtcurrent.eyecdosize; /* shear distance */ 765 while (ixx < 5) { 766 if ((sdist >= shrdst[ixx]) && (sdist < shrdst[ixx + 1])) { 767 spart = (float) ((sdist - shrdst[ixx]) / (shrdst[ixx + 1] - shrdst[ixx])); 768 xaddtno = (float) ((spart * (shrcat[ixx + 1] - shrcat[ixx]))); 769 ddvor = (float) (shrcat[ixx] + xaddtno); 770 ixx = 5; 771 } else { 772 ixx++; 773 } 774 } 775 diffchkcat = 0; /* added for test - shear cases */ 776 } else { 777 /* EYE or NO EYE */ 778 if (odtcurrent.eyescene <= 2) { 779 /* EYE */ 780 xaddtno = (float) (xpart * (eno[idomain_v72][cloudcat + 1] - eno[idomain_v72][cloudcat])); 781 /* 782 * cloud category must be white (-70C) or below for full 783 * adjustment; value will be merged in starting at black (-64C) 784 * / if(cloudcat<5) { / gray shades / xparteye=0.00; } else 785 * if(cloudcat==5) { / black / xparteye=xpart; } else { / white 786 * and colder / xparteye=1.00; } 787 */ 788 eyeadj = (float) eyeadjfacEYE[idomain_v72] 789 * (eyetemp - cloudtemp); 790 /* symadj=-0.02*(odtcurrent_v72->IR.cloudsymave); */ 791 symadj = (float) symadjfacEYE[idomain_v72] 792 * (odtcurrent.cloudsymave); 793 /* 794 * printf("EYE : cloudsymave=%f symadj=%f\n",odtcurrent_v72->IR. 795 * cloudsymave,symadj); 796 */ 797 ddvor = (float) eno[idomain_v72][cloudcat] + xaddtno + eyeadj 798 + symadj; 799 /* 800 * printf("EYE : xaddtno=%f eyeadj=%f symadj=%f ddvor=%f\n",xaddtno 801 * ,eyeadj,symadj,ddvor); 802 */ 803 ddvor = Math.min(ddvor, 9.0f); 804 /* printf("ddvor=%f\n",ddvor); */ 805 if (odtcurrent.eyescene == 2) { 806 ddvor = Math.min(ddvor - 0.5f, 6.5f); /* LARGE EYE adjustment */ 807 } 808 /* 809 * if(odtcurrent_v72->IR.eyescene==3) 810 * ddvor=Math.min(ddvor-0.5,6.0); / LARGE RAGGED EYE adjustment 811 */ 812 diffchkcat = 1; /* added for test - eye cases */ 813 /* printf("ddvor=%f\n",ddvor); */ 814 } else { 815 /* NO EYE */ 816 /* CDO */ 817 xaddtno = (float) (xpart * (cdo[idomain_v72][cloudcat + 1] - cdo[idomain_v72][cloudcat])); 818 /* dgraysizeadj=0.002*odtcurrent_v72->IR.eyecdosize; */ 819 dgraysizeadj = (float) dgraysizefacCLD[idomain_v72] 820 * odtcurrent.eyecdosize; 821 /* 822 * printf("CDO : dgraysize=%f symadj=%f\n",odtcurrent_v72->IR.eyecdosize 823 * ,dgraysizeadj); 824 */ 825 /* symadj=-0.03*(odtcurrent_v72->IR.cloudsymave); */ 826 symadj = (float) symadjfacCLD[idomain_v72] 827 * (odtcurrent.cloudsymave); 828 /* 829 * printf("CDO : cloudsymave=%f symadj=%f\n",odtcurrent_v72->IR. 830 * cloudsymave,symadj); 831 */ 832 ddvor = (float) cdo[idomain_v72][cloudcat] + xaddtno 833 + dgraysizeadj + symadj; 834 ddvor = ddvor - 0.1f; /* bias adjustment */ 835 /* 836 * printf("CDO : xaddtno=%f dgraysizeadj=%f symadj=%f ddvor=%f\n" 837 * ,xaddtno,dgraysizeadj,symadj,ddvor); 838 */ 839 ciadj = 0.0f; 840 if (odtcurrent.cloudscene == 0) { /* CDO */ 841 if (lastci >= 4.5) { 842 ciadj = Math.max(0.0f, Math.min(1.0f, lastci - 4.5f)); 843 } 844 if (lastci <= 3.0) { 845 ciadj = Math.min(0.0f, Math.max(-1.0f, lastci - 3.0f)); 846 } 847 /* printf("CDO : lastci=%f xaddtno=%f\n",lastci,ciadj); */ 848 ddvor = ddvor + ciadj; 849 } 850 if (odtcurrent.cloudscene == 1) { /* EMBEDDED CENTER */ 851 ciadj = Math.max(0.0f, Math.min(1.5f, lastci - 4.0f)); 852 /* printf("EMBC : lastci=%f xaddtno=%f\n",lastci,ciadj); */ 853 ddvor = ddvor + ciadj; /* changed from 0.5 */ 854 } 855 if (odtcurrent.cloudscene == 2) { /* IRREGULAR CDO (PT=3.5) */ 856 ddvor = ddvor + 0.3f; /* additional IrrCDO bias adjustment */ 857 ddvor = Math.min(3.5f, Math.max(2.5f, ddvor)); 858 } 859 diffchkcat = 2; /* added for test - non-eye/shear cases */ 860 } 861 } 862 863 dvorchart = ((float) (int) (ddvor * 10.0f)) / 10.0f; 864 // odtcurrent_v72IR.TrawO=dvorchart; 865 866 return dvorchart; 867 868 } 869 870 }