Mercurial > dive4elements > river
diff artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/BedQualityD50KmValueFinder.java @ 8901:0a900d605d52
S-INFO Flowdepth work on TKH calculation
author | mschaefer |
---|---|
date | Thu, 22 Feb 2018 17:04:06 +0100 |
parents | 89f3c5462a16 |
children | 37ff7f435912 |
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/BedQualityD50KmValueFinder.java Thu Feb 22 14:11:19 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/BedQualityD50KmValueFinder.java Thu Feb 22 17:04:06 2018 +0100 @@ -18,15 +18,22 @@ import org.apache.commons.math.analysis.interpolation.LinearInterpolator; import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; import org.apache.log4j.Logger; +import org.dive4elements.river.artifacts.math.Utils; import org.dive4elements.river.artifacts.model.DateRange; import org.dive4elements.river.backend.SedDBSessionHolder; import org.dive4elements.river.model.River; +import org.dive4elements.river.utils.DoubleUtil; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.hibernate.type.StandardBasicTypes; +import gnu.trove.TDoubleArrayList; + /** - * Searchable sorted km array with parallel bed measurements value array and linear interpolation for km and d50 between the array elements. + * Searchable sorted km array with parallel bed measurements value array and linear interpolation for km and d50 between the array elements.<br /> + * <br /> + * See comment of SQL command on how the values are filtered and aggregated. + * * @author Matthias Schäfer * */ @@ -154,18 +161,35 @@ private static final String[] SQL_BED_D50_SELECT_ALIAS = {"km", "mindate", "maxdate", "cnt", "mindepth", "maxdepth", "d50"}; /** - * Real linear interpolator for kms and d50 values + * Kms of the loaded river range */ - private PolynomialSplineFunction interpolator; + private TDoubleArrayList kms; + + /** + * D50 for each km in kms + */ + private TDoubleArrayList values; + /***** METHODS *****/ /** * Returns the d50 value interpolated according to a km - * @throws ArgumentOutsideDomainException + * @return d50 (mm) of the km, or NaN */ public double findD50(double km) throws ArgumentOutsideDomainException { - return interpolator.value(km); + if ((kms == null) || (kms.size() == 0)) + return Double.NaN; + int i = kms.binarySearch(km); + if (i >= 0) + return values.get(i); + i = -i - 1; + if ((i - 1 >= 0) && Utils.epsilonEquals(km, kms.get(i - 1), 0.0001)) + return values.get(i - 1); + else if ((i >= 0) && (i <= kms.size() - 1) && Utils.epsilonEquals(km, kms.get(i), 0.0001)) + return values.get(i); + else + return Double.NaN; } /** @@ -191,18 +215,15 @@ sqlQuery.setDate("todate", dateRange.getTo()); @SuppressWarnings("unchecked") final List<Object[]> rows = sqlQuery.list(); - final double[] kms = new double[rows.size()]; - final double[] values = new double[rows.size()]; + kms = new TDoubleArrayList(); + values = new TDoubleArrayList(); D50Measurement measurement; - int i = -1; for (Object[] row : rows) { measurement = new D50Measurement(row, SQL_BED_D50_SELECT_ALIAS); - i++; - kms[i] = measurement.getKm(); - values[i] = measurement.getD50(); - log.debug(String.format("loadValues km %.3f d50(mm) %.1f count %d", kms[i], values[i], measurement.getCnt())); + kms.add(measurement.getKm()); + values.add(measurement.getD50()); + log.debug(String.format("loadValues km %.3f d50(mm) %.1f count %d", kms.get(kms.size()-1), values.get(values.size()-1), measurement.getCnt())); } - interpolator = new LinearInterpolator().interpolate(kms, values); return true; }