# HG changeset patch # User mschaefer # Date 1519374624 -3600 # Node ID 37ff7f43591222df1152f715af27ee958516229c # Parent d9c89651bd6780feb3cbc0f1c0e3b0e505032d31 SINFO Flowdepth: more error checks, d50 interpolation, avoid negative tkh diff -r d9c89651bd67 -r 37ff7f435912 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/BedQualityD50KmValueFinder.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/BedQualityD50KmValueFinder.java Thu Feb 22 18:46:37 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/BedQualityD50KmValueFinder.java Fri Feb 23 09:30:24 2018 +0100 @@ -161,15 +161,10 @@ private static final String[] SQL_BED_D50_SELECT_ALIAS = {"km", "mindate", "maxdate", "cnt", "mindepth", "maxdepth", "d50"}; /** - * Kms of the loaded river range + * Real linear interpolator for kms and d50 values */ - private TDoubleArrayList kms; + private PolynomialSplineFunction interpolator; - /** - * D50 for each km in kms - */ - private TDoubleArrayList values; - /***** METHODS *****/ @@ -178,6 +173,8 @@ * @return d50 (mm) of the km, or NaN */ public double findD50(double km) throws ArgumentOutsideDomainException { + return interpolator.value(km); + /* ohne interpolation: if ((kms == null) || (kms.size() == 0)) return Double.NaN; int i = kms.binarySearch(km); @@ -189,7 +186,7 @@ else if ((i >= 0) && (i <= kms.size() - 1) && Utils.epsilonEquals(km, kms.get(i), 0.0001)) return values.get(i); else - return Double.NaN; + return Double.NaN; */ } /** @@ -215,16 +212,24 @@ sqlQuery.setDate("todate", dateRange.getTo()); @SuppressWarnings("unchecked") final List rows = sqlQuery.list(); - kms = new TDoubleArrayList(); - values = new TDoubleArrayList(); + final double[] kms = new double[rows.size()]; + final double[] values = new double[rows.size()]; D50Measurement measurement; + int i = -1; for (Object[] row : rows) { measurement = new D50Measurement(row, SQL_BED_D50_SELECT_ALIAS); - 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())); + 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())); } - return true; + try { + interpolator = new LinearInterpolator().interpolate(kms, values); + return true; + } catch (Exception e) { + interpolator = null; + return false; + } } } diff -r d9c89651bd67 -r 37ff7f435912 artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java Thu Feb 22 18:46:37 2018 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java Fri Feb 23 09:30:24 2018 +0100 @@ -154,8 +154,14 @@ } BedQualityD50KmValueFinder bedMeasurementsFinder = null; - if (doCalcTkh) + if (doCalcTkh) { bedMeasurementsFinder = loadBedMeasurements(river, calcRange, sounding.getYear().intValue()); + if (bedMeasurementsFinder == null) { + final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingSoilKind", null, label); + problems.addProblem(message); + doCalcTkh = false; + } + } final String bedHeightLabel = bedHeight.getDescription(); final String wstLabel = wstKms.getName(); @@ -165,7 +171,13 @@ DoubleRange qRange = null; if (doCalcTkh) { qInterpolator = DoubleUtil.getLinearInterpolator(((QKms) wstKms).allKms(), ((QKms) wstKms).allQs()); - qRange = new DoubleRange( ((QKms) wstKms).allQs().min(), ((QKms) wstKms).allQs().max()); + if (qInterpolator != null) + qRange = new DoubleRange( ((QKms) wstKms).allQs().min(), ((QKms) wstKms).allQs().max()); + else { + final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingQ", null, label); + problems.addProblem(message); + doCalcTkh = false; + } } // FIXME: sort by station first, but in what direction? @@ -180,13 +192,21 @@ SoilKindKmValueFinder soilKindFinder = null; if (doCalcTkh) { soilKindFinder = new SoilKindKmValueFinder(); - soilKindFinder.loadValues(river, calcRange); + if (!soilKindFinder.loadValues(river, calcRange)) { + doCalcTkh = false; + final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingSoilKind", null, label); + problems.addProblem(message); + } } FlowVelocityModelKmValueFinder flowVelocitiesFinder = null; if (doCalcTkh) { flowVelocitiesFinder = new FlowVelocityModelKmValueFinder(); - flowVelocitiesFinder.loadValues(river, calcRange, qRange); + if (!flowVelocitiesFinder.loadValues(river, calcRange, qRange)) { + doCalcTkh = false; + final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingVelocity", null, label); + problems.addProblem(message); + } } for (final BedHeightValue bedHeightValue : sortedValues) { @@ -219,11 +239,13 @@ else discharge = Double.NaN; - // FIXME: calculate tkh + // Calculate tkh double tkh = 0; if (doCalcTkh) { - double d50 = bedMeasurementsFinder.findD50(km); - if (Double.isNaN(d50)) { + double d50 = Double.NaN; + try { + d50 = bedMeasurementsFinder.findD50(km); + } catch (Exception e) { final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingD50", null, label); problems.addProblem(km, message); //FIXME: cumulate problems to one message? @@ -231,6 +253,8 @@ if (!Double.isNaN(d50)) { if (flowVelocitiesFinder.findKmQValues(km, discharge)) { tkh = calculateTkh(wst - meanBedHeight, flowVelocitiesFinder.getFindVmainFound(), d50, flowVelocitiesFinder.getFindTauFound()); + if (!Double.isNaN(tkh) && (tkh < 0)) + tkh = 0; /* log.debug(String.format("calculateTkh km %.3f q %.0f w %.2f mbh %.2f vm %.1f tau %.1f d50(mm) %.1f tkh(cm) %.1f", km, discharge, wst, meanBedHeight, flowVelocitiesFinder.getFindVmainFound(), flowVelocitiesFinder.getFindTauFound(), d50*1000, tkh)); */ } diff -r d9c89651bd67 -r 37ff7f435912 artifacts/src/main/resources/messages.properties --- a/artifacts/src/main/resources/messages.properties Thu Feb 22 18:46:37 2018 +0100 +++ b/artifacts/src/main/resources/messages.properties Fri Feb 23 09:30:24 2018 +0100 @@ -770,11 +770,12 @@ state.sinfo.calculation_mode=Calculation Mode sinfo_calc_flow_depth=Flie\u00dftiefen -sinfo_calc_flow_depth.warning.missingQ = {0}: keine Abflussdaten vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich +sinfo_calc_flow_depth.warning.missingQ = {0}: no discharge available, calculation of transport body height not possible sinfo_calc_flow_depth.warning.waterlevel_discretisation = Wasserspiegel {0}: r\u00e4umliche Aufl\u00f6sung betr\u00e4gt mehr als 1000m sinfo_calc_flow_depth.warning.year_difference = {0}: Sie verwenden als Differenzenpaar eine Wasserspiegellage aus dem Jahr {1} und eine Peilung aus dem Jahr {2}. Dies kann zu unplausiblen Werten f\u00fchren. -sinfo_calc_flow_depth.warning.missingSoilKind = {0}: keine Sohlart vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich -sinfo_calc_flow_depth.warning.missingD50 = {0}: kein D50 vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich +sinfo_calc_flow_depth.warning.missingSoilKind = {0}: no soil kind available, calculation of transport body height not possible +sinfo_calc_flow_depth.warning.missingD50 = {0}: no D50 available, calculation of transport body height not possible +sinfo_calc_flow_depth.warning.missingVelocity = {0}: no flow velocities available, calculation of transport body height not possible sinfo_calc_flow_depth_development=Flie\u00dftiefenentwicklung sinfo_calc_flow_depth_minmax=Minimale und Maximale Flie\u00dftiefe diff -r d9c89651bd67 -r 37ff7f435912 artifacts/src/main/resources/messages_de.properties --- a/artifacts/src/main/resources/messages_de.properties Thu Feb 22 18:46:37 2018 +0100 +++ b/artifacts/src/main/resources/messages_de.properties Fri Feb 23 09:30:24 2018 +0100 @@ -781,6 +781,7 @@ sinfo_calc_flow_depth.warning.year_difference = {0}: Sie verwenden als Differenzenpaar eine Wasserspiegellage aus dem Jahr {1} und eine Peilung aus dem Jahr {2}. Dies kann zu unplausiblen Werten f\u00fchren. sinfo_calc_flow_depth.warning.missingSoilKind = {0}: keine Sohlart vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich sinfo_calc_flow_depth.warning.missingD50 = {0}: kein D50 vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich +sinfo_calc_flow_depth.warning.missingVelocity = {0}: keine Flie\u00dfgeschwindigkeiten vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich sinfo_calc_flow_depth_development=Flie\u00dftiefenentwicklung sinfo_calc_flow_depth_minmax=Minimale und Maximale Flie\u00dftiefe diff -r d9c89651bd67 -r 37ff7f435912 artifacts/src/main/resources/messages_de_DE.properties --- a/artifacts/src/main/resources/messages_de_DE.properties Thu Feb 22 18:46:37 2018 +0100 +++ b/artifacts/src/main/resources/messages_de_DE.properties Fri Feb 23 09:30:24 2018 +0100 @@ -777,6 +777,7 @@ sinfo_calc_flow_depth.warning.year_difference = {0}: Sie verwenden als Differenzenpaar eine Wasserspiegellage aus dem Jahr {1} und eine Peilung aus dem Jahr {2}. Dies kann zu unplausiblen Werten f\u00fchren. sinfo_calc_flow_depth.warning.missingSoilKind = {0}: keine Sohlart vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich sinfo_calc_flow_depth.warning.missingD50 = {0}: kein D50 vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich +sinfo_calc_flow_depth.warning.missingVelocity = {0}: keine Flie\u00dfgeschwindigkeiten vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich Zeitliche Abweichung betr\u00e4gt {1} Jahre. Dies kann zu unplausiblen Ergebnissen f\u00fchren diff -r d9c89651bd67 -r 37ff7f435912 artifacts/src/main/resources/messages_en.properties --- a/artifacts/src/main/resources/messages_en.properties Thu Feb 22 18:46:37 2018 +0100 +++ b/artifacts/src/main/resources/messages_en.properties Fri Feb 23 09:30:24 2018 +0100 @@ -773,9 +773,10 @@ sinfo_calc_flow_depth=Flie\u00dftiefen sinfo_calc_flow_depth.warning.missingQ = {0}: keine Abflussdaten vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich sinfo_calc_flow_depth.warning.waterlevel_discretisation = Wasserspiegel {0}: r\u00e4umliche Aufl\u00f6sung betr\u00e4gt mehr als 1000m -sinfo_calc_flow_depth.warning.year_difference = {0}: Sie verwenden als Differenzenpaar eine Wasserspiegellage aus dem Jahr {1} und eine Peilung aus dem Jahr {2}. Dies kann zu unplausiblen Werten f\u00fchren. +sinfo_calc_flow_depth.warning.year_difference = {0}: Sie verwenden als Differenzenpaar eine Wasserspiegellage aus dem Jahr {1} und eine Peilung aus dem Jahr {2}. Dies kann zu unplausiblen Werten f\u00fchren. sinfo_calc_flow_depth.warning.missingSoilKind = {0}: keine Sohlart vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich sinfo_calc_flow_depth.warning.missingD50 = {0}: kein D50 vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich +sinfo_calc_flow_depth.warning.missingVelocity = {0}: keine Flie\u00dfgeschwindigkeiten vorhanden, Transportk\u00f6rperh\u00f6henberechnung nicht m\u00f6glich sinfo_calc_flow_depth_development=Flie\u00dftiefenentwicklung sinfo_calc_flow_depth_minmax=Minimale und Maximale Flie\u00dftiefe