changeset 9522:23d97d60b889

Selection range of D50 values for tkh calculation can now be configured with a river specific table.
author gernotbelger
date Mon, 01 Oct 2018 16:37:12 +0200
parents ce54388d6efe
children d421c2bf0195
files artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/BedQualityD50KmValueFinder.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/BedQualityD50TimeRangeConfig.java
diffstat 3 files changed, 66 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/BedQualityD50KmValueFinder.java	Mon Oct 01 16:35:03 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/BedQualityD50KmValueFinder.java	Mon Oct 01 16:37:12 2018 +0200
@@ -10,7 +10,7 @@
 
 package org.dive4elements.river.artifacts.sinfo.tkhcalculation;
 
-import java.util.Calendar;
+import java.io.IOException;
 import java.util.Date;
 import java.util.List;
 
@@ -21,6 +21,10 @@
 import org.apache.log4j.Logger;
 import org.dive4elements.river.artifacts.math.Utils;
 import org.dive4elements.river.artifacts.model.Calculation;
+import org.dive4elements.river.artifacts.model.DateRange;
+import org.dive4elements.river.artifacts.sinfo.tkhstate.BedQualityD50TimeRangeConfig;
+import org.dive4elements.river.artifacts.sinfo.tkhstate.BedQualityD50TimeRangeConfig.BedQualityParseException;
+import org.dive4elements.river.artifacts.sinfo.tkhstate.TsvHelper.TsvReaderException;
 import org.dive4elements.river.backend.SedDBSessionHolder;
 import org.dive4elements.river.model.River;
 import org.hibernate.SQLQuery;
@@ -57,20 +61,19 @@
      * query.
      */
     private static final String SQL_BED_D50_SUBLAYER_MEASUREMENT = //
-            "SELECT s.km, t.datum, p.tiefevon, p.tiefebis, a.d50"
-            + " FROM sohltest t INNER JOIN station s ON t.stationid = s.stationid"
-            + "    INNER JOIN gewaesser g ON s.gewaesserid = g.gewaesserid"
-            + "    INNER JOIN sohlprobe p ON t.sohltestid = p.sohltestid"
-            + "    INNER JOIN siebanalyse a ON p.sohlprobeid = a.sohlprobeid"
-            + " WHERE (g.name = :name)"
-            + "    AND (p.tiefevon > 0.0) AND (p.tiefebis <= 0.5)"
-            + "    AND (t.datum BETWEEN :fromdate AND :todate)"
+            "SELECT s.km, t.datum, p.tiefevon, p.tiefebis, a.d50" //
+                    + " FROM sohltest t INNER JOIN station s ON t.stationid = s.stationid" //
+                    + "    INNER JOIN gewaesser g ON s.gewaesserid = g.gewaesserid" //
+                    + "    INNER JOIN sohlprobe p ON t.sohltestid = p.sohltestid" //
+                    + "    INNER JOIN siebanalyse a ON p.sohlprobeid = a.sohlprobeid" //
+                    + " WHERE (g.name = :name)" //
+                    + "    AND (p.tiefevon > 0.0) AND (p.tiefebis <= 0.5)" //
+                    + "    AND (t.datum BETWEEN :fromdate AND :todate)" //
             + " ORDER BY s.km ASC, a.d50 ASC";
 
-    // + " WHERE (g.name = :name) AND (s.km BETWEEN :fromkm - 0.0001 AND :tokm + 0.0001)"
-    // + " AND (p.tiefevon > 0.0) AND (p.tiefebis <= 0.5)"
-    // + " AND (t.datum BETWEEN :fromdate AND :todate)"
-    // + " ORDER BY s.km ASC, a.d50 ASC";
+    public static final Date MIN_DATE = new Date(-10000000000000l); // Database does not cope with Long.MIN/Long.Max, so we go just a few hundred years
+    // back/forward
+    public static final Date MAX_DATE = new Date(10000000000000l);
 
     private Calculation problems;
 
@@ -94,19 +97,23 @@
      * Abhängig von Peiljahr
      *
      * @param problems
+     * @throws BedQualityParseException
+     * @throws TsvReaderException
+     * @throws IOException
      */
     public static BedQualityD50KmValueFinder loadBedMeasurements(final Calculation problems, final River river, final DoubleRange kmRange,
-            final int soundingYear, final int validYears) {
+            final int soundingYear) throws BedQualityParseException, IOException, TsvReaderException {
 
-        /* construct valid measurement time range */
-        final Calendar cal = Calendar.getInstance();
-        cal.clear();
+        final DateRange rangeFromConfigFile = BedQualityD50TimeRangeConfig.getDefaults(river, soundingYear, problems);
+        final DateRange dateRange = rangeFromConfigFile != null ? rangeFromConfigFile : new DateRange(MIN_DATE, MAX_DATE);
+        return loadBedMeasurements(problems, river, kmRange, dateRange, soundingYear);
+    }
 
-        cal.set(soundingYear - validYears, 0, 1);
-        final Date startTime = cal.getTime();
+    private static BedQualityD50KmValueFinder loadBedMeasurements(final Calculation problems, final River river, final DoubleRange kmRange,
+            final DateRange dateRange, final int soundingYear) {
 
-        cal.set(soundingYear + validYears, 11, 31);
-        final Date endTime = cal.getTime();
+        final Date startTime = dateRange.getFrom();
+        final Date endTime = dateRange.getTo();
 
         final String seddbRiver = river.nameForSeddb();
         log.debug(String.format("loadValues '%s' km %.3f - %.3f %tF - %tF", seddbRiver, kmRange.getMinimumDouble(), kmRange.getMaximumDouble(), startTime,
@@ -171,8 +178,8 @@
         try {
             return this.interpolator.value(km);
         }
-        catch (final ArgumentOutsideDomainException e) {
-            // No stack trace because this might happen a lot (intended) and we produce an error message anyways.            
+        catch (@SuppressWarnings("unused") final ArgumentOutsideDomainException e) {
+            // No stack trace because this might happen a lot (intended) and we produce an error message anyways.
             // e.printStackTrace();
 
             if (this.problems != null) {
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java	Mon Oct 01 16:35:03 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java	Mon Oct 01 16:37:12 2018 +0200
@@ -9,12 +9,16 @@
  */
 package org.dive4elements.river.artifacts.sinfo.tkhcalculation;
 
+import java.io.IOException;
+
 import org.apache.commons.lang.math.DoubleRange;
 import org.dive4elements.river.artifacts.common.GeneralResultType;
 import org.dive4elements.river.artifacts.common.ResultRow;
 import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
 import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder;
+import org.dive4elements.river.artifacts.sinfo.tkhstate.BedQualityD50TimeRangeConfig.BedQualityParseException;
+import org.dive4elements.river.artifacts.sinfo.tkhstate.TsvHelper.TsvReaderException;
 import org.dive4elements.river.model.River;
 
 /**
@@ -30,8 +34,6 @@
         SUCCESS, NO_W, NO_BED_HEIGHT, NO_DISCHARGE, NO_SOILKIND, NO_D50, NO_VELOCITY, NO_TKH
     }
 
-    private static final int VALID_BED_MEASUREMENT_YEARS = 20;
-
     private final BedQualityD50KmValueFinder bedMeasurementsFinder;
 
     private final SoilKindKmValueFinder soilKindFinder;
@@ -58,14 +60,7 @@
 
         /* access bed quality data */
         final int soundingYear = bedHeightsProvider.getInfo().getYear();
-        BedQualityD50KmValueFinder bedMeasurementsFinder = null;
-        // try {
-        bedMeasurementsFinder = BedQualityD50KmValueFinder.loadBedMeasurements(problems, river, calcRange, soundingYear, VALID_BED_MEASUREMENT_YEARS);
-        // }
-        // catch (final BedQualityParseException | IOException | TsvReaderException e) {
-        // e.printStackTrace();
-        // }
-
+        final BedQualityD50KmValueFinder bedMeasurementsFinder = loadBedMeasurementsFinder(problems, river, calcRange, soundingYear);
         if (bedMeasurementsFinder == null)
             return new TkhCalculator(null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null);
 
@@ -82,6 +77,18 @@
         return new TkhCalculator(bedMeasurementsFinder, waterlevelProvider, dischargeProvider, bedHeightsProvider, soilKindFinder, flowVelocitiesFinder);
     }
 
+    private static BedQualityD50KmValueFinder loadBedMeasurementsFinder(final Calculation problems, final River river, final DoubleRange calcRange,
+            final int soundingYear) {
+
+        try {
+            return BedQualityD50KmValueFinder.loadBedMeasurements(problems, river, calcRange, soundingYear);
+        }
+        catch (final BedQualityParseException | IOException | TsvReaderException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
     private TkhCalculator(final BedQualityD50KmValueFinder bedMeasurementsFinder, final WaterlevelValuesFinder waterlevelProvider,
             final DischargeValuesFinder dischargeProvider, final BedHeightsFinder bedHeightsProvider, final SoilKindKmValueFinder soilKindFinder,
             final FlowVelocityModelKmValueFinder flowVelocitiesFinder) {
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/BedQualityD50TimeRangeConfig.java	Mon Oct 01 16:35:03 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/BedQualityD50TimeRangeConfig.java	Mon Oct 01 16:37:12 2018 +0200
@@ -19,6 +19,7 @@
 
 import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.model.DateRange;
+import org.dive4elements.river.artifacts.sinfo.tkhcalculation.BedQualityD50KmValueFinder;
 import org.dive4elements.river.artifacts.sinfo.tkhstate.TsvHelper.TsvReaderException;
 import org.dive4elements.river.model.River;
 
@@ -39,13 +40,17 @@
 
         private static final long serialVersionUID = 1L;
 
-        private BedQualityParseException(final String string) {
-            super(string);
+        BedQualityParseException(final String message) {
+            super(message);
+        }
+
+        BedQualityParseException(final String message, final Throwable cause) {
+            super(message, cause);
         }
     }
 
     public static synchronized DateRange getDefaults(final River river, final int soundingYear, final Calculation problems)
-            throws BedQualityParseException, IOException, TsvReaderException {
+            throws BedQualityParseException {
         return INSTANCE.getBedHeightDefaultsForRiver(river, soundingYear, problems);
     }
 
@@ -92,11 +97,11 @@
             return Integer.valueOf(value);
         }
         catch (final NumberFormatException e) {
-            throw new BedQualityParseException("Invalid input; should be year ('yyyy') or 'MIN' or 'MAX'");
+            throw new BedQualityParseException("Invalid input; should be year ('yyyy') or 'MIN' or 'MAX'", e);
         }
     }
 
-    private static class CalRange {
+    private static final class CalRange {
         private final long startTimeSounding;
         private final long endTimeSounding;
 
@@ -105,23 +110,20 @@
 
         private final static Calendar cal = Calendar.getInstance();
 
-        private Date getStartTimeQuery() {
+        public Date getStartTimeQuery() {
             return new Date(this.startTimeQuery);
         }
 
-        private Date getEndTimeQuery() {
+        public Date getEndTimeQuery() {
             return new Date(this.endTimeQuery);
         }
 
-        private CalRange(final Integer startYearSounding, final Integer endYearSounding, final Integer startYearQuery, final Integer endYearQuery) {
+        public CalRange(final Integer startYearSounding, final Integer endYearSounding, final Integer startYearQuery, final Integer endYearQuery) {
 
-            this.startTimeSounding = 1L;// (startYearSounding != null) ? getLongValForYear(startYearSounding, 0, 1) :
-                                        // BedQualityD50KmValueFinder.MIN_DATE.getTime();
-            this.startTimeQuery = 1L;// (startYearQuery != null) ? getLongValForYear(startYearQuery, 0, 1) : BedQualityD50KmValueFinder.MIN_DATE.getTime();
-            this.endTimeSounding = 1L;// (endYearSounding != null) ? getLongValForYear(endYearSounding, 11, 31) :
-                                      // BedQualityD50KmValueFinder.MAX_DATE.getTime();
-            this.endTimeQuery = 1L;// (endYearQuery != null) ? getLongValForYear(endYearQuery, 11, 31) : BedQualityD50KmValueFinder.MAX_DATE.getTime();
-
+            this.startTimeSounding = (startYearSounding != null) ? getLongValForYear(startYearSounding, 0, 1) : BedQualityD50KmValueFinder.MIN_DATE.getTime();
+            this.startTimeQuery = (startYearQuery != null) ? getLongValForYear(startYearQuery, 0, 1) : BedQualityD50KmValueFinder.MIN_DATE.getTime();
+            this.endTimeSounding = (endYearSounding != null) ? getLongValForYear(endYearSounding, 11, 31) : BedQualityD50KmValueFinder.MAX_DATE.getTime();
+            this.endTimeQuery = (endYearQuery != null) ? getLongValForYear(endYearQuery, 11, 31) : BedQualityD50KmValueFinder.MAX_DATE.getTime();
         }
 
         private long getLongValForYear(final int year, final int month0based, final int dayOfMonth) {
@@ -131,7 +133,7 @@
             return cal.getTimeInMillis();
         }
 
-        private boolean isSoundingYearInRange(final int soundingYear) {
+        public boolean isSoundingYearInRange(final int soundingYear) {
             cal.clear();
 
             cal.set(soundingYear, 5, 5); // random date in the middle of the year
@@ -143,7 +145,5 @@
 
             return false;
         }
-
     }
-
-}
+}
\ No newline at end of file

http://dive4elements.wald.intevation.org