001/*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2016
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas
009 * 
010 * All Rights Reserved
011 * 
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.  
014 * 
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 * 
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023 * GNU Lesser Public License for more details.
024 * 
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program.  If not, see http://www.gnu.org/licenses.
027 */
028
029package edu.wisc.ssec.mcidasv.control.cyclone;
030
031import 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
038public 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}