Skip to content
Snippets Groups Projects
Commit 7c85e6fc authored by Brita Linnestad's avatar Brita Linnestad
Browse files

Merge branch 'main' into 'release'

Main

See merge request !2
parents 83798469 9ae0a88a
Branches
Tags
1 merge request!2Main
Pipeline #3961 passed
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<groupId>no.nibio.vips.model</groupId> <groupId>no.nibio.vips.model</groupId>
<artifactId>DayDegreesModel</artifactId> <artifactId>DayDegreesModel</artifactId>
<version>0.1.1</version> <version>0.1.2-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<dependencies> <dependencies>
......
/*
* Copyright (c) 2016 NIBIO <http://www.nibio.no/>.
*
* This file is part of PsilaRosaeTempModel.
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package no.nibio.vips.model.daydegreemodel;
import no.nibio.vips.util.DateMap;
/**
* @copyright 2016 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/
public class DataMatrix extends DateMap{
public final static String TMD = "TMD";
public final static String TMD0C = "TMD0C";
}
...@@ -18,10 +18,13 @@ ...@@ -18,10 +18,13 @@
package no.nibio.vips.model.daydegreemodel; package no.nibio.vips.model.daydegreemodel;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException; import java.io.IOException;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.TimeZone; import java.util.TimeZone;
...@@ -46,94 +49,65 @@ import no.nibio.vips.util.WeatherUtil; ...@@ -46,94 +49,65 @@ import no.nibio.vips.util.WeatherUtil;
* @author Tor J. Johansen <tor.johansen@nibio.no> (Model research) * @author Tor J. Johansen <tor.johansen@nibio.no> (Model research)
* @author Tor-Einar Skog <tor-einar.skog@nibio.no> (Programming) * @author Tor-Einar Skog <tor-einar.skog@nibio.no> (Programming)
*/ */
public class DayDegreeModel extends I18nImpl implements Model { public class DayDegreeModel implements Model {
public final static ModelId MODEL_ID = new ModelId("DAYDEGREES"); private ModelUtil modelUtil;
private Float dayDegreeBaseTemp;
private final ModelUtil modelUtil; private List<WeatherObservation> TM;
private TimeZone timeZone;
private DataMatrix dataMatrix;
private List<WeatherObservation> TM; // Temporary storage of hourly values private final static TimeZone DEFAULT_TIME_ZONE = TimeZone.getTimeZone("Europe/Oslo");
private final Double dayDegreeBaseTemp = 0.0;
// Threshold values
//private final Double THRESHOLD_1 = 260.0;
//private final Double THRESHOLD_2 = 360.0;
//private final Double THRESHOLD_3 = 560.0;
public final static ModelId MODEL_ID = new ModelId("DAYDEGREES");
public DayDegreeModel() public DayDegreeModel()
{ {
super("no.nibio.vips.model.psilarosaetempmodel.texts");
this.modelUtil = new ModelUtil(); this.modelUtil = new ModelUtil();
} }
@Override @Override
public List<Result> getResult() throws ModelExcecutionException { public List<Result> getResult() throws ModelExcecutionException {
this.calculateTemperatureSum(DataMatrix.TMD, DataMatrix.TMD0C);
List<Result> retVal = new ArrayList<>(); Collections.sort(this.TM);
Date currentDate = this.dataMatrix.getFirstDateWithParameterValue(DataMatrix.TMD0C);
Calendar cal = Calendar.getInstance(this.timeZone); Double dayDegreeSum = 0.0;
List<Result> results = new ArrayList<>();
Calendar cal = Calendar.getInstance(this.DEFAULT_TIME_ZONE);
DecimalFormat dFormat = new DecimalFormat("###.##"); DecimalFormat dFormat = new DecimalFormat("###.##");
while(this.dataMatrix.getParamDoubleValueForDate(currentDate, DataMatrix.TMD0C) != null) for(WeatherObservation obs:this.TM)
{ {
Result result = new ResultImpl();
result.setValidTimeStart(currentDate);
Double TMCurrentDate = ((WeatherObservation) this.dataMatrix.getParamValueForDate(currentDate, DataMatrix.TMD)).getValue();
Double TMD0C = this.dataMatrix.getParamDoubleValueForDate(currentDate, DataMatrix.TMD0C);
if(obs.getValue() > 0)
{
/* dayDegreeSum += obs.getValue();
result.setValue(CommonNamespaces.NS_WEATHER, DataMatrix.TMD, dFormat.format(TMCurrentDate)); }
result.setValue(CommonNamespaces.NS_WEATHER, DataMatrix.TMDD5C, dFormat.format(TMDD5C));
result.setValue(CommonNamespaces.NS_WEATHER, DataMatrix.TMD5C, dFormat.format(TMD5C)); Result result = new ResultImpl();
result.setValue(PsilaRosaeTempModel.MODEL_ID.toString(), "THRESHOLD_1", dFormat.format(this.THRESHOLD_1)); result.setValidTimeStart(obs.getTimeMeasured());
result.setValue(PsilaRosaeTempModel.MODEL_ID.toString(), "THRESHOLD_2", dFormat.format(this.THRESHOLD_2)); result.setValue(this.getModelId().toString(), "DayDegreeSum", dayDegreeSum.toString());
result.setValue(PsilaRosaeTempModel.MODEL_ID.toString(), "THRESHOLD_3", dFormat.format(this.THRESHOLD_3));
Integer warningStatus = Result.WARNING_STATUS_NO_RISK;
if(TMDD5C >= this.THRESHOLD_1)
{
warningStatus = Result.WARNING_STATUS_MINOR_RISK;
}
if(TMDD5C >= this.THRESHOLD_2)
{
warningStatus = Result.WARNING_STATUS_HIGH_RISK;
}
if(TMDD5C >= this.THRESHOLD_3)
{
warningStatus = Result.WARNING_STATUS_NO_WARNING;
}
result.setWarningStatus(warningStatus);
retVal.add(result);
// Moving on...
cal.setTime(currentDate);
cal.add(Calendar.DATE, 1);
currentDate = cal.getTime();*/
}
return null; results.add(result);
//return retVal; }
return results;
} }
@Override @Override
public ModelId getModelId() { public ModelId getModelId() {
return DayDegreeModel.MODEL_ID; return DayDegreeModel.MODEL_ID;
} }
@Override @Override
public String getModelName() { public String getModelName() {
return this.getModelName(Model.DEFAULT_LANGUAGE); return null;
} }
@Override @Override
public String getModelName(String language) { public String getModelName(String language) {
return this.getText("name", language); return "Day Degree model";
} }
@Override @Override
...@@ -162,6 +136,7 @@ public class DayDegreeModel extends I18nImpl implements Model { ...@@ -162,6 +136,7 @@ public class DayDegreeModel extends I18nImpl implements Model {
return "(c) 2015-2021 NIBIO (http://www.nibio.no/). Contact: post@nibio.no"; return "(c) 2015-2021 NIBIO (http://www.nibio.no/). Contact: post@nibio.no";
} }
@Override @Override
public String getModelDescription() { public String getModelDescription() {
return this.getModelDescription(Model.DEFAULT_LANGUAGE); return this.getModelDescription(Model.DEFAULT_LANGUAGE);
...@@ -169,39 +144,32 @@ public class DayDegreeModel extends I18nImpl implements Model { ...@@ -169,39 +144,32 @@ public class DayDegreeModel extends I18nImpl implements Model {
@Override @Override
public String getModelDescription(String language) { public String getModelDescription(String language) {
try return null;
{
return this.modelUtil.getTextWithBase64EncodedImages(this.getText("description", language), this.getClass());
}
catch(IOException ex)
{
return this.getText("description", language);
}
} }
@Override @Override
public String getWarningStatusInterpretation() { public String getWarningStatusInterpretation() {
return this.getWarningStatusInterpretation(Model.DEFAULT_LANGUAGE); return null;
} }
@Override @Override
public String getWarningStatusInterpretation(String language) { public String getWarningStatusInterpretation(String language) {
return this.getText("statusInterpretation", language); return null;
} }
@Override @Override
public String getModelUsage() { public String getModelUsage() {
return this.getModelUsage(Model.DEFAULT_LANGUAGE); return null;
} }
@Override @Override
public String getModelUsage(String language) { public String getModelUsage(String language) {
return this.getText("usage", language); return null;
} }
@Override @Override
public String getSampleConfig() { public String getSampleConfig() {
System.out.println("Kjører i getSampleConfig------");
return "{\n" + return "{\n" +
"\t\"loginInfo\":{\n" + "\t\"loginInfo\":{\n" +
"\t\t\"username\":\"example\",\n" + "\t\t\"username\":\"example\",\n" +
...@@ -209,7 +177,7 @@ public class DayDegreeModel extends I18nImpl implements Model { ...@@ -209,7 +177,7 @@ public class DayDegreeModel extends I18nImpl implements Model {
"\t},\n" + "\t},\n" +
"\t\"modelId\":\"" + MODEL_ID.toString() + "\",\n" + "\t\"modelId\":\"" + MODEL_ID.toString() + "\",\n" +
"\t\"configParameters\":{\n" + "\t\"configParameters\":{\n" +
"\t\t\"timeZone\": \"Europe/Oslo\",\n" + "\t\t\"basisTemp\":0,\n" +
"\t\t\"observations\":[\n" + "\t\t\"observations\":[\n" +
"\t\t{\n" + "\t\t{\n" +
"\t\t\t\t\"timeMeasured\": \"2015-01-01T00:00:00+02:00\",\n" + "\t\t\t\t\"timeMeasured\": \"2015-01-01T00:00:00+02:00\",\n" +
...@@ -222,97 +190,40 @@ public class DayDegreeModel extends I18nImpl implements Model { ...@@ -222,97 +190,40 @@ public class DayDegreeModel extends I18nImpl implements Model {
@Override @Override
public void setConfiguration(ModelConfiguration config) throws ConfigValidationException { public void setConfiguration(ModelConfiguration config) throws ConfigValidationException {
// Initialize the weather data collections // Initialize the weather data collections
this.TM = new ArrayList<>(); this.TM = new ArrayList<>();
this.dayDegreeBaseTemp = Float.parseFloat((String) config.getConfigParameter("basisTemp"));
// Init data matrix
this.dataMatrix = new DataMatrix();
// Setting timezone ObjectMapper mapper = new ObjectMapper();
this.timeZone = TimeZone.getTimeZone((String) config.getConfigParameter("timeZone"));
//System.out.println("TimeZone=" + this.timeZone);
// Importing weather data, creating collections List<WeatherObservation> observations = this.modelUtil.extractWeatherObservationList(config.getConfigParameter("observations"));
// Can accept both hourly and daily data
WeatherUtil wUtil = new WeatherUtil();
List<WeatherObservation> observations = modelUtil.extractWeatherObservationList(config.getConfigParameter("observations")); // Must be complete set of daily mean temperatures
if(observations == null || observations.isEmpty()) WeatherUtil wUtil = new WeatherUtil();
Date potentialHole = wUtil.findFirstHoleInObservationSeries(observations, WeatherObservation.LOG_INTERVAL_ID_1D, DayDegreeModel.DEFAULT_TIME_ZONE);
if(potentialHole != null)
{ {
throw new ConfigValidationException("Please provide weather data."); throw new ConfigValidationException("Hole found in temperature series at = " + potentialHole);
} }
for(WeatherObservation o:observations) for(WeatherObservation o:observations)
{ {
switch(o.getElementMeasurementTypeId()) switch(o.getElementMeasurementTypeId())
{ {
case WeatherElements.TEMPERATURE_MEAN: case WeatherElements.TEMPERATURE_MEAN:
if(o.getLogIntervalId().equals(WeatherObservation.LOG_INTERVAL_ID_1H)) if(o.getLogIntervalId().equals(WeatherObservation.LOG_INTERVAL_ID_1D))
{ {
this.TM.add(o); this.TM.add(o);
}else { }
o.setTimeMeasured(wUtil.pragmaticAdjustmentToMidnight(o.getTimeMeasured(), timeZone)); break;
this.dataMatrix.setParamValueForDate(o.getTimeMeasured(), DataMatrix.TMD, o);
}break;
default: default:
// Keep calm and continue importing data // TODO: Throw validation error?
break; break;
} }
} }
// If we've received hourly weather data, create and store daily values
// Air temperature
if(dataMatrix.getFirstDateWithParameterValue(DataMatrix.TMD) == null)
{
try {
List<WeatherObservation> dailyTemperatures = new WeatherUtil().getAggregatedDailyValues(
this.TM,
this.timeZone,
15,
WeatherUtil.AGGREGATION_TYPE_AVERAGE,
0,
true);
for(WeatherObservation obs:dailyTemperatures)
{
this.dataMatrix.setParamValueForDate(obs.getTimeMeasured(), DataMatrix.TMD, obs);
}
} catch (WeatherObservationListException | InvalidAggregationTypeException ex) {
throw new ConfigValidationException(ex.getMessage());
}
}
//System.out.println("DataMatrix");
//System.out.println(this.dataMatrix.toString());
}
/**
* Operates on the datamatrix
* @param inputParameterName the parameter to sum
* @param outputParameterName the result
*/
private void calculateTemperatureSum(String inputParameterName, String outputParameterName) throws ModelExcecutionException {
Date today = this.dataMatrix.getFirstDateWithParameterValue(inputParameterName);
Date lastDate = this.dataMatrix.getLastDateWithParameterValue(inputParameterName);
Calendar cal = Calendar.getInstance(this.timeZone);
Double sum = 0.0;
while(today.compareTo(lastDate) <= 0)
{
WeatherObservation todayTemp = (WeatherObservation)this.dataMatrix.getParamValueForDate(today, inputParameterName);
if(todayTemp == null)
{
throw new ModelExcecutionException("Missing weather data at " + today + ": " + inputParameterName);
}
//System.out.println("today=" + today + ",todayTemp=" + todayTemp);
Double dailyContribution = Math.max(0.0, todayTemp.getValue() - this.dayDegreeBaseTemp);
this.dataMatrix.setParamDoubleValueForDate(today, DataMatrix.TMD0C, dailyContribution);
sum += dailyContribution;
this.dataMatrix.setParamDoubleValueForDate(today, outputParameterName, sum);
cal.setTime(today);
cal.add(Calendar.DATE, 1);
today = cal.getTime();
}
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment