diff flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation6.java @ 3468:f37e7e8907cb

merged flys-artifacts/2.8.1
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:39 +0200
parents 200e70f31f6f
children b6ba9bbb5122
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation6.java	Fri Sep 28 12:14:39 2012 +0200
@@ -0,0 +1,315 @@
+package de.intevation.flys.artifacts.model;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.flys.model.DischargeTable;
+import de.intevation.flys.model.Gauge;
+import de.intevation.flys.model.TimeInterval;
+
+
+/**
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class Calculation6 extends Calculation {
+
+    private static final Logger logger = Logger.getLogger(Calculation6.class);
+
+    private int      mode;
+    private long[]   timerange;
+    private double[] values;
+
+
+    public static final int MODE_W = 0;
+    public static final int MODE_Q = 1;
+
+    public static final double SCALE = 100d;
+
+
+    public Calculation6(int mode, long[] timerange, double[] values) {
+        this.mode      = mode;
+        this.timerange = timerange;
+        this.values    = values;
+    }
+
+
+    public CalculationResult calculate(Gauge gauge) {
+        if (!checkParameters() || gauge == null) {
+            logger.warn("Parameters not valid for calculation.");
+
+            return null;
+        }
+
+        if (logger.isDebugEnabled()) {
+            debug();
+        }
+
+        DischargeTable  refTable = fetchReferenceTable(gauge);
+        List<DischargeTable> dts = fetchDischargeTables(gauge);
+
+        int numTables = dts.size();
+
+        logger.debug("Take " + numTables + " into account.");
+
+        if (numTables == 0) {
+            addProblem("cannot.find.hist.q.tables");
+        }
+
+        WQTimerange[] wqt = prepareCalculationData(refTable, dts);
+
+        logger.debug("Number of calculation results: " + wqt.length);
+
+        return new CalculationResult(wqt, this);
+    }
+
+
+    protected boolean checkParameters() {
+        if (!(mode == MODE_W || mode == MODE_Q)) {
+            logger.warn("Invalid mode '" + mode + "' for calculation.");
+            return false;
+        }
+
+        if (timerange == null || timerange.length < 2) {
+            logger.warn("Invalid timerange for calculation.");
+            return false;
+        }
+
+        if (values == null || values.length == 0) {
+            logger.warn("No values for W or Q specified.");
+            return false;
+        }
+
+        return true;
+    }
+
+
+    protected DischargeTable fetchReferenceTable(Gauge gauge) {
+        return gauge.fetchMasterDischargeTable();
+    }
+
+
+    protected List<DischargeTable> fetchDischargeTables(Gauge gauge) {
+        List<DischargeTable> relevant = new ArrayList<DischargeTable>();
+        List<DischargeTable> all      = gauge.getDischargeTables();
+
+        for (DischargeTable dt: all) {
+            if (isDischargeTableRelevant(dt)) {
+                relevant.add(dt);
+            }
+        }
+
+        return relevant;
+    }
+
+
+    protected boolean isDischargeTableRelevant(DischargeTable dt) {
+        TimeInterval ti = dt.getTimeInterval();
+
+        if (dt.getKind() == Gauge.MASTER_DISCHARGE_TABLE || ti == null) {
+            return false;
+        }
+
+        Date start     = ti.getStartTime();
+        long startTime = start.getTime();
+
+        if (startTime >= timerange[0] && startTime <= timerange[1]) {
+            return true;
+        }
+
+        Date stop     = ti.getStopTime();
+        long stopTime = stop != null ? stop.getTime() : -1l;
+
+        if (stopTime >= timerange[0] && stopTime <= timerange[1]) {
+            return true;
+        }
+
+        logger.debug("DischargeTable not in range: " + start + " -> " + stop);
+
+        return false;
+    }
+
+
+    protected WQTimerange[] prepareCalculationData(
+        DischargeTable       refTable,
+        List<DischargeTable> dts
+    ) {
+        if (refTable == null) {
+            addProblem("cannot.find.hist.q.reftable");
+            return prepareSimpleData(dts);
+        }
+        else {
+            return prepareData(refTable, dts);
+        }
+    }
+
+
+    protected WQTimerange[] prepareSimpleData(List<DischargeTable> dts) {
+        List<WQTimerange> wqts =
+            new ArrayList<WQTimerange>(values.length);
+
+        for (double value: values) {
+            logger.debug("Prepare data for value: " + value);
+
+            String name      = mode == MODE_W ? "W=" + value : "Q=" + value;
+            WQTimerange wqt  = null;
+
+            for (DischargeTable dt: dts) {
+                Date[]   ti = prepareTimeInterval(dt);
+                Timerange t = new Timerange(ti[0], ti[1]);
+                double    w;
+                double    q;
+
+                if (mode == MODE_W) {
+                    w = value;
+                    q = findValueForW(dt, w);
+
+                    if (Double.isNaN(q)) {
+                        logger.warn("Cannot find Q for W: " + w);
+                        addProblem("cannot.find.hist.q.for.w", w, ti[0], ti[1]);
+                        continue;
+                    }
+                }
+                else {
+                    q = value;
+                    w = findValueForQ(dt, q);
+                }
+
+                logger.debug("Q=" + q + " | W=" + w);
+
+                if (wqt == null) {
+                    wqt = new WQTimerange(name);
+                }
+
+                wqt.add(w, q, t);
+            }
+
+            if (wqt != null) {
+                wqts.add(wqt);
+            }
+        }
+
+        return wqts.toArray(new WQTimerange[wqts.size()]);
+    }
+
+
+    protected HistoricalWQTimerange[] prepareData(
+        DischargeTable       refTable,
+        List<DischargeTable> dts
+    ) {
+        List<HistoricalWQTimerange> wqts =
+            new ArrayList<HistoricalWQTimerange>(values.length);
+
+        for (double value: values) {
+            logger.debug("Prepare data plus diff for value: " + value);
+
+            String name = mode == MODE_W ? "W=" + value : "Q=" + value;
+            HistoricalWQTimerange wqt  = null;
+
+            double ref;
+            double diff;
+
+            if (refTable != null && mode == MODE_W) {
+                ref = findValueForW(refTable, value);
+            }
+            else if (refTable != null) {
+                ref = findValueForQ(refTable, value);
+            }
+            else {
+                ref = Double.NaN;
+            }
+
+            for (DischargeTable dt: dts) {
+                Date[] ti = prepareTimeInterval(dt);
+
+                Timerange t = new Timerange(ti[0] ,ti[1]);
+                double    w;
+                double    q;
+
+                if (mode == MODE_W) {
+                    w    = value;
+                    q    = findValueForW(dt, w);
+
+                    if (Double.isNaN(q)) {
+                        logger.warn("Cannot find Q for W: " + w);
+                        addProblem("cannot.find.hist.q.for.w", w, ti[0], ti[1]);
+                        continue;
+                    }
+
+                    diff = ref-q;
+                }
+                else {
+                    q    = value;
+                    w    = findValueForQ(dt, q);
+                    diff = ref-w;
+                }
+
+                logger.debug("Q=" + q + " | W=" + w + " | Ref = " + ref);
+
+                if (wqt == null) {
+                    wqt = new HistoricalWQTimerange(name);
+                }
+
+                wqt.add(w, q, diff, t);
+            }
+
+            if (wqt != null) {
+                wqts.add(wqt);
+            }
+        }
+
+        return (HistoricalWQTimerange[])
+            wqts.toArray(new HistoricalWQTimerange[wqts.size()]);
+    }
+
+
+    protected Date[] prepareTimeInterval(DischargeTable dt) {
+        TimeInterval ti = dt.getTimeInterval();
+
+        Date start = ti.getStartTime();
+        Date end   = ti.getStopTime();
+
+        if (end == null) {
+            logger.warn("TimeInterval has no stop time set!");
+
+            end = new Date();
+        }
+
+        return new Date[] { start, end };
+    }
+
+
+    protected double findValueForW(DischargeTable dt, double w) {
+        double[][] vs = DischargeTables.loadDischargeTableValues(dt, SCALE);
+        double [] qs = DischargeTables.getQsForW(vs, w);
+        return qs.length == 0 ? Double.NaN : qs[0];
+    }
+
+
+    protected double findValueForQ(DischargeTable dt, double q) {
+        double[][] vs = DischargeTables.loadDischargeTableValues(dt, SCALE);
+        logger.warn("TODO: IMPLEMENT ME!");
+
+        return 10;
+    }
+
+
+    /**
+     * Writes the parameters used for this calculation to logger.
+     */
+    public void debug() {
+        StringBuilder sb = new StringBuilder();
+        for (double value: values) {
+            sb.append(String.valueOf(value) + " ");
+        }
+
+        logger.debug("========== Calculation6 ==========");
+        logger.debug("   Mode:         " + mode);
+        logger.debug("   Timerange:    " + timerange[0] + " - " + timerange[1]);
+        logger.debug("   Input values: " + sb.toString());
+        logger.debug("==================================");
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org