changeset 642:2dbbb5be30a1

Re-eanbled the calculation of the backjump correction. flys-artifacts/trunk@2026 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 27 May 2011 16:52:37 +0000
parents ab9b6cae0d0d
children a9bde508824a
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/BackJumpCorrector.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WQAdapted.java
diffstat 4 files changed, 131 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Fri May 27 10:09:46 2011 +0000
+++ b/flys-artifacts/ChangeLog	Fri May 27 16:52:37 2011 +0000
@@ -1,3 +1,14 @@
+2011-05-27	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/math/BackJumpCorrector.java:
+	  Make it work independent of river flow direction.
+
+	* src/main/java/de/intevation/flys/artifacts/states/WQAdapted.java:
+	  Fixed bug in ordering segments
+
+	* src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java: Re-enabled
+	  calculation of the back jump correction. Fixed more flow direction issues.
+	  
 2011-05-27  Ingo Weinzierl <ingo@intevation.de>
 
 	* src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java:
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java	Fri May 27 10:09:46 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java	Fri May 27 16:52:37 2011 +0000
@@ -497,6 +497,28 @@
         return wqkms;
     }
 
+    private static final double [] getBounds(double [][] segments) {
+        boolean down = true;
+        double min =  Double.MAX_VALUE;
+        double max = -Double.MAX_VALUE;
+
+        for (double [] segment: segments) {
+            if (down = segment[0] > segment[1]) {
+                if (segment[1] < min) min = segment[1];
+                if (segment[0] > max) max = segment[0];
+            }
+            else {
+                if (segment[0] < min) min = segment[0];
+                if (segment[1] > max) max = segment[1];
+            }
+        }
+
+        return down
+            ?  new double [] { max, min }
+            :  new double [] { min, max };
+
+    }
+
     /**
      * Returns the data computed by the discharge longitudinal section
      * computation.
@@ -554,12 +576,12 @@
         double [] boundKms;
 
         if (segments.length == 2) {
-            boundKms = new double [] { segments[0][0], segments[1][1] };
+            boundKms = getBounds(segments);
         }
         else {
             TDoubleArrayList bounds = new TDoubleArrayList();
 
-            bounds.add(segments[0][0]);
+            bounds.add(Math.min(segments[0][0], segments[0][1]));
 
             for (int i = 1; i < segments.length-1; ++i) {
                 double [] segment = segments[i];
@@ -576,7 +598,10 @@
                 }
             }
 
-            bounds.add(segments[segments.length-1][1]);
+            bounds.add(Math.max(
+                segments[segments.length-1][0],
+                segments[segments.length-1][1]));
+
             boundKms = bounds.toNativeArray();
         }
 
@@ -654,16 +679,14 @@
 
             wst.interpolate(okms, ows, oqs, qPosition, remap);
 
-            /*
             BackJumpCorrector bjc = new BackJumpCorrector();
             if (bjc.doCorrection(okms, ows)) {
                 logger.debug("Discharge longitudinal section has backjumps.");
                 results.add(new WQCKms(okms, oqs, ows, bjc.getCorrected()));
             }
             else {
-            */
                 results.add(new WQKms(okms, oqs, ows));
-            //}
+            }
         }
 
         WQKms [] wqkms = results.toArray(new WQKms[results.size()]);
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/BackJumpCorrector.java	Fri May 27 10:09:46 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/BackJumpCorrector.java	Fri May 27 16:52:37 2011 +0000
@@ -38,41 +38,33 @@
         return corrected;
     }
 
-    private static final boolean isIncreasing(double [] ws) {
-        int inc = 0;
-        int dec = 0;
-        int sweet = (ws.length-1)/2;
-        for (int i = 1; i < ws.length; ++i) {
-            if (ws[i] > ws[i-1]) {
-                if (++inc > sweet) {
-                    return true;
-                }
-            }
-            else if (++dec > sweet) {
-                return false;
-            }
+    public boolean doCorrection(double [] km, double [] ws) {
+
+        boolean wsUp = isIncreasing(ws);
+
+        if (wsUp) {
+            km = swapClone(km);
+            ws = swapClone(ws);
         }
-        return inc > sweet;
-    }
-
-    public boolean doCorrection(double [] km, double [] ws) {
-        boolean isIncreasing = isIncreasing(ws);
 
-        if (isIncreasing) {
-            // mirror along x axis to simulate decreasing values
-            ws = (double [])ws.clone();
-            for (int i = 0; i < ws.length; ++i) {
-                ws[i] = -ws[i];
-            }
+        boolean kmUp = isIncreasing(km);
+
+        if (!kmUp) {
+            km = sumDiffs(km);
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("BackJumpCorrector.doCorrection ------- enter");
+            log.debug("  km increasing: " + isIncreasing(km));
+            log.debug("  ws increasing: " + isIncreasing(ws));
+            log.debug("BackJumpCorrector.doCorrection ------- leave");
         }
 
         boolean hasBackJumps = doCorrectionClean(km, ws);
 
-        if (hasBackJumps && isIncreasing) {
+        if (hasBackJumps && wsUp) {
             // mirror back
-            for (int i = 0; i < corrected.length; ++i) {
-                corrected[i] = -corrected[i];
-            }
+            swap(corrected);
         }
 
         return hasBackJumps;
@@ -134,7 +126,7 @@
             }
 
             if (back < 0) {
-                log.debug("run over left border");
+                //log.debug("run over left border");
                 // fill with same as ws[i]
                 for (int j = 0; j < i; ++j) {
                     ws[j] = ws[i];
@@ -195,6 +187,12 @@
                 interpolator = new SplineInterpolator();
             }
 
+            if (log.isDebugEnabled()) {
+                for (int j = 0; j < x.length; ++j) {
+                    log.debug("   " + x[j] + " -> " + y[j]);
+                }
+            }
+
             PolynomialSplineFunction spline = interpolator.interpolate(x, y);
 
             try {
@@ -224,5 +222,64 @@
 
         return !backjumps.isEmpty();
     }
+
+    public static final boolean isIncreasing(double [] array) {
+        int inc = 0;
+        int dec = 0;
+        int sweet = (array.length-1)/2;
+        for (int i = 1; i < array.length; ++i) {
+            if (array[i] > array[i-1]) {
+                if (++inc > sweet) {
+                    return true;
+                }
+            }
+            else if (++dec > sweet) {
+                return false;
+            }
+        }
+        return inc > sweet;
+    }
+
+    public static final double [] swap(double [] array) {
+        int lo = 0;
+        int hi = array.length-1;
+        while (hi > lo) {
+            double t  = array[lo];
+            array[lo] = array[hi];
+            array[hi] = t;
+            ++lo;
+            --hi;
+        }
+
+        return array;
+    }
+
+    public static final double [] swapClone(double [] array) {
+        double [] out = new double[array.length];
+        int lo = 0;
+
+        int hi = array.length-1;
+        while (hi > lo) {
+            out[lo] = array[hi];
+            out[hi] = array[lo];
+            ++lo;
+            --hi;
+        }
+        return out;
+    }
+
+    public static final double [] sumDiffs(double [] in) {
+        double [] out = new double[in.length];
+
+        if (out.length > 0) {
+            out[0] = 0d;
+        }
+
+        for (int i = 1; i < out.length; ++i) {
+            out[i] = out[i-1] + Math.abs(in[i-1] - in[i]);
+        }
+
+        return out;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WQAdapted.java	Fri May 27 10:09:46 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WQAdapted.java	Fri May 27 16:52:37 2011 +0000
@@ -44,7 +44,7 @@
         private int order;
 
         public GaugeOrder(boolean up) {
-            order = up ? 1 : 1;
+            order = up ? 1 : -1;
         }
 
         public int compare(Gauge a, Gauge b) {
@@ -149,13 +149,15 @@
         }
         else {
             Collections.sort(gauges, GAUGE_DOWN);
+            rangeFrom = dist[1];
+            rangeTo   = dist[0];
             for (Gauge gauge: gauges) {
                 Range range = gauge.getRange();
                 double lower = range.getA().doubleValue();
                 double upper = range.getB().doubleValue();
 
-                double to   = upper < rangeTo   ? rangeTo   : upper;
-                double from = lower > rangeFrom ? rangeFrom : lower;
+                double from = lower < rangeFrom ? rangeFrom : lower;
+                double to   = upper > rangeTo   ? rangeTo   : upper;
 
                 elements[idx++] = createItem(
                     cr, new String[] { to + ";" + from, ""});

http://dive4elements.wald.intevation.org