Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixATWriter.java @ 3402:0336132ec9db
Adjusted Delta W(t) CSV exporter to customers wishes.
flys-artifacts/trunk@5044 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 18 Jul 2012 16:28:00 +0000 |
parents | 0c8a6145098b |
children | 1dc904370a64 |
line wrap: on
line source
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 :