changeset 3220:0c8a6145098b

FixA: Added AT writer for fitted functions. flys-artifacts/trunk@4843 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sun, 01 Jul 2012 11:18:59 +0000
parents fa30e6322ef3
children 06ae0258269b
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/exports/ATWriter.java flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java flys-artifacts/src/main/resources/messages.properties flys-artifacts/src/main/resources/messages_de.properties flys-artifacts/src/main/resources/messages_de_DE.properties flys-artifacts/src/main/resources/messages_en.properties
diffstat 7 files changed, 205 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Sun Jul 01 08:46:04 2012 +0000
+++ b/flys-artifacts/ChangeLog	Sun Jul 01 11:18:59 2012 +0000
@@ -1,3 +1,21 @@
+2012-07-01	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	Part of flys/issue687
+
+	* src/main/java/de/intevation/flys/exports/ATWriter.java:
+	  New. Samples fitting function to AT files.
+
+	  !!! Untested and expected to be slightly broken. !!!
+
+	* src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java:
+	  Made some formatting things public to be reusable.
+
+	* src/main/resources/messages.properties,
+	  src/main/resources/messages_de_DE.properties,
+	  src/main/resources/messages_en.properties,
+	  src/main/resources/messages_de.properties:
+	  Added i18n strings for AT headers.
+
 2012-07-01	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* doc/conf/artifact-db.xml,
@@ -15,6 +33,7 @@
 2012-06-30	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	Added parameter exporter for fixings analysis.
+	Part of flys/issue689
 
 	* src/main/java/de/intevation/flys/exports/fixings/ParametersExporter.java:
 	  New. Exports the contents of the parameters of the fix analysis.
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ATWriter.java	Sun Jul 01 08:46:04 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ATWriter.java	Sun Jul 01 11:18:59 2012 +0000
@@ -92,7 +92,7 @@
         }
     }
 
-    protected static void printQ(PrintWriter out, double q) {
+    public static void printQ(PrintWriter out, double q) {
         String format;
              if (q <   1d) format = " % 8.3f";
         else if (q <  10d) format = " % 8.2f";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java	Sun Jul 01 11:18:59 2012 +0000
@@ -0,0 +1,177 @@
+package de.intevation.flys.exports.fixings;
+
+import de.intevation.artifacts.CallMeta;
+
+import de.intevation.flys.artifacts.math.fitting.Function;
+
+import de.intevation.flys.artifacts.model.Parameters;
+
+import de.intevation.flys.artifacts.resources.Resources;
+
+import de.intevation.flys.exports.ATWriter;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Writer;
+
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.Locale;
+
+import org.apache.log4j.Logger;
+
+public class FixATWriter
+{
+    private static Logger log = Logger.getLogger(FixATWriter.class);
+
+    public static final String I18N_HEADER_KEY =
+        "fix.export.at.header";
+
+    public static final String I18N_HEADER_DEFAULT =
+        "Exported fixings discharge curve for {0} {0}-km: {1}";
+
+    public static final String [] Q_MAX_COLUMN = new String [] { "max_q" };
+
+    public static class WQ {
+
+        protected double w;
+        protected double q;
+
+        public WQ() {
+        }
+
+        public WQ(double w, double q) {
+            this.w = w;
+            this.q = q;
+        }
+    } // class WQ
+
+    protected Function   function;
+    protected Parameters parameters;
+
+    public FixATWriter() {
+    }
+
+    public FixATWriter(Function function, Parameters parameters) {
+        this.function   = function;
+        this.parameters = parameters;
+    }
+
+    public void write(
+        Writer   writer,
+        CallMeta meta,
+        String   river,
+        double   km
+    )
+    throws IOException {
+        PrintWriter out = new PrintWriter(writer);
+        printHeader(out, meta, river, km);
+
+        double [] coeffs = parameters.interpolate(
+            "km", km, function.getParameterNames());
+
+        double [] qMax = parameters.interpolate(
+            "km", km, Q_MAX_COLUMN);
+
+        if (coeffs == null || qMax == null) {
+            log.debug("No data found at km " + km + ".");
+            return;
+        }
+
+        de.intevation.flys.artifacts.math.Function funcInst =
+            function.instantiate(coeffs);
+
+        double wMax = funcInst.value(qMax[0]);
+
+        if (Double.isNaN(wMax) || wMax < 0d) {
+            log.debug("function '" + function.getName() +
+                "' eval failed at " + wMax);
+            return;
+        }
+
+        Function inverse = function.getInverse();
+
+        de.intevation.flys.artifacts.math.Function invInst =
+            inverse.instantiate(coeffs);
+
+        /* TODO: Do some fancy root finding stuff with the
+         * first derivative of the inverse function to find
+         * the minimum of function and directly export
+         * the longest strict monotonous ascending run of
+         * ws of the inverse in range [0, wMax].
+         *
+         * To simplify the situation we iterate in steps
+         * of 10cm over the range and export the longest
+         * run.
+         */
+
+        ArrayDeque<WQ> longest = new ArrayDeque<WQ>();
+        ArrayDeque<WQ> current = new ArrayDeque<WQ>();
+
+        for (double w = 0d; w <= wMax; w += 0.1d) {
+            double q = invInst.value(w);
+
+            if (Double.isNaN(q)) {
+                log.debug("Eval of inverse for " + w + " failed.");
+                continue;
+            }
+
+            WQ wq = new WQ(w, q);
+
+            if (current.isEmpty() || current.getLast().q < q) {
+                current.add(wq);
+            }
+            else {
+                if (current.size() >= longest.size()) {
+                    longest = current;
+                }
+                current = new ArrayDeque<WQ>();
+                current.add(wq);
+            }
+        }
+
+        if (current.size() >= longest.size()) {
+            longest = current;
+        }
+
+        printWQs(out, longest);
+        out.flush();
+    }
+
+    protected void printWQs(PrintWriter out, Collection<WQ> wqs) {
+        int lastColumn = 10;
+        for (WQ wq: wqs) {
+            int column = (int)(wq.w * 10d) % 10;
+
+            if (lastColumn > column) {
+                for (; lastColumn < 10; ++lastColumn) {
+                    out.print(ATWriter.EMPTY);
+                }
+                out.println();
+                out.printf(Locale.US, "%8d", (int)Math.round(wq.w*100.0));
+                lastColumn = 0;
+            }
+            for (;lastColumn < column-1; ++lastColumn) {
+                out.print(ATWriter.EMPTY);
+            }
+            ATWriter.printQ(out, wq.q);
+
+            lastColumn = column;
+        }
+        out.println();
+    }
+
+    protected void printHeader(
+        PrintWriter out,
+        CallMeta    meta,
+        String      river,
+        double      km
+    ) {
+        out.println(Resources.format(
+            meta,
+            I18N_HEADER_KEY,
+            I18N_HEADER_DEFAULT,
+            river, km));
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/resources/messages.properties	Sun Jul 01 08:46:04 2012 +0000
+++ b/flys-artifacts/src/main/resources/messages.properties	Sun Jul 01 11:18:59 2012 +0000
@@ -369,3 +369,5 @@
 fix.km.chart.w.axis=W [NN + m]
 fix.km.chart.measured=measured
 fix.km.chart.interpolated=interpolated
+
+fix.export.at.header = Exported fixings discharge curve for {0} {0}-km: {1}
--- a/flys-artifacts/src/main/resources/messages_de.properties	Sun Jul 01 08:46:04 2012 +0000
+++ b/flys-artifacts/src/main/resources/messages_de.properties	Sun Jul 01 11:18:59 2012 +0000
@@ -370,3 +370,5 @@
 fix.km.chart.w.axis=W [NN + m]
 fix.km.chart.measured=gemessen
 fix.km.chart.interpolated=interpoliert
+
+fix.export.at.header =  Abflusskurve aus der Fixierungsanalyse f\u00fcr {0} {0}-km: {1}
--- a/flys-artifacts/src/main/resources/messages_de_DE.properties	Sun Jul 01 08:46:04 2012 +0000
+++ b/flys-artifacts/src/main/resources/messages_de_DE.properties	Sun Jul 01 11:18:59 2012 +0000
@@ -369,3 +369,5 @@
 fix.km.chart.w.axis=W [NN + m]
 fix.km.chart.measured=gemessen
 fix.km.chart.interpolated=interpoliert
+
+fix.export.at.header =  Abflusskurve aus der Fixierungsanalyse f\u00fcr {0} {0}-km: {1}
--- a/flys-artifacts/src/main/resources/messages_en.properties	Sun Jul 01 08:46:04 2012 +0000
+++ b/flys-artifacts/src/main/resources/messages_en.properties	Sun Jul 01 11:18:59 2012 +0000
@@ -369,3 +369,5 @@
 fix.km.chart.w.axis=W [NN + m]
 fix.km.chart.measured=measured
 fix.km.chart.interpolated=interpolated
+
+fix.export.at.header = Exported fixings discharge curve for {0} {0}-km: {1}

http://dive4elements.wald.intevation.org