teichmann@5863: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5863: * Software engineering by Intevation GmbH teichmann@5863: * teichmann@5994: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5994: * documentation coming with Dive4Elements River for details. teichmann@5863: */ teichmann@5863: teichmann@5831: package org.dive4elements.river.artifacts.model.fixings; sascha@3437: gernotbelger@9415: import java.util.List; gernotbelger@9415: teichmann@5831: import org.dive4elements.river.artifacts.access.FixRealizingAccess; teichmann@5831: import org.dive4elements.river.artifacts.math.fitting.Function; teichmann@5831: import org.dive4elements.river.artifacts.model.CalculationResult; gernotbelger@9415: import org.dive4elements.river.artifacts.model.Parameters; teichmann@5831: import org.dive4elements.river.artifacts.model.RiverFactory; teichmann@5831: import org.dive4elements.river.artifacts.model.Segment; teichmann@5831: import org.dive4elements.river.artifacts.model.WQKms; teichmann@5831: import org.dive4elements.river.model.River; sascha@3419: felix@5150: /** Calculation for FixRealize (german: ausgel. WSPL). */ gernotbelger@9415: public class FixRealizingCalculation extends FixCalculation { gernotbelger@9415: private static final long serialVersionUID = 1L; sascha@3414: gernotbelger@9415: protected boolean isQ; gernotbelger@9415: sascha@3419: protected List segments; sascha@3419: sascha@3414: public FixRealizingCalculation() { sascha@3414: } sascha@3414: gernotbelger@9415: public FixRealizingCalculation(final FixRealizingAccess access) { sascha@3420: super(access); sascha@3420: gernotbelger@9415: final Boolean isQ = access.isQ(); gernotbelger@9415: final List segments = access.getSegments(); sascha@3419: sascha@3419: if (isQ == null) { sascha@3419: addProblem("fix.realize.missing.is.q"); sascha@3419: } sascha@3419: sascha@3419: if (segments == null || segments.isEmpty()) { sascha@3419: addProblem("fix.realize.missing.segments"); sascha@3419: } sascha@3419: gernotbelger@9415: final River r = RiverFactory.getRiver(this.river); sascha@3449: sascha@3449: if (r == null) { sascha@3449: addProblem("fix.no.such.river"); sascha@3449: } sascha@3449: sascha@3419: if (!hasProblems()) { gernotbelger@9415: this.isQ = isQ; sascha@3419: this.segments = segments; sascha@3449: sascha@3449: // Convert from W to Q sascha@3449: Segment.setReferencePointConvertQ(segments, r, isQ, this); sascha@3419: } sascha@3414: } sascha@3414: sascha@3437: @Override gernotbelger@9415: protected CalculationResult innerCalculate(final FixingsOverview overview, final Function func) { gernotbelger@9415: final ColumnCache cc = new ColumnCache(); gernotbelger@9415: final FitResult fitResult = doFitting(overview, cc, func); sascha@3449: sascha@3449: if (fitResult == null) { sascha@3449: return new CalculationResult(this); sascha@3449: } sascha@3449: gernotbelger@9415: Segment segment = this.segments.get(0); gernotbelger@9415: final int numResults = segment.numValues(); sascha@3449: gernotbelger@9415: final WQKms[] results = new WQKms[numResults]; sascha@3449: for (int i = 0; i < results.length; ++i) { sascha@3449: results[i] = new WQKms(); sascha@3449: } sascha@3449: gernotbelger@9415: final Parameters parameters = fitResult.getParameters(); sascha@3449: gernotbelger@9415: final int kmIndex = parameters.columnIndex("km"); gernotbelger@9415: final int[] parameterIndices = parameters.columnIndices(func.getParameterNames()); sascha@3449: gernotbelger@9415: final double[] parameterValues = new double[parameterIndices.length]; sascha@3449: sascha@3449: for (int row = 0, R = parameters.size(); row < R; ++row) { gernotbelger@9415: final double km = parameters.get(row, kmIndex); sascha@3449: sascha@3449: if (!segment.inside(km)) { sascha@3449: Segment nextSeg = null; gernotbelger@9415: for (final Segment seg : this.segments) { sascha@3449: if (seg.inside(km)) { sascha@3449: nextSeg = seg; sascha@3449: break; sascha@3449: } sascha@3449: } sascha@3449: if (nextSeg == null) { sascha@3449: addProblem(km, "fix.cannot.find.segment"); sascha@3449: continue; sascha@3449: } sascha@3449: segment = nextSeg; sascha@3449: } sascha@3449: sascha@3449: parameters.get(row, parameterIndices, parameterValues); sascha@3449: gernotbelger@9415: final org.dive4elements.river.artifacts.math.Function instance = func.instantiate(parameterValues); sascha@3449: gernotbelger@9415: final double[] values = segment.getValues(); sascha@3449: for (int i = 0; i < numResults; ++i) { gernotbelger@9415: final double q = values[i]; gernotbelger@9415: final double w = instance.value(q); sascha@3449: sascha@3449: if (Double.isNaN(w)) { sascha@3449: addProblem(km, "fix.cannot.calculate.function", q); gernotbelger@9415: } else { sascha@3449: results[i].add(w, q, km); sascha@3449: } sascha@3449: } sascha@3449: } sascha@3449: felix@5150: // Name the curves. gernotbelger@9360: for (int i = 0; i < results.length; ++i) sascha@3449: results[i].setName(createName(i)); sascha@3449: gernotbelger@9415: final FixRealizingResult frr = new FixRealizingResult(parameters, fitResult.getResultColumns(), results); sascha@3450: sascha@3450: return new CalculationResult(frr, this); sascha@3414: } sascha@3449: felix@4968: // TODO: issue1109/2 gernotbelger@9415: protected String createName(final int index) { sascha@3449: // TODO: i18n gernotbelger@9415: final StringBuilder sb = new StringBuilder(this.isQ ? "Q" : "W"); sascha@3449: sb.append(" benutzerdefiniert ("); gernotbelger@9415: for (int i = 0, N = this.segments.size(); i < N; ++i) { sascha@3449: if (i > 0) { sascha@3449: sb.append("; "); sascha@3449: } gernotbelger@9415: final Segment segment = this.segments.get(i); gernotbelger@9415: final double[] backup = segment.getBackup(); gernotbelger@9415: final double[] values = segment.getValues(); sascha@3449: sb.append((backup != null ? backup : values)[index]); sascha@3449: } sascha@3449: sb.append(')'); sascha@3449: return sb.toString(); sascha@3449: } gernotbelger@9415: }