diff flys-artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixATWriter.java @ 5831:bd047b71ab37

Repaired internal references
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 12:06:39 +0200
parents flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java@8bbb9e173297
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixATWriter.java	Thu Apr 25 12:06:39 2013 +0200
@@ -0,0 +1,187 @@
+package org.dive4elements.river.exports.fixings;
+
+import org.dive4elements.artifacts.CallMeta;
+
+import org.dive4elements.river.artifacts.math.fitting.Function;
+
+import org.dive4elements.river.artifacts.model.Parameters;
+
+import org.dive4elements.river.artifacts.resources.Resources;
+
+import org.dive4elements.river.exports.ATWriter;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Writer;
+
+import java.util.Locale;
+
+import org.apache.log4j.Logger;
+
+/** Export Fixation Analysis Results to AT. */
+public class FixATWriter
+{
+    /** Private logger. */
+    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" };
+
+    private static final int    MAX_ITERATIONS = 10000;
+    private static final double EPSILON        = 1e-8;
+    private static final double MIN_Q          = 1e-4;
+
+    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;
+        }
+
+        org.dive4elements.river.artifacts.math.Function funcInst =
+            function.instantiate(coeffs);
+
+        // Increase Q max about 5%.
+        qMax[0] += Math.abs(qMax[0])*0.05;
+
+        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();
+
+        org.dive4elements.river.artifacts.math.Function invInst =
+            inverse.instantiate(coeffs);
+
+        double wMin = minW(invInst, wMax, qMax[0]);
+
+        double wMinCM = wMin * 100d;
+        double wMaxCM = wMax * 100d;
+
+        int wRow = ((int)wMinCM / 10) * 10;
+
+        if ((wMinCM - (int)wMinCM) > 0d) {
+            wMinCM = (int)wMinCM + 1d;
+        }
+
+        double w = wMinCM / 100.0;
+
+        int wcm = ((int)wMinCM) % 10;
+
+        if (log.isDebugEnabled()) {
+            log.debug("wMinCM: " + wMinCM);
+            log.debug("wMaxCM: " + wMaxCM);
+            log.debug("wcm: " + wcm);
+        }
+
+        out.printf(Locale.US, "%8d", wRow);
+
+        if (wcm > 0) {
+            int rest = 10 - wcm;
+            while (rest-- > 0) {
+                out.print(ATWriter.EMPTY);
+            }
+        }
+
+        for (;;) {
+            while (wcm++ < 10) {
+                if (w > wMax) {
+                    break;
+                }
+                double q = invInst.value(w);
+                if (Double.isNaN(w)) {
+                    out.print(ATWriter.EMPTY);
+                }
+                else {
+                    ATWriter.printQ(out, q);
+                }
+                w += 0.01d;
+            }
+            out.println();
+            if (w > wMax) {
+                break;
+            }
+            out.printf(Locale.US, "%8d", wRow += 10);
+            wcm = 0;
+        }
+
+        out.flush();
+    }
+
+    protected void printHeader(
+        PrintWriter out,
+        CallMeta    meta,
+        String      river,
+        double      km
+    ) {
+        out.println(Resources.format(
+            meta,
+            I18N_HEADER_KEY,
+            I18N_HEADER_DEFAULT,
+            river, km));
+    }
+
+    private static double minW(
+        org.dive4elements.river.artifacts.math.Function function,
+        double maxW,
+        double maxQ
+    ) {
+        double stepWidth = 10d;
+
+        double lastW = maxW;
+        double lastQ = maxQ;
+
+        for (int i = 0; i < MAX_ITERATIONS; ++i) {
+            double w = lastW - stepWidth;
+            double q = function.value(w);
+
+            if (Double.isNaN(q) || q > lastQ || q < MIN_Q) {
+                if (stepWidth < EPSILON) {
+                    break;
+                }
+                stepWidth *= 0.5d;
+                continue;
+            }
+
+            lastW = w;
+            lastQ = q;
+        }
+
+        return lastW;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org