view artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixRealizingCalculation.java @ 9479:2b83d3a96703

i18n TODO "benutzerdefiniert" = "custom" fixed
author gernotbelger
date Mon, 10 Sep 2018 15:31:55 +0200
parents 9744ce3c3853
children
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */

package org.dive4elements.river.artifacts.model.fixings;

import java.util.List;

import org.dive4elements.artifacts.CallMeta;
import org.dive4elements.river.artifacts.access.FixRealizingAccess;
import org.dive4elements.river.artifacts.math.fitting.Function;
import org.dive4elements.river.artifacts.model.CalculationResult;
import org.dive4elements.river.artifacts.model.Parameters;
import org.dive4elements.river.artifacts.model.RiverFactory;
import org.dive4elements.river.artifacts.model.Segment;
import org.dive4elements.river.artifacts.model.WQKms;
import org.dive4elements.river.artifacts.resources.Resources;
import org.dive4elements.river.model.River;

/** Calculation for FixRealize (german: ausgel. WSPL). */
public class FixRealizingCalculation extends FixCalculation {
    private static final long serialVersionUID = 1L;

    protected boolean isQ;

    protected List<Segment> segments;

    public FixRealizingCalculation() {
    }

    public FixRealizingCalculation(final FixRealizingAccess access) {
        super(access);

        final Boolean isQ = access.isQ();
        final List<Segment> segments = access.getSegments();

        if (isQ == null) {
            addProblem("fix.realize.missing.is.q");
        }

        if (segments == null || segments.isEmpty()) {
            addProblem("fix.realize.missing.segments");
        }

        final River r = RiverFactory.getRiver(this.river);

        if (r == null) {
            addProblem("fix.no.such.river");
        }

        if (!hasProblems()) {
            this.isQ = isQ;
            this.segments = segments;

            // Convert from W to Q
            Segment.setReferencePointConvertQ(segments, r, isQ, this);
        }
    }

    @Override
    protected CalculationResult innerCalculate(final FixingsOverview overview, final Function func, final CallMeta meta) {
        final ColumnCache cc = new ColumnCache();
        final FitResult fitResult = doFitting(overview, cc, func);

        if (fitResult == null) {
            return new CalculationResult(this);
        }

        Segment segment = this.segments.get(0);
        final int numResults = segment.numValues();

        final WQKms[] results = new WQKms[numResults];
        for (int i = 0; i < results.length; ++i) {
            results[i] = new WQKms();
        }

        final Parameters parameters = fitResult.getParameters();

        final int kmIndex = parameters.columnIndex("km");
        final int[] parameterIndices = parameters.columnIndices(func.getParameterNames());

        final double[] parameterValues = new double[parameterIndices.length];

        for (int row = 0, R = parameters.size(); row < R; ++row) {
            final double km = parameters.get(row, kmIndex);

            if (!segment.inside(km)) {
                Segment nextSeg = null;
                for (final Segment seg : this.segments) {
                    if (seg.inside(km)) {
                        nextSeg = seg;
                        break;
                    }
                }
                if (nextSeg == null) {
                    addProblem(km, "fix.cannot.find.segment");
                    continue;
                }
                segment = nextSeg;
            }

            parameters.get(row, parameterIndices, parameterValues);

            final org.dive4elements.river.artifacts.math.Function instance = func.instantiate(parameterValues);

            final double[] values = segment.getValues();
            for (int i = 0; i < numResults; ++i) {
                final double q = values[i];
                final double w = instance.value(q);

                if (Double.isNaN(w)) {
                    addProblem(km, "fix.cannot.calculate.function", q);
                } else {
                    results[i].add(w, q, km);
                }
            }
        }

        // Name the curves.
        final String custom = Resources.getMsg(meta, "common.custom");
        for (int i = 0; i < results.length; ++i)
            results[i].setName(createName(i, custom));

        final FixRealizingResult frr = new FixRealizingResult(parameters, fitResult.getResultColumns(), results);

        return new CalculationResult(frr, this);
    }

    // TODO: issue1109/2
    protected String createName(final int index, final String custom) {
        final StringBuilder sb = new StringBuilder(this.isQ ? "Q" : "W");
        sb.append(" ").append(custom).append(" (");
        for (int i = 0, N = this.segments.size(); i < N; ++i) {
            if (i > 0) {
                sb.append("; ");
            }
            final Segment segment = this.segments.get(i);
            final double[] backup = segment.getBackup();
            final double[] values = segment.getValues();
            sb.append((backup != null ? backup : values)[index]);
        }
        sb.append(')');
        return sb.toString();
    }
}

http://dive4elements.wald.intevation.org