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