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