From 97ef399ebba4b025455142a3d99c5f761632783c Mon Sep 17 00:00:00 2001
From: Tor-Einar Skog <tor-einar.skog@bioforsk.no>
Date: Thu, 20 Mar 2014 16:15:18 +0100
Subject: [PATCH] Improved weather data handling

---
 .../model/applescabmodel/AppleScabModel.java  | 74 +++++++++++--------
 .../applescabmodel/AppleScabModelTest.java    |  4 +-
 2 files changed, 45 insertions(+), 33 deletions(-)

diff --git a/src/main/java/no/bioforsk/vips/model/applescabmodel/AppleScabModel.java b/src/main/java/no/bioforsk/vips/model/applescabmodel/AppleScabModel.java
index 5d237cf..4f61810 100644
--- a/src/main/java/no/bioforsk/vips/model/applescabmodel/AppleScabModel.java
+++ b/src/main/java/no/bioforsk/vips/model/applescabmodel/AppleScabModel.java
@@ -18,6 +18,8 @@
  */
 package no.bioforsk.vips.model.applescabmodel;
 
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.ArrayList;
 import java.util.Calendar;
@@ -115,7 +117,7 @@ public class AppleScabModel extends I18nImpl implements Model{
             Logger.getLogger(AppleScabModel.class.getName()).log(Level.SEVERE, null, ex);
             throw new ModelExcecutionException(ex.getMessage());
         }
-        
+        //System.out.println(this.calculations.toString());
         // Looping through background data, adding as much as possible
         List<Result> results = new ArrayList<>();
         for(Date timeStamp:this.calculations.getSortedDateKeys())
@@ -263,7 +265,7 @@ public class AppleScabModel extends I18nImpl implements Model{
      */
     @Override
     public void setConfiguration(ModelConfiguration config) throws ConfigValidationException {
-        
+        // TODO: Validate all input!!!!
         initCollections();
         ObjectMapper mapper = new ObjectMapper();
         
@@ -279,27 +281,19 @@ public class AppleScabModel extends I18nImpl implements Model{
         catch (NullPointerException ex){
             throw new ConfigValidationException("startDateAscosporeMaturity not set");
         }
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+        format.setTimeZone(timeZone);
         try
         {
-            Integer year = Integer.valueOf(dateparts[0]);
-            Integer month = Integer.valueOf(dateparts[1]);
-            Integer date = Integer.valueOf(dateparts[2]);
-
-            Calendar cal = Calendar.getInstance(timeZone);
-            cal.set(year, month-1, date, 0, 0, 0);
-            cal.set(Calendar.MILLISECOND, 0);
-
-            this.startDateAscosporeMaturity = cal.getTime();
+          
+            this.startDateAscosporeMaturity = format.parse(config.getConfigParameter("startDateAscosporeMaturity").toString());
         }
-        catch(NumberFormatException | ArrayIndexOutOfBoundsException ex)
+        catch(ParseException | NullPointerException ex)
         {
             throw new ConfigValidationException("Illegal date format for startDateAscosporeMaturity: " + config.getConfigParameter("startDateAscosporeMaturity"));
         }
         
-        
-        
-        
-        //mapper.convertValue(config.getConfigParameter("timeZone"), new TypeReference<java.util.TimeZone>(){});
+        // Weather data are OK, let's add them to calculations matrix
         this.calculations = new AppleScabCalculations();
         List<WeatherObservation> observations = mapper.convertValue(config.getConfigParameter("observations"), new TypeReference<List<WeatherObservation>>(){});
         for(WeatherObservation o:observations)
@@ -308,15 +302,13 @@ public class AppleScabModel extends I18nImpl implements Model{
             {
                 case WeatherElements.TEMPERATURE_MEAN:
                     this.TM.add(o); 
-                    this.calculations.setParamDoubleValueForDate(o.getTimeMeasured(), AppleScabCalculations.TM, o.getValue());
+                    
                     break;
                 case WeatherElements.PRECIPITATION:
                     this.RR.add(o); 
-                    this.calculations.setParamDoubleValueForDate(o.getTimeMeasured(), AppleScabCalculations.RR, o.getValue());
                     break;
                 case WeatherElements.LEAF_WETNESS:
                     this.BT.add(o); 
-                    this.calculations.setParamDoubleValueForDate(o.getTimeMeasured(), AppleScabCalculations.BT, o.getValue());
                     break;
                 case WeatherElements.RELATIVE_HUMIDITY:
                     this.UM.add(o); 
@@ -326,8 +318,13 @@ public class AppleScabModel extends I18nImpl implements Model{
                     break;
             }
         }
-        // TODO: Validate all input!!!!
+        
+        
+        //mapper.convertValue(config.getConfigParameter("timeZone"), new TypeReference<java.util.TimeZone>(){});
+        
+        
 
+        WeatherUtil wUtil = new WeatherUtil();
         // Problems with weather observations
         // Unequal length of lists
         if  (        
@@ -339,23 +336,15 @@ public class AppleScabModel extends I18nImpl implements Model{
             // Fallback if missing leaf wetness: If we have relative humidity. leaf wetness may be calculated
             if(this.BT.size() != this.TM.size() && this.UM.size() == this.TM.size())
             {
-                WeatherUtil wUtil = new WeatherUtil();
+                
                 Collections.sort(this.TM);
                 Collections.sort(this.RR);
                 Collections.sort(this.UM);
                 this.BT = wUtil.calculateLeafWetnessHourSeriesSimple(this.TM, this.RR, this.UM);
                 
-                if(this.BT.size() == this.TM.size())
-                {
-                    // Need to set the values in result set
-                    for(WeatherObservation o: this.BT)
-                    {
-                        this.calculations.setParamDoubleValueForDate(o.getTimeMeasured(), AppleScabCalculations.BT, o.getValue());
-                    }
-                }
-                else
+                if(this.BT.size() != this.TM.size())
                 {
-                    throw new ConfigValidationException("Missing leaf wetness data. Also, attempting to calculate leaf wetness from other weather parameters failed.");
+                   throw new ConfigValidationException("Missing leaf wetness data. Also, attempting to calculate leaf wetness from other weather parameters failed.");
                 }
             }
             else
@@ -371,6 +360,28 @@ public class AppleScabModel extends I18nImpl implements Model{
             throw new ConfigValidationException("Minimum number of weather data = " + minimumNumberOfWeatherData);
         }
         
+        // If all that's OK, chop of all hour values exceeding the last full day
+        // of hourly data
+        this.TM = wUtil.cutTrailingHourlyValues(this.TM, timeZone);
+        this.BT = wUtil.cutTrailingHourlyValues(this.BT, timeZone);
+        this.RR = wUtil.cutTrailingHourlyValues(this.RR, timeZone);
+        
+        // Then, at last, add to calculations
+        for(WeatherObservation o: this.TM)
+        {
+            this.calculations.setParamDoubleValueForDate(o.getTimeMeasured(), AppleScabCalculations.TM, o.getValue());
+        }
+        for(WeatherObservation o: this.RR)
+        {
+            this.calculations.setParamDoubleValueForDate(o.getTimeMeasured(), AppleScabCalculations.RR, o.getValue());
+        }
+        for(WeatherObservation o: this.BT)
+        {
+            this.calculations.setParamDoubleValueForDate(o.getTimeMeasured(), AppleScabCalculations.BT, o.getValue());
+        }
+        
+        
+        
         // the date for which to start calculation of ascospore maturity must be in the range of weather data
         if(this.startDateAscosporeMaturity.compareTo(this.calculations.getFirstDateWithValues()) < 0
                 || this.startDateAscosporeMaturity.compareTo(this.calculations.getLastDateWithValues()) > 0
@@ -515,6 +526,7 @@ public class AppleScabModel extends I18nImpl implements Model{
         //Integer consecutiveDryDays = 0;
         for(Date currentDate:this.calculations.getSortedDateAtMidnightKeys(this.timeZone))
         {
+            //System.out.println("currentDate=" + currentDate);
             if(currentDate.compareTo(this.startDateAscosporeMaturity) >= 0)
             {
                 Double leafWetness = this.calculations.getParamDoubleValueForDate(currentDate, AppleScabCalculations.AGGREGATED_LEAF_WETNESS);
diff --git a/src/test/java/no/bioforsk/vips/model/applescabmodel/AppleScabModelTest.java b/src/test/java/no/bioforsk/vips/model/applescabmodel/AppleScabModelTest.java
index f34a9af..56f31d3 100644
--- a/src/test/java/no/bioforsk/vips/model/applescabmodel/AppleScabModelTest.java
+++ b/src/test/java/no/bioforsk/vips/model/applescabmodel/AppleScabModelTest.java
@@ -88,7 +88,7 @@ public class AppleScabModelTest extends TestCase {
             System.out.println("Model execution took " + (new Date().getTime() - start.getTime()) + " milliseconds");
             // Toggle this to print results when testing
             //if(results != null)
-            if(false)
+            if(true)
             {
                 SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm");
                 Collections.sort(results);
@@ -160,7 +160,7 @@ public class AppleScabModelTest extends TestCase {
             System.out.println("Model execution took " + (new Date().getTime() - start.getTime()) + " milliseconds");
             // Toggle this to print results when testing
             //if(results != null)
-            if(false)
+            if(true)
             {
                 SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy HH:mm");
                 Collections.sort(results);
-- 
GitLab