changeset 678:19a3185822a4

Added error reporting to 'Wasserspiegellage' calculation. flys-artifacts/trunk@2102 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 10 Jun 2011 15:59:47 +0000
parents a95f34f1f39a
children 9a035ef7b595
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/Calculation1.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQCKms.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQKms.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java
diffstat 6 files changed, 145 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Fri Jun 10 14:24:15 2011 +0000
+++ b/flys-artifacts/ChangeLog	Fri Jun 10 15:59:47 2011 +0000
@@ -1,3 +1,20 @@
+2011-06-10  Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/Calculation1.java:
+	  New. Factored out version of "Wasserspiegellage" calculation.
+	* src/main/java/de/intevation/flys/artifacts/model/WQKms.java:
+
+	  Removed some dead code.
+
+	* src/main/java/de/intevation/flys/artifacts/model/WQCKms.java:
+	  Added Override annotation and used quick access method.
+
+	* src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java:
+	  Looped through error reporting use by interpolate.
+
+	* src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java:
+	  Used factored out version of calculation 1. Removed dead code.
+
 2011-06-10  Sascha L. Teichmann <sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/artifacts/model/Calculation2.java:
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java	Fri Jun 10 14:24:15 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java	Fri Jun 10 15:59:47 2011 +0000
@@ -1,9 +1,6 @@
 package de.intevation.flys.artifacts;
 
 import java.util.List;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.ArrayList;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -32,8 +29,8 @@
 import de.intevation.flys.artifacts.model.WQDay;
 import de.intevation.flys.artifacts.model.WQKms;
 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.Calculation1;
 import de.intevation.flys.artifacts.model.Calculation2;
 import de.intevation.flys.artifacts.model.Calculation3;
 import de.intevation.flys.artifacts.model.Calculation4;
@@ -279,43 +276,14 @@
             throw new NullPointerException("No Wst found for selected river.");
         }
 
-        HashSet<Integer> failed = new HashSet<Integer>();
-
         WQKms[] results = computeWaterlevelData(
-            kms, qs, wst, river.getKmUp(), failed);
+            kms, qs, ws, wst, river.getKmUp());
 
         // TODO Introduce a caching mechanism here!
 
-        setWaterlevelNames(
-            results, qSel ? qs : ws, qSel ? "Q" : "W", failed);
-
         return results;
     }
 
-
-    /**
-     * Sets the name for waterlevels where each WQKms in <i>r</i> represents a
-     * column.
-     *
-     * @param r The waterlevel columns.
-     * @param v The input values of the computations.
-     * @param wq The WQ mode - can be one of "W" or "Q".
-     */
-    public static void setWaterlevelNames(
-        WQKms[]  r, 
-        double[] v, 
-        String   wq, 
-        Set      failed
-    ) {
-        int pos = 0;
-        for (int i = 0; i < v.length; i++) {
-            if (!failed.contains(i)) {
-                r[pos++].setName(wq + "=" + v[i]);
-            }
-        }
-    }
-
-
     /**
      * Computes the data of a waterlevel computation based on the interpolation
      * in WstValueTable.
@@ -327,35 +295,21 @@
      * @return an array of data triples that consist of W, Q and Kms.
      */
     public static WQKms[] computeWaterlevelData(
-        double[]      kms,
-        double[]      qs,
+        double []     kms,
+        double []     qs,
+        double []     ws,
         WstValueTable wst,
-        boolean       up,
-        Set<Integer>  failed
+        boolean       up
     ) {
         logger.info("WINFOArtifact.computeWaterlevelData");
 
-        WQKms[] wqkms = new WQKms[qs.length];
-
-        ArrayList<WQKms> results = new ArrayList<WQKms>();
-
-        int referenceIndex = up ? 0 : kms.length-1; 
+        Calculation1 calculation = new Calculation1(kms, qs, ws, up);
 
-        for (int i = 0; i < qs.length; i++) {
-            double [] oqs = new double[kms.length];
-            double [] ows = new double[kms.length];
-            WstValueTable.QPosition qPosition =
-                wst.interpolate(qs[i], kms[referenceIndex], kms, ows, oqs);
-            if (qPosition != null) {
-                results.add(new WQKms(kms, oqs, ows));
-            }
-            else {
-                logger.warn("interpolation failed for q = " + qs[i]);
-                failed.add(i);
-            }
-        }
+        WQKms[] wqkms = calculation.calculate(wst);
 
-        return results.toArray(new WQKms[results.size()]);
+        // TODO: report problems to user
+
+        return wqkms;
     }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation1.java	Fri Jun 10 15:59:47 2011 +0000
@@ -0,0 +1,73 @@
+package de.intevation.flys.artifacts.model;
+
+import java.util.ArrayList;
+
+import org.apache.log4j.Logger;
+
+public class Calculation1
+extends      Calculation
+{
+    private static Logger logger = Logger.getLogger(Calculation1.class);
+
+    protected double [] kms;
+    protected double [] qs;
+    protected double [] ws;
+    protected boolean   up;
+
+    public Calculation1() {
+    }
+
+    public Calculation1(
+        double [] kms, 
+        double [] qs, 
+        double [] ws,
+        boolean   up
+    ) {
+        this.kms = kms;
+        this.qs  = qs;
+        this.ws  = ws;
+        this.up  = up;
+    }
+
+    public WQKms [] calculate(WstValueTable wst) {
+
+        ArrayList<WQKms> results = new ArrayList<WQKms>();
+
+        double ref = kms[up ? 0 : kms.length-1];
+
+        String    prefix;
+        double [] origData;
+
+        if (ws != null) { prefix = "W="; origData = ws; }
+        else            { prefix = "Q="; origData = qs; }
+
+        int oldNumProblems = numProblems();
+
+        for (int i = 0; i < qs.length; i++) {
+
+            double [] oqs = new double[kms.length];
+            double [] ows = new double[kms.length];
+
+            boolean success =
+                wst.interpolate(qs[i], ref, kms, ows, oqs, this) != null;
+
+            int newNumProblems = numProblems();
+
+            if (success) {
+                WQKms result = new WQKms(kms, oqs, ows, prefix + origData[i]);
+                if (oldNumProblems != newNumProblems) {
+                    logger.debug(
+                        qs[i] + " caused " + (newNumProblems-oldNumProblems) + 
+                        " new problem(s).");
+                    result.removeNaNs();
+                }
+                results.add(result);
+            }
+
+            oldNumProblems = newNumProblems;
+        }
+        
+        return results.toArray(new WQKms[results.size()]);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQCKms.java	Fri Jun 10 14:24:15 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQCKms.java	Fri Jun 10 15:59:47 2011 +0000
@@ -58,6 +58,7 @@
      *
      * @return a 4dim array of [W, Q, Kms, CW] in dst.
      */
+    @Override
     public double[] get(int idx, double[] dst) {
         dst = super.get(idx, dst);
 
@@ -66,7 +67,7 @@
         }
 
         if (cw != null && cw.size() > idx) {
-            dst[3] = cw.get(idx);
+            dst[3] = cw.getQuick(idx);
         }
 
         return dst;
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQKms.java	Fri Jun 10 14:24:15 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQKms.java	Fri Jun 10 15:59:47 2011 +0000
@@ -111,14 +111,6 @@
         this.kms.add(kms);
     }
 
-
-    public void add(double[] w, double[] q, double[] kms) {
-        this.w.add(w);
-        this.q.add(q);
-        this.kms.add(kms);
-    }
-
-
     /**
      * Returns the number of triples stored in this data pool.
      *
@@ -172,37 +164,7 @@
     public String toString() {
         double from = getKms(0);
         double to   = getKms(size()-1);
-        return Double.toString(from) + " - " + Double.toString(to);
-    }
-
-
-    /**
-     * Merges the WQKms objects of an incoming 2dim array (table) where the
-     * objects of a column belong together.
-     *
-     * @param toMerge The objects that need to be merged.
-     *
-     * @return an array of merged WQKms objects.
-     */
-    public static WQKms[] merge(WQKms[][] toMerge) {
-        int num = toMerge[0].length;
-
-        // TODO IS THE LENGTH CORRECT?
-        WQKms[] merged = new WQKms[num];
-        for (int i = 0; i < num; i++) {
-            merged[i] = new WQKms();
-        }
-
-        for (int i = 0; i < toMerge.length; i++) {
-            WQKms[] tmp = toMerge[i];
-
-            for (int j = 0; j < num; j++) {
-                WQKms toAdd = tmp[j];
-                merged[j].add(toAdd.getWs(), toAdd.getQs(), toAdd.getKms());
-            }
-        }
-
-        return merged;
+        return from + " - " + to;
     }
 }
 // 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 14:24:15 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java	Fri Jun 10 15:59:47 2011 +0000
@@ -494,28 +494,36 @@
     }
 
     public QPosition interpolate(
-        double    q,
-        double    referenceKm,
-        double [] kms,
-        double [] ws,
-        double [] qs
+        double      q,
+        double      referenceKm,
+        double []   kms,
+        double []   ws,
+        double []   qs,
+        Calculation errors
     ) {
-        return interpolate(q, referenceKm, kms, ws, qs, 0, kms.length);
+        return interpolate(
+            q, referenceKm, kms, ws, qs, 0, kms.length, errors);
     }
 
     public QPosition interpolate(
-        double    q,
-        double    referenceKm,
-        double [] kms,
-        double [] ws,
-        double [] qs,
-        int       startIndex,
-        int       length
+        double      q,
+        double      referenceKm,
+        double []   kms,
+        double []   ws,
+        double []   qs,
+        int         startIndex,
+        int         length,
+        Calculation errors
     ) {
         QPosition qPosition = getQPosition(referenceKm, q);
 
         if (qPosition == null) {
             // we cannot locate q at km
+            Arrays.fill(ws, Double.NaN);
+            Arrays.fill(qs, Double.NaN);
+            if (errors != null) {
+                errors.addProblem(referenceKm, "cannot find q");
+            }
             return null;
         }
 
@@ -524,15 +532,24 @@
         int R1 = rows.size()-1;
 
         for (int i = startIndex, end = startIndex+length; i < end; ++i) {
-            kmKey.km = kms[i];
 
+            if (Double.isNaN(qs[i] = getQ(qPosition, kms[i]))) {
+                if (errors != null) {
+                    errors.addProblem(kms[i], "cannot find q");
+                }
+                ws[i] = Double.NaN;
+                continue;
+            }
+
+            kmKey.km = kms[i];
             int rowIndex = Collections.binarySearch(rows, kmKey);
 
-            qs[i] = getQ(qPosition, kms[i]);
-
             if (rowIndex >= 0) {
                 // direct row match
-                ws[i] = rows.get(rowIndex).getW(qPosition);
+                if (Double.isNaN(ws[i] = rows.get(rowIndex).getW(qPosition))
+                && errors != null) {
+                    errors.addProblem(kms[i], "cannot find w");
+                }
                 continue;
             }
 
@@ -540,13 +557,19 @@
 
             if (rowIndex < 1 || rowIndex >= R1) {
                 // do not extrapolate
+                if (errors != null) {
+                    errors.addProblem(kms[i], "cannot find km");
+                }
                 ws[i] =  Double.NaN;
                 continue;
             }
             Row r1 = rows.get(rowIndex-1);
             Row r2 = rows.get(rowIndex);
 
-            ws[i] = r1.getW(r2, kms[i], qPosition);
+            if (Double.isNaN(ws[i] = r1.getW(r2, kms[i], qPosition))
+            && errors != null) {
+                errors.addProblem(kms[i], "cannot find w");
+            }
         }
 
         return qPosition;

http://dive4elements.wald.intevation.org