changeset 677:a95f34f1f39a

Added error reporting to 'Abflusskurve' calculation. flys-artifacts/trunk@2101 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 10 Jun 2011 14:24:15 +0000
parents c501f27c1f71
children 19a3185822a4
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation2.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java
diffstat 4 files changed, 159 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Fri Jun 10 12:38:08 2011 +0000
+++ b/flys-artifacts/ChangeLog	Fri Jun 10 14:24:15 2011 +0000
@@ -1,3 +1,14 @@
+2011-06-10  Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/Calculation2.java:
+	  New. Factored out version of "Abflusskurve".
+
+	* src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java:
+	  Loop errors through w/q at km interpolation.
+
+	* src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java:
+	  Use factored out version of calculation 2.
+
 2011-06-10  Sascha L. Teichmann <sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/artifacts/model/Calculation3.java:
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java	Fri Jun 10 12:38:08 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java	Fri Jun 10 14:24:15 2011 +0000
@@ -34,6 +34,7 @@
 import de.intevation.flys.artifacts.model.WstValueTable;
 import de.intevation.flys.artifacts.model.WstValueTable.QPosition;
 import de.intevation.flys.artifacts.model.WstValueTableFactory;
+import de.intevation.flys.artifacts.model.Calculation2;
 import de.intevation.flys.artifacts.model.Calculation3;
 import de.intevation.flys.artifacts.model.Calculation4;
 import de.intevation.flys.artifacts.model.Segment;
@@ -455,24 +456,11 @@
 
         // TODO Introduce a caching mechanism here!
 
-        setComputedDischargeCurveNames(wqkms, locations[0]);
-
         return wqkms;
     }
 
 
     /**
-     * Sets the name of the computed discharge curve data.
-     *
-     * @param wqkms The computed WQKms object.
-     * @param l The location used for the computation.
-     */
-    public static void setComputedDischargeCurveNames(WQKms wqkms, double l) {
-        wqkms.setName(Double.toString(l));
-    }
-
-
-    /**
      * Computes the data used to create computed discharge curves.
      *
      * @param wst The WstValueTable that is used for the interpolation.
@@ -487,21 +475,11 @@
     {
         logger.info("WINFOArtifact.computeDischargeCurveData");
 
-        double[][] wqs = wst.interpolateWQ(location);
-
-        if (wqs == null) {
-            logger.error("Cannot compute discharge curve data.");
-            return null;
-        }
+        Calculation2 calculation = new Calculation2(location);
 
-        double[] ws = wqs[0];
-        double[] qs = wqs[1];
+        WQKms wqkms = calculation.calculate(wst);
 
-        WQKms wqkms = new WQKms(ws.length);
-
-        for (int i = 0; i < ws.length; i++) {
-            wqkms.add(ws[i], qs[i], location);
-        }
+        // TODO: Report errors to the user
 
         return wqkms;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation2.java	Fri Jun 10 14:24:15 2011 +0000
@@ -0,0 +1,48 @@
+package de.intevation.flys.artifacts.model;
+
+import java.util.Arrays;
+
+import org.apache.log4j.Logger;
+
+public class Calculation2
+extends      Calculation
+{
+    private static Logger logger = Logger.getLogger(Calculation2.class);
+
+    protected double km;
+
+    public Calculation2() {
+    }
+
+    public Calculation2(double km) {
+        this.km = km;
+    }
+
+    public WQKms calculate(WstValueTable wst) {
+
+        logger.debug("Calculation2.calculate");
+
+        double [][] wqs = wst.interpolateWQ(km, this);
+
+        if (wqs == null || wqs[0].length == 0) {
+            logger.debug("Cannot compute discharge curve data.");
+            return null;
+        }
+
+        double [] ws = wqs[0];
+        double [] qs = wqs[1];
+        double [] kms = new double[ws.length];
+
+        Arrays.fill(kms, km);
+
+        WQKms wqkms = new WQKms(kms, qs, ws, String.valueOf(km));
+
+        if (hasProblems()) {
+            logger.debug("found + "+numProblems()+" problems.");
+            wqkms.removeNaNs();
+        }
+
+        return wqkms;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java	Fri Jun 10 12:38:08 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java	Fri Jun 10 14:24:15 2011 +0000
@@ -18,6 +18,8 @@
 
 import org.apache.commons.math.ArgumentOutsideDomainException;
 
+import org.apache.commons.math.exception.MathIllegalArgumentException;
+
 public class WstValueTable
 implements   Serializable
 {
@@ -144,11 +146,16 @@
             Row           other,
             double        km,
             int           steps,
-            WstValueTable table
+            WstValueTable table,
+            Calculation   errors
         ) {
             int W = Math.min(ws.length, other.ws.length);
 
             if (W < 1) {
+                if (errors != null) {
+                    // TODO: I18N
+                    errors.addProblem("no ws found");
+                }
                 return new double[2][0];
             }
 
@@ -167,21 +174,44 @@
                     table.getQIndex(i, km),
                     table.getQIndex(i, other.km));
 
+                if (Double.isNaN(wws) || Double.isNaN(wqs)) {
+                    if (errors != null) {
+                        // TODO: I18N
+                        errors.addProblem(km, "cannot find w or q");
+                    }
+                }
+                else {
+                    if (wqs < minQ) minQ = wqs;
+                    if (wqs > maxQ) maxQ = wqs;
+                }
+
                 splineW[i] = wws;
                 splineQ[i] = wqs;
-                if (wqs < minQ) minQ = wqs;
-                if (wqs > maxQ) maxQ = wqs;
             }
 
             double stepWidth = (maxQ - minQ)/steps;
 
             SplineInterpolator interpolator = new SplineInterpolator();
-            PolynomialSplineFunction spline =
-                interpolator.interpolate(splineQ, splineW);
+            PolynomialSplineFunction spline;
+
+            try {
+                spline = interpolator.interpolate(splineQ, splineW);
+            }
+            catch (MathIllegalArgumentException miae) {
+                if (errors != null) {
+                    // TODO: I18N
+                    errors.addProblem(km, "spline creation failed");
+                }
+                log.error("spline creation failed");
+                return new double[2][0];
+            }
 
             double [] outWs = new double[steps];
             double [] outQs = new double[steps];
 
+            Arrays.fill(outWs, Double.NaN);
+            Arrays.fill(outQs, Double.NaN);
+
             try {
                 double q = minQ;
                 for (int i = 0; i < outWs.length; ++i, q += stepWidth) {
@@ -189,17 +219,28 @@
                 }
             }
             catch (ArgumentOutsideDomainException aode) {
-                log.error("Spline interpolation failed.", aode);
+                if (errors != null) {
+                    // TODO: I18N
+                    errors.addProblem(km, "spline interpolation failed");
+                }
+                log.error("spline interpolation failed", aode);
             }
 
             return new double [][] { outWs, outQs };
         }
 
-        public double [][] interpolateWQ(int steps, WstValueTable table) {
-
+        public double [][] interpolateWQ(
+            int           steps, 
+            WstValueTable table,
+            Calculation   errors
+        ) {
             int W = ws.length;
 
             if (W < 1) {
+                if (errors != null) {
+                    // TODO: I18N
+                    errors.addProblem(km, "no ws found");
+                }
                 return new double[2][0];
             }
 
@@ -208,24 +249,46 @@
             double minQ =  Double.MAX_VALUE; 
             double maxQ = -Double.MAX_VALUE; 
 
-            QPosition qPosition = new QPosition();
-
             for (int i = 0; i < W; ++i) {
-                splineQ[i] = table.getQIndex(i, km);
-                if (splineQ[i] < minQ) minQ = splineQ[i];
-                if (splineQ[i] > maxQ) maxQ = splineQ[i];
+                double sq = table.getQIndex(i, km);
+                if (Double.isNaN(sq)) {
+                    if (errors != null) {
+                        // TODO: I18N
+                        errors.addProblem(
+                            km, "no q found in " + (i+1) + " column");
+                    }
+                }
+                else {
+                    if (sq < minQ) minQ = sq;
+                    if (sq > maxQ) maxQ = sq;
+                }
+                splineQ[i] = sq;
             }
 
             double stepWidth = (maxQ - minQ)/steps;
 
             SplineInterpolator interpolator = new SplineInterpolator();
 
-            PolynomialSplineFunction spline =
-                interpolator.interpolate(splineQ, ws);
+            PolynomialSplineFunction spline;
+            
+            try {
+                spline = interpolator.interpolate(splineQ, ws);
+            }
+            catch (MathIllegalArgumentException miae) {
+                if (errors != null) {
+                    // TODO: I18N
+                    errors.addProblem(km, "spline creation failed");
+                }
+                log.error("spline creation failed");
+                return new double[2][0];
+            }
 
             double [] outWs = new double[steps];
             double [] outQs = new double[steps];
 
+            Arrays.fill(outWs, Double.NaN);
+            Arrays.fill(outQs, Double.NaN);
+
             try {
                 double q = minQ;
                 for (int i = 0; i < outWs.length; ++i, q += stepWidth) {
@@ -233,7 +296,11 @@
                 }
             }
             catch (ArgumentOutsideDomainException aode) {
-                log.error("Spline interpolation failed.", aode);
+                if (errors != null) {
+                    // TODO: I18N
+                    errors.addProblem(km, "spline interpolation failed");
+                }
+                log.error("spline interpolation failed.", aode);
             }
 
             return new double [][] { outWs, outQs };
@@ -337,6 +404,7 @@
                 // do not extrapolate
                 Arrays.fill(ws, Double.NaN);
                 if (errors != null) {
+                    // TODO: I18N
                     errors.addProblem(km, "km not found");
                 }
             }
@@ -351,29 +419,37 @@
     }
 
     public double [][] interpolateWQ(double km) {
-        return interpolateWQ(km, DEFAULT_Q_STEPS);
+        return interpolateWQ(km, null);
     }
 
-    public double [][] interpolateWQ(double km, int steps) {
+    public double [][] interpolateWQ(double km, Calculation errors) {
+        return interpolateWQ(km, DEFAULT_Q_STEPS, errors);
+    }
+
+    public double [][] interpolateWQ(double km, int steps, Calculation errors) {
 
         int rowIndex = Collections.binarySearch(rows, new Row(km));
 
         if (rowIndex >= 0) { // direct row match
             Row row = rows.get(rowIndex);
-            return row.interpolateWQ(steps, this);
+            return row.interpolateWQ(steps, this, errors);
         }
 
         rowIndex = -rowIndex -1;
 
         if (rowIndex < 1 || rowIndex >= rows.size()) {
             // do not extrapolate
+            if (errors != null) {
+                // TODO: I18N
+                errors.addProblem(km, "km not found");
+            }
             return new double[2][0];
         }
 
         Row r1 = rows.get(rowIndex-1);
         Row r2 = rows.get(rowIndex);
 
-        return r1.interpolateWQ(r2, km, steps, this);
+        return r1.interpolateWQ(r2, km, steps, this, errors);
     }
 
     public boolean interpolate(

http://dive4elements.wald.intevation.org