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

Merge branch 'develop' into 'Observation'

# Conflicts:
#   src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties
#   src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties
#   src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties
#   src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties
#   src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties
#   src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties
parents 4afacefd a032cf5f
Branches
Tags
2 merge requests!22Develop,!19Observation
Showing
with 1053 additions and 10 deletions
#!groovy
node {
try {
stage 'Checkout'
checkout scm
stage 'Test'
sh """
mvn test
"""
stage 'Build'
}
catch (err) {
throw err
}
}
...@@ -186,6 +186,12 @@ ...@@ -186,6 +186,12 @@
<version>2.9.8</version> <version>2.9.8</version>
<type>jar</type> <type>jar</type>
</dependency> </dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.9.8</version>
<type>jar</type>
</dependency>
<dependency> <dependency>
<groupId>org.locationtech.jts</groupId> <groupId>org.locationtech.jts</groupId>
<artifactId>jts-core</artifactId> <artifactId>jts-core</artifactId>
......
...@@ -55,6 +55,8 @@ public class VIPSLogicApplication extends Application ...@@ -55,6 +55,8 @@ public class VIPSLogicApplication extends Application
resources.add(no.nibio.vips.logic.modules.applefruitmoth.AppleFruitMothService.class); resources.add(no.nibio.vips.logic.modules.applefruitmoth.AppleFruitMothService.class);
resources.add(no.nibio.vips.logic.service.ObservationService.class); resources.add(no.nibio.vips.logic.service.ObservationService.class);
resources.add(no.nibio.vips.logic.service.ModelFormService.class); resources.add(no.nibio.vips.logic.service.ModelFormService.class);
resources.add(no.nibio.vips.logic.service.GrowthStageService.class);
resources.add(no.nibio.vips.logic.service.JacksonConfig.class); resources.add(no.nibio.vips.logic.service.JacksonConfig.class);
//resources.add(no.nibio.vips.logic.service.JSONBConfig.class); //resources.add(no.nibio.vips.logic.service.JSONBConfig.class);
//resources.add(no.nibio.vips.coremanager.service.ManagerResourceImpl.class); //resources.add(no.nibio.vips.coremanager.service.ManagerResourceImpl.class);
...@@ -71,6 +73,7 @@ public class VIPSLogicApplication extends Application ...@@ -71,6 +73,7 @@ public class VIPSLogicApplication extends Application
resources.add(no.nibio.vips.logic.modules.barleynetblotch.BarleyNetBlotchModelService.class); resources.add(no.nibio.vips.logic.modules.barleynetblotch.BarleyNetBlotchModelService.class);
resources.add(no.nibio.vips.logic.modules.roughage.RoughageService.class); resources.add(no.nibio.vips.logic.modules.roughage.RoughageService.class);
resources.add(no.nibio.vips.logic.modules.wheatleafblotch.WheatLeafBlotchModelService.class); resources.add(no.nibio.vips.logic.modules.wheatleafblotch.WheatLeafBlotchModelService.class);
resources.add(no.nibio.vips.logic.service.GrowthStageService.class);
resources.add(no.nibio.vips.logic.service.JSONBConfig.class); resources.add(no.nibio.vips.logic.service.JSONBConfig.class);
resources.add(no.nibio.vips.logic.service.JacksonConfig.class); resources.add(no.nibio.vips.logic.service.JacksonConfig.class);
resources.add(no.nibio.vips.logic.service.LogicService.class); resources.add(no.nibio.vips.logic.service.LogicService.class);
......
...@@ -563,7 +563,7 @@ public class ForecastBean { ...@@ -563,7 +563,7 @@ public class ForecastBean {
* @param camelCaseName * @param camelCaseName
* @return MODELID_CAMEL_CASE_NAME * @return MODELID_CAMEL_CASE_NAME
*/ */
private String getDeCamelizedFieldName(String modelId, String camelCaseName) public String getDeCamelizedFieldName(String modelId, String camelCaseName)
{ {
StringBuilder deCamelizedFieldName = new StringBuilder(modelId.toUpperCase()); StringBuilder deCamelizedFieldName = new StringBuilder(modelId.toUpperCase());
for(String phrase : camelCaseName.split("(?=\\p{Lu})")) for(String phrase : camelCaseName.split("(?=\\p{Lu})"))
...@@ -573,7 +573,7 @@ public class ForecastBean { ...@@ -573,7 +573,7 @@ public class ForecastBean {
return deCamelizedFieldName.toString(); return deCamelizedFieldName.toString();
} }
public List<ForecastModelConfiguration> getForecastModelConfigurations(Long forecastConfigurationId) public List<ForecastModelConfiguration> getForecastModelConfigurations(Long forecastConfigurationId)
{ {
...@@ -1203,4 +1203,17 @@ public class ForecastBean { ...@@ -1203,4 +1203,17 @@ public class ForecastBean {
.setParameter("userId", user.getUserId()) .setParameter("userId", user.getUserId())
.executeUpdate(); .executeUpdate();
} }
/**
*
* @param modelId
* @param year
* @return
*/
public List<ForecastConfiguration> getForecastConfigurationsForModel(String modelId, Integer year) {
return em.createNamedQuery("ForecastConfiguration.findByModelIdAndYear")
.setParameter("modelId", modelId)
.setParameter("year", year)
.getResultList();
}
} }
...@@ -292,6 +292,10 @@ public class ObservationBean { ...@@ -292,6 +292,10 @@ public class ObservationBean {
public void deleteObservation(Integer observationId) { public void deleteObservation(Integer observationId) {
Observation observation = em.find(Observation.class, observationId); Observation observation = em.find(Observation.class, observationId);
// Delete all current group memberships
em.createNativeQuery("DELETE FROM public.organization_group_observation WHERE observation_id=:observationId")
.setParameter("observationId", observation.getObservationId())
.executeUpdate();
em.remove(observation); em.remove(observation);
} }
......
...@@ -46,7 +46,7 @@ import no.nibio.vips.logic.entity.OrganismLocalePK; ...@@ -46,7 +46,7 @@ import no.nibio.vips.logic.entity.OrganismLocalePK;
import no.nibio.vips.logic.util.HierarchyCategoryLocaleNames; import no.nibio.vips.logic.util.HierarchyCategoryLocaleNames;
/** /**
* @copyright 2014 <a href="http://www.nibio.no/">NIBIO</a> * @copyright 2014-2020 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no> * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/ */
@Stateless @Stateless
...@@ -481,4 +481,11 @@ public class OrganismBean { ...@@ -481,4 +481,11 @@ public class OrganismBean {
public List<Organism> findOrganismsByLatinNames(List<String> latinNames) { public List<Organism> findOrganismsByLatinNames(List<String> latinNames) {
return em.createNamedQuery("Organism.findByLatinNames").setParameter("latinNames", latinNames).getResultList(); return em.createNamedQuery("Organism.findByLatinNames").setParameter("latinNames", latinNames).getResultList();
} }
public List<Organism> findOrganismsByLocalNames(List<String> localNames, String locale) {
return em.createNamedQuery("Organism.findByLocalNames")
.setParameter("localNames", localNames)
.setParameter("locale", locale)
.getResultList();
}
} }
...@@ -483,7 +483,96 @@ public class PointOfInterestBean { ...@@ -483,7 +483,96 @@ public class PointOfInterestBean {
.setParameter("name", dataSourceName) .setParameter("name", dataSourceName)
.getSingleResult(); .getSingleResult();
} }
/**
* Utility method to find the nearest weather station
* @param location
* @return
*/
public PointOfInterestWeatherStation findClosestWeatherStation(com.vividsolutions.jts.geom.Coordinate location)
{
return this.findClosestWeatherStation(location.x, location.y);
}
public PointOfInterestWeatherStation findClosestWeatherStation(Double longitude, Double latitude)
{
List<PointOfInterestWeatherStation> weatherStations = em.createNamedQuery("PointOfInterestWeatherStation.findAll", PointOfInterestWeatherStation.class)
.getResultList();
return this.findClosestWeatherStation(longitude, latitude, weatherStations);
}
/**
* Utility method to find the nearest weather station
* @param location
* @return
*/
public PointOfInterestWeatherStation findClosestWeatherStation(com.vividsolutions.jts.geom.Coordinate location, List<PointOfInterestWeatherStation> weatherStations)
{
return this.findClosestWeatherStation(location.x, location.y, weatherStations);
}
/**
* Utility method to find the nearest weather station
* @param longitude
* @param latitude
* @return
*/
public PointOfInterestWeatherStation findClosestWeatherStation(Double longitude, Double latitude, List<PointOfInterestWeatherStation> weatherStations)
{
PointOfInterestWeatherStation retVal = null;
Double minimumDistance = null; // km
for(PointOfInterestWeatherStation ws:weatherStations)
{
Double distance = this.calculateDistance(latitude, longitude, ws.getLatitude(), ws.getLongitude());
if(minimumDistance == null || minimumDistance >= distance)
{
minimumDistance = distance;
retVal = ws;
}
}
return retVal;
}
/**
* Based on <a href="http://www.movable-type.co.uk/scripts/latlong.html">this</a>. Explanation:
* <pre>
* This uses the "haversine" formula to calculate the great-circle distance between two points ? that is, the shortest distance over the earth?s surface ? giving an ?as-the-crow-flies? distance between the points (ignoring any hills, of course!).
Haversine formula:
a = sin²(∆lat/2) + cos(lat1).cos(lat2).sin²(∆long/2)
c = 2 * atan2(√a,√(1-a))
d = R*c
where R is earth's radius (mean radius = 6,371km);
Note that angles need to be in radians to pass to trig functions!
* </pre>
* @param lat1 WGS84 latitude of point 1
* @param long1 WGS84 longitude of point 1
* @param lat2 WGS84 latitude of point 2
* @param long2 WGS84 longitude of point 2
* @return distance in km
*/
public Double calculateDistance(Double lat1, Double long1, Double lat2, Double long2)
{
Integer R = 6371; // km
Double dLat = Math.toRadians(lat2-lat1);
Double dLon = Math.toRadians(long2-long1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
Double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
Double d = R * c;
return d;
}
} }
...@@ -82,7 +82,8 @@ import org.hibernate.annotations.TypeDefs; ...@@ -82,7 +82,8 @@ import org.hibernate.annotations.TypeDefs;
@NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.isPrivate = FALSE"), @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.isPrivate = FALSE"),
@NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdsAndModelIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.modelId IN (:modelIds) AND f.isPrivate = FALSE"), @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdsAndModelIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.modelId IN (:modelIds) AND f.isPrivate = FALSE"),
@NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdsAndModelIdsAndDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.modelId IN (:modelIds) AND f.dateStart <= :to AND f.dateEnd >= :from AND f.isPrivate = FALSE"), @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdsAndModelIdsAndDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.modelId IN (:modelIds) AND f.dateStart <= :to AND f.dateEnd >= :from AND f.isPrivate = FALSE"),
@NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdsAndDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.dateStart <= :to AND f.dateEnd >= :from AND f.isPrivate = FALSE") @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdsAndDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.dateStart <= :to AND f.dateEnd >= :from AND f.isPrivate = FALSE"),
@NamedQuery(name = "ForecastConfiguration.findByModelIdAndYear", query = "SELECT f FROM ForecastConfiguration f WHERE f.modelId = :modelId AND YEAR(f.dateStart) <= :year AND YEAR(f.dateEnd) >= :year AND f.isPrivate = FALSE")
}) })
public class ForecastConfiguration implements Serializable, Comparable { public class ForecastConfiguration implements Serializable, Comparable {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "forecastConfiguration", fetch = FetchType.EAGER) @OneToMany(cascade = CascadeType.ALL, mappedBy = "forecastConfiguration", fetch = FetchType.EAGER)
......
...@@ -42,7 +42,7 @@ import javax.validation.constraints.Size; ...@@ -42,7 +42,7 @@ import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
/** /**
* @copyright 2013-2014 <a href="http://www.nibio.no/">NIBIO</a> * @copyright 2013-2020 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no> * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/ */
@Entity @Entity
...@@ -57,6 +57,7 @@ import javax.xml.bind.annotation.XmlRootElement; ...@@ -57,6 +57,7 @@ import javax.xml.bind.annotation.XmlRootElement;
@NamedQuery(name = "Organism.findByParentOrganismId", query = "SELECT o FROM Organism o WHERE o.parentOrganismId = :parentOrganismId"), @NamedQuery(name = "Organism.findByParentOrganismId", query = "SELECT o FROM Organism o WHERE o.parentOrganismId = :parentOrganismId"),
@NamedQuery(name = "Organism.findByLatinName", query = "SELECT o FROM Organism o WHERE o.latinName = :latinName"), @NamedQuery(name = "Organism.findByLatinName", query = "SELECT o FROM Organism o WHERE o.latinName = :latinName"),
@NamedQuery(name = "Organism.findByLatinNames", query = "SELECT o FROM Organism o WHERE o.latinName IN :latinNames"), @NamedQuery(name = "Organism.findByLatinNames", query = "SELECT o FROM Organism o WHERE o.latinName IN :latinNames"),
@NamedQuery(name = "Organism.findByLocalNames", query = "SELECT o FROM Organism o WHERE o.organismId IN (SELECT ol.organismId FROM OrganismLocale ol WHERE ol.localName IN(:localNames) AND ol.organismLocalePK.locale = :locale)"),
@NamedQuery(name = "Organism.findByTradeName", query = "SELECT o FROM Organism o WHERE o.tradeName = :tradeName"), @NamedQuery(name = "Organism.findByTradeName", query = "SELECT o FROM Organism o WHERE o.tradeName = :tradeName"),
@NamedQuery(name = "Organism.findByLogicallyDeleted", query = "SELECT o FROM Organism o WHERE o.logicallyDeleted = :logicallyDeleted")}) @NamedQuery(name = "Organism.findByLogicallyDeleted", query = "SELECT o FROM Organism o WHERE o.logicallyDeleted = :logicallyDeleted")})
public class Organism implements Serializable { public class Organism implements Serializable {
......
...@@ -30,7 +30,7 @@ import javax.validation.constraints.Size; ...@@ -30,7 +30,7 @@ import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
/** /**
* @copyright 2013-2014 <a href="http://www.nibio.no/">NIBIO</a> * @copyright 2013-2020 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no> * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/ */
@Entity @Entity
...@@ -40,7 +40,8 @@ import javax.xml.bind.annotation.XmlRootElement; ...@@ -40,7 +40,8 @@ import javax.xml.bind.annotation.XmlRootElement;
@NamedQuery(name = "OrganismLocale.findAll", query = "SELECT o FROM OrganismLocale o"), @NamedQuery(name = "OrganismLocale.findAll", query = "SELECT o FROM OrganismLocale o"),
@NamedQuery(name = "OrganismLocale.findByOrganismId", query = "SELECT o FROM OrganismLocale o WHERE o.organismLocalePK.organismId = :organismId"), @NamedQuery(name = "OrganismLocale.findByOrganismId", query = "SELECT o FROM OrganismLocale o WHERE o.organismLocalePK.organismId = :organismId"),
@NamedQuery(name = "OrganismLocale.findByLocale", query = "SELECT o FROM OrganismLocale o WHERE o.organismLocalePK.locale = :locale"), @NamedQuery(name = "OrganismLocale.findByLocale", query = "SELECT o FROM OrganismLocale o WHERE o.organismLocalePK.locale = :locale"),
@NamedQuery(name = "OrganismLocale.findByLocalName", query = "SELECT o FROM OrganismLocale o WHERE o.localName = :localName")}) @NamedQuery(name = "OrganismLocale.findByLocalName", query = "SELECT o FROM OrganismLocale o WHERE o.localName = :localName")//,
})
public class OrganismLocale implements Serializable { public class OrganismLocale implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@EmbeddedId @EmbeddedId
......
/*
* Copyright (c) 2020 NIBIO <http://www.nibio.no/>.
*
* This file is part of VIPSLogic.
* VIPSLogic 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.
*
* VIPSLogic 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 VIPSLogic. If not, see <http://www.nibio.no/licenses/>.
*
*/
package no.nibio.vips.logic.modules.wheatleafblotch;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
/**
* @copyright 2020 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/
@Entity
@Table(name = "growth_stage_location_date", schema = "wheatleafb")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "GrowthStageLocationDate.findAll", query = "SELECT g FROM GrowthStageLocationDate g"),
@NamedQuery(name = "GrowthStageLocationDate.findByPointOfInterestId", query = "SELECT g FROM GrowthStageLocationDate g WHERE g.growthStageLocationDatePK.pointOfInterestId = :pointOfInterestId"),
@NamedQuery(name = "GrowthStageLocationDate.findByCropOrganismId", query = "SELECT g FROM GrowthStageLocationDate g WHERE g.growthStageLocationDatePK.cropOrganismId = :cropOrganismId"),
@NamedQuery(name = "GrowthStageLocationDate.findByCropOrganismIdAndPointOfInterestId", query = "SELECT g FROM GrowthStageLocationDate g WHERE g.growthStageLocationDatePK.cropOrganismId = :cropOrganismId AND g.growthStageLocationDatePK.pointOfInterestId = :pointOfInterestId")
})
public class GrowthStageLocationDate implements Serializable, Comparable {
private static final long serialVersionUID = 1L;
@EmbeddedId
private GrowthStageLocationDatePK growthStageLocationDatePK;
@Column(name = "day_number")
private Integer dayNumber;
public GrowthStageLocationDate() {
}
public GrowthStageLocationDate(GrowthStageLocationDatePK growthStateLocationPK) {
this.growthStageLocationDatePK = growthStateLocationPK;
}
@Override
public int hashCode() {
int hash = 0;
hash += (getGrowthStageLocationDatePK() != null ? getGrowthStageLocationDatePK().hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof GrowthStageLocationDate)) {
return false;
}
GrowthStageLocationDate other = (GrowthStageLocationDate) object;
if ((this.getGrowthStageLocationDatePK() == null && other.getGrowthStageLocationDatePK() != null) || (this.getGrowthStageLocationDatePK() != null && !this.growthStageLocationDatePK.equals(other.growthStageLocationDatePK))) {
return false;
}
return true;
}
@Override
public String toString() {
return "no.nibio.vips.logic.modules.wheatleafblotch.GrowthStageLocationDate[ growthStageLocationDatePK=" + getGrowthStageLocationDatePK() + " ]";
}
/**
* @return the dayNumber
*/
public Integer getDayNumber() {
return dayNumber;
}
/**
* @param dayNumber the dayNumber to set
*/
public void setDayNumber(Integer dayNumber) {
this.dayNumber = dayNumber;
}
@Override
public int compareTo(Object t) {
return this.getGrowthStageLocationDatePK().getGrowthStage().compareTo(((GrowthStageLocationDate) t).getGrowthStageLocationDatePK().getGrowthStage()
);
}
/**
* @return the growthStageLocationDatePK
*/
public GrowthStageLocationDatePK getGrowthStageLocationDatePK() {
return growthStageLocationDatePK;
}
/**
* @param growthStageLocationDatePK the growthStageLocationDatePK to set
*/
public void setGrowthStageLocationDatePK(GrowthStageLocationDatePK growthStageLocationDatePK) {
this.growthStageLocationDatePK = growthStageLocationDatePK;
}
}
/*
* Copyright (c) 2020 NIBIO <http://www.nibio.no/>.
*
* This file is part of VIPSLogic.
* VIPSLogic 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.
*
* VIPSLogic 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 VIPSLogic. If not, see <http://www.nibio.no/licenses/>.
*
*/
package no.nibio.vips.logic.modules.wheatleafblotch;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.validation.constraints.NotNull;
import no.nibio.vips.logic.entity.Organism;
import no.nibio.vips.logic.entity.PointOfInterest;
/**
* @copyright 2020 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/
@Embeddable
public class GrowthStageLocationDatePK implements Serializable {
@Basic(optional = false)
@NotNull
@JoinColumn(name = "crop_organism_id", referencedColumnName = "organism_id")
@ManyToOne
private Organism cropOrganismId;
@Basic(optional = false)
@NotNull
@JoinColumn(name = "point_of_interest_id", referencedColumnName = "point_of_interest_id")
@ManyToOne
private PointOfInterest pointOfInterestId;
@Column(name = "growth_stage")
private Integer growthStage;
public GrowthStageLocationDatePK() {
}
public GrowthStageLocationDatePK(Organism organism, PointOfInterest pointOfInterestId) {
this.cropOrganismId = organism;
this.pointOfInterestId = pointOfInterestId;
}
public Organism getCropOrganismId() {
return cropOrganismId;
}
public void setCropOrganismId(Organism cropOrganismId) {
this.cropOrganismId = cropOrganismId;
}
public PointOfInterest getPointOfInterestId() {
return pointOfInterestId;
}
public void setPointOfInterestId(PointOfInterest pointOfInterestId) {
this.pointOfInterestId = pointOfInterestId;
}
public Integer getGrowthStage() {
return growthStage;
}
public void setGrowthStage(Integer growthStage) {
this.growthStage = growthStage;
}
@Override
public int hashCode() {
int hash = 0;
hash += (int) cropOrganismId.getOrganismId();
hash += (int) pointOfInterestId.getPointOfInterestId();
hash += (int) growthStage;
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof GrowthStageLocationDatePK)) {
return false;
}
GrowthStageLocationDatePK other = (GrowthStageLocationDatePK) object;
if (this.cropOrganismId != other.cropOrganismId) {
return false;
}
if (this.pointOfInterestId != other.pointOfInterestId) {
return false;
}
if(! this.growthStage.equals(other.growthStage)){
return false;
}
return true;
}
@Override
public String toString() {
return "no.nibio.vips.logic.modules.wheatleafblotch.YieldLossPK[ organism=" + cropOrganismId + ", pointOfInterestId=" + pointOfInterestId + " ]";
}
}
...@@ -143,6 +143,46 @@ public class WheatLeafBlotchModelService { ...@@ -143,6 +143,46 @@ public class WheatLeafBlotchModelService {
} }
} }
/**
* Returns the yield loss from Septoria in wheat(?)
* @param organizationId
* @param season
* @return
*/
@GET
@Path("yieldloss/septoria/{organizationId}/{season}")
@Produces("application/json;charset=UTF-8")
public Response getYieldLoss(
@PathParam("organizationId") Integer organizationId,
@PathParam("season") Integer season
)
{
List<YieldLoss> retVal;
if(organizationId <= 0)
{
retVal = em.createNamedQuery("YieldLoss.findBySeason")
.setParameter("season", season)
.getResultList();
}
else
{
retVal = em.createNativeQuery("SELECT * FROM wheatleafb.yield_loss \n" +
"WHERE season = :season\n" +
"AND point_of_interest_id IN (\n" +
" SELECT point_of_interest_id FROM point_of_interest\n" +
" WHERE user_id IN (SELECT user_id FROM vips_logic_user WHERE organization_id = :organizationId" +
" )\n" +
")"
,
YieldLoss.class
)
.setParameter("organizationId", organizationId)
.setParameter("season", season)
.getResultList();
}
return Response.ok().entity(retVal).build();
}
@GET @GET
@Path("runmodel/{organizationId}") @Path("runmodel/{organizationId}")
@Produces("application/json;charset=UTF-8") @Produces("application/json;charset=UTF-8")
......
/*
* Copyright (c) 2019 NIBIO <http://www.nibio.no/>.
*
* This file is part of VIPSLogic.
* VIPSLogic 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.
*
* VIPSLogic 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 VIPSLogic. If not, see <http://www.nibio.no/licenses/>.
*
*/
package no.nibio.vips.logic.modules.wheatleafblotch;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;
import no.nibio.vips.logic.entity.PointOfInterest;
/**
* @copyright 2019 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/
@Entity
@Table(name = "yield_loss", schema = "wheatleafb")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "YieldLoss.findAll", query = "SELECT y FROM YieldLoss y"),
@NamedQuery(name = "YieldLoss.findBySeason", query = "SELECT y FROM YieldLoss y WHERE y.yieldLossPK.season = :season"),
@NamedQuery(name = "YieldLoss.findByPointOfInterestId", query = "SELECT y FROM YieldLoss y WHERE y.yieldLossPK.pointOfInterestId = :pointOfInterestId"),
@NamedQuery(name = "YieldLoss.findByYieldLoss", query = "SELECT y FROM YieldLoss y WHERE y.yieldLoss = :yieldLoss")
})
public class YieldLoss implements Serializable {
private static final long serialVersionUID = 1L;
@EmbeddedId
protected YieldLossPK yieldLossPK;
@Column(name = "yield_loss")
private Double yieldLoss;
public YieldLoss() {
}
public YieldLoss(YieldLossPK yieldLossPK) {
this.yieldLossPK = yieldLossPK;
}
public YieldLoss(int season, PointOfInterest pointOfInterestId) {
this.yieldLossPK = new YieldLossPK(season, pointOfInterestId);
}
public YieldLossPK getYieldLossPK() {
return yieldLossPK;
}
public void setYieldLossPK(YieldLossPK yieldLossPK) {
this.yieldLossPK = yieldLossPK;
}
public Double getYieldLoss() {
return yieldLoss;
}
public void setYieldLoss(Double yieldLoss) {
this.yieldLoss = yieldLoss;
}
@Override
public int hashCode() {
int hash = 0;
hash += (yieldLossPK != null ? yieldLossPK.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof YieldLoss)) {
return false;
}
YieldLoss other = (YieldLoss) object;
if ((this.yieldLossPK == null && other.yieldLossPK != null) || (this.yieldLossPK != null && !this.yieldLossPK.equals(other.yieldLossPK))) {
return false;
}
return true;
}
@Override
public String toString() {
return "no.nibio.vips.logic.modules.wheatleafblotch.YieldLoss[ yieldLossPK=" + yieldLossPK + " ]";
}
}
/*
* Copyright (c) 2019 NIBIO <http://www.nibio.no/>.
*
* This file is part of VIPSLogic.
* VIPSLogic 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.
*
* VIPSLogic 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 VIPSLogic. If not, see <http://www.nibio.no/licenses/>.
*
*/
package no.nibio.vips.logic.modules.wheatleafblotch;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.validation.constraints.NotNull;
import no.nibio.vips.logic.entity.PointOfInterest;
/**
* @copyright 2019 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/
@Embeddable
public class YieldLossPK implements Serializable {
@Basic(optional = false)
@NotNull
@Column(name = "season")
private int season;
@Basic(optional = false)
@NotNull
@JoinColumn(name = "point_of_interest_id", referencedColumnName = "point_of_interest_id")
@ManyToOne
private PointOfInterest pointOfInterestId;
public YieldLossPK() {
}
public YieldLossPK(int season, PointOfInterest pointOfInterestId) {
this.season = season;
this.pointOfInterestId = pointOfInterestId;
}
public int getSeason() {
return season;
}
public void setSeason(int season) {
this.season = season;
}
public PointOfInterest getPointOfInterestId() {
return pointOfInterestId;
}
public void setPointOfInterestId(PointOfInterest pointOfInterestId) {
this.pointOfInterestId = pointOfInterestId;
}
@Override
public int hashCode() {
int hash = 0;
hash += (int) season;
hash += (int) pointOfInterestId.getPointOfInterestId();
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof YieldLossPK)) {
return false;
}
YieldLossPK other = (YieldLossPK) object;
if (this.season != other.season) {
return false;
}
if (this.pointOfInterestId != other.pointOfInterestId) {
return false;
}
return true;
}
@Override
public String toString() {
return "no.nibio.vips.logic.modules.wheatleafblotch.YieldLossPK[ season=" + season + ", pointOfInterestId=" + pointOfInterestId + " ]";
}
}
...@@ -26,6 +26,7 @@ import java.util.Map; ...@@ -26,6 +26,7 @@ import java.util.Map;
import no.nibio.vips.logic.scheduling.tasks.DeleteAllExpiredUserUuidsTask; import no.nibio.vips.logic.scheduling.tasks.DeleteAllExpiredUserUuidsTask;
import no.nibio.vips.logic.scheduling.tasks.RunAllForecastConfigurationsForOrganizationTask; import no.nibio.vips.logic.scheduling.tasks.RunAllForecastConfigurationsForOrganizationTask;
import no.nibio.vips.logic.scheduling.tasks.RunAllForecastConfigurationsTask; import no.nibio.vips.logic.scheduling.tasks.RunAllForecastConfigurationsTask;
import no.nibio.vips.logic.scheduling.tasks.RunForecastConfigurationsByIdTask;
import no.nibio.vips.logic.scheduling.tasks.RunGridModelsTask; import no.nibio.vips.logic.scheduling.tasks.RunGridModelsTask;
import no.nibio.vips.logic.scheduling.tasks.SendForecastEventNotificationsTask; import no.nibio.vips.logic.scheduling.tasks.SendForecastEventNotificationsTask;
import no.nibio.vips.logic.scheduling.tasks.UpdateForecastResultCacheTableTask; import no.nibio.vips.logic.scheduling.tasks.UpdateForecastResultCacheTableTask;
...@@ -47,8 +48,9 @@ public class VipsLogicTaskFactory { ...@@ -47,8 +48,9 @@ public class VipsLogicTaskFactory {
public static final int SEND_FORECAST_EVENT_NOTIFICATIONS_TASK = 6; public static final int SEND_FORECAST_EVENT_NOTIFICATIONS_TASK = 6;
public static final int RUN_ALL_FORECAST_CONFIGURATIONS_FOR_ORGANIZATION_TASK = 7; public static final int RUN_ALL_FORECAST_CONFIGURATIONS_FOR_ORGANIZATION_TASK = 7;
public static final int RUN_GRID_MODELS_TASK = 8; public static final int RUN_GRID_MODELS_TASK = 8;
public static final int RUN_FORECAST_CONFIGURATIONS_BY_ID_TASK = 9;
private final static int[] ALL_TASK_IDS = {1,2,3,4,5,6,7,8}; private final static int[] ALL_TASK_IDS = {1,2,3,4,5,6,7,8,9};
private final static int[] ORGANIZATION_ADMIN_TASK_IDS = {7}; private final static int[] ORGANIZATION_ADMIN_TASK_IDS = {7};
...@@ -90,6 +92,9 @@ public class VipsLogicTaskFactory { ...@@ -90,6 +92,9 @@ public class VipsLogicTaskFactory {
case RUN_GRID_MODELS_TASK: case RUN_GRID_MODELS_TASK:
retVal = new RunGridModelsTask(); retVal = new RunGridModelsTask();
break; break;
case RUN_FORECAST_CONFIGURATIONS_BY_ID_TASK:
retVal = new RunForecastConfigurationsByIdTask();
break;
default: default:
return null; return null;
} }
......
/*
* Copyright (c) 2019 NIBIO <http://www.nibio.no/>.
*
* This file is part of VIPSLogic.
* VIPSLogic 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.
*
* VIPSLogic 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 VIPSLogic. If not, see <http://www.nibio.no/licenses/>.
*
*/
package no.nibio.vips.logic.scheduling.model.preprocessor;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import no.nibio.vips.entity.ModelConfiguration;
import no.nibio.vips.entity.WeatherObservation;
import no.nibio.vips.logic.entity.ForecastConfiguration;
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.util.WeatherElements;
import no.nibio.vips.util.weather.WeatherDataSourceException;
import no.nibio.vips.util.weather.WeatherDataSourceUtil;
/**
* @copyright 2016 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/
public class RainyDaysModelPreprocessor extends ModelRunPreprocessor {
@Override
public ModelConfiguration getModelConfiguration(ForecastConfiguration configuration) throws PreprocessorException {
PointOfInterestWeatherStation weatherStation = (PointOfInterestWeatherStation) configuration.getWeatherStationPointOfInterestId();
// What timezone is the calculation for
TimeZone timeZone = TimeZone.getTimeZone(weatherStation.getTimeZone());
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date seasonStart = configuration.getDateStartInTimeZone();
Date seasonEnd = configuration.getDateEndInTimeZone();
try
{
if(configuration.getForecastModelConfigurationValue(this.getModelId() + "_SEASON_START") != null)
{
seasonStart = format.parse(configuration.getForecastModelConfigurationValue(this.getModelId() + "_SEASON_START"));
}
if(configuration.getForecastModelConfigurationValue(this.getModelId() + "_SEASON_END") != null)
{
seasonEnd = format.parse(configuration.getForecastModelConfigurationValue(this.getModelId() + "_SEASON_END"));
}
}
catch(ParseException ex)
{
// Keep calm and carry on?
}
ModelConfiguration retVal = new ModelConfiguration();
WeatherDataSourceUtil wdsUtil = new WeatherDataSourceUtil();
List<WeatherObservation> observations;
try {
observations = wdsUtil.getWeatherObservations(
weatherStation,
WeatherObservation.LOG_INTERVAL_ID_1D,
new String[]{
WeatherElements.PRECIPITATION
},
seasonStart,
seasonEnd);
} catch (WeatherDataSourceException ex) {
throw new PreprocessorException(ex.getMessage());
}
// If daily observations are not available, try hourly
if(observations == null || observations.isEmpty())
{
//System.out.println("No daily obs from " + weatherStation.getName() +", trying hourly");
try {
observations = wdsUtil.getWeatherObservations(
weatherStation,
WeatherObservation.LOG_INTERVAL_ID_1H,
new String[]{
WeatherElements.PRECIPITATION
},
seasonStart,
seasonEnd
);
//System.out.println("Got hourly obs from " + weatherStation.getName() +", a total of " + observations.size() + " items.");
} catch (WeatherDataSourceException ex) {
throw new PreprocessorException(ex.getMessage());
}
}
// TODO: weather data validation
retVal.setModelId(this.getModelId());
retVal.setConfigParameter("timeZone", timeZone.getID());
retVal.setConfigParameter("observations", observations);
return retVal;
}
@Override
public String getModelId() {
return "RAINYDAYSM";
}
}
...@@ -19,14 +19,20 @@ ...@@ -19,14 +19,20 @@
package no.nibio.vips.logic.scheduling.model.preprocessor; package no.nibio.vips.logic.scheduling.model.preprocessor;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.TimeZone;
import no.nibio.vips.entity.ModelConfiguration; import no.nibio.vips.entity.ModelConfiguration;
import no.nibio.vips.entity.WeatherObservation; import no.nibio.vips.entity.WeatherObservation;
import no.nibio.vips.logic.controller.session.ForecastBean;
import no.nibio.vips.logic.entity.ForecastConfiguration; import no.nibio.vips.logic.entity.ForecastConfiguration;
import no.nibio.vips.logic.entity.PointOfInterestWeatherStation; import no.nibio.vips.logic.entity.PointOfInterestWeatherStation;
import no.nibio.vips.logic.scheduling.model.ModelRunPreprocessor; import no.nibio.vips.logic.scheduling.model.ModelRunPreprocessor;
import no.nibio.vips.logic.scheduling.model.PreprocessorException; import no.nibio.vips.logic.scheduling.model.PreprocessorException;
import no.nibio.vips.logic.util.SessionControllerGetter;
import no.nibio.vips.util.WeatherElements; import no.nibio.vips.util.WeatherElements;
import no.nibio.vips.util.weather.WeatherDataSourceException; import no.nibio.vips.util.weather.WeatherDataSourceException;
import no.nibio.vips.util.weather.WeatherDataSourceUtil; import no.nibio.vips.util.weather.WeatherDataSourceUtil;
...@@ -40,12 +46,24 @@ public class SeptoriaHumidityModelPreprocessor extends ModelRunPreprocessor{ ...@@ -40,12 +46,24 @@ public class SeptoriaHumidityModelPreprocessor extends ModelRunPreprocessor{
@Override @Override
public ModelConfiguration getModelConfiguration(ForecastConfiguration configuration) throws PreprocessorException public ModelConfiguration getModelConfiguration(ForecastConfiguration configuration) throws PreprocessorException
{ {
ForecastBean forecastBean = SessionControllerGetter.getForecastBean();
ModelConfiguration retVal = new ModelConfiguration(); ModelConfiguration retVal = new ModelConfiguration();
retVal.setModelId(this.getModelId()); retVal.setModelId(this.getModelId());
retVal.setConfigParameter("timeZone", configuration.getTimeZone()); retVal.setConfigParameter("timeZone", configuration.getTimeZone());
String[] modelConfigurationValueNames = {"dateSpraying1","dateSpraying2","dateGs31","date3rdUpperLeafEmerging",
"date2ndUpperLeafEmerging","dateUpperLeafEmerging","dateGs75","thresholdRelativeHumidity","thresholdLeafWetness",
"thresholdPrecipitation","slidingHoursPast","slidingHoursAhead","thresholdHumidPeriodHours","sprayingProtectionDays",
"leafLifeTime"};
for(String modelConfigurationValueName: modelConfigurationValueNames)
{
retVal.setConfigParameter(modelConfigurationValueName, configuration.getForecastModelConfigurationValue(forecastBean.getDeCamelizedFieldName(this.getModelId(),modelConfigurationValueName)));
}
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
format.setTimeZone(TimeZone.getTimeZone(configuration.getTimeZone()));
WeatherDataSourceUtil wdsUtil = new WeatherDataSourceUtil(); WeatherDataSourceUtil wdsUtil = new WeatherDataSourceUtil();
try try
{ {
Date gs31 = format.parse((String)retVal.getConfigParameter("dateGs31"));
List<WeatherObservation> observations = wdsUtil.getWeatherObservations( List<WeatherObservation> observations = wdsUtil.getWeatherObservations(
(PointOfInterestWeatherStation) configuration.getWeatherStationPointOfInterestId(), (PointOfInterestWeatherStation) configuration.getWeatherStationPointOfInterestId(),
WeatherObservation.LOG_INTERVAL_ID_1H, WeatherObservation.LOG_INTERVAL_ID_1H,
...@@ -55,13 +73,13 @@ public class SeptoriaHumidityModelPreprocessor extends ModelRunPreprocessor{ ...@@ -55,13 +73,13 @@ public class SeptoriaHumidityModelPreprocessor extends ModelRunPreprocessor{
WeatherElements.RELATIVE_HUMIDITY_MEAN, WeatherElements.RELATIVE_HUMIDITY_MEAN,
WeatherElements.LEAF_WETNESS_DURATION WeatherElements.LEAF_WETNESS_DURATION
}, },
configuration.getDateStart(), gs31,
configuration.getDateEnd() configuration.getDateEnd()
); );
Collections.sort(observations); Collections.sort(observations);
retVal.setConfigParameter("observations", observations); retVal.setConfigParameter("observations", observations);
} }
catch(WeatherDataSourceException ex) catch(WeatherDataSourceException | ParseException ex)
{ {
throw new PreprocessorException(ex.getMessage()); throw new PreprocessorException(ex.getMessage());
} }
......
/*
* Copyright (c) 2019 NIBIO <http://www.nibio.no/>.
*
* This file is part of VIPSLogic.
* VIPSLogic 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.
*
* VIPSLogic 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 VIPSLogic. If not, see <http://www.nibio.no/licenses/>.
*
*/
package no.nibio.vips.logic.scheduling.model.preprocessor;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import no.nibio.vips.entity.ModelConfiguration;
import no.nibio.vips.entity.WeatherObservation;
import no.nibio.vips.logic.entity.ForecastConfiguration;
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.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;
/**
* @copyright 2018 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/
public class SeptoriaReferenceHumidityModelPreprocessor extends ModelRunPreprocessor{
@Override
public ModelConfiguration getModelConfiguration(ForecastConfiguration configuration) throws PreprocessorException {
ModelConfiguration modelConfig = new ModelConfiguration();
// Which weather stations??
// Ilseng and Apelsvoll to start with ;-)
PointOfInterestWeatherStation station = (PointOfInterestWeatherStation) configuration.getWeatherStationPointOfInterestId();
//List<WeatherObservation> stationObs = getStationObs(station, configuration);
WeatherUtil wUtil = new WeatherUtil();
WeatherDataSourceUtil wdsUtil = new WeatherDataSourceUtil();
List<WeatherObservation> stationObs;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date seasonStart = configuration.getDateStartInTimeZone();
Date seasonEnd = configuration.getDateEndInTimeZone();
try
{
if(configuration.getForecastModelConfigurationValue(this.getModelId() + "_SEASON_START") != null)
{
seasonStart = format.parse(configuration.getForecastModelConfigurationValue(this.getModelId() + "_SEASON_START"));
}
if(configuration.getForecastModelConfigurationValue(this.getModelId() + "_SEASON_END") != null)
{
seasonEnd = format.parse(configuration.getForecastModelConfigurationValue(this.getModelId() + "_SEASON_END"));
}
}
catch(ParseException ex)
{
// Keep calm and carry on?
}
try
{
stationObs = wdsUtil.getWeatherObservations(
station,
WeatherObservation.LOG_INTERVAL_ID_1H,
new String[]{
WeatherElements.LEAF_WETNESS_DURATION,
WeatherElements.RELATIVE_HUMIDITY_MEAN,
WeatherElements.PRECIPITATION,
WeatherElements.TEMPERATURE_MEAN
},
seasonStart,
seasonEnd);
// We need TM, UM and RR. BT is optional
//List<WeatherObservation> mandatory = wUtil.filterWeatherObservationsByParameter(stationObs, new HashSet<>(Arrays.asList("TM","UM","RR")));
//stationObs = wUtil.checkForAndFixHourlyTimeSeriesHolesMultiParameter(mandatory, 6);
stationObs = wUtil.filterWeatherObservationsByParameter(stationObs, new HashSet<>(Arrays.asList("TM","UM","RR")));
}
catch(WeatherDataSourceException ex)
{
throw new PreprocessorException("Problem with station " + station.getPointOfInterest().getName() + " (#" + station.getPointOfInterestId() + "): " + ex.getMessage());
}
// Checking for BT
//try
//{
List<WeatherObservation> BT = wUtil.filterWeatherObservationsByParameter(stationObs, new HashSet<>(Arrays.asList("BT")));
//stationObs.addAll(wUtil.checkForAndFixHourlyTimeSeriesHoles(BT, 6));
stationObs.addAll(BT);
//}
//catch(WeatherObservationListException ex)
//{
// System.out.println("Problem with station " + station.getPointOfInterest().getName() + " (#" + station.getPointOfInterestId() + "): " + ex.getMessage());
//}
modelConfig.setConfigParameter("observations", stationObs);
modelConfig.setModelId(this.getModelId());
modelConfig.setConfigParameter("timeZone", configuration.getTimeZone());
return modelConfig;
}
@Override
public String getModelId() {
return "SEPTREFHUM";
}
}
/*
* Copyright (c) 2019 NIBIO <http://www.nibio.no/>.
*
* This file is part of VIPSLogic.
* VIPSLogic 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.
*
* VIPSLogic 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 VIPSLogic. If not, see <http://www.nibio.no/licenses/>.
*
*/
package no.nibio.vips.logic.scheduling.tasks;
import it.sauronsoftware.cron4j.TaskExecutionContext;
import java.util.Map;
import no.nibio.vips.i18n.I18nImpl;
import no.nibio.vips.logic.entity.ForecastConfiguration;
import no.nibio.vips.logic.entity.ModelInformation;
import no.nibio.vips.logic.scheduling.SchedulingUtil;
import no.nibio.vips.logic.scheduling.VipsLogicTask;
import no.nibio.vips.logic.scheduling.model.PreprocessorException;
import no.nibio.vips.logic.util.RunModelException;
import no.nibio.vips.logic.util.SessionControllerGetter;
import no.nibio.web.forms.FormField;
/**
* @copyright 2013-2018 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/
public class RunForecastConfigurationsByIdTask extends VipsLogicTask{
private I18nImpl i18n;
//private boolean DEBUG=true;
@Override
public void execute(TaskExecutionContext tec) throws RuntimeException {
String[] forecastConfigurationIds;
if(this.getConfiguration() != null && this.getConfiguration().get("forecastConfigurationIds") != null)
{
forecastConfigurationIds = ((String) (this.getConfiguration().get("forecastConfigurationIds")[0])).split(",");
}
else
{
tec.setCompleteness(1.0);
tec.setStatusMessage("No forecast configurations were specified");
return;
}
String errorMessage = "";
tec.setCompleteness(0d);
Integer numberOfAttemptedForecastConfigurations = 0;
Integer numberOfCompletedForecastConfigurations = 0;
Boolean noForecastConfigurationsFound = forecastConfigurationIds.length == 0;
Map<String, ModelInformation> modelInformationMap = SessionControllerGetter.getForecastBean().getIndexedBatchableModelInformation();
for(String forecastConfigurationId:forecastConfigurationIds)
{
noForecastConfigurationsFound = false;
ForecastConfiguration forecastConfiguration = SessionControllerGetter.getForecastBean().getForecastConfiguration(Long.valueOf(forecastConfigurationId));
try
{
numberOfAttemptedForecastConfigurations++;
//System.out.println("Running forecast #" + forecastConfiguration.getForecastConfigurationId());
SessionControllerGetter.getForecastBean().runForecast(forecastConfiguration);
/*
if(DEBUG && totalNumberofForecastConfigurations == 2)
{
throw new RunModelException("This is a test!!!");
}*/
numberOfCompletedForecastConfigurations++;
//System.out.println("All went well");
}
catch (PreprocessorException | RunModelException ex)
{
errorMessage +=
SchedulingUtil.createSchedulingMessageHTML(
"Error with forecast #" + forecastConfiguration.getForecastConfigurationId() + " (" + forecastConfiguration.getLocationPointOfInterestId().getName() + " - " + modelInformationMap.get(forecastConfiguration.getModelId()).getDefaultName() + ")",
ex.getMessage(),
SchedulingUtil.MESSAGE_STATUS_DANGER)
;
//System.out.println("########################### Error caught: " + errorMessage);
//System.out.println("numberOfCompletedForecastConfigurations=" + numberOfCompletedForecastConfigurations);
//System.out.println("totalNumberofForecastConfigurations=" + totalNumberofForecastConfigurations);
//continue;
}
double completeness = (double) numberOfCompletedForecastConfigurations/forecastConfigurationIds.length;
tec.setCompleteness(completeness);
}
if(noForecastConfigurationsFound)
{
tec.setCompleteness(1.0);
tec.setStatusMessage("No current forecast configurations were found");
}
//System.out.println("Total completeness=" + tec.getTaskExecutor().getCompleteness());
if(tec.getTaskExecutor().getCompleteness() != 1.0)
{
//System.out.println("Error detected, RuntimeException thrown just after this");
tec.setStatusMessage(errorMessage);
throw new RuntimeException();
}
}
@Override
public boolean supportsStatusTracking()
{
return true;
}
@Override
public boolean supportsCompletenessTracking()
{
return true;
}
/**
*
* @return Form definition
*/
@Override
public String getConfigFormDefinition(String language) {
StringBuilder retVal = new StringBuilder()
.append("{")
.append(" \"fields\":[")
.append(" {")
.append(" \"name\":\"forecastConfigurationIds\",")
.append(" \"dataType\":\"").append(FormField.DATA_TYPE_STRING).append("\",")
.append(" \"fieldType\":\"").append(FormField.FIELD_TYPE_INPUT).append("\",")
.append(" \"nullValue\":\"\",")
.append(" \"required\":true")
.append(" }")
.append(" ]")
.append("}");
return retVal.toString();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment