sascha@729: package de.intevation.flys.exports; sascha@729: sascha@729: import java.io.IOException; sascha@729: import java.io.Writer; sascha@729: import java.io.PrintWriter; sascha@729: sascha@729: import java.util.Locale; sascha@729: sascha@729: import de.intevation.flys.artifacts.model.WQ; sascha@729: sascha@732: import org.apache.commons.math.analysis.UnivariateRealFunction; sascha@729: sascha@732: import org.apache.commons.math.analysis.interpolation.SplineInterpolator; sascha@732: import org.apache.commons.math.analysis.interpolation.LinearInterpolator; sascha@729: sascha@732: import org.apache.commons.math.analysis.polynomials.PolynomialFunction; sascha@732: sascha@732: import org.apache.commons.math.FunctionEvaluationException; sascha@729: sascha@729: import org.apache.log4j.Logger; sascha@729: sascha@729: public class ATWriter sascha@729: { sascha@729: private static Logger logger = Logger.getLogger(ATWriter.class); sascha@729: sascha@729: public static final int COLUMNS = 10; sascha@729: sascha@732: public static final String EMPTY = " "; sascha@729: sascha@729: protected double minW; sascha@729: protected double maxW; sascha@729: protected double minQ; sascha@729: protected double maxQ; sascha@729: sascha@732: protected UnivariateRealFunction qFunc; sascha@729: sascha@729: public ATWriter() { sascha@729: } sascha@729: sascha@729: public ATWriter(WQ wq) throws IllegalArgumentException { sascha@729: sascha@729: int maxIndex = maxIncreasingWIndex(wq); sascha@729: sascha@729: if (maxIndex < 1) { // Only first w can be written out. sascha@729: minW = maxW = wq.getW(0); sascha@729: minQ = maxQ = wq.getQ(0); sascha@732: // constant function sascha@732: qFunc = new PolynomialFunction(new double [] { minQ }); sascha@729: return; sascha@729: } sascha@729: sascha@729: double [] ws = new double[maxIndex+1]; sascha@729: double [] qs = new double[ws.length]; sascha@729: sascha@729: for (int i = 0; i < ws.length; ++i) { sascha@729: ws[i] = wq.getW(i); sascha@729: qs[i] = wq.getQ(i); sascha@729: } sascha@729: sascha@732: qFunc = ws.length < 3 sascha@732: ? new LinearInterpolator().interpolate(ws, qs) sascha@732: : new SplineInterpolator().interpolate(ws, qs); sascha@729: sascha@729: minW = wq.getW(0); sascha@729: maxW = wq.getW(maxIndex); sascha@729: minQ = wq.getQ(0); sascha@729: maxQ = wq.getQ(maxIndex); sascha@729: } sascha@729: sascha@729: public static int maxIncreasingWIndex(WQ wq) { sascha@729: sascha@729: int N = wq.size(); sascha@729: sascha@729: if (N < 2) { sascha@729: return N-1; sascha@729: } sascha@729: sascha@729: double last = wq.getW(0); sascha@729: sascha@729: for (int i = 1; i < N; ++i) { sascha@729: double current = wq.getW(i); sascha@729: if (current <= last) { sascha@729: return i-1; sascha@729: } sascha@729: } sascha@729: sascha@729: return N-1; sascha@729: } sascha@729: sascha@729: public double getQ(double w) { sascha@729: sascha@729: try { sascha@729: return qFunc.value(w); sascha@729: } sascha@732: catch (FunctionEvaluationException aode) { sascha@729: // should not happen sascha@729: logger.warn("spline interpolation failed", aode); sascha@729: return w <= minW ? minQ : maxQ; sascha@729: } sascha@729: } sascha@729: sascha@729: protected static void printQ(PrintWriter out, double q) { sascha@729: String format; sascha@732: if (q < 1d) format = " % 8.3f"; sascha@732: else if (q < 10d) format = " % 8.2f"; sascha@732: else if (q < 100d) format = " % 8.1f"; sascha@729: else { sascha@729: format = " % 8.0f"; sascha@732: if (q > 1000d) q = Math.rint(q/10d)*10d; sascha@729: } sascha@729: out.printf(Locale.US, format, q); sascha@729: } sascha@729: sascha@729: public void write(Writer writer) throws IOException { sascha@729: sascha@729: PrintWriter out = new PrintWriter(writer); sascha@729: sascha@732: double rest = Math.abs(minW % COLUMNS); sascha@729: sascha@732: double startW = Math.round(minW*10.0)/10.0; sascha@729: if (rest >= 1d) { sascha@732: startW -= 0.1; sascha@732: out.printf(Locale.US, "%8d", (int)Math.round(startW*100.0)); sascha@729: int columns = (int)Math.floor(rest); sascha@729: for (int i = columns; i < COLUMNS; ++i) { sascha@729: out.print(EMPTY); sascha@729: } sascha@732: for (int i = COLUMNS-columns; i < COLUMNS; ++i) { sascha@732: printQ(out, getQ(startW + i*0.01)); sascha@729: } sascha@732: out.println(); sascha@732: startW += 0.1; sascha@729: } sascha@729: sascha@729: int col = 0; sascha@732: for (double w = startW; w <= maxW; w += 0.01) { sascha@732: if (col == 0) { sascha@732: out.printf(Locale.US, "%8d", (int)Math.round(w*100.0)); sascha@732: } sascha@729: sascha@729: printQ(out, getQ(w)); sascha@729: sascha@729: if (++col >= COLUMNS) { sascha@729: out.println(); sascha@729: col = 0; sascha@729: } sascha@729: } sascha@729: sascha@729: if (col > 0) { sascha@729: out.println(); sascha@729: } sascha@729: sascha@729: out.flush(); sascha@729: } sascha@729: } sascha@729: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :