diff --git a/resources/model-constants.json b/resources/model-constants.json index 7e6f89a65aa2eac338bb9c83a2890b7792979e9b..0360133f838f673e086532b203f2040b3928a5bb 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 65f5f348c064e2d3dfd2d07764ff43282d0526a9..5dbd8166eec0c1de5d6ffa4b15ab1fc418918b00 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 3349680c8e702a9085712cf7b135a31bc63ed2cf..24206cd393e704c895a004dee3715b55e14d6392 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 8342d9f9ad67771f9d0762fbc46cfe23bb532236..f4f6c45e677fc6a39307ca727ea81dae85928593 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 51550203c6b88db64f4cf74f37f0f5bd9215f327..61cbf0161b4619529ff7611cb549f266c3126c9a 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");