diff artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/FlowVelocityModelKmValueFinder.java @ 8964:45f1ad66560e

Code cleanup concerning calculations: improved error handling; improved interpolation; bed heights are now always used for spatial discretisation
author gernotbelger
date Thu, 29 Mar 2018 15:48:17 +0200
parents d9dbf0b74bc2
children 9b9f5f4ddb80
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/FlowVelocityModelKmValueFinder.java	Wed Mar 28 17:04:20 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/FlowVelocityModelKmValueFinder.java	Thu Mar 29 15:48:17 2018 +0200
@@ -17,6 +17,7 @@
 import org.apache.log4j.Logger;
 import org.dive4elements.river.artifacts.math.Linear;
 import org.dive4elements.river.artifacts.math.Utils;
+import org.dive4elements.river.artifacts.model.Calculation;
 import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowVelocityKmModelValues;
 import org.dive4elements.river.backend.SessionHolder;
 import org.dive4elements.river.model.River;
@@ -37,6 +38,7 @@
  *
  * @author Matthias Schäfer
  */
+// TODO: noch mal prüfen, ob wir eine interpolationsschranke brauchen (max. km-abstand)
 final class FlowVelocityModelKmValueFinder {
     /***** FIELDS *****/
 
@@ -115,6 +117,8 @@
      */
     private final List<FlowVelocityKmModelValues> values = new ArrayList<>();
 
+    private Calculation problems;
+
     /**
      * Searched km of the last findKmValue
      */
@@ -135,6 +139,10 @@
      */
     private double findQ;
 
+    public FlowVelocityModelKmValueFinder(final Calculation problems) {
+        this.problems = problems;
+    }
+
     /***** METHODS *****/
 
     /**
@@ -163,10 +171,11 @@
     public double getFindTauFound() {
         if (this.leftIndexFound < 0)
             return Double.NaN;
-        else if (this.leftIndexFound == this.rightIndexFound)
+
+        if (this.leftIndexFound == this.rightIndexFound)
             return getLeftValues().getTauFound();
-        else
-            return Linear.linear(this.findKm, getLeftValues().getKm(), getRightValues().getKm(), getLeftValues().getTauFound(), getRightValues().getTauFound());
+
+        return Linear.linear(this.findKm, getLeftValues().getKm(), getRightValues().getKm(), getLeftValues().getTauFound(), getRightValues().getTauFound());
     }
 
     /**
@@ -179,14 +188,17 @@
     /**
      * Static constructor: queries a range of a river's kms with all their q-v-tau values.
      *
+     * @param problems
+     *
      * @return Whether the load has been successful the new instance, <code>null</code> otherwise.
      */
-    public static FlowVelocityModelKmValueFinder loadValues(final River river, final DoubleRange kmRange, final DoubleRange qRange) {
+    public static FlowVelocityModelKmValueFinder loadValues(final Calculation problems, final River river, final DoubleRange kmRange,
+            final DoubleRange qRange) {
         // DB session
         log.debug(String.format("loadValues km %.3f - %.3f / q %.1f - %.1f", kmRange.getMinimumDouble(), kmRange.getMaximumDouble(), qRange.getMinimumDouble(),
                 qRange.getMaximumDouble()));
 
-        final FlowVelocityModelKmValueFinder instance = new FlowVelocityModelKmValueFinder();
+        final FlowVelocityModelKmValueFinder instance = new FlowVelocityModelKmValueFinder(problems);
 
         final TDoubleArrayList kms = instance.kms;
         final List<FlowVelocityKmModelValues> values = instance.values;
@@ -249,8 +261,10 @@
 
         log.debug(String.format("loadValues %d kms, %d values loaded", kmcount, rowcount));
 
-        if (kms.size() == 0)
+        if (kms.size() == 0) {
+            problems.addProblem("flowvelocitymodelkmvaluefinder.empty");
             return null;
+        }
 
         return instance;
     }
@@ -283,19 +297,35 @@
      */
     public boolean findKmQValues(final double km, final double q) {
         this.findQ = q;
+
+        final boolean found = doFindKmQValues(km, q);
+
+        if (this.problems != null) {
+
+            this.problems.addProblem(km, "flowvelocitymodelkmvaluefinder.missing");
+
+            // report only once
+            this.problems = null;
+        }
+
+        return found;
+    }
+
+    private boolean doFindKmQValues(final double km, final double q) {
         if (!searchKm(km))
             return false;
+
         if (this.leftIndexFound == this.rightIndexFound) {
             // Exact km match
             final double qfound = getLeftValues().findQ(q);
             log.debug(String.format("findKmQValues km %.3f q %.0f = %.0f (%d)", km, q, qfound, this.leftIndexFound));
             return !Double.isNaN(qfound);
-        } else {
-            final double[] qfound = { getLeftValues().findQ(q), getRightValues().findQ(q) };
-            log.debug(String.format("findKmQValues km %.3f q %.0f = %.0f (%d, %.3f) - %.0f (%d, %.3f)", km, q, qfound[0], this.leftIndexFound,
-                    getLeftValues().getKm(), qfound[1], this.rightIndexFound, getRightValues().getKm()));
-            return !Double.isNaN(qfound[0]) && !Double.isNaN(qfound[1]);
         }
+
+        final double[] qfound = { getLeftValues().findQ(q), getRightValues().findQ(q) };
+        log.debug(String.format("findKmQValues km %.3f q %.0f = %.0f (%d, %.3f) - %.0f (%d, %.3f)", km, q, qfound[0], this.leftIndexFound,
+                getLeftValues().getKm(), qfound[1], this.rightIndexFound, getRightValues().getKm()));
+        return !Double.isNaN(qfound[0]) && !Double.isNaN(qfound[1]);
     }
 
     /**
@@ -307,24 +337,23 @@
         this.findKm = km;
         this.leftIndexFound = -1;
         this.rightIndexFound = -1;
-        if ((this.kms == null) || (this.kms.size() == 0))
-            return false;
+
         int i = this.kms.binarySearch(km);
         if (i >= 0) {
             // Exact km match
             this.leftIndexFound = i;
             this.rightIndexFound = i;
             return true;
-        } else {
-            // Out of range or within km interval
-            if (i < 0)
-                i = -i - 1;
-            if ((i <= 0) || (i >= this.kms.size()))
-                return false;
-            this.leftIndexFound = i - 1;
-            this.rightIndexFound = i;
-            return true;
         }
+
+        // Out of range or within km interval
+        if (i < 0)
+            i = -i - 1;
+        if ((i <= 0) || (i >= this.kms.size()))
+            return false;
+        this.leftIndexFound = i - 1;
+        this.rightIndexFound = i;
+        return true;
     }
 
     private FlowVelocityKmModelValues getLeftValues() {

http://dive4elements.wald.intevation.org