view flys-artifacts/src/main/java/de/intevation/flys/artifacts/MainValuesArtifact.java @ 5430:ba489a16f4d8

Datacage Function Resolver: Lift from static to object space.
author Sascha L. Teichmann <teichmann@intevation.de>
date Tue, 26 Mar 2013 16:16:12 +0100
parents a916e1202f0f
children
line wrap: on
line source
package de.intevation.flys.artifacts;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import org.w3c.dom.Document;

import de.intevation.artifactdatabase.data.DefaultStateData;
import de.intevation.artifactdatabase.state.Facet;
import de.intevation.artifactdatabase.state.FacetActivity;
import de.intevation.artifactdatabase.state.DefaultOutput;
import de.intevation.artifactdatabase.state.State;

import de.intevation.artifacts.Artifact;
import de.intevation.artifacts.ArtifactFactory;
import de.intevation.artifacts.CallMeta;

import de.intevation.flys.model.Gauge;
import de.intevation.flys.model.MainValue;
import de.intevation.flys.model.River;

import de.intevation.flys.artifacts.access.RangeAccess;
import de.intevation.flys.artifacts.model.Calculation;
import de.intevation.flys.artifacts.model.FacetTypes;
import de.intevation.flys.artifacts.model.MainValuesQFacet;
import de.intevation.flys.artifacts.model.MainValuesWFacet;
import de.intevation.flys.artifacts.model.NamedDouble;
import de.intevation.flys.artifacts.model.WstValueTable;
import de.intevation.flys.artifacts.model.WstValueTableFactory;

import de.intevation.flys.artifacts.states.StaticState;
import de.intevation.flys.artifacts.resources.Resources;

import de.intevation.flys.utils.FLYSUtils;


/**
 * Artifact to access main and extreme values of a river.
 * This artifact neglects (Static)FLYSArtifacts capabilities of interaction
 * with the StateEngine by overriding the getState*-methods.
 */
public class MainValuesArtifact
extends      StaticFLYSArtifact
implements   FacetTypes
{
    /** The logger for this class. */
    private static Logger logger = Logger.getLogger(MainValuesArtifact.class);

    /** The name of the artifact. */
    public static final String ARTIFACT_NAME = "mainvalue";

    /** The name of the static state for this artifact. */
    public static final String STATIC_STATE_NAME = "state.mainvalue.static";

    /** One and only state to be in. */
    protected transient State state = null;


    static {
        // TODO: Move to configuration.
        FacetActivity.Registry.getInstance().register(
            ARTIFACT_NAME,
            new FacetActivity() {
                @Override
                public Boolean isInitialActive(
                    Artifact artifact,
                    Facet    facet,
                    String   outputName
                ) {
                    return outputName.equals("computed_discharge_curve")
                        || outputName.equals("duration_curve");
                }
            });
    }


    /**
     * Trivial Constructor.
     */
    public MainValuesArtifact() {
        logger.debug("MainValuesArtifact.MainValuesartifact()");
    }


    /**
     * Gets called from factory, to set things up.
     */
    @Override
    public void setup(
        String          identifier,
        ArtifactFactory factory,
        Object          context,
        CallMeta        callMeta,
        Document        data)
    {
        logger.debug("MainValuesArtifact.setup");
        state = new StaticState(STATIC_STATE_NAME);

        List<Facet> fs = new ArrayList<Facet>();
        addFacets(state.getID(), fs);
        spawnState();
        super.setup(identifier, factory, context, callMeta, data);
        String restriction = getDatacageIDValue(data);
        logger.debug("mainvalue restriction " + restriction);
        boolean restricted = restriction.endsWith("q") || restriction.endsWith("w");
        if (!restricted || restriction.endsWith("q")) {
            Facet qfacet0 = new MainValuesQFacet(
                DURATION_MAINVALUES_Q,
                Resources.getMsg(
                    callMeta,
                    "facet.discharge_curves.mainvalues.q",
                    "facet.discharge_curves.mainvalues.q"),
                false);
            Facet qfacet1 = new MainValuesQFacet(
                COMPUTED_DISCHARGE_MAINVALUES_Q,
                Resources.getMsg(
                    callMeta,
                    "facet.discharge_curves.mainvalues.q",
                    "facet.discharge_curves.mainvalues.q"),
                false);
            Facet qfacet2 = new MainValuesQFacet(
                MAINVALUES_Q,
                Resources.getMsg(
                    callMeta,
                    "facet.discharge_curves.mainvalues.q",
                    "facet.discharge_curves.mainvalues.q"),
                true);
            Facet qfacet3 = new MainValuesQFacet(
                HISTORICAL_DISCHARGE_MAINVALUES_Q,
                Resources.getMsg(
                    callMeta,
                    "historical_discharge.mainvalues.q",
                    "historical_discharge.mainvalues.q"),
                false);

            fs.add(qfacet0);
            fs.add(qfacet1);
            fs.add(qfacet2);
            fs.add(qfacet3);
        }
        if (!restricted || restriction.endsWith("w")) {
            Facet wfacet1 = new MainValuesWFacet(
                COMPUTED_DISCHARGE_MAINVALUES_W,
                Resources.getMsg(
                    callMeta,
                    "facet.discharge_curves.mainvalues.w",
                    "facet.discharge_curves.mainvalues.w"),
                false);
            Facet wfacet2 = new MainValuesWFacet(
                MAINVALUES_W,
                Resources.getMsg(
                    callMeta,
                    "facet.discharge_curves.mainvalues.w",
                    "facet.discharge_curves.mainvalues.w"),
                true);
            Facet wfacet3 = new MainValuesWFacet(
                HISTORICAL_DISCHARGE_MAINVALUES_W,
                Resources.getMsg(
                    callMeta,
                    "historical_discharge.mainvalues.w",
                    "historical_discharge.mainvalues.w"),
                true);
            fs.add(wfacet1);
            fs.add(wfacet2);
            fs.add(wfacet3);
        }
    }


    /**
     * Create "the" state.
     */
    protected State spawnState() {
        state = new StaticState(STATIC_STATE_NAME);
        List<Facet> fs = (List<Facet>) getFacets(STATIC_STATE_NAME);

        DefaultOutput mainValuesOutput = new DefaultOutput(
            "computed_discharge_curve",
            "output.computed_discharge_curve", "image/png",
            fs,
            "chart");

        state.getOutputs().add(mainValuesOutput);
        return state;
    }


    /** Get important data from the 'calling' artifact. */
    @Override
    protected void initialize(Artifact artifact, Object context, CallMeta meta) {
        logger.debug("MainValuesArtifact.initialize");
        FLYSArtifact winfo = (FLYSArtifact) artifact;
        RangeAccess rangeAccess = new RangeAccess(winfo, null);
        double [] locations = rangeAccess.getKmRange();

        if (locations != null) {
            double location = locations[0];
            addData("ld_locations", new DefaultStateData("ld_locations", null, null,
                    String.valueOf(location)));
        }
        else {
            logger.error("No location for mainvalues given.");
        }
        importData(winfo, "river");
        // In the case of DischargeWQCurves, there are no locations, but a gauge.
        if (getDataAsString("ld_locations") == null) {
            // TODO its a tad difficult to remodel Range/Gauge-Access to
            // do this.
            String refGaugeID = winfo.getDataAsString("reference_gauge");
            if (refGaugeID != null) {
                Gauge g = Gauge.getGaugeByOfficialNumber(Integer.parseInt(refGaugeID));
                addData("ld_locations", new DefaultStateData("ld_locations", null, null,
                    String.valueOf(g.getStation())));
            }
            else {
                logger.error("MainValuesArtifact: No location/gauge.");
            }
        }
    }


    /**
     * Get a list containing the one and only State.
     * @param  context ignored.
     * @return list with one and only state.
     */
    @Override
    protected List<State> getStates(Object context) {
        ArrayList<State> states = new ArrayList<State>();
        states.add(getState());
        return states;
    }


    /**
     * Get the "current" state.
     * @param cc ignored.
     * @return the "current" state.
     */
    @Override
    public State getCurrentState(Object cc) {
        return getState();
    }


    /**
     * Get the only possible state.
     * @return the state.
     */
    protected State getState() {
        return getState(null, null);
    }


    /**
     * Get the state.
     * @param context ignored.
     * @param stateID ignored.
     * @return the state.
     */
    @Override
    protected State getState(Object context, String stateID) {
        if (state != null)
            return state;
        else
            return spawnState();
    }


    /**
     * Access the Gauge that the mainvalues are taken from.
     * @return Gauge that main values are taken from or null in case of
     *         invalid parameterization.
     */
    protected Gauge getGauge() {
        River river = FLYSUtils.getRiver(this);

        // TODO use helper to get location as double
        String locationStr = getDataAsString("ld_locations");

        if (river == null) {
            logger.error("River is null");
            return null;
        }

        if (locationStr == null) {
            logger.error("Locationstr is null");
            return null;
        }

        double location = Double.parseDouble(locationStr);

        return river.determineGaugeByPosition(location);
    }


    /**
     * Get current location.
     * @return the location.
     */
    public double getLocation() {
        double location = Double.parseDouble(getDataAsString("ld_locations"));
        return location;
    }


    /**
     * Get a list of "Q" main values.
     * @return list of Q main values.
     */
    public List<NamedDouble> getMainValuesQ(boolean atGauge) {
        List<NamedDouble> filteredList = new ArrayList<NamedDouble>();
        Gauge gauge = getGauge();
        WstValueTable interpolator = WstValueTableFactory.getTable(FLYSUtils.getRiver(this));
        Calculation c = new Calculation();
        double w_out[] = {0.0f};
        double q_out[] = {0.0f};
        double kms[] = {getLocation()};
        double gaugeStation = gauge.getStation().doubleValue();
        if (gauge != null) {
            List<MainValue> orig = gauge.getMainValues();
            for (MainValue mv : orig) {
                if (mv.getMainValue().getType().getName().equals("Q")) {
                    if (atGauge) {
                        q_out[0] = mv.getValue().doubleValue();
                    }
                    else {
                        interpolator.interpolate(mv.getValue().doubleValue(),
                            gaugeStation, kms, w_out, q_out, c);
                    }
                    filteredList.add(new NamedDouble(
                                mv.getMainValue().getName(),
                                q_out[0]
                                ));
                }
            }
        }
        return filteredList;
    }


    /**
     * Get a list of "W" main values.
     * @param atGauge if true, do not interpolate
     * @return list of W main values.
     */
    public List<NamedDouble> getMainValuesW(boolean atGauge) {
        List<NamedDouble> filteredList = new ArrayList<NamedDouble>();
        Gauge gauge = getGauge();
        WstValueTable interpolator = WstValueTableFactory.getTable(FLYSUtils.getRiver(this));
        Calculation c = new Calculation();

        double gaugeStation = gauge.getStation().doubleValue();
        double w_out[] = {0.0f};
        double q_out[] = {0.0f};
        double kms[] = {getLocation()};
        if (gauge != null) {
            List<MainValue> orig = gauge.getMainValues();
            for (MainValue mv : orig) {
                if (atGauge) {
                    if (mv.getMainValue().getType().getName().equals("W")) {
                        filteredList.add(new NamedDouble(mv.getMainValue().getName(),
                                mv.getValue().doubleValue()));

                    }
                } else
                // We cannot interpolate the W values, so derive them
                // from given Q values.
                if (mv.getMainValue().getType().getName().equals("Q")) {
                    interpolator.interpolate(mv.getValue().doubleValue(),
                            gaugeStation, kms, w_out, q_out, c);
                    filteredList.add(new NamedDouble(
                                "W(" + mv.getMainValue().getName() +")",
                                w_out[0]
                                ));
                }
            }
        }
        return filteredList;
    }


    /**
     * Returns the name of this artifact ('mainvalue').
     *
     * @return 'mainvalue'
     */
    public String getName() {
        return ARTIFACT_NAME;
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org