Skip to content
Snippets Groups Projects
Commit 65884c11 authored by Tor-Einar Skog's avatar Tor-Einar Skog
Browse files

Initial commit

parents
No related branches found
No related tags found
No related merge requests found
target/
classes/
<?xml version="1.0" encoding="UTF-8"?>
<project-shared-configuration>
<!--
This file contains additional configuration written by modules in the NetBeans IDE.
The configuration is intended to be shared among all the users of project and
therefore it is assumed to be part of version control checkout.
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
-->
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
<!--
Properties that influence various parts of the IDE, especially code formatting and the like.
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
That way multiple projects can share the same settings (useful for formatting rules for example).
Any value defined here will override the pom.xml file value but is only applicable to the current project.
-->
<netbeans.hint.license>nibio_open_source_license.ftl</netbeans.hint.license>
</properties>
</project-shared-configuration>
pom.xml 0 → 100644
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>no.nibio.vips.model</groupId>
<artifactId>SeptoriaWetHourModel</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>no.nibio.vips.common</groupId>
<artifactId>VIPSCommon</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>
\ No newline at end of file
/*
* Copyright (c) 2018 NIBIO <http://www.nibio.no/>.
*
* This file is part of SeptoriaWetHourModel.
* SeptoriaWetHourModel is free software: you can redistribute it and/or modify
* it under the terms of the NIBIO Open Source License as published by
* NIBIO, either version 1 of the License, or (at your option) any
* later version.
*
* SeptoriaWetHourModel is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* NIBIO Open Source License for more details.
*
* You should have received a copy of the NIBIO Open Source License
* along with SeptoriaWetHourModel. If not, see <http://www.nibio.no/licenses/>.
*
*/
package no.nibio.vips.model.septoriawethourmodel;
import no.nibio.vips.util.DateMap;
/**
* @copyright 2018 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/
public class DataMatrix extends DateMap {
// Hourly precipitation
public final static String RR = "RR";
// Hourly relative humidity
public final static String UM = "UM";
// Hourly leaf wetness
public final static String BT = "BT";
// Wet hour sum for sliding middle
public final static String WHS = "WHS";
// Current hour is wet hour? 1 : 0
public final static String WH = "WH";
}
/*
* Copyright (c) 2018 NIBIO <http://www.nibio.no/>.
*
* This file is part of SeptoriaWetHourModel.
* SeptoriaWetHourModel is free software: you can redistribute it and/or modify
* it under the terms of the NIBIO Open Source License as published by
* NIBIO, either version 1 of the License, or (at your option) any
* later version.
*
* SeptoriaWetHourModel is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* NIBIO Open Source License for more details.
*
* You should have received a copy of the NIBIO Open Source License
* along with SeptoriaWetHourModel. If not, see <http://www.nibio.no/licenses/>.
*
*/
package no.nibio.vips.model.septoriawethourmodel;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import no.nibio.vips.entity.ModelConfiguration;
import no.nibio.vips.entity.Result;
import no.nibio.vips.entity.WeatherObservation;
import no.nibio.vips.model.ConfigValidationException;
import no.nibio.vips.model.Model;
import no.nibio.vips.model.ModelExcecutionException;
import no.nibio.vips.model.ModelId;
import no.nibio.vips.util.WeatherElements;
import no.nibio.vips.util.WeatherUtil;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.Optional;
import no.nibio.vips.entity.ResultImpl;
import no.nibio.vips.util.CommonNamespaces;
import no.nibio.vips.util.XDate;
/**
* Model developed by SEGES, Denmark
* @copyright 2018 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/
public class SeptoriaWetHourModel implements Model {
private final static ModelId MODEL_ID = new ModelId("SEPTORIAWH");
private Date dateGs31, date3rdUpperLeafEmerging, date2ndUpperLeafEmerging, dateUpperLeafEmerging, dateGs75;
private TimeZone timeZone;
private Double thresholdRelativeHumidity, thresholdLeafWetness, thresholdPrecipitation;
private Integer thresholdHumidPeriodHours, slidingHoursPast, slidingHoursAhead;
private DataMatrix dataMatrix;
private final WeatherUtil weatherUtil;
public SeptoriaWetHourModel(){
this.weatherUtil = new WeatherUtil();
}
@Override
public List<Result> getResult() throws ModelExcecutionException {
// Start date for calculation is dateGs31 (mandatory), last date is whatever is first of today + 2 days or dateGs75
// But inside the model, we just use the weather data as far as they reach
XDate currentDate = new XDate(this.dateGs31);
Date lastDate = this.dataMatrix.getLastDateWithParameterValue("RR");
Calendar cal = Calendar.getInstance();
// Calculating values
LinkedList<Integer> humidHours = new LinkedList<>();
List<Result> retVal = new ArrayList<>();
while(currentDate.compareTo(lastDate) <= 0){
Double RR = this.dataMatrix.getParamDoubleValueForDate(currentDate, DataMatrix.RR);
Double UM = this.dataMatrix.getParamDoubleValueForDate(currentDate, DataMatrix.UM);
Double BT = this.dataMatrix.getParamDoubleValueForDate(currentDate, DataMatrix.BT);
if(humidHours.size() > this.slidingHoursPast + this.slidingHoursAhead){
humidHours.removeFirst();
}
Integer humidHour = (
(BT != null && BT >= this.thresholdLeafWetness)
|| (UM != null && UM >= this.thresholdRelativeHumidity)
|| (RR != null && RR >= this.thresholdPrecipitation)
) ?
1:0;
humidHours.addLast(humidHour);
this.dataMatrix.setParamIntValueForDate(currentDate, DataMatrix.WH, humidHour);
cal.setTime(currentDate);
cal.add(Calendar.HOUR_OF_DAY, -this.slidingHoursAhead );
Date middleOfSlidingWindowDate = cal.getTime();
Integer slidingWindowSum = humidHours.stream().mapToInt(Integer::intValue).sum();
this.dataMatrix.setParamIntValueForDate(middleOfSlidingWindowDate, DataMatrix.WHS, slidingWindowSum);
Result r = new ResultImpl();
r.setValidTimeStart(new Date(currentDate.getTime()));
r.setValue(SeptoriaWetHourModel.MODEL_ID.toString(), DataMatrix.WH, String.valueOf(this.dataMatrix.getParamIntValueForDate(currentDate, DataMatrix.WH)));
r.setValue(CommonNamespaces.NS_WEATHER, WeatherElements.LEAF_WETNESS, String.valueOf(this.dataMatrix.getParamDoubleValueForDate(currentDate, DataMatrix.BT)));
r.setValue(CommonNamespaces.NS_WEATHER, WeatherElements.RELATIVE_HUMIDITY_MEAN, String.valueOf(this.dataMatrix.getParamDoubleValueForDate(currentDate, DataMatrix.UM)));
r.setValue(CommonNamespaces.NS_WEATHER, WeatherElements.PRECIPITATION, String.valueOf(this.dataMatrix.getParamDoubleValueForDate(currentDate, DataMatrix.RR)));
Optional<Result> previousR = retVal.stream().filter(res->res.getValidTimeStart().compareTo(middleOfSlidingWindowDate) == 0).findFirst();
if(previousR.isPresent()){
previousR.get().setValue(SeptoriaWetHourModel.MODEL_ID.toString(), DataMatrix.WHS, slidingWindowSum.toString());
}
retVal.add(r);
currentDate.add1Hour();
}
//System.out.println(this.dataMatrix.toCSV());
return retVal;
}
@Override
public ModelId getModelId() {
return SeptoriaWetHourModel.MODEL_ID;
}
@Override
public String getModelName() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String getModelName(String language) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String getLicense() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String getCopyright() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String getModelDescription() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String getModelDescription(String language) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String getWarningStatusInterpretation() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String getWarningStatusInterpretation(String language) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String getModelUsage() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String getModelUsage(String language) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public String getSampleConfig() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void setConfiguration(ModelConfiguration config) throws ConfigValidationException {
System.out.println("JAUDA");
this.dataMatrix = new DataMatrix();
// Object deserialization tool
ObjectMapper mapper = new ObjectMapper();
try
{
this.thresholdRelativeHumidity = mapper.convertValue(config.getConfigParameter("thresholdRelativeHumidity"), Double.class);
this.thresholdLeafWetness = mapper.convertValue(config.getConfigParameter("thresholdLeafWetness"), Double.class);
this.thresholdPrecipitation = mapper.convertValue(config.getConfigParameter("thresholdPrecipitation"), Double.class);
this.thresholdHumidPeriodHours = mapper.convertValue(config.getConfigParameter("thresholdHumidPeriodHours"), Integer.class);
this.slidingHoursPast = mapper.convertValue(config.getConfigParameter("slidingHoursPast"), Integer.class);
this.slidingHoursAhead = mapper.convertValue(config.getConfigParameter("slidingHoursAhead"), Integer.class);
this.timeZone = TimeZone.getTimeZone((String) config.getConfigParameter("timeZone"));
}
catch(NullPointerException npe)
{
throw new ConfigValidationException("Missing one or more of these parameters: "
+ "thresholdRelativeHumidity, thresholdLeafWetness, thresholdPrecipitation, "
+ "thresholdHumidPeriodHours, slidingHoursPast, slidingHoursAhead, timeZone");
}
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
format.setTimeZone(timeZone);
try
{
this.dateGs31 = format.parse(config.getConfigParameter("dateGs31").toString());
}
catch(ParseException | NullPointerException ex)
{
throw new ConfigValidationException("Illegal date format for (or missing completely) dateGs31: " + config.getConfigParameter("dateGs31"));
}
WeatherUtil wUtil = new WeatherUtil();
List<WeatherObservation> observations = mapper.convertValue(config.getConfigParameter("observations"), new TypeReference<List<WeatherObservation>>(){});
for(WeatherObservation o:observations)
{
switch(o.getElementMeasurementTypeId())
{
case WeatherElements.PRECIPITATION:
if(o.getLogIntervalId().equals(WeatherObservation.LOG_INTERVAL_ID_1H))
{
this.dataMatrix.setParamDoubleValueForDate(o.getTimeMeasured(), DataMatrix.RR, o.getValue());
}
break;
case WeatherElements.RELATIVE_HUMIDITY_MEAN:
if(o.getLogIntervalId().equals(WeatherObservation.LOG_INTERVAL_ID_1H))
{
this.dataMatrix.setParamDoubleValueForDate(o.getTimeMeasured(), DataMatrix.UM, o.getValue());
}
break;
case WeatherElements.LEAF_WETNESS:
if(o.getLogIntervalId().equals(WeatherObservation.LOG_INTERVAL_ID_1H))
{
this.dataMatrix.setParamDoubleValueForDate(o.getTimeMeasured(), DataMatrix.BT, o.getValue());
}
default:
// Keep calm and continue importing data
break;
}
}
// Make sure we have weather data from dateGs31
calculateGrowthStages();
if(this.dataMatrix.getFirstDateWithParameterValue("RR").after(dateGs31))
{
throw new ConfigValidationException("ERROR: Missing weather data. First date with precipitation data is " + this.dataMatrix.getFirstDateWithParameterValue("RR") + ", date for GS 31 = " + this.dateGs31);
}
}
private void calculateGrowthStages(){
this.dateGs31 = weatherUtil.normalizeToExactDate(dateGs31, timeZone);
Calendar cal = Calendar.getInstance(this.timeZone);
cal.setTime(this.dateGs31);
cal.add(Calendar.DATE, 10);
this.date3rdUpperLeafEmerging = cal.getTime();
cal.add(Calendar.DATE, 10);
this.date2ndUpperLeafEmerging = cal.getTime();
cal.add(Calendar.DATE, 10);
this.dateUpperLeafEmerging = cal.getTime();
cal.setTime(this.date3rdUpperLeafEmerging);
cal.set(Calendar.MONTH, Calendar.JUNE);
cal.set(Calendar.DATE,30);
this.dateGs75 = cal.getTime();
}
}
/*
* Copyright (c) 2018 NIBIO <http://www.nibio.no/>.
*
* This file is part of SeptoriaWetHourModel.
* SeptoriaWetHourModel is free software: you can redistribute it and/or modify
* it under the terms of the NIBIO Open Source License as published by
* NIBIO, either version 1 of the License, or (at your option) any
* later version.
*
* SeptoriaWetHourModel is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* NIBIO Open Source License for more details.
*
* You should have received a copy of the NIBIO Open Source License
* along with SeptoriaWetHourModel. If not, see <http://www.nibio.no/licenses/>.
*
*/
package no.nibio.vips.model.septoriawethourmodel;
import java.util.List;
import no.nibio.vips.entity.ModelConfiguration;
import no.nibio.vips.entity.Result;
import no.nibio.vips.model.ModelId;
import no.nibio.vips.util.test.WeatherDataFileReader;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author treinar
*/
public class SeptoriaWetHourModelTest {
private WeatherDataFileReader weatherDataFileReader;
public SeptoriaWetHourModelTest() {
}
@BeforeClass
public static void setUpClass() {
}
@AfterClass
public static void tearDownClass() {
}
@Before
public void setUp() {
this.weatherDataFileReader = new WeatherDataFileReader();
}
@After
public void tearDown() {
}
/**
* Test of getResult method, of class SeptoriaWetHourModel.
*/
@org.junit.Test
public void testGetResult() throws Exception {
System.out.println("getResult");
SeptoriaWetHourModel instance = new SeptoriaWetHourModel();
ModelConfiguration config = this.weatherDataFileReader.getModelConfigurationWithWeatherData("/2017_aalborg.json", instance.getModelId().toString());
config.setConfigParameter("timeZone", "Europe/Oslo");
config.setConfigParameter("thresholdRelativeHumidity", 85.0);
config.setConfigParameter("thresholdLeafWetness", 30.0);
config.setConfigParameter("thresholdPrecipitation", 0.2);
config.setConfigParameter("thresholdHumidPeriodHours", 19);
config.setConfigParameter("slidingHoursPast", 36);
config.setConfigParameter("slidingHoursAhead", 36);
config.setConfigParameter("dateGs31", "2017-05-01");
instance.setConfiguration(config);
List<Result> expResult = null;
List<Result> result = instance.getResult();
assertNotNull(result);
result.stream().forEach(r->System.out.println(r));
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of getModelId method, of class SeptoriaWetHourModel.
*/
//@org.junit.Test
public void testGetModelId() {
System.out.println("getModelId");
SeptoriaWetHourModel instance = new SeptoriaWetHourModel();
ModelId expResult = null;
ModelId result = instance.getModelId();
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of getModelName method, of class SeptoriaWetHourModel.
*/
//@org.junit.Test
public void testGetModelName_0args() {
System.out.println("getModelName");
SeptoriaWetHourModel instance = new SeptoriaWetHourModel();
String expResult = "";
String result = instance.getModelName();
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of getModelName method, of class SeptoriaWetHourModel.
*/
//@org.junit.Test
public void testGetModelName_String() {
System.out.println("getModelName");
String language = "";
SeptoriaWetHourModel instance = new SeptoriaWetHourModel();
String expResult = "";
String result = instance.getModelName(language);
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of getLicense method, of class SeptoriaWetHourModel.
*/
//@org.junit.Test
public void testGetLicense() {
System.out.println("getLicense");
SeptoriaWetHourModel instance = new SeptoriaWetHourModel();
String expResult = "";
String result = instance.getLicense();
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of getCopyright method, of class SeptoriaWetHourModel.
*/
//@org.junit.Test
public void testGetCopyright() {
System.out.println("getCopyright");
SeptoriaWetHourModel instance = new SeptoriaWetHourModel();
String expResult = "";
String result = instance.getCopyright();
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of getModelDescription method, of class SeptoriaWetHourModel.
*/
//@org.junit.Test
public void testGetModelDescription_0args() {
System.out.println("getModelDescription");
SeptoriaWetHourModel instance = new SeptoriaWetHourModel();
String expResult = "";
String result = instance.getModelDescription();
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of getModelDescription method, of class SeptoriaWetHourModel.
*/
//@org.junit.Test
public void testGetModelDescription_String() {
System.out.println("getModelDescription");
String language = "";
SeptoriaWetHourModel instance = new SeptoriaWetHourModel();
String expResult = "";
String result = instance.getModelDescription(language);
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of getWarningStatusInterpretation method, of class SeptoriaWetHourModel.
*/
//@org.junit.Test
public void testGetWarningStatusInterpretation_0args() {
System.out.println("getWarningStatusInterpretation");
SeptoriaWetHourModel instance = new SeptoriaWetHourModel();
String expResult = "";
String result = instance.getWarningStatusInterpretation();
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of getWarningStatusInterpretation method, of class SeptoriaWetHourModel.
*/
//@org.junit.Test
public void testGetWarningStatusInterpretation_String() {
System.out.println("getWarningStatusInterpretation");
String language = "";
SeptoriaWetHourModel instance = new SeptoriaWetHourModel();
String expResult = "";
String result = instance.getWarningStatusInterpretation(language);
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of getModelUsage method, of class SeptoriaWetHourModel.
*/
//@org.junit.Test
public void testGetModelUsage_0args() {
System.out.println("getModelUsage");
SeptoriaWetHourModel instance = new SeptoriaWetHourModel();
String expResult = "";
String result = instance.getModelUsage();
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of getModelUsage method, of class SeptoriaWetHourModel.
*/
//@org.junit.Test
public void testGetModelUsage_String() {
System.out.println("getModelUsage");
String language = "";
SeptoriaWetHourModel instance = new SeptoriaWetHourModel();
String expResult = "";
String result = instance.getModelUsage(language);
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of getSampleConfig method, of class SeptoriaWetHourModel.
*/
//@org.junit.Test
public void testGetSampleConfig() {
System.out.println("getSampleConfig");
SeptoriaWetHourModel instance = new SeptoriaWetHourModel();
String expResult = "";
String result = instance.getSampleConfig();
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of setConfiguration method, of class SeptoriaWetHourModel.
*/
@org.junit.Test
public void testSetConfiguration() throws Exception {
System.out.println("setConfiguration");
SeptoriaWetHourModel instance = new SeptoriaWetHourModel();
ModelConfiguration config = this.weatherDataFileReader.getModelConfigurationWithWeatherData("/2017_aas.json", instance.getModelId().toString());
config.setConfigParameter("timeZone", "Europe/Oslo");
config.setConfigParameter("thresholdRelativeHumidity", 85.0);
config.setConfigParameter("thresholdLeafWetness", 30.0);
config.setConfigParameter("thresholdPrecipitation", 0.2);
config.setConfigParameter("thresholdHumidPeriodHours", 19);
config.setConfigParameter("slidingHoursPast", 36);
config.setConfigParameter("slidingHoursAhead", 36);
config.setConfigParameter("dateGs31", "2017-05-01");
instance.setConfiguration(config);
}
}
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment