From 1e91d73164f0710e56dbf598b2b1ca57ffdf45fc Mon Sep 17 00:00:00 2001 From: jtn <jtn@omoikane> Date: Tue, 23 Apr 2019 16:44:55 +0300 Subject: [PATCH] Added tracking for days since the start of the model The tracking starts from the first day of the weather data, and tracks if enough days have passed. If enough days have passed, the effect of tillage will be changed from Tillage to TillageEffectAfter parameter in the configuration file. TillageEffectDays sets the number of days for this to happen. If the effect is not wanted in a model run, it can be disabled by setting the timeTillageEffects parameter to false. By default, the effect is in use. --- resources/model-constants.json | 6 ++ .../model/cerealmodels/FinnCerealModels.java | 11 +++ .../mtt/model/diseasepressure/BaseRisk.java | 39 ++++++++++- .../diseasepressure/DiseasePressureModel.java | 67 ++++++++++++++++++- .../cerealmodels/FinnCerealModelsTest.java | 1 + 5 files changed, 120 insertions(+), 4 deletions(-) diff --git a/resources/model-constants.json b/resources/model-constants.json index 7e6f89a..0360133 100644 --- a/resources/model-constants.json +++ b/resources/model-constants.json @@ -9,6 +9,8 @@ "Pulse":{ "Intensive":{ "Value":-30 }, "Reduced":{ "Value":-70 }, "None":{ "Value":-100 } } }, "Tillage":{ "Intensive":{ "Value":100 }, "Reduced":{ "Value":150 }, "None":{ "Value":200 } }, + "TillageEffectDays":{ "Value":30 }, + "TillageEffectAfter" : { "Intensive":{ "Value":150 }, "Reduced":{ "Value":150 }, "None":{ "Value":200 } }, "CropSusceptibility":{ "Sensitive":{ "Value":1.5 }, "Normal":{ "Value":1 }, "Resistant":{ "Value":0.5 } }, "DiseaseProgress":{ "[0,9]":{ "Value":1 }, "[10,19]":{ "Value":1 }, "[20,29]":{ "Value":1 }, "[30,44]":{ "Value":1.1 }, "[45,[":{ "Value":1.2 } }, "SporeDevelopment":{ @@ -42,6 +44,8 @@ "Pulse":{ "Intensive":{ "Value":-30 }, "Reduced":{ "Value":-70 }, "None":{ "Value":-100 } } }, "Tillage":{ "Intensive":{ "Value":100 }, "Reduced":{ "Value":150 }, "None":{ "Value":200 } }, + "TillageEffectDays":{ "Value":30 }, + "TillageEffectAfter" : { "Intensive":{ "Value":150 }, "Reduced":{ "Value":150 }, "None":{ "Value":200 } }, "CropSusceptibility":{ "Sensitive":{ "Value":1.5 }, "Normal":{ "Value":1 }, "Resistant":{ "Value":0.5 } }, "DiseaseProgress":{ "[0,9]":{ "Value":1 }, "[10,19]":{ "Value":1 }, "[20,29]":{ "Value":1 }, "[30,44]":{ "Value":1 }, "[45,[":{ "Value":1.2 } }, "SporeDevelopment":{ @@ -76,6 +80,8 @@ "Pulse":{ "Intensive":{ "Value":-50 }, "Reduced":{ "Value":-100 }, "None":{ "Value":-100 } } }, "Tillage":{ "Intensive":{ "Value":100 }, "Reduced":{ "Value":150 }, "None":{ "Value":200 } }, + "TillageEffectDays":{ "Value":30 }, + "TillageEffectAfter" : { "Intensive":{ "Value":150 }, "Reduced":{ "Value":150 }, "None":{ "Value":200 } }, "CropSusceptibility":{ "Sensitive":{ "Value":1.5 }, "Normal":{ "Value":1 }, "Resistant":{ "Value":0.5 } }, "DiseaseProgress":{ "[0,9]":{ "Value":1 }, "[10,19]":{ "Value":1 }, "[20,29]":{ "Value":1 }, "[30,44]":{ "Value":1.1 }, "[45,[":{ "Value":1.2 } }, "SporeDevelopment":{ diff --git a/src/main/java/fi/luke/vips/model/cerealmodels/FinnCerealModels.java b/src/main/java/fi/luke/vips/model/cerealmodels/FinnCerealModels.java index 65f5f34..5dbd816 100644 --- a/src/main/java/fi/luke/vips/model/cerealmodels/FinnCerealModels.java +++ b/src/main/java/fi/luke/vips/model/cerealmodels/FinnCerealModels.java @@ -117,8 +117,13 @@ public class FinnCerealModels implements Model { List<Result> resultList = new ArrayList<>(); // reset model Double accumulatedRisk = 0.0; + // sowing date now presumed to be the first date in the data set + // XXX this may be a bad idea + Date firstDate = dailyTemperature2.get(0).getTimeMeasured(); + m.setSowingDay(firstDate); for(int i=0; i < dailyTemperature2.size(); i++) { Date currentDate = dailyTemperature2.get(i).getTimeMeasured(); + m.setCurrentDay(currentDate); Result r = new ResultImpl(); m.setTemperature(dailyTemperature2.get(i).getValue()); r.setValue(pathogen, "ATemp", ""+dailyTemperature2.get(i).getValue()); @@ -325,6 +330,12 @@ public class FinnCerealModels implements Model { } else { m.setDailyLeafWetnessDuration(d); } + Boolean b = (Boolean)arg0.getConfigParameter("timeTillageEffects"); + if(b == null) { + m.setTimeTillageEffects(true); + } else { + m.setTimeTillageEffects(b); + } // weather information ObjectMapper objectMapper = new ObjectMapper(); diff --git a/src/main/java/fi/uef/envi/mtt/model/diseasepressure/BaseRisk.java b/src/main/java/fi/uef/envi/mtt/model/diseasepressure/BaseRisk.java index 3349680..24206cd 100644 --- a/src/main/java/fi/uef/envi/mtt/model/diseasepressure/BaseRisk.java +++ b/src/main/java/fi/uef/envi/mtt/model/diseasepressure/BaseRisk.java @@ -7,6 +7,7 @@ package fi.uef.envi.mtt.model.diseasepressure; import java.io.File; import java.io.IOException; +import java.util.Calendar; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; @@ -37,6 +38,7 @@ public class BaseRisk implements Risk { private String tillageType; private String cropSusceptibilityType; private String pathogenType; + private boolean tillageEffect; private static ObjectMapper mapper = new ObjectMapper(); public BaseRisk() throws JsonProcessingException, IOException { @@ -52,8 +54,13 @@ public class BaseRisk implements Risk { throw new NullPointerException("[node = null]"); this.node = node; + this.tillageEffect = true; } + public void setTillageEffect(boolean b) { + tillageEffect=b; + } + public void setPathogen(String type) { this.pathogenType = type; } @@ -65,7 +72,7 @@ public class BaseRisk implements Risk { public void setTillage(String type) { this.tillageType = type; } - + public void setCropSusceptibility(String type) { this.cropSusceptibilityType = type; } @@ -120,7 +127,11 @@ public class BaseRisk implements Risk { double a = n.asDouble(); - n = pathogenTypeNode.get("Tillage"); + if(tillageEffect) { + n = pathogenTypeNode.get("Tillage"); + } else { + n = pathogenTypeNode.get("TillageEffectAfter"); + } if (n == null) throw new NullPointerException("Tillage not found [pathogenType = " @@ -168,4 +179,28 @@ public class BaseRisk implements Risk { return (a + b) * c; } + + public boolean isTillageInEffect(Calendar sowingDay, Calendar currentDay) { + // TODO Auto-generated method stub + JsonNode pathogenTypeNode = node.get(pathogenType); + JsonNode n = pathogenTypeNode.get("TillageEffectDays"); + if (n == null) + throw new NullPointerException( + "Value not found [pathogenType = " + + pathogenType + "; TillageEffectDays ]"); + + n = n.get("Value"); + if (n == null) + throw new NullPointerException( + "Value not found [pathogenType = " + + pathogenType + "; TillageEffectDays ]"); + int days = n.asInt(); + // less days since sowing than the maximum that the tillage is in effect + return (currentDay.get(Calendar.DAY_OF_YEAR) < (sowingDay.get(Calendar.DAY_OF_YEAR)+days)); + } + + public boolean getTillageEffect() { + // TODO Auto-generated method stub + return tillageEffect; + } } diff --git a/src/main/java/fi/uef/envi/mtt/model/diseasepressure/DiseasePressureModel.java b/src/main/java/fi/uef/envi/mtt/model/diseasepressure/DiseasePressureModel.java index 8342d9f..f4f6c45 100644 --- a/src/main/java/fi/uef/envi/mtt/model/diseasepressure/DiseasePressureModel.java +++ b/src/main/java/fi/uef/envi/mtt/model/diseasepressure/DiseasePressureModel.java @@ -10,6 +10,8 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.util.Calendar; +import java.util.Date; import java.util.List; import com.fasterxml.jackson.databind.JsonNode; @@ -42,17 +44,37 @@ public class DiseasePressureModel { private SporeSpreading sporeSpreading; private InfectionProbability infectionProbability; private ObjectMapper mapper = new ObjectMapper(); + private Calendar sowingDay, currentDay; + // if timeTillageEffects is true, then the model keeps track of how long it has been + // since tillage, and at certain point stops using the Tillage configuration value + // and starts using the TillageEffectAfter -value. + // if timeTillageEffects is false, the value of Tillage field in the configuration is used + // always. The default is true if sowing date is given, false otherwise + private boolean timeTillageEffects; public DiseasePressureModel() { this(DiseasePressureModel.class.getClassLoader().getResourceAsStream( - Options.MODEL_CONSTANTS_FILE)); + Options.MODEL_CONSTANTS_FILE), new Date()); } + public DiseasePressureModel(Date date) { + this(DiseasePressureModel.class.getClassLoader().getResourceAsStream( + Options.MODEL_CONSTANTS_FILE), date); + } + + public DiseasePressureModel(File file, Date date) throws FileNotFoundException { + this(new FileInputStream(file), date); + } + public DiseasePressureModel(File file) throws FileNotFoundException { - this(new FileInputStream(file)); + this(new FileInputStream(file), new Date()); } public DiseasePressureModel(InputStream stream) { + this(stream, new Date()); + } + + public DiseasePressureModel(InputStream stream, Date sowingDay) { JsonNode node; try { @@ -61,6 +83,18 @@ public class DiseasePressureModel { throw new RuntimeException(e); } + this.sowingDay = Calendar.getInstance(); + this.currentDay = Calendar.getInstance(); + timeTillageEffects = false; + if(sowingDay != null) { + this.sowingDay.setTime(sowingDay); + this.currentDay.setTime(sowingDay); + timeTillageEffects = true; + } +// this.sowingDay.set(Calendar.HOUR_OF_DAY,0); +// this.sowingDay.set(Calendar.MINUTE,0); +// this.sowingDay.set(Calendar.SECOND,0); +// this.sowingDay.set(Calendar.MILLISECOND,1); baseRisk = new BaseRisk(node); dailyRisk = new DailyRisk(); accumulatedRisk = new AccumulatedRisk(node); @@ -125,8 +159,29 @@ public class DiseasePressureModel { public void setLeafIsWet(List<Boolean> leafIsWet) { sporeSpreading.setLeafIsWet(leafIsWet); } + + public void setSowingDay(Date d) { + sowingDay.setTime(d); + } + public void setCurrentDay(Date d) { +// if(currentDay == null) { +// currentDay = Calendar.getInstance(); +// } + currentDay.setTime(d); +// currentDay.set(Calendar.HOUR_OF_DAY,0); +// currentDay.set(Calendar.HOUR,0); +// currentDay.set(Calendar.MINUTE,0); +// currentDay.set(Calendar.MILLISECOND,1); + } + public double getBaseRisk() { + // tillage is not timed, thus it is always on. + if(!timeTillageEffects) { + baseRisk.setTillageEffect(true); + } else if(baseRisk.getTillageEffect()) { + baseRisk.setTillageEffect(baseRisk.isTillageInEffect(sowingDay,currentDay)); + } return baseRisk.compute(); } @@ -137,6 +192,14 @@ public class DiseasePressureModel { public double getAccumulatedRisk() { return accumulatedRisk.compute(); } + + public boolean isTimeTillageEffects() { + return timeTillageEffects; + } + + public void setTimeTillageEffects(boolean timeTillageEffects) { + this.timeTillageEffects = timeTillageEffects; + } diff --git a/src/test/java/fi/luke/vips/model/cerealmodels/FinnCerealModelsTest.java b/src/test/java/fi/luke/vips/model/cerealmodels/FinnCerealModelsTest.java index 5155020..61cbf01 100644 --- a/src/test/java/fi/luke/vips/model/cerealmodels/FinnCerealModelsTest.java +++ b/src/test/java/fi/luke/vips/model/cerealmodels/FinnCerealModelsTest.java @@ -136,6 +136,7 @@ public class FinnCerealModelsTest { m.setConfigParameter("rh", rh); m.setConfigParameter("windspeed", windSpeedAll); + m.setConfigParameter("timeTillageEffects", new Boolean(false)); m.setConfigParameter("precedingCrop","Wheat"); m.setConfigParameter("tillageMethod","Intensive"); m.setConfigParameter("diseaseSusceptibility","Normal"); -- GitLab