001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2017 005 * Space Science and Engineering Center (SSEC) 006 * University of Wisconsin - Madison 007 * 1225 W. Dayton Street, Madison, WI 53706, USA 008 * https://www.ssec.wisc.edu/mcidas 009 * 010 * All Rights Reserved 011 * 012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 013 * some McIDAS-V source code is based on IDV and VisAD source code. 014 * 015 * McIDAS-V is free software; you can redistribute it and/or modify 016 * it under the terms of the GNU Lesser Public License as published by 017 * the Free Software Foundation; either version 3 of the License, or 018 * (at your option) any later version. 019 * 020 * McIDAS-V is distributed in the hope that it will be useful, 021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 023 * GNU Lesser Public License for more details. 024 * 025 * You should have received a copy of the GNU Lesser Public License 026 * along with this program. If not, see http://www.gnu.org/licenses. 027 */ 028 029package edu.wisc.ssec.mcidasv.adt; 030 031import java.io.File; 032import java.io.IOException; 033import java.util.Scanner; 034 035import org.slf4j.Logger; 036import org.slf4j.LoggerFactory; 037 038public class Forecasts { 039 040 private static final Logger logger = LoggerFactory.getLogger(Forecasts.class); 041 042 private static double ForecastLatitudes[] = new double[10]; 043 044 private static double ForecastLongitudes[] = new double[10]; 045 046 private static double ForecastTimes[] = new double[10]; 047 048 private static String[] MonthID_StringX = { 049 "JAN","FEB","MAR","APR","MAY","JUN", "JUL","AUG","SEP","OCT","NOV","DEC" 050 }; 051 052 public Forecasts() { 053 } 054 055 public static double[] ReadForecasts(String ForecastFileName, 056 int ForecastFileType, 057 double ThresholdTime) 058 throws IOException 059 { 060 String delims = "[, ]+"; 061 062 double ReturnLatitudeInterpolation = -999.5; 063 double ReturnLongitudeInterpolation = -999.5; 064 double ReturnCurrentIntensity = -999.5; 065 double CurrentDayValue; 066 int ReturnFlagValue = -1; 067 String TmpStr1; 068 String TmpStr2; 069 String TmpStr3; 070 String TmpStr4; 071 String TmpStr5; 072 String TmpStr6; 073 String TmpStr7; 074 String TmpStr8; 075 String TmpStr9; 076 String TmpStr12; 077 int WindVal; 078 int YearIntVal; 079 int MonthIntVal; 080 int DayIntVal; 081 int HMSTimeIntVal; 082 int FcstTimeIntVal; 083 int JulianDayIntVal; 084 int FcstTimeIntValPrev; 085 int LocVar1,LocVar2; 086 int DayIntValXX; 087 int MonthIntValXX; 088 int YearIntValXX; 089 int JulianDayIntValXX; 090 double TimeArray[] = new double[10]; 091 double LatitudeArray[] = new double[10]; 092 double LongitudeArray[] = new double[10]; 093 double StrengthArray[] = new double[10]; 094 double TmpTimeVal2; 095 double NSFactor; 096 double WEFactor; 097 098 ReturnFlagValue = 0; 099 100 logger.debug("ReadForecasts in..."); 101 System.out.printf("Forecast File Name=%s Type=%d\n", ForecastFileName,ForecastFileType); 102 File forecastfile = new File(ForecastFileName); 103 Scanner in = new Scanner(forecastfile); 104 105 int ImageDate = Data.IRData_JulianDate; 106 int ImageTime = Data.IRData_HHMMSSTime; 107 System.out.printf("IMAGE DATE=%d TIME=%d\n", Data.IRData_JulianDate, Data.IRData_HHMMSSTime); 108 /* int ImageDate = History.IRCurrentRecord.date; */ 109 /* int ImageTime = History.IRCurrentRecord.time; */ 110 double CurrentTime = Functions.calctime(ImageDate,ImageTime); 111 int XInc=0; 112 int YInc=0; 113 FcstTimeIntValPrev=-1; 114 115 try { 116 117 /* char aChar = ATCFStormIDString.charAt(2); */ 118 if(ForecastFileType==0) { 119 while (in.hasNextLine()) { 120 String forecastRec = in.nextLine(); 121 String[] tokens = forecastRec.split(delims); 122 TmpStr1 = tokens[0]; 123 TmpStr2 = tokens[1]; 124 TmpStr3 = tokens[2]; 125 TmpStr4 = tokens[3]; 126 TmpStr5 = tokens[4]; 127 TmpStr6 = tokens[5]; 128 TmpStr7 = tokens[6]; 129 TmpStr8 = tokens[7]; 130 TmpStr9 = tokens[8]; 131 TmpStr12 = tokens[11]; 132 WindVal=0; 133 if((TmpStr12.length()>1)&&(TmpStr12.matches("\\d+"))) { 134 WindVal = Integer.parseInt(TmpStr12.substring(0,2)); /* (int)aodt_atoif(TmpStr12,1,2); */ 135 } 136 /* 137 * System.out.printf("1=%s* 2=%s* 3=%s* 4=%s* 5=%s* 6=%s* 7=%s* 8=%s* 9=%s* 10=%s* 11=%s* 12=%s* \n", 138 * TmpStr1,TmpStr2,TmpStr3,TmpStr4,TmpStr5,TmpStr6,TmpStr7,TmpStr8,TmpStr9,TmpStr10,TmpStr11,TmpStr12); 139 */ 140 if(WindVal==34) { 141 YearIntVal = Integer.parseInt(TmpStr3.substring(0,4)); /* (int)aodt_atoif(TmpStr3,1,4); */ 142 MonthIntVal = Integer.parseInt(TmpStr3.substring(4,6)); /* (int)aodt_atoif(TmpStr3,5,6); */ 143 DayIntVal = Integer.parseInt(TmpStr3.substring(6,8)); /* (int)aodt_atoif(TmpStr3,7,8); */ 144 /* System.out.printf("year=%d month=%d day=%d\n",YearIntVal,MonthIntVal,DayIntVal); */ 145 HMSTimeIntVal = 10000*Integer.parseInt(TmpStr3.substring(8,10)); /* 10000*((int)aodt_atoif(TmpStr3,9,10)); */ 146 FcstTimeIntVal = 10000*Integer.parseInt(TmpStr6); /* 10000*((int)aodt_atoif(TmpStr6,1,strlen(TmpStr6))); */ 147 JulianDayIntVal = Functions.idmyyd(DayIntVal,MonthIntVal,YearIntVal); 148 TmpTimeVal2 = Functions.calctime(JulianDayIntVal,HMSTimeIntVal); 149 /* System.out.printf("YInc=%d tmptime=%f\n",YInc,TmpTimeVal2); */ 150 if((TmpTimeVal2<CurrentTime)&& 151 (FcstTimeIntValPrev!=FcstTimeIntVal)&&(YInc<6)) { 152 LocVar1 = ((int)(FcstTimeIntVal+HMSTimeIntVal))/240000; 153 LocVar2 = (((int)(FcstTimeIntVal+HMSTimeIntVal))%240000); 154 TimeArray[YInc] = Functions.calctime(JulianDayIntVal+LocVar1,LocVar2); 155 NSFactor = (TmpStr7.charAt(TmpStr7.length()-1)=='N') ? 1.0 : -1.0; 156 WEFactor = (TmpStr8.charAt(TmpStr8.length()-1)=='W') ? 1.0 : -1.0; 157 LatitudeArray[YInc] = NSFactor*Double.parseDouble(TmpStr7.substring(0,TmpStr7.length()-1))/10.0; /* (aodt_atoif(TmpStr7,1,strlen(TmpStr7)))/10.0; */ 158 LongitudeArray[YInc] = WEFactor*Double.parseDouble(TmpStr8.substring(0,TmpStr8.length()-1))/10.0; /* (aodt_atoif(TmpStr8,1,strlen(TmpStr8)))/10.0; */ 159 StrengthArray[YInc] = Double.parseDouble(TmpStr9); /* aodt_atoif(TmpStr9,1,4); */ 160 YInc++; 161 FcstTimeIntValPrev = FcstTimeIntVal; 162 XInc=YInc; 163 } 164 } 165 } 166 } else if(ForecastFileType==1) { /* NHC */ 167 /* read NHC forecast file, quit at EOF */ 168 DayIntValXX = 0; 169 MonthIntValXX = 0; 170 YearIntValXX = 0; 171 JulianDayIntValXX = 0; 172 DayIntVal = 0; 173 MonthIntVal = 0; 174 YearIntVal = 0; 175 JulianDayIntVal = 0; 176 boolean NewNHCFormatFlag = false; 177 boolean FoundMonthTF = false; 178 boolean FoundForecast = false; 179 while ((in.hasNextLine())&&(XInc<6)) { 180 String forecastRec = in.nextLine(); 181 String[] tokens = forecastRec.split(delims); 182 if(!FoundMonthTF) { 183 if((tokens.length==7)&&(tokens[1].equals("AM")||tokens[1].equals("PM"))) { 184 /* 185 * this is reading the header at the top of the forecast file. It 186 * is done to obtain the current month and year of the forecast so 187 * that we can check it accurately against the image date/time 188 */ 189 DayIntValXX = Integer.parseInt(tokens[5].substring(0,2)); /* (int)aodt_atoif(TmpStr6,1,2); */ 190 YearIntValXX = Integer.parseInt(tokens[6].substring(0,4)); /* (int)aodt_atoif(TmpStr7,1,4); */ 191 while((!tokens[4].equals(MonthID_StringX[MonthIntValXX]))&&(MonthIntValXX<12)) { 192 MonthIntValXX++; 193 } 194 JulianDayIntValXX = Functions.idmyyd(DayIntValXX,MonthIntValXX+1,YearIntValXX); 195 FoundMonthTF = true; 196 /* System.out.printf("XX julday=%d day=%d month=%d year=%d\n",JulianDayIntValXX,DayIntValXX,MonthIntValXX+1,YearIntValXX); */ 197 } 198 MonthIntVal = MonthIntValXX; 199 YearIntVal = YearIntValXX; 200 } else { 201 if((FoundForecast)&&(tokens.length>=6)) { 202 /* System.out.printf("length=%d\n",tokens.length); */ 203 if(XInc==0) { 204 if(tokens[0].equals("INITIAL")) { 205 NewNHCFormatFlag = false; 206 } else if((tokens[0].equals("INIT"))&&(YearIntVal>=2011)) { 207 NewNHCFormatFlag = true; 208 } else { 209 NewNHCFormatFlag = false; 210 } 211 /* System.out.printf("newformatflag=%b\n",NewNHCFormatFlag); */ 212 } 213 int iadd = (tokens[0].length()==0) ? 1 : 0; 214 if((NewNHCFormatFlag)||((!NewNHCFormatFlag)&&(XInc==0))) { 215 TmpStr1 = tokens[0+iadd]; 216 TmpStr2 = tokens[1+iadd]; 217 TmpStr3 = tokens[2+iadd]; 218 TmpStr4 = tokens[3+iadd]; 219 TmpStr5 = tokens[4+iadd]; 220 TmpStr6 = tokens[5+iadd]; 221 } else { 222 TmpStr1 = tokens[0+iadd]; 223 TmpStr2 = tokens[2+iadd]; 224 TmpStr3 = tokens[3+iadd]; 225 TmpStr4 = tokens[4+iadd]; 226 TmpStr5 = tokens[5+iadd]; 227 TmpStr6 = tokens[6+iadd]; 228 } 229 /* System.out.printf("1=%s* 1a=%s* 2=%s* 3=%s* 4=%s* 5=%s* 6=%s*\n",TmpStr1,TmpStr1a,TmpStr2,TmpStr3,TmpStr4,TmpStr5,TmpStr6); */ 230 if(TmpStr6.substring(0,2).equals("KT")) { 231 if(TmpStr2.charAt(7)=='Z') { 232 DayIntVal = Integer.parseInt(TmpStr2.substring(0,2)); /* ((int)aodt_atoif(TmpStr2,1,7))/10000; */ 233 HMSTimeIntVal = 100*(Integer.parseInt(TmpStr2.substring(3,7))); /* 100*(((int)aodt_atoif(TmpStr2,1,7))%10000); */ 234 if(DayIntVal<DayIntValXX) { 235 MonthIntVal++; 236 if(MonthIntVal==12) { 237 YearIntVal++; 238 MonthIntVal = 0; 239 } 240 JulianDayIntVal = Functions.idmyyd(DayIntVal,MonthIntVal+1,YearIntVal); 241 } else { 242 JulianDayIntVal = JulianDayIntValXX+(DayIntVal-DayIntValXX); 243 } 244 TimeArray[XInc] = Functions.calctime(JulianDayIntVal,HMSTimeIntVal); 245 NSFactor = (TmpStr3.charAt(TmpStr3.length()-1)=='N') ? 1.0 : -1.0; 246 WEFactor = (TmpStr4.charAt(TmpStr4.length()-1)=='W') ? 1.0 : -1.0; 247 LatitudeArray[XInc] = NSFactor*Double.parseDouble(TmpStr3.substring(0,TmpStr3.length()-1)); 248 LongitudeArray[XInc] = WEFactor*Double.parseDouble(TmpStr4.substring(0,TmpStr4.length()-1)); 249 StrengthArray[XInc] = Integer.parseInt(TmpStr5); 250 XInc++; 251 } 252 } 253 } else { 254 if(tokens[0].equals("FORECAST")&&tokens[1].equals("POSITIONS")) FoundForecast = true; 255 } 256 } 257 } 258 } else if(ForecastFileType==2) { 259 /* 260 * read JTWC forecast file, quit at EOF 261 * 262 * o.k... since JTWC does not put the month and year 263 * on their bulletins, they will need to be "made up". 264 * We will assume that the forecast is current and the 265 * month and year from the image is equal to the month 266 * and year of the forecast file. 267 */ 268 int[] ReturnValues = Functions.adt_yddmy((int)CurrentTime); 269 DayIntValXX = ReturnValues[0]; 270 MonthIntValXX = ReturnValues[1]; 271 YearIntValXX = ReturnValues[2]; 272 /* System.out.printf("DayIntValXX=%d\n",DayIntValXX); */ 273 /* System.out.printf("MonthIntValXX=%d\n",MonthIntValXX); */ 274 /* System.out.printf("YearIntValXX=%d\n",YearIntValXX); */ 275 int datexxx = 0; 276 int monthxxx = 0; 277 int yearxxx = 0; 278 int DayIntValSub = 0; 279 JulianDayIntVal = 0; 280 while (in.hasNextLine()) { 281 String forecastRec = in.nextLine(); 282 String[] tokens = forecastRec.split(delims); 283 if (tokens.length>=5) { 284 int iadd = (tokens[0].length()==0) ? 1 : 0; 285 TmpStr1 = tokens[0+iadd]; 286 TmpStr2 = tokens[1+iadd]; 287 TmpStr3 = tokens[2+iadd]; 288 TmpStr4 = tokens[3+iadd]; 289 if(TmpStr2.equals("---")) { 290 if(XInc==0) { 291 TmpStr5 = tokens[4+iadd]; 292 /* System.out.printf("XInc=%d : 1=%s* 2=%s* 3=%s* 4=%s* 5=%s* \n",XInc,TmpStr1,TmpStr2,TmpStr3,TmpStr4,TmpStr5); */ 293 DayIntVal = Integer.parseInt(TmpStr1.substring(0,2)); 294 HMSTimeIntVal = 100*Integer.parseInt(TmpStr1.substring(2,6)); 295 /* System.out.printf("dayintval=%d hmstimeintval=%d\n",DayIntVal,HMSTimeIntVal); */ 296 DayIntValSub=DayIntValXX-DayIntVal; 297 int[] ReturnValues2 = Functions.adt_yddmy(ImageDate); 298 datexxx = ReturnValues2[0]; 299 monthxxx = ReturnValues2[1]; 300 yearxxx = ReturnValues2[2]; 301 if(DayIntVal==DayIntValXX) { 302 /* 303 * dates are the same... probably o.k.... 304 * should check times 305 */ 306 JulianDayIntVal = (int)CurrentTime; 307 } else if((DayIntValSub<=2)&&(DayIntValSub>=0)) { 308 /* 309 * this is probably o.k too... 310 * should check times 311 */ 312 JulianDayIntVal = (int)CurrentTime+(DayIntVal-DayIntValXX); 313 } else { 314 /* 315 * dates are invalid. Either image date is before 316 * forecast or is well beyond forecast availability 317 */ 318 if(DayIntValSub<-27) { 319 /* System.out.printf("month crossing\n"); */ 320 /* System.out.printf("datexxx=%d\n",datexxx); */ 321 if((datexxx<=2)&&(monthxxx==1)) { 322 /* System.out.printf("year crossing... image during new year: %d %d\n",yearxxx-1,DayIntVal); */ 323 JulianDayIntVal = Functions.idmyyd(DayIntVal,12,yearxxx-1); 324 } else { 325 JulianDayIntVal = Functions.idmyyd(DayIntVal,monthxxx-1,yearxxx); 326 } 327 /* System.out.printf("JulianDayIntVal=%d\n",JulianDayIntVal); */ 328 } else { 329 ReturnFlagValue = -1; 330 } 331 } 332 /* System.out.printf("JulianDayIntVal=%d\n",JulianDayIntVal); */ 333 TimeArray[XInc] = Functions.calctime(JulianDayIntVal,HMSTimeIntVal); 334 /* System.out.printf("TimeArray[%d]=%f\n",XInc,TimeArray[XInc]); */ 335 NSFactor = (TmpStr4.charAt(TmpStr4.length()-1)=='N') ? 1.0 : -1.0; 336 WEFactor = (TmpStr5.charAt(TmpStr5.length()-1)=='W') ? 1.0 : -1.0; 337 LatitudeArray[XInc] = NSFactor*Double.parseDouble(TmpStr4.substring(0,TmpStr4.length()-1)); 338 LongitudeArray[XInc] = WEFactor*Double.parseDouble(TmpStr5.substring(0,TmpStr5.length()-1)); 339 } else { 340 /* System.out.printf("XInc=%d : 1=%s* 2=%s* 3=%s* 4=%s* \n",XInc,TmpStr1,TmpStr2,TmpStr3,TmpStr4); */ 341 DayIntVal = Integer.parseInt(TmpStr1.substring(0,2)); 342 HMSTimeIntVal = 100*Integer.parseInt(TmpStr1.substring(2,6)); 343 /* System.out.printf("dayintval=%d hmstimeintval=%d\n",DayIntVal,HMSTimeIntVal); */ 344 DayIntValSub = DayIntValXX-DayIntVal; 345 if(DayIntValSub<-27) { 346 if((monthxxx-1)==0) { 347 JulianDayIntVal = Functions.idmyyd(DayIntVal,12,yearxxx-1); 348 } else { 349 JulianDayIntVal = Functions.idmyyd(DayIntVal,monthxxx-1,yearxxx); 350 } 351 } else { 352 if(DayIntValSub>27) { 353 if((monthxxx+1)>12) { 354 JulianDayIntVal = Functions.idmyyd(DayIntVal,1,yearxxx+1); 355 } else { 356 JulianDayIntVal = Functions.idmyyd(DayIntVal,monthxxx+1,yearxxx); 357 } 358 } else { 359 JulianDayIntVal = Functions.idmyyd(DayIntVal,monthxxx,yearxxx); 360 } 361 } 362 /* System.out.printf("JulianDayIntVal=%d\n",JulianDayIntVal); */ 363 TimeArray[XInc] = Functions.calctime(JulianDayIntVal,HMSTimeIntVal); 364 /* System.out.printf("TimeArray[%d]=%f\n",XInc,TimeArray[XInc]); */ 365 NSFactor = (TmpStr3.charAt(TmpStr3.length()-1)=='N') ? 1.0 : -1.0; 366 WEFactor = (TmpStr4.charAt(TmpStr4.length()-1)=='W') ? 1.0 : -1.0; 367 LatitudeArray[XInc] = NSFactor*Double.parseDouble(TmpStr3.substring(0,TmpStr3.length()-1)); 368 LongitudeArray[XInc] = WEFactor*Double.parseDouble(TmpStr4.substring(0,TmpStr4.length()-1)); 369 } 370 } 371 if((TmpStr1.equals("MAX"))&&(TmpStr4.charAt(0)=='-')) { 372 TmpStr5 = tokens[4+iadd]; 373 if(XInc==0) { 374 StrengthArray[XInc] = Double.parseDouble(TmpStr5); 375 } 376 XInc++; 377 } 378 } 379 } 380 } else if(ForecastFileType==3) { 381 /* generic forecast file input */ 382 while (in.hasNextLine()) { 383 String forecastRec = in.nextLine(); 384 String[] tokens = forecastRec.split(delims); 385 if(tokens.length>=5) { 386 TmpStr1 = tokens[0]; 387 TmpStr2 = tokens[1]; 388 TmpStr3 = tokens[2]; 389 TmpStr4 = tokens[3]; 390 TmpStr5 = tokens[4]; 391 TmpStr6 = tokens[5]; 392 TmpStr7 = tokens[6]; 393 DayIntVal = Integer.parseInt(TmpStr1.substring(0,2)); 394 MonthIntVal = Integer.parseInt(TmpStr2.substring(0,2)); 395 YearIntVal = Integer.parseInt(TmpStr3.substring(0,4)); 396 HMSTimeIntVal = 100*Integer.parseInt(TmpStr4.substring(0,4)); 397 JulianDayIntVal = Functions.idmyyd(DayIntVal,MonthIntVal,YearIntVal); 398 TimeArray[XInc] = Functions.calctime(JulianDayIntVal,HMSTimeIntVal); 399 NSFactor = (TmpStr5.charAt(TmpStr5.length()-1)=='N') ? 1.0 : -1.0; 400 WEFactor = (TmpStr6.charAt(TmpStr6.length()-1)=='W') ? 1.0 : -1.0; 401 LatitudeArray[XInc] = NSFactor*Double.parseDouble(TmpStr5.substring(0,TmpStr5.length()-1)); 402 LongitudeArray[XInc] = WEFactor*Double.parseDouble(TmpStr6.substring(0,TmpStr6.length()-1)); 403 StrengthArray[XInc] = Double.parseDouble(TmpStr5); 404 XInc++; 405 } 406 } 407 } else if(ForecastFileType==4) { 408 String delims4 = "[:+/ ]+"; 409 /* RSMC ICAO (FK?? or WT??) forecast file input */ 410 /* 411 * Convert the ICAO RSMC bulletin positions from degrees minutes 412 * to degrees and tenths of degrees. 413 * fix courtesy : YanLuo/NOAA 07/22/09 * 414 */ 415 int xxx1 = 0; 416 int xxx2 = 0; 417 double LatMultFact = 0.0; 418 double LonMultFact = 0.0; 419 while (in.hasNextLine()) { 420 String forecastRec = in.nextLine(); 421 String[] tokens = forecastRec.split(delims4); 422 if(tokens[0].equals("DTG")) { 423 TmpStr1 = tokens[1]; 424 /* System.out.printf("TmpStr1=%s*\n",TmpStr1); */ 425 DayIntVal = Integer.parseInt(TmpStr1.substring(6,8)); 426 MonthIntVal = Integer.parseInt(TmpStr1.substring(4,6)); 427 YearIntVal = Integer.parseInt(TmpStr1.substring(0,4)); 428 if(tokens.length==2) { 429 HMSTimeIntVal = 100*Integer.parseInt(TmpStr1.substring(8,12)); 430 } else { 431 TmpStr2 = tokens[2]; 432 HMSTimeIntVal = 100*Integer.parseInt(TmpStr2.substring(0,4)); 433 } 434 JulianDayIntVal = Functions.idmyyd(DayIntVal,MonthIntVal,YearIntVal); 435 TimeArray[XInc] = Functions.calctime(JulianDayIntVal,HMSTimeIntVal); 436 /* System.out.printf("time0=%f hmstime=%d\n",TimeArray[XInc],HMSTimeIntVal); */ 437 } else if(tokens[0].equals("PSN")) { 438 TmpStr1 = tokens[1]; 439 TmpStr2 = tokens[2]; 440 LatMultFact = (TmpStr1.charAt(0)=='N') ? 1.0 : -1.0; 441 LonMultFact = (TmpStr2.charAt(0)=='W') ? 1.0 : -1.0; 442 xxx1 = Integer.parseInt(TmpStr1.substring(1,TmpStr1.length())); 443 xxx2 = Integer.parseInt(TmpStr2.substring(1,TmpStr2.length())); 444 /* initial lat/lon */ 445 double LatitudeWhole=((double)xxx1)/100.0; 446 double LatitudePart=((double)xxx1-(LatitudeWhole*100.0))/60.0; 447 LatitudeArray[XInc]=LatMultFact*(LatitudeWhole+LatitudePart); 448 double LongitudeWhole=((double)xxx2)/100.0; 449 double LongitudePart=((double)xxx2-(LongitudeWhole*100.0))/60.0; 450 LongitudeArray[XInc]=LonMultFact*(LongitudeWhole+LongitudePart); 451 XInc++; 452 } else if((tokens[0].equals("MAX"))&&(XInc==0)) { 453 /* initial lat/lon */ 454 TmpStr1 = tokens[2]; 455 StrengthArray[XInc] = Double.parseDouble(TmpStr1.substring(0,TmpStr1.length()-2)); 456 } else if((tokens[0].equals("FCST"))&&(tokens[1].equals("PSN"))) { 457 int numtokens = tokens.length; 458 TmpStr1 = tokens[2]; 459 TmpStr2 = tokens[numtokens-2]; 460 TmpStr3 = tokens[numtokens-1]; 461 /* System.out.printf("1=%s* 2=%s* 3=%s*\n",TmpStr1,TmpStr2,TmpStr3); */ 462 LatMultFact = (TmpStr2.charAt(0)=='N') ? 1.0 : -1.0; 463 LonMultFact = (TmpStr3.charAt(0)=='W') ? 1.0 : -1.0; 464 xxx1 = Integer.parseInt(TmpStr2.substring(1,TmpStr2.length())); 465 xxx2 = Integer.parseInt(TmpStr3.substring(1,TmpStr3.length())); 466 int FcstHrAddIntVal = Integer.parseInt(TmpStr1.substring(0,2)); 467 /* initial lat/lon */ 468 double LatitudeWhole=((double)xxx1)/100.0; 469 double LatitudePart=((double)xxx1-(LatitudeWhole*100.0))/60.0; 470 LatitudeArray[XInc]=LatMultFact*(LatitudeWhole+LatitudePart); 471 double LongitudeWhole=((double)xxx2)/100.0; 472 double LongitudePart=((double)xxx2-(LongitudeWhole*100.0))/60.0; 473 LongitudeArray[XInc]=LonMultFact*(LongitudeWhole+LongitudePart); 474 double FcstHrAddDblVal=((double)FcstHrAddIntVal)/24.0; 475 /* System.out.printf("XInc=%d time0=%f fcsthr=%f\n",XInc,TimeArray[0],FcstHrAddDblVal); */ 476 TimeArray[XInc]=TimeArray[0]+FcstHrAddDblVal; 477 XInc++; 478 } 479 } 480 } else if(ForecastFileType==5) { 481 /* RSMC WTIO30 forecast file input */ 482 String delims5 = "[,:/= ]+"; 483 while (in.hasNextLine()) { 484 String forecastRec = in.nextLine(); 485 String[] tokens = forecastRec.split(delims5); 486 if(tokens[0].equals("2.A")) { 487 TmpStr1 = tokens[2]; 488 TmpStr2 = tokens[3]; 489 TmpStr3 = tokens[4]; 490 TmpStr4 = tokens[6]; 491 YearIntVal = Integer.parseInt(TmpStr1); 492 MonthIntVal = Integer.parseInt(TmpStr2); 493 DayIntVal = Integer.parseInt(TmpStr3); 494 HMSTimeIntVal = 100*Integer.parseInt(TmpStr4); 495 JulianDayIntVal = Functions.idmyyd(DayIntVal,MonthIntVal,YearIntVal); 496 TimeArray[XInc] = Functions.calctime(JulianDayIntVal,HMSTimeIntVal); 497 forecastRec = in.nextLine(); 498 tokens = forecastRec.split(delims5); 499 if(tokens.length==2) { 500 TmpStr1 = tokens[0]; 501 TmpStr2 = tokens[1]; 502 } else { 503 /* expecting line like 504 * WITHIN 20 NM RADIUS OF POINT 22.2S / 50.8E 505 */ 506 TmpStr1 = tokens[6]; 507 TmpStr2 = tokens[7]; 508 } 509 NSFactor = (TmpStr1.charAt(TmpStr1.length()-1)=='N') ? 1.0 : -1.0; 510 WEFactor = (TmpStr2.charAt(TmpStr2.length()-1)=='W') ? 1.0 : -1.0; 511 LatitudeArray[XInc] = NSFactor*Double.parseDouble(TmpStr1.substring(0,TmpStr1.length()-1)); 512 LongitudeArray[XInc] = WEFactor*Double.parseDouble(TmpStr2.substring(0,TmpStr2.length()-1)); 513 } else if(tokens[0].equals("5.A")) { 514 TmpStr1 = tokens[tokens.length-2]; 515 StrengthArray[XInc] = Double.parseDouble(TmpStr1); 516 } else if(tokens[0].equals("1.B")) { 517 XInc=1; 518 forecastRec = in.nextLine(); 519 tokens = forecastRec.split(delims5); 520 boolean ICAOValidFcstTF = true; 521 while((ICAOValidFcstTF)&&(XInc<6)) { 522 TmpStr1 = tokens[1]; 523 TmpStr2 = tokens[2]; 524 TmpStr3 = tokens[3]; 525 TmpStr4 = tokens[4]; 526 TmpStr5 = tokens[6]; 527 TmpStr6 = tokens[7]; 528 TmpStr7 = tokens[10]; 529 YearIntVal = Integer.parseInt(TmpStr1); 530 MonthIntVal = Integer.parseInt(TmpStr2); 531 DayIntVal = Integer.parseInt(TmpStr3); 532 HMSTimeIntVal = 10000*Integer.parseInt(TmpStr4); 533 JulianDayIntVal = Functions.idmyyd(DayIntVal,MonthIntVal,YearIntVal); 534 TimeArray[XInc] = Functions.calctime(JulianDayIntVal,HMSTimeIntVal); 535 NSFactor = (TmpStr5.charAt(TmpStr5.length()-1)=='N') ? 1.0 : -1.0; 536 WEFactor = (TmpStr6.charAt(TmpStr6.length()-1)=='W') ? 1.0 : -1.0; 537 LatitudeArray[XInc] = NSFactor*Double.parseDouble(TmpStr5.substring(0,TmpStr5.length()-1)); 538 LongitudeArray[XInc] = WEFactor*Double.parseDouble(TmpStr6.substring(0,TmpStr6.length()-1)); 539 StrengthArray[XInc] = (double)Integer.parseInt(TmpStr7.substring(0,3)); 540 forecastRec = in.nextLine(); 541 tokens = forecastRec.split(delims5); 542 String TmpStr0 = tokens[0]; 543 if(tokens[0].equals("2.C")) { 544 ICAOValidFcstTF = false; 545 } else { 546 if(TmpStr0.charAt(2)!='H') { 547 forecastRec = in.nextLine(); 548 ICAOValidFcstTF = false; 549 } 550 } 551 XInc++; 552 } 553 } 554 } 555 } else if(ForecastFileType==6) { 556 /* TCWC AXAU Tech Bulletins file input */ 557 String delims6 = "[,:/ ]+"; 558 JulianDayIntVal = 0; 559 MonthIntVal = 0; 560 YearIntVal = 0; 561 while (in.hasNextLine()) { 562 String forecastRec = in.nextLine(); 563 String[] tokens = forecastRec.split(delims6); 564 if(tokens[0].equals("at")) { 565 /* initial date */ 566 TmpStr1 = tokens[1]; 567 TmpStr2 = tokens[3]; 568 TmpStr3 = tokens[4]; 569 TmpStr4 = tokens[5]; 570 YearIntVal = Integer.parseInt(TmpStr4); 571 MonthIntVal = Integer.parseInt(TmpStr3); 572 DayIntVal = Integer.parseInt(TmpStr2); 573 /* HMSTimeIntVal = 100*Integer.parseInt(TmpStr1); */ 574 JulianDayIntVal = Functions.idmyyd(DayIntVal,MonthIntVal,YearIntVal); 575 } 576 if(tokens[0].equals("Data")) { 577 /* initial time */ 578 TmpStr1 = tokens[2]; 579 HMSTimeIntVal = 100*Integer.parseInt(TmpStr1); 580 TimeArray[XInc] = Functions.calctime(JulianDayIntVal,HMSTimeIntVal); 581 } 582 if(tokens[0].equals("Latitude")) { 583 /* initial latitude */ 584 TmpStr1 = tokens[1]; 585 NSFactor = (TmpStr1.charAt(TmpStr1.length()-1)=='N') ? 1.0 : -1.0; 586 LatitudeArray[XInc] = NSFactor*Double.parseDouble(TmpStr1.substring(0,TmpStr1.length()-1)); 587 } 588 if(tokens[0].equals("Longitude")) { 589 /* initial longitude */ 590 TmpStr1 = tokens[1]; 591 WEFactor = (TmpStr1.charAt(TmpStr1.length()-1)=='W') ? 1.0 : -1.0; 592 LongitudeArray[XInc] = WEFactor*Double.parseDouble(TmpStr1.substring(0,TmpStr1.length()-1)); 593 } 594 if(tokens[0].equals("Maximum")) { 595 if(tokens[1].equals("10-Minute")) { 596 /* initial strength */ 597 TmpStr1 = tokens[3]; 598 StrengthArray[XInc] = (double)Integer.parseInt(TmpStr1); 599 } 600 } 601 if(tokens[0].equals("FORECAST")) { 602 XInc=1; 603 forecastRec = in.nextLine(); 604 forecastRec = in.nextLine(); 605 forecastRec = in.nextLine(); 606 tokens = forecastRec.split(delims6); 607 boolean ICAOValidFcstTF = true; 608 while((ICAOValidFcstTF)&&(XInc<6)) { 609 TmpStr1 = tokens[1]; 610 TmpStr2 = tokens[2]; 611 TmpStr3 = tokens[3]; 612 TmpStr4 = tokens[4]; 613 TmpStr5 = tokens[7]; 614 DayIntVal = Integer.parseInt(TmpStr1); 615 HMSTimeIntVal = 100*Integer.parseInt(TmpStr2); 616 JulianDayIntVal = Functions.idmyyd(DayIntVal,MonthIntVal,YearIntVal); 617 TimeArray[XInc] = Functions.calctime(JulianDayIntVal,HMSTimeIntVal); 618 NSFactor = (TmpStr3.charAt(TmpStr3.length()-1)=='N') ? 1.0 : -1.0; 619 WEFactor = (TmpStr4.charAt(TmpStr4.length()-1)=='W') ? 1.0 : -1.0; 620 LatitudeArray[XInc] = NSFactor*Double.parseDouble(TmpStr3.substring(0,TmpStr3.length()-1)); 621 LongitudeArray[XInc] = WEFactor*Double.parseDouble(TmpStr4.substring(0,TmpStr4.length()-1)); 622 StrengthArray[XInc] = (double)Integer.parseInt(TmpStr5); 623 if(TimeArray[XInc]<TimeArray[XInc-1]) { 624 MonthIntVal=MonthIntVal+1; 625 /* YearIntVal=YearIntVal; */ 626 if(MonthIntVal==13) { 627 YearIntVal=YearIntVal+1; 628 MonthIntVal=1; 629 } 630 JulianDayIntVal = Functions.idmyyd(DayIntVal,MonthIntVal,YearIntVal); 631 TimeArray[XInc] = Functions.calctime(JulianDayIntVal,HMSTimeIntVal); 632 } 633 forecastRec = in.nextLine(); 634 tokens = forecastRec.split(delims6); 635 if(tokens[0].equals("REMARKS")) { 636 ICAOValidFcstTF = false; 637 } 638 XInc++; 639 } 640 } 641 } 642 } else if(ForecastFileType==8) { 643 /* BEST - best track b-deck file input */ 644 int LastDateValueInt = 1; 645 while (in.hasNextLine()) { 646 String forecastRec = in.nextLine(); 647 String[] tokens = forecastRec.split(delims); 648 /* AL, 04, 2010073106, , BEST, 0, 88N, 329W, 20, 1009, LO, 0, , 0, 0, 0, 0, 1011, 180, 75, 0, 0, */ 649 if(tokens[3].equals("BEST")) { 650 TmpStr1 = tokens[2]; 651 TmpStr2 = tokens[5]; 652 TmpStr3 = tokens[6]; 653 TmpStr4 = tokens[7]; 654 /* System.out.printf("1=%s* 2=%s* 3=%s* 4=%s*\n",TmpStr1,TmpStr2,TmpStr3,TmpStr4); */ 655 YearIntVal = Integer.parseInt(TmpStr1.substring(0,4)); 656 MonthIntVal = Integer.parseInt(TmpStr1.substring(4,6)); 657 DayIntVal = Integer.parseInt(TmpStr1.substring(6,8)); 658 HMSTimeIntVal = 10000*Integer.parseInt(TmpStr1.substring(8,10)); 659 JulianDayIntVal = Functions.idmyyd(DayIntVal,MonthIntVal,YearIntVal); 660 /* System.out.printf("day=%d month=%d year=%d hms=%d julian=%d \n",DayIntVal,MonthIntVal,YearIntVal,HMSTimeIntVal,JulianDayIntVal); */ 661 double TmpTimeVal1 = Functions.calctime(JulianDayIntVal,HMSTimeIntVal); 662 NSFactor = (TmpStr2.charAt(TmpStr2.length()-1)=='N') ? 1.0 : -1.0; 663 WEFactor = (TmpStr3.charAt(TmpStr3.length()-1)=='W') ? 1.0 : -1.0; 664 int CurrentDateValueInt=HMSTimeIntVal; 665 if(CurrentDateValueInt!=LastDateValueInt) { 666 /* System.out.printf("tmptimeval=%f currenttime=%f\n",TmpTimeVal1,CurrentTime); */ 667 if(TmpTimeVal1<CurrentTime) { 668 TimeArray[0] = TmpTimeVal1; 669 LatitudeArray[0] = NSFactor*Double.parseDouble(TmpStr2.substring(0,TmpStr2.length()-1))/10.0; 670 LongitudeArray[0] = WEFactor*Double.parseDouble(TmpStr3.substring(0,TmpStr3.length()-1))/10.0; 671 StrengthArray[0] = (double)Integer.parseInt(TmpStr4); 672 } else { 673 if((TmpTimeVal1>=CurrentTime)&&(XInc<5)) { 674 XInc++; 675 TimeArray[XInc] = TmpTimeVal1; 676 LatitudeArray[XInc] = NSFactor*Double.parseDouble(TmpStr2.substring(0,TmpStr2.length()-1))/10.0; 677 LongitudeArray[XInc] = WEFactor*Double.parseDouble(TmpStr3.substring(0,TmpStr3.length()-1))/10.0; 678 StrengthArray[XInc] = (double)Integer.parseInt(TmpStr4); 679 } 680 } 681 } 682 LastDateValueInt=CurrentDateValueInt; 683 } 684 } 685 } else if(ForecastFileType==9) { 686 /* HURDAT - best track file input */ 687 while (in.hasNextLine()) { 688 String forecastRec = in.nextLine(); 689 String[] tokens = forecastRec.split(delims); 690 TmpStr1 = tokens[2]; 691 TmpStr2 = tokens[3]; 692 TmpStr3 = tokens[4]; 693 TmpStr4 = tokens[5]; 694 TmpStr5 = tokens[6]; 695 TmpStr6 = tokens[7]; 696 TmpStr7 = tokens[8]; 697 YearIntVal = Integer.parseInt(TmpStr1); 698 MonthIntVal = Integer.parseInt(TmpStr2); 699 DayIntVal = Integer.parseInt(TmpStr3); 700 HMSTimeIntVal=(10000*Integer.parseInt(TmpStr4)); 701 JulianDayIntVal = Functions.idmyyd(DayIntVal,MonthIntVal,YearIntVal); 702 double TmpTimeVal1 = Functions.calctime(JulianDayIntVal,HMSTimeIntVal); 703 /* NSFactor = (TmpStr5.charAt(TmpStr5.length()-1)=='N') ? 1.0 : -1.0; */ 704 /* WEFactor = (TmpStr6.charAt(TmpStr6.length()-1)=='W') ? 1.0 : -1.0; */ 705 NSFactor = 1.0; 706 WEFactor = 1.0; 707 if(TmpTimeVal1<CurrentTime) { 708 TimeArray[0] = TmpTimeVal1; 709 LatitudeArray[0] = NSFactor*Double.parseDouble(TmpStr5.substring(0,TmpStr5.length()-1)); 710 LongitudeArray[0] = WEFactor*Double.parseDouble(TmpStr6.substring(0,TmpStr6.length()-1)); 711 StrengthArray[0] = (double)Integer.parseInt(TmpStr7); 712 } else { 713 if((TmpTimeVal1>=CurrentTime)&&(XInc<5)) { 714 XInc++; 715 TimeArray[XInc] = TmpTimeVal1; 716 LatitudeArray[XInc] = NSFactor*Double.parseDouble(TmpStr5.substring(0,TmpStr5.length()-1)); 717 LongitudeArray[XInc] = WEFactor*Double.parseDouble(TmpStr6.substring(0,TmpStr6.length()-1)); 718 StrengthArray[XInc] = (double)Integer.parseInt(TmpStr7); 719 } 720 } 721 } 722 } else { 723 ReturnFlagValue = -2; 724 } 725 } catch (Exception e) { 726 System.err.println("Failed to read Forecast file..."); 727 in.close(); 728 return null; 729 } 730 731 int ZInc; 732 int MinFcstValue; 733 int LastDateJulianHoldValue = 0; 734 int CurrentYear = 0; 735 double StrengthValue = 0; 736 double LastDateValue = 0; 737 boolean ChangeHemispheresTF = false; 738 boolean YearChangeFlag = false; 739 740 /* System.out.printf("returnflagvalue=%d\n",ReturnFlagValue); */ 741 if(ReturnFlagValue>=0) { 742 StrengthValue=StrengthArray[0]; 743 MinFcstValue=XInc; 744 /* initialize forecast info array */ 745 for(ZInc=0;ZInc<5;ZInc++) { 746 ForecastTimes[ZInc] = 9999999.5; 747 ForecastLatitudes[ZInc] = 999.5; 748 ForecastLongitudes[ZInc] = 999.5; 749 } 750 /* XInc--; */ 751 XInc = Math.min(5,XInc); 752 /* System.out.printf("%d %f %f %f\n",0,TimeArray[0],LatitudeArray[0],LongitudeArray[0]); */ 753 LastDateValue = TimeArray[0]; 754 ForecastTimes[0] = TimeArray[0]; 755 for(ZInc=1;ZInc<XInc;ZInc++) { 756 ForecastTimes[ZInc] = TimeArray[ZInc]; 757 if((TimeArray[ZInc]-LastDateValue)>100.0) { 758 /* there has been a year change during the forecast time */ 759 if(!YearChangeFlag) { 760 LastDateJulianHoldValue = (int)LastDateValue; 761 YearChangeFlag = true; 762 } 763 CurrentYear = ((int)TimeArray[ZInc])/1000; 764 CurrentDayValue = TimeArray[ZInc]-(double)(CurrentYear*1000); 765 TimeArray[ZInc] = (double)((int)LastDateJulianHoldValue+CurrentDayValue); 766 LastDateValue = TimeArray[ZInc]; 767 } 768 /* System.out.printf("%d %f %f %f\n",ZInc,TimeArray[ZInc],LatitudeArray[ZInc],LongitudeArray[ZInc]); */ 769 if(Math.abs(LongitudeArray[ZInc]-LongitudeArray[0])>180.0) { 770 /* System.out.printf("changing hemispheres... adjusting longitude\n"); */ 771 ChangeHemispheresTF = true; 772 if(LongitudeArray[0]<0) { 773 LongitudeArray[ZInc] = -360.0+LongitudeArray[ZInc]; 774 } else { 775 LongitudeArray[ZInc] = 360.0+LongitudeArray[ZInc]; 776 } 777 /* System.out.printf("%d %f %f %f\n",ZInc,TimeArray[ZInc],LatitudeArray[ZInc],LongitudeArray[ZInc]); */ 778 } 779 } 780 if(YearChangeFlag) { 781 /* System.out.printf("YearChangeFlag=TRUE\n"); */ 782 /* System.out.printf("CurrentTime=%f\n",CurrentTime); */ 783 /* need to adjust current image time to fit into adjusted date array */ 784 if((CurrentTime-TimeArray[0])>100.0) { 785 CurrentYear = ((int)CurrentTime)/1000; 786 CurrentDayValue = CurrentTime-(double)(CurrentYear*1000); 787 CurrentTime = (double)((int)LastDateJulianHoldValue+CurrentDayValue); 788 /* System.out.printf("CurrentTime=%f\n",CurrentTime); */ 789 } 790 } 791 if(CurrentTime<TimeArray[0]) { 792 /* 793 * check to see if latest image is only 15 minutes 794 * before current forecast time 795 */ 796 if(CurrentTime>(TimeArray[0]-.015)) TimeArray[0] = CurrentTime; 797 } 798 799 /* determine number of valid forecast times for given image time */ 800 YInc = 0; 801 while((TimeArray[YInc]<=CurrentTime)&&(YInc<XInc)) { 802 YInc++; 803 } 804 /* System.out.printf("yinc=%d xinc=%d curtime=%f time0=%f threshtime=%f\n",YInc,XInc,CurrentTime,TimeArray[0],ThresholdTime); */ 805 if((YInc==0)&&(TimeArray[0]!=CurrentTime)) { 806 /* printf("INVALID FORECAST FILE, IMAGE BEFORE/AFTER FORECAST TIMES\n"); */ 807 System.out.printf("%d %f %f %d\n",-1,-99.99,-999.99,99); 808 ReturnFlagValue = -1; 809 } 810 if((YInc==XInc)&&(CurrentTime>=TimeArray[XInc])) { 811 System.out.printf("%d %f %f %d\n",-2,-99.99,-999.99,99); 812 ReturnFlagValue = -1; 813 } 814 if (ReturnFlagValue>=0) { 815 if((CurrentTime-ThresholdTime)>TimeArray[0]) { 816 /* printf("FORECAST FILE MORE THAN 24 HOURS OLD\n"); */ 817 System.out.printf("%d %f %f %f\n",-3,-99.99,-999.99,-99.99); 818 ReturnFlagValue = -1; 819 } else { 820 for(ZInc=0;ZInc<=MinFcstValue;ZInc++) { 821 ForecastLatitudes[ZInc] = LatitudeArray[ZInc]; 822 ForecastLongitudes[ZInc] = LongitudeArray[ZInc]; 823 } 824 825 double InterpLatitude = adt_polint(TimeArray,LatitudeArray,XInc,CurrentTime); 826 double InterpLongitude = adt_polint(TimeArray,LongitudeArray,XInc,CurrentTime); 827 828 if ((InterpLatitude<=-999.)||(InterpLongitude<=-999.)) { 829 System.out.printf("%d %f %f %f\n",-4,-99.99,-999.99,-99.99); 830 ReturnFlagValue = -1; 831 } else { 832 if(ChangeHemispheresTF) { 833 if(InterpLongitude>180.0) { 834 InterpLongitude = -360.0+InterpLongitude; 835 } else if(InterpLongitude<-180.0) { 836 InterpLongitude = 360.0+InterpLongitude; 837 } else { 838 /* InterpLongitude=InterpLongitude; */ 839 } 840 } 841 System.out.printf("%d %f %f %f\n",1,InterpLatitude,InterpLongitude,StrengthValue); 842 ReturnLatitudeInterpolation = InterpLatitude; 843 ReturnLongitudeInterpolation = InterpLongitude; 844 ReturnFlagValue = 0; 845 } /* ReturnFlagValue=-4 */ 846 } /* ReturnFlagValue=-3 */ 847 } /* ReturnFlagValue=-1/-2 */ 848 } /* ReturnFlagValue=-6 */ 849 850 in.close(); 851 852 ReturnCurrentIntensity = StrengthValue; 853 854 /* McIDAS-V Conversion */ 855 ReturnLongitudeInterpolation = -1.0 * ReturnLongitudeInterpolation; 856 logger.debug("ReadForecasts out..."); 857 858 return new double[] { 859 (double)ReturnFlagValue, 860 ReturnLatitudeInterpolation, 861 ReturnLongitudeInterpolation, 862 ReturnCurrentIntensity 863 }; 864 865 } 866 867 /** 868 * Polynomial interpolation scheme program derived from FORTRAN 869 * program POLINT in : Numerical Recipies - The Art of Scientific 870 * Computing, 1986, Press, Flannery, Teukolsky, and Vetterling, Cambridge Press 871 * 872 * @param TimeArrayInput Array containing time values. 873 * @param PositionArrayInput Array containing variable to interpolate. 874 * @param NumberOfPointsInput Number of points in array. 875 * @param CurrentTime Time to interpolate to. 876 * 877 * @return Interpolated position value. Note: if value is {@code -999.5}, 878 * it means that the denominator is 0, signifying that there was an 879 * interpolation error. 880 */ 881 private static double adt_polint(double[] TimeArrayInput, 882 double[] PositionArrayInput, 883 int NumberOfPointsInput, 884 double CurrentTime) 885 { 886 double PositionValue; 887 double PositionError; 888 double DenominatorValue; 889 double TimeDifferenceValue1; 890 double TimeDifferenceValue2; 891 double TimeValue1; 892 double TimeValue2; 893 double[] LocalArray1 = new double[10]; 894 double[] LocalArray2 = new double[10]; 895 int XInc; 896 int YInc; 897 int StoreValue = 1; 898 899 TimeDifferenceValue1 = Math.abs(CurrentTime-TimeArrayInput[0]); 900 for(XInc=1;XInc<=NumberOfPointsInput;XInc++) { 901 TimeDifferenceValue2 = Math.abs(CurrentTime-TimeArrayInput[XInc-1]); 902 if(TimeDifferenceValue2<TimeDifferenceValue1) { 903 StoreValue = XInc; 904 TimeDifferenceValue1 = TimeDifferenceValue2; 905 } 906 /* System.out.printf("Xinc-1=%d position array=%f\n",XInc-1,PositionArrayInput[XInc-1]); */ 907 LocalArray1[XInc-1] = PositionArrayInput[XInc-1]; 908 LocalArray2[XInc-1] = PositionArrayInput[XInc-1]; 909 } 910 double PositionValueLocal = PositionArrayInput[StoreValue-1]; 911 PositionError = 0.0; 912 StoreValue--; 913 for(YInc=1;YInc<=NumberOfPointsInput-1;YInc++) { 914 for(XInc=1;XInc<=NumberOfPointsInput-YInc;XInc++) { 915 TimeValue1 = TimeArrayInput[XInc-1]-CurrentTime; 916 TimeValue2 = TimeArrayInput[(XInc-1)+YInc]-CurrentTime; 917 PositionValue = LocalArray1[XInc]-LocalArray2[XInc-1]; 918 DenominatorValue = TimeValue1-TimeValue2; 919 if(DenominatorValue==0.0) { 920 /* interpolation error - denominator = 0 */ 921 return -999.5; /* EXIT */ 922 } 923 DenominatorValue = PositionValue/DenominatorValue; 924 LocalArray1[XInc-1] = TimeValue1*DenominatorValue; 925 LocalArray2[XInc-1] = TimeValue2*DenominatorValue; 926 /* System.out.printf("YInc=%d XInc=%d demon=%f local1=%f local2=%f\n",YInc,XInc,DenominatorValue,LocalArray1[XInc-1],LocalArray2[XInc-1]); */ 927 } 928 if((2*StoreValue)<(NumberOfPointsInput-YInc)) { 929 PositionError = LocalArray1[StoreValue]; 930 } else { 931 PositionError = LocalArray2[StoreValue-1]; 932 StoreValue--; 933 } 934 PositionValueLocal = PositionValueLocal+PositionError; 935 } 936 /* System.out.printf("interpolated position=%f error=%f\n",PositionValueLocal,PositionError); */ 937 double InterpolatedPosition = PositionValueLocal; 938 939 /* 940 * NOTE : additional function return point above 941 * - return -1 if interpolation fails/denominator is zero 942 */ 943 944 return InterpolatedPosition; 945 946 } 947 948 949}