view flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation6.java @ 4205:0dd8963cec9c

Set also the width of the GaugeTree when resizing the GaugePanel GWT is no longer able to calculate and set the correct width of the GaugeTree since the GaugeTree is added via a Canvas wrapper. Therefore set the width manually when resizing the GaugeTree.
author Björn Ricks <bjoern.ricks@intevation.de>
date Mon, 22 Oct 2012 15:33:16 +0200
parents 1d9c9a3493ea
children b3aa91e45010
line wrap: on
line source
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 = 1d;


    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, DischargeTables.HISTORICAL_SCALE);

                    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, DischargeTables.MASTER_SCALE);
            }
            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, DischargeTables.HISTORICAL_SCALE);

                    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 scale) {
        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