changeset 9533:d9fda7af24ca

No discharge zone calculation and output for gauges unknown in flys for sinfo collision (Meilenstein 2, 2.2.1)
author mschaefer
date Thu, 04 Oct 2018 12:48:57 +0200 (2018-10-04)
parents 8e6b9cb9486a
children b380a5693514
files artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeDischargeValuesFinder.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeMainValueFinder.java artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesCrossSectionProcessor.java backend/src/main/java/org/dive4elements/river/model/River.java
diffstat 5 files changed, 89 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java	Tue Oct 02 18:19:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/collision/CollisionCalculation.java	Thu Oct 04 12:48:57 2018 +0200
@@ -24,7 +24,6 @@
 import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.model.CalculationResult;
 import org.dive4elements.river.artifacts.model.DateRange;
-import org.dive4elements.river.artifacts.model.river.RiverInfoProvider;
 import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
 import org.dive4elements.river.artifacts.sinfo.common.GaugeDischargeValuesFinder;
@@ -33,7 +32,6 @@
 import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
 import org.dive4elements.river.artifacts.sinfo.util.RiverInfo;
 import org.dive4elements.river.backend.utils.DateUtil;
-import org.dive4elements.river.model.Gauge;
 import org.dive4elements.river.model.MainValueType.MainValueTypeKey;
 import org.dive4elements.river.model.River;
 import org.dive4elements.river.model.sinfo.CollisionAggregateValue;
@@ -88,19 +86,12 @@
                 overViewRows);
         results.addResult(overviewResult, problems);
 
-        // create q-for-w-finders for all gauges of the calculation km range
-        final RiverInfoProvider infoProvider = RiverInfoProvider.forRange(this.context, river, calcRange);
-        final Map<Gauge, GaugeDischargeValuesFinder> qFinders = new HashMap<>();
-        final Map<Gauge, GaugeMainValueFinder> zoneFinders = new HashMap<>();
-        for (final Gauge gauge : river.determineGauges(calcRange.getMinimumDouble(), calcRange.getMaximumDouble())) {
-            qFinders.put(gauge, GaugeDischargeValuesFinder.loadValues(gauge, problems));
-            zoneFinders.put(gauge, GaugeMainValueFinder.loadValues(MainValueTypeKey.Q, gauge, problems));
-        }
+        // calculate secondary results for each year
+        final Map<String, GaugeDischargeValuesFinder> qFinders = new HashMap<>();
+        final Map<String, GaugeMainValueFinder> zoneFinders = new HashMap<>();
         final Collection<ResultRow> detailsRows = new ArrayList<>();
-
-        // calculate secondary results for each year
         for (final Integer year : detailYears)
-            calculateDetails(detailsRows, infoProvider, access.getLowerKm(), access.getUpperKm(), year, qFinders, zoneFinders);
+            calculateDetails(detailsRows, river, access.getLowerKm(), access.getUpperKm(), year, qFinders, zoneFinders, problems);
         final CollisionCalcDetailResult detailResult = new CollisionCalcDetailResult("Details", detailsRows);
         results.addResult(detailResult, problems);
 
@@ -145,17 +136,52 @@
     /**
      * Calculates the collision details for a km range of a river and a year, and adds them to a ResultRow collection
      */
-    private void calculateDetails(final Collection<ResultRow> rows, final RiverInfoProvider riverInfo, final double fromKm, final double toKm,
-            final int year, final Map<Gauge, GaugeDischargeValuesFinder> qFinders, final Map<Gauge, GaugeMainValueFinder> zoneFinders) {
-        for (final CollisionValue collision : CollisionValue.getValues(riverInfo.getRiver(), fromKm, toKm, DateUtil.getStartDateFromYear(year),
+    private void calculateDetails(final Collection<ResultRow> rows, final River river, final double fromKm, final double toKm,
+            final int year, final Map<String, GaugeDischargeValuesFinder> qFinders, final Map<String, GaugeMainValueFinder> zoneFinders,
+            final Calculation problems) {
+
+        for (final CollisionValue collision : CollisionValue.getValues(river, fromKm, toKm, DateUtil.getStartDateFromYear(year),
                 DateUtil.getEndDateFromYear(year))) {
-            final Gauge gauge = riverInfo.getGauge(collision.getStation(), true);
-            final double q = qFinders.get(gauge).getDischarge(collision.getGaugeW());
+            final String gaugeName = collision.getGaugeName();
+            final double q = getQ(qFinders, gaugeName, collision.getGaugeW().doubleValue(), river, problems);
             final double qOut = Double.isInfinite(q) ? Double.NaN : q;
+            final String zone = getZone(zoneFinders, gaugeName, q, river, problems);
             rows.add(ResultRow.create().putValue(GeneralResultType.station, collision.getStation())
-                    .putValue(GeneralResultType.dateShort, collision.getEventDate()).putValue(SInfoResultType.collisionGaugeW, collision.getGaugeW())
-                    .putValue(GeneralResultType.gaugeLabelCm, collision.getGaugeName()).putValue(SInfoResultType.dischargeLong, qOut)
-                    .putValue(SInfoResultType.dischargeZone, zoneFinders.get(gauge).findZoneName(q)));
+                    .putValue(GeneralResultType.dateShort, collision.getEventDate())
+                    .putValue(SInfoResultType.collisionGaugeW, collision.getGaugeW())
+                    .putValue(GeneralResultType.gaugeLabelCm, gaugeName)
+                    .putValue(SInfoResultType.dischargeLong, qOut)
+                    .putValue(SInfoResultType.dischargeZone, zone));
         }
     }
+
+    /**
+     * Gets the discharge of a gauge and a W
+     */
+    private double getQ(final Map<String, GaugeDischargeValuesFinder> qFinders, final String gaugeName, final double w,
+            final River river, final Calculation problems) {
+        // Find the gauge and load its discharge table, if not already in the map
+        final String gnKey = gaugeName.toLowerCase();
+        if (!qFinders.containsKey(gnKey))
+            qFinders.put(gnKey, GaugeDischargeValuesFinder.loadValues(river, gaugeName, problems));
+        // Interpolate W.
+        if (qFinders.get(gnKey) == null)
+            return Double.NaN;
+        return qFinders.get(gnKey).getDischarge(w);
+    }
+
+    /**
+     * Gets the main value zone name of a gauge and a Q
+     */
+    private String getZone(final Map<String, GaugeMainValueFinder> zoneFinders, final String gaugeName, final double q,
+            final River river, final Calculation problems) {
+        // Find the gauge and load its main value list, if not already in the map
+        final String gnKey = gaugeName.toLowerCase();
+        if (!zoneFinders.containsKey(gnKey))
+            zoneFinders.put(gnKey, GaugeMainValueFinder.loadValues(MainValueTypeKey.Q, river, gaugeName, problems));
+        // Build the zone name
+        if (zoneFinders.get(gnKey) == null)
+            return "";
+        return zoneFinders.get(gnKey).findZoneName(q);
+    }
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeDischargeValuesFinder.java	Tue Oct 02 18:19:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeDischargeValuesFinder.java	Thu Oct 04 12:48:57 2018 +0200
@@ -17,6 +17,7 @@
 import org.dive4elements.river.model.DischargeTable;
 import org.dive4elements.river.model.DischargeTableValue;
 import org.dive4elements.river.model.Gauge;
+import org.dive4elements.river.model.River;
 
 import gnu.trove.TDoubleArrayList;
 
@@ -78,9 +79,23 @@
      * @return The discharge table values finder of the gauge, or null
      */
     public static GaugeDischargeValuesFinder loadValues(final Gauge gauge, final Calculation problems) {
-        final DischargeTable table = gauge.fetchMasterDischargeTable();
+        return loadValues(gauge, gauge.getName(), problems);
+    }
+
+    /**
+     * Loads the the main discharge table of a river's gauge ({gauge}.at)
+     *
+     * @return The discharge table values finder of the gauge, or null
+     */
+    public static GaugeDischargeValuesFinder loadValues(final River river, final String gaugeName, final Calculation problems) {
+        final Gauge gauge = river.determineGaugeByName(gaugeName);
+        return loadValues(gauge, gaugeName, problems);
+    }
+
+    private static GaugeDischargeValuesFinder loadValues(final Gauge gauge, final String gaugeName, final Calculation problems) {
+        final DischargeTable table = (gauge != null) ? gauge.fetchMasterDischargeTable() : null;
         if ((table == null) || (table.getDischargeTableValues().size() == 0)) {
-            problems.addProblem("gauge_discharge_table.missing", gauge.getName());
+            problems.addProblem("gauge_discharge_table.missing", gaugeName);
             return null;
         }
         else
@@ -103,7 +118,7 @@
      */
     public double getDischarge(final double w) {
         try {
-            if (this.wInterpolator == null)
+            if (!this.isValid())
                 return Double.NaN;
             else if (w < this.wRange.getMinimumDouble())
                 return Double.NEGATIVE_INFINITY;
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeMainValueFinder.java	Tue Oct 02 18:19:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeMainValueFinder.java	Thu Oct 04 12:48:57 2018 +0200
@@ -17,6 +17,7 @@
 import org.dive4elements.river.model.Gauge;
 import org.dive4elements.river.model.MainValue;
 import org.dive4elements.river.model.MainValueType.MainValueTypeKey;
+import org.dive4elements.river.model.River;
 
 /**
  * Loading the main values of a gauge to find relative positions of a value and build a corresponding zone name
@@ -49,15 +50,17 @@
 
     /***** CONSTRUCTORS *****/
 
-    private GaugeMainValueFinder(final MainValueTypeKey keyType, final Gauge gauge, final Calculation problems) {
+    private GaugeMainValueFinder(final MainValueTypeKey keyType, final Gauge gauge, final String gaugeName, final Calculation problems) {
         this.gauge = gauge;
         this.problems = problems;
         this.keyType = keyType;
         this.mainValues = new TreeMap<>();
-        for (final MainValue mainValue : MainValue.getValuesOfGaugeAndType(gauge, keyType))
-            this.mainValues.put(Double.valueOf(mainValue.getValue().doubleValue()), mainValue);
+        if (gauge != null) {
+            for (final MainValue mainValue : MainValue.getValuesOfGaugeAndType(gauge, keyType))
+                this.mainValues.put(Double.valueOf(mainValue.getValue().doubleValue()), mainValue);
+        }
         if (this.mainValues.isEmpty() && (this.problems != null)) {
-            this.problems.addProblem("gauge_main_values.missing", gauge.getName());
+            this.problems.addProblem("gauge_main_values.missing", gaugeName);
             // Report only once
             this.problems = null;
         }
@@ -67,12 +70,22 @@
     /***** METHODS *****/
 
     /**
-     * Loads the the main values table of a type and a gauge (GAUGE.sta)
+     * Loads the the main values table of a type and a gauge ({gauge}.sta)
      *
      * @return The main values finder of a type and a gauge, or null
      */
     public static GaugeMainValueFinder loadValues(final MainValueTypeKey type, final Gauge gauge, final Calculation problems) {
-        return new GaugeMainValueFinder(type, gauge, problems);
+        return new GaugeMainValueFinder(type, gauge, gauge.getName(), problems);
+    }
+
+    /**
+     * Loads the the main values table of a type and a river's gauge ({gauge}.sta)
+     *
+     * @return The main values finder of the type and gauge, or null
+     */
+    public static GaugeMainValueFinder loadValues(final MainValueTypeKey type, final River river, final String gaugeName, final Calculation problems) {
+        final Gauge gauge = river.determineGaugeByName(gaugeName);
+        return new GaugeMainValueFinder(type, gauge, gaugeName, problems);
     }
 
     /**
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesCrossSectionProcessor.java	Tue Oct 02 18:19:44 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/vegetationzones/VegetationZonesCrossSectionProcessor.java	Thu Oct 04 12:48:57 2018 +0200
@@ -121,7 +121,7 @@
         final MainWstValues mainWstValues = MainWstValues.forRiver(river);
         final double mw = mainWstValues.getW(river, MAIN_VALUE_MQ, station);
 
-        // Üfd = -70,559 ∗ ln((DGM - MW) + 0,5) + 80,711
+        // Üfd = -70,559 ∗ ln((DGM - MW) + 0,5) + 88,711
         final double f1 = -70.559;
         final double f2 = 88.711;
 
--- a/backend/src/main/java/org/dive4elements/river/model/River.java	Tue Oct 02 18:19:44 2018 +0200
+++ b/backend/src/main/java/org/dive4elements/river/model/River.java	Thu Oct 04 12:48:57 2018 +0200
@@ -254,9 +254,9 @@
     public Gauge determineGaugeByName(final String name) {
         final Session session = SessionHolder.HOLDER.get();
         final Query query = session.createQuery(
-                "from Gauge where river=:river and name=:name");
+                "from Gauge where river=:river and lower(name)=:name");
         query.setParameter("river", this);
-        query.setParameter("name", name);
+        query.setParameter("name", name.toLowerCase());
         final List<Gauge> gauges = query.list();
         return gauges.isEmpty() ? null : gauges.get(0);
     }
@@ -428,7 +428,7 @@
         }
         return null;
     }
-    
+
     public Gauge firstUpstreamGauge() {
         final List<Gauge> gauges = getGauges();
 
@@ -445,7 +445,7 @@
         if (byKm.isEmpty())
             return null;
 
-        if (kmUp)
+        if (this.kmUp)
             return byKm.lastEntry().getValue();
 
         return byKm.firstEntry().getValue();

http://dive4elements.wald.intevation.org