Mercurial > dive4elements > river
view artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixATWriter.java @ 6140:60b94dec104b
Add handling of bound artifacts.
When an artifact is bound to an out its facets will only be shown
in that Out. They will be removed in the blackboard pass and marked
as incompatible by the AttributeWriter
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Fri, 31 May 2013 15:29:30 +0200 |
parents | af13ceeba52a |
children | 715e010d40de |
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde * Software engineering by Intevation GmbH * * This file is Free Software under the GNU AGPL (>=v3) * and comes with ABSOLUTELY NO WARRANTY! Check out the * documentation coming with Dive4Elements River for details. */ 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 :