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    }