diff flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java @ 686:3dc61e00385e facets-slt

Merged with trunk and introduced hashing of computed values. flys-artifacts/branches/facets-slt@2126 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 15 Jun 2011 15:28:54 +0000
parents 913b52064449
children eab5e5089d77
line wrap: on
line diff
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java	Wed Jun 08 13:03:21 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java	Wed Jun 15 15:28:54 2011 +0000
@@ -18,6 +18,8 @@
 
 import org.apache.commons.math.ArgumentOutsideDomainException;
 
+import org.apache.commons.math.exception.MathIllegalArgumentException;
+
 public class WstValueTable
 implements   Serializable
 {
@@ -107,7 +109,8 @@
             double        km,
             double []     iqs,
             double []     ows,
-            WstValueTable table
+            WstValueTable table,
+            Calculation   errors
         ) {
             double kmWeight = Linear.factor(km, this.km, other.km);
 
@@ -117,9 +120,23 @@
                 if (table.getQPosition(km, iqs[i], qPosition) != null) {
                     double wt =       getW(qPosition);
                     double wo = other.getW(qPosition);
-                    ows[i] = Linear.weight(kmWeight, wt, wo);
+                    if (Double.isNaN(wt) || Double.isNaN(wo)) {
+                        if (errors != null) {
+                            // TODO: I18N
+                            errors.addProblem(
+                                km, "cannot find w for q = " + iqs[i]);
+                        }
+                        ows[i] = Double.NaN;
+                    }
+                    else {
+                        ows[i] = Linear.weight(kmWeight, wt, wo);
+                    }
                 }
                 else {
+                    if (errors != null) {
+                        // TODO: I18N
+                        errors.addProblem(km, "cannot find q = " + iqs[i]);
+                    }
                     ows[i] = Double.NaN;
                 }
             }
@@ -129,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];
             }
 
@@ -152,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) {
@@ -174,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];
             }
 
@@ -193,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) {
@@ -218,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 };
@@ -282,7 +364,15 @@
     }
 
     public double [] interpolateW(double km, double [] qs, double [] ws) {
+        return interpolateW(km, qs, ws, null);
+    }
 
+    public double [] interpolateW(
+        double      km,
+        double []   qs, 
+        double []   ws,
+        Calculation errors
+    ) {
         int rowIndex = Collections.binarySearch(rows, new Row(km));
 
         QPosition qPosition = new QPosition();
@@ -290,9 +380,21 @@
         if (rowIndex >= 0) { // direct row match
             Row row = rows.get(rowIndex);
             for (int i = 0; i < qs.length; ++i) {
-                ws[i] = getQPosition(km, qs[i], qPosition) != null
-                    ? row.getW(qPosition)
-                    : Double.NaN;
+                if (getQPosition(km, qs[i], qPosition) == null) {
+                    if (errors != null) {
+                        // TODO: I18N
+                        errors.addProblem(km, "cannot find q = " + qs[i]);
+                    }
+                    ws[i] = Double.NaN;
+                }
+                else {
+                    if (Double.isNaN(ws[i] = row.getW(qPosition))
+                    && errors != null) {
+                        // TODO: I18N
+                        errors.addProblem(
+                            km, "cannot find w for q = " + qs[i]);
+                    }
+                }
             }
         }
         else { // needs bilinear interpolation
@@ -301,11 +403,15 @@
             if (rowIndex < 1 || rowIndex >= rows.size()) {
                 // do not extrapolate
                 Arrays.fill(ws, Double.NaN);
+                if (errors != null) {
+                    // TODO: I18N
+                    errors.addProblem(km, "km not found");
+                }
             }
             else {
                 Row r1 = rows.get(rowIndex-1);
                 Row r2 = rows.get(rowIndex);
-                r1.interpolateW(r2, km, qs, ws, this);
+                r1.interpolateW(r2, km, qs, ws, this, errors);
             }
         }
 
@@ -313,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(
@@ -380,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;
         }
 
@@ -410,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;
             }
 
@@ -426,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