From 23208793dd6924663d1e97d6c000ae6f2b0746da Mon Sep 17 00:00:00 2001 From: bhabesh <bhabesh.mukhopadhyay@nibio.no> Date: Wed, 3 Jun 2020 11:40:57 +0200 Subject: [PATCH] Updating Alternaria Pre processor Calculate missing BT using other parameters --- .../AltenariaModelPreprocessor.java | 188 +++++++++++++++++- 1 file changed, 182 insertions(+), 6 deletions(-) diff --git a/src/main/java/no/nibio/vips/logic/scheduling/model/preprocessor/AltenariaModelPreprocessor.java b/src/main/java/no/nibio/vips/logic/scheduling/model/preprocessor/AltenariaModelPreprocessor.java index d4b1d7e8..94f36d73 100644 --- a/src/main/java/no/nibio/vips/logic/scheduling/model/preprocessor/AltenariaModelPreprocessor.java +++ b/src/main/java/no/nibio/vips/logic/scheduling/model/preprocessor/AltenariaModelPreprocessor.java @@ -20,8 +20,12 @@ Error reading included file Templates/Classes/Templates/Licenses/license-nibio_o package no.nibio.vips.logic.scheduling.model.preprocessor; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; +import java.util.Collections; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.TimeZone; import no.nibio.vips.entity.ModelConfiguration; @@ -31,7 +35,9 @@ import no.nibio.vips.logic.entity.PointOfInterestWeatherStation; import no.nibio.vips.logic.scheduling.model.ModelRunPreprocessor; import no.nibio.vips.logic.scheduling.model.PreprocessorException; import no.nibio.vips.logic.util.SystemTime; +import no.nibio.vips.model.ConfigValidationException; import no.nibio.vips.util.WeatherElements; +import no.nibio.vips.util.WeatherObservationListException; import no.nibio.vips.util.WeatherUtil; import no.nibio.vips.util.weather.WeatherDataSourceException; import no.nibio.vips.util.weather.WeatherDataSourceUtil; @@ -41,6 +47,8 @@ import no.nibio.vips.util.weather.WeatherDataSourceUtil; * @author bhabesh */ public class AltenariaModelPreprocessor extends ModelRunPreprocessor{ + + private final boolean DEBUG = false; /** * method name : getModelConfiguration @@ -74,10 +82,13 @@ public class AltenariaModelPreprocessor extends ModelRunPreprocessor{ try { observations = wdsUtil.getWeatherObservations( weatherStation, - WeatherObservation.LOG_INTERVAL_ID_1D, + //WeatherObservation.LOG_INTERVAL_ID_1D, + WeatherObservation.LOG_INTERVAL_ID_1H, new String[]{ - WeatherElements.TEMPERATURE_MEAN, - WeatherElements.SOIL_TEMPERATURE_10CM_MEAN + WeatherElements.TEMPERATURE_MEAN, + WeatherElements.PRECIPITATION, + WeatherElements.LEAF_WETNESS_DURATION, + WeatherElements.RELATIVE_HUMIDITY_MEAN }, startDate, endDate); @@ -86,7 +97,8 @@ public class AltenariaModelPreprocessor extends ModelRunPreprocessor{ } // If daily observations are not available, try hourly - if(observations == null || observations.isEmpty()) +/* + if(observations == null || observations.isEmpty() ) { try { observations = wdsUtil.getWeatherObservations( @@ -94,7 +106,7 @@ public class AltenariaModelPreprocessor extends ModelRunPreprocessor{ WeatherObservation.LOG_INTERVAL_ID_1H, new String[]{ WeatherElements.TEMPERATURE_MEAN, - WeatherElements.SOIL_TEMPERATURE_10CM_MEAN + WeatherElements.LEAF_WETNESS_DURATION }, startDate, endDate); @@ -102,7 +114,45 @@ public class AltenariaModelPreprocessor extends ModelRunPreprocessor{ throw new PreprocessorException(ex.getMessage()); } } - + */ + + Collections.sort(observations); + + // These weather data are for leaf wetness calculation only. We could + // possibly do without them, using the simple LW algorithm + try { + List<WeatherObservation> calcObs = wdsUtil.getWeatherObservations( + weatherStation, + WeatherObservation.LOG_INTERVAL_ID_1H, + new String[]{ + WeatherElements.GLOBAL_RADIATION, + WeatherElements.WIND_SPEED_2M + }, + startDate, + endDate + ); + observations.addAll(calcObs); + } catch (WeatherDataSourceException ex) { + // We do nothing + } + + + if(DEBUG) + { + System.out.println("Finished getting weather data at " + new Date().toString()); + } + try { + observations = validateAndSanitizeObservations(observations, startDate); + } catch (ConfigValidationException | WeatherObservationListException ex) { + //ex.printStackTrace(); + throw new PreprocessorException(ex.getMessage()); + } + if(DEBUG) + { + System.out.println("Observations=" + observations.toString()); + } + + // TODO: weather data validation retVal.setModelId(this.getModelId()); retVal.setConfigParameter("timeZone", timeZone.getID()); @@ -112,6 +162,132 @@ public class AltenariaModelPreprocessor extends ModelRunPreprocessor{ } + + /** + * Returns list of TM, RR and BT (possibly calculated, either in whole or partially) + * Should be complete series. + * @param observations + * @return + * @throws ConfigValidationException + * @throws WeatherObservationListException + */ + private List<WeatherObservation> validateAndSanitizeObservations(List<WeatherObservation> observations, Date firstTimeStamp) throws ConfigValidationException, WeatherObservationListException { + if(DEBUG) + { + System.out.println("validateAndSanitizeObservations"); + } + + WeatherUtil wUtil = new WeatherUtil(); + + // First we remove all duplicates + observations = wUtil.removeDuplicateWeatherObservations(observations, null); + + // Fix weather data + List<WeatherObservation> fixedObservations = wUtil.fixHourlyValuesForParameters( + observations, + new HashSet(Arrays.asList("TM","RR")), + firstTimeStamp, + null + ); + + + // Now we need to validate and possibly try to fix the weather data + List<WeatherObservation> TM = new ArrayList<>(); + List<WeatherObservation> RR = new ArrayList<>(); + + for(WeatherObservation o:fixedObservations) + { + switch(o.getElementMeasurementTypeId()) + { + case WeatherElements.TEMPERATURE_MEAN: + TM.add(o); + break; + case WeatherElements.PRECIPITATION: + RR.add(o); + break; + + } + } + + List<WeatherObservation> BT = new ArrayList<>(); + List<WeatherObservation> UM = new ArrayList<>(); + List<WeatherObservation> Q0 = new ArrayList<>(); + List<WeatherObservation> FM2 = new ArrayList<>(); + for(WeatherObservation o:observations) + { + switch(o.getElementMeasurementTypeId()) + { + case WeatherElements.LEAF_WETNESS_DURATION: + BT.add(o); + break; + case WeatherElements.RELATIVE_HUMIDITY_MEAN: + UM.add(o); + break; + case WeatherElements.GLOBAL_RADIATION: + Q0.add(o); + break; + case WeatherElements.WIND_SPEED_2M: + FM2.add(o); + break; + default: + // Let it pass in silence + break; + } + } + + // Problems with weather observations + + // Holes in series + if(DEBUG) + { + System.out.println("checkForAndFixHourlyTimeSeriesHoles"); + //System.out.println(wUtil.dumpWeatherObservationList(RR)); + } + + + + // Unequal length of lists + if ( + RR.size() != TM.size() + || BT.size() != TM.size() + || RR.size() != TM.size() + ) + { + UM = wUtil.fixHourlyValuesForParameters( + UM, + new HashSet(Arrays.asList("UM")), + firstTimeStamp, + null + ); + + System.out.println("Value of relative Humidity : "+UM); + + // Fallback if missing leaf wetness: If we have relative humidity. leaf wetness may be calculated + if((BT.size() != TM.size()) && (UM.size() == TM.size())) + { + BT = wUtil.calculateLeafWetnessHourSeriesBestEffort(BT,TM, RR, Q0, FM2, UM); + + if(BT.size() != TM.size()) + { + throw new ConfigValidationException("Missing leaf wetness data. Also, attempting to calculate leaf wetness from other weather parameters failed."); + } + } + else + { + System.out.println("TM starts " + TM.get(0).getTimeMeasured() + ", ends " + TM.get(TM.size()-1).getTimeMeasured()); + //System.out.println("UM starts " + UM.get(0).getTimeMeasured() + ", ends " + UM.get(UM.size()-1).getTimeMeasured()); + throw new ConfigValidationException("Incorrect number of weather data. TM.size() = " + TM.size() + ", BT.size()=" + BT.size() + ", RR.size()=" + RR.size() + ", UM.size()=" + UM.size() ); + } + } + List<WeatherObservation> retVal = new ArrayList<>(); + retVal.addAll(TM); + retVal.addAll(RR); + retVal.addAll(BT); + return retVal; + } + + + /** * method name : getModelId * @param : -- GitLab