Mercurial > dive4elements > river
view artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeDischargeValuesFinder.java @ 9269:83ebeb620b5a
Station specific main value annotations in S-Info flood duration curve, corrected infrastructure flood duration calculation
author | mschaefer |
---|---|
date | Thu, 19 Jul 2018 08:07:03 +0200 |
parents | b4402594213b |
children | d9fda7af24ca |
line wrap: on
line source
/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde * Software engineering by * Björnsen Beratende Ingenieure GmbH * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt * * 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.sinfo.common; import org.apache.commons.lang.math.DoubleRange; import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.analysis.UnivariateRealFunction; import org.apache.commons.math.analysis.interpolation.LinearInterpolator; import org.dive4elements.river.artifacts.model.Calculation; import org.dive4elements.river.model.DischargeTable; import org.dive4elements.river.model.DischargeTableValue; import org.dive4elements.river.model.Gauge; import gnu.trove.TDoubleArrayList; /** * Loading and search/interpolation of a gauge's discharge table (.at) * * @author Matthias Schäfer * */ public final class GaugeDischargeValuesFinder { /***** FIELDS *****/ // private static Logger log = Logger.getLogger(GaugeDischargeValuesFinder.class); private final Gauge gauge; private Calculation problems; private final UnivariateRealFunction wInterpolator; private final DoubleRange wRange; /***** CONSTRUCTORS *****/ private GaugeDischargeValuesFinder(final Gauge gauge, final Calculation problems, final DischargeTable dischargeTable) { // Load W-Q-values from database this.gauge = gauge; this.problems = problems; final TDoubleArrayList ws = new TDoubleArrayList(); final TDoubleArrayList qs = new TDoubleArrayList(); for (final DischargeTableValue v : DischargeTable.fetchValuesSortedByW(dischargeTable)) { ws.add(v.getW().doubleValue()); qs.add(v.getQ().doubleValue()); } // Build interpolator if (ws.size() >= 2) { this.wInterpolator = new LinearInterpolator().interpolate(ws.toNativeArray(), qs.toNativeArray()); this.wRange = new DoubleRange(ws.get(0), ws.get(ws.size() - 1)); } else { this.wInterpolator = null; this.wRange = null; } if ((this.wInterpolator == null) && (this.problems != null)) { this.problems.addProblem("gauge_discharge_table.missing", gauge.getName()); // Report only once this.problems = null; } } /***** METHODS *****/ /** * Loads the the main discharge table of a gauge ({gauge}.at) * * @return The discharge table values finder of the gauge, or null */ public static GaugeDischargeValuesFinder loadValues(final Gauge gauge, final Calculation problems) { final DischargeTable table = gauge.fetchMasterDischargeTable(); if ((table == null) || (table.getDischargeTableValues().size() == 0)) { problems.addProblem("gauge_discharge_table.missing", gauge.getName()); return null; } else return new GaugeDischargeValuesFinder(gauge, problems, table); } /** * If this provider may return valid data at all. */ public boolean isValid() { return (this.wInterpolator != null); } /** * Discharge for a W * * @param w * W in cm above gauge datum * @return Q, or NegInf for w less than all, or PosInf for w greater then all, or NaN in case of exception */ public double getDischarge(final double w) { try { if (this.wInterpolator == null) return Double.NaN; else if (w < this.wRange.getMinimumDouble()) return Double.NEGATIVE_INFINITY; else if (w > this.wRange.getMaximumDouble()) return Double.POSITIVE_INFINITY; else return this.wInterpolator.value(w); } catch (@SuppressWarnings("unused") final FunctionEvaluationException e) { // ignore exception because this can/will happen regularly return Double.NaN; } } }