view flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/SQRelationCalculation.java @ 3389:816ceb0418b9

Q is not taken from MESSUNG.Q but from MESSUNG.Q_BPEGEL flys-artifacts/trunk@5017 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 16 Jul 2012 09:12:56 +0000
parents 8af1111af180
children 1c9aaef89f51
line wrap: on
line source
package de.intevation.flys.artifacts.model.sq;

import de.intevation.flys.artifacts.access.SQRelationAccess;

import de.intevation.flys.artifacts.math.fitting.Function;
import de.intevation.flys.artifacts.math.fitting.FunctionFactory;

import de.intevation.flys.artifacts.model.Calculation;
import de.intevation.flys.artifacts.model.CalculationResult;
import de.intevation.flys.artifacts.model.DateRange;
import de.intevation.flys.artifacts.model.Parameters;

import de.intevation.flys.backend.SedDBSessionHolder;

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

import org.apache.log4j.Logger;

public class SQRelationCalculation extends Calculation {

    private static final Logger log =
        Logger.getLogger(SQRelationCalculation.class);

    public static final String SQ_FUNCTION_NAME = "sq-pow";

    protected String       river;
    protected double       location;
    protected DateRange [] periods;
    protected double       outliers;

    public SQRelationCalculation() {
    }

    public SQRelationCalculation(SQRelationAccess access) {

        String       river    = access.getRiver();
        Double       location = access.getLocation();
        DateRange [] periods  = access.getPeriods();
        Double       outliers = access.getOutliers();

        if (river == null) {
            // TODO: i18n
            addProblem("sq.missing.river");
        }

        if (location == null) {
            // TODO: i18n
            addProblem("sq.missing.location");
        }

        if (periods == null || periods.length == 0) {
            // TODO: i18n
            addProblem("sq.missing.periods");
        }

        if (outliers == null) {
            // TODO: i18n
            addProblem("sq.missing.outliers");
        }

        if (!hasProblems()) {
            this.river    = river;
            this.location = location;
            this.periods  = periods;
            this.outliers = outliers;
        }
    }


    public CalculationResult calculate() {
        log.debug("SQRelationCalculation.calculate");

        if (hasProblems()) {
            return new CalculationResult(this);
        }

        SedDBSessionHolder.acquire();
        try {
            return internalCalculate();
        }
        finally {
            SedDBSessionHolder.release();
        }
    }

    protected CalculationResult internalCalculate() {

        boolean debug = log.isDebugEnabled();

        Function function = FunctionFactory
            .getInstance()
            .getFunction(SQ_FUNCTION_NAME);

        if (function == null) {
            log.error("No '" + SQ_FUNCTION_NAME + "' function found.");
            // TODO: i18n
            addProblem("sq.missing.sq.function");
        }


        String [] parameterNames = function.getParameterNames();

        List<SQResult> results = new ArrayList<SQResult>(periods.length);

        Fitting fitting = new Fitting(function, outliers);

        for (DateRange period: periods) {
            Measurements measurements =
                MeasurementFactory.getMeasurements(river, location, period);

            if (debug) {
                log.debug(measurements.toString());
            }

            SQFractionResult [] fractionResults =
                new SQFractionResult[SQResult.NUMBER_FRACTIONS];

            for (int i = 0; i < fractionResults.length; ++i) {
                List<SQ> sqs = measurements.getSQs(i);

                SQFractionResult fractionResult;

                if (!fitting.fit(sqs)) {
                    // TODO: i18n
                    addProblem("sq.fitting.failed." + i);
                    fractionResult = new SQFractionResult();
                }
                else {
                    Parameters parameters = createParameters(parameterNames);
                    int row = parameters.newRow();
                    double [] coeffs = fitting.getParameters();
                    for (int j = 0; j < parameterNames.length; ++j) {
                        parameters.set(row, parameterNames[j], coeffs[j]);
                    }
                    parameters.set(row, "chi_sqr", fitting.getChiSqr());
                    parameters.set(row, "std_dev", fitting.getStandardDeviation());

                    fractionResult = new SQFractionResult(
                        parameters,
                        fitting.getRemaining(),
                        fitting.getOutliers());
                }
                fitting.reset();
                fractionResults[i] = fractionResult;
            }
            results.add(new SQResult(fractionResults));
        }

        return new CalculationResult(
            results.toArray(new SQResult[results.size()]),
            this);
    }

    public static final Parameters createParameters(String [] names) {

        String [] columns = new String[names.length + 2];
        columns[0] = "chi_sqr";
        columns[1] = "std_dev";
        System.arraycopy(names, 0, columns, 2, names.length);
        return new Parameters(columns);
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org