changeset 9335:7dc238bd062c

Fixed: calculation of flow depth and tkh with rounding to cm, calculator return differentiated
author mschaefer
date Mon, 30 Jul 2018 08:03:46 +0200
parents f30bae00a161
children 1899595a8070
files artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java
diffstat 5 files changed, 49 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java	Mon Jul 30 08:00:24 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculator.java	Mon Jul 30 08:03:46 2018 +0200
@@ -18,6 +18,7 @@
 import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator;
+import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator.TkhCalculateState;
 import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder;
 import org.dive4elements.river.artifacts.sinfo.util.WstInfo;
 
@@ -78,7 +79,9 @@
         final String location = this.riverInfoProvider.getLocation(station);
         row.putValue(GeneralResultType.location, location);
 
-        if (this.tkhCalculator.calculateTkh(station, row))
+        final TkhCalculateState calcState = this.tkhCalculator.calculateTkh(station, row);
+        if ((calcState == TkhCalculateState.SUCCESS) || ((calcState != TkhCalculateState.NO_W) && (calcState != TkhCalculateState.NO_BED_HEIGHT)))
             this.rows.add(row);
+        // REMARK: Siehe Softwaretest Zwischenrelease 1 2.2.3, Bedingung nach Ruecksprache ggf. auf SUCCESS reduzieren
     }
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java	Mon Jul 30 08:00:24 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthminmax/FlowDepthMinMaxCalculation.java	Mon Jul 30 08:03:46 2018 +0200
@@ -35,6 +35,7 @@
 import org.dive4elements.river.artifacts.states.WaterlevelData;
 import org.dive4elements.river.artifacts.states.WaterlevelFetcher;
 import org.dive4elements.river.model.River;
+import org.dive4elements.river.utils.Formatter;
 
 /**
  * @author Gernot Belger
@@ -134,8 +135,8 @@
                 final double maxBedHeightValue = bedHeight.getMaxBedHeight(station);
                 final double meanBedHeight = bedHeight.getMeanBedHeight(station);
 
-                final double minFlowDepth = wst - maxBedHeightValue;
-                final double maxFlowDepth = wst - minBedHeightValue;
+                final double minFlowDepth = Math.max(Formatter.roundFlowDepth(wst) - Formatter.roundFlowDepth(maxBedHeightValue), 0.0);
+                final double maxFlowDepth = Math.max(Formatter.roundFlowDepth(wst) - Formatter.roundFlowDepth(minBedHeightValue), 0.0);
 
                 // REMARK: access the location once only during calculation
                 final String location = riverInfoProvider.getLocation(station);
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java	Mon Jul 30 08:00:24 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java	Mon Jul 30 08:03:46 2018 +0200
@@ -16,12 +16,21 @@
 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
 import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder;
 import org.dive4elements.river.model.River;
+import org.dive4elements.river.utils.Formatter;
 
 /**
  * @author Gernot Belger
  */
 public final class TkhCalculator {
 
+    /**
+     * Return type of the tkh calculation
+     *
+     */
+    public enum TkhCalculateState {
+        SUCCESS, NO_W, NO_BED_HEIGHT, NO_DISCHARGE, NO_SOILKIND, NO_D50, NO_VELOCITY, NO_TKH
+    }
+
     private static final int VALID_BED_MEASUREMENT_YEARS = 20;
 
     private final BedQualityD50KmValueFinder bedMeasurementsFinder;
@@ -109,7 +118,7 @@
         return this.bedMeasurementsFinder.findD50(km);
     }
 
-    public boolean calculateTkh(final double km, final ResultRow row) {
+    public TkhCalculateState calculateTkh(final double km, final ResultRow row) {
 
         row.putValue(GeneralResultType.station, km);
 
@@ -119,70 +128,68 @@
         final double wst = this.waterlevelProvider.getWaterlevel(km);
         row.putValue(SInfoResultType.waterlevel, wst);
         if (Double.isNaN(wst))
-            return false;
+            return TkhCalculateState.NO_W;
 
         final double meanBedHeight = this.bedHeightsProvider.getMeanBedHeight(km);
         row.putValue(SInfoResultType.meanBedHeight, meanBedHeight);
         if (Double.isNaN(meanBedHeight))
-            return false;
+            return TkhCalculateState.NO_BED_HEIGHT;
 
-        final double flowDepth = wst - meanBedHeight;
+        final double flowDepth = Formatter.roundFlowDepth(wst) - Formatter.roundFlowDepth(meanBedHeight);
         row.putValue(SInfoResultType.flowdepth, flowDepth);
-        if (Double.isNaN(flowDepth))
-            return false;
 
         final double discharge = this.dischargeProvider.getDischarge(km);
         row.putValue(SInfoResultType.discharge, discharge);
 
         if (!this.hasTkh())
-            return true;
+            return TkhCalculateState.SUCCESS;
 
         // Missing discharge or kind is only a problem if we want to calculate tkh
         if (Double.isNaN(discharge))
-            return false;
+            return TkhCalculateState.NO_DISCHARGE;
         if (kind == null)
-            return false;
+            return TkhCalculateState.NO_SOILKIND;
 
         final double d50 = getBedMeasurement(km);
         row.putValue(SInfoResultType.d50, d50);
         if (Double.isNaN(d50))
-            return false;
+            return TkhCalculateState.NO_D50;
 
         if (!this.flowVelocitiesFinder.findKmQValues(km, discharge))
-            return false;
+            return TkhCalculateState.NO_VELOCITY;
 
         final double velocity = this.flowVelocitiesFinder.getFindVmainFound();
         row.putValue(SInfoResultType.velocity, velocity);
         if (Double.isNaN(velocity))
-            return false;
+            return TkhCalculateState.NO_VELOCITY;
 
         final double tau = this.flowVelocitiesFinder.getFindTauFound();
         row.putValue(SInfoResultType.tau, tau);
         if (Double.isNaN(tau))
-            return false;
+            return TkhCalculateState.NO_VELOCITY;
 
-        final double tkh = calculateTkh(wst - meanBedHeight, velocity, d50, tau);
+        final double tkh = calculateTkh(flowDepth, velocity, d50, tau);
         row.putValue(SInfoResultType.tkh, tkh);
         if (Double.isNaN(tkh))
-            return false;
+            return TkhCalculateState.NO_TKH;
 
         switch (kind) {
         case starr:
-            row.putValue(SInfoResultType.tkhup, tkh);
+            row.putValue(SInfoResultType.tkhup, (double) Math.round(tkh));
             row.putValue(SInfoResultType.tkhdown, 0.0);
             break;
 
         case mobil:
         default:
-            row.putValue(SInfoResultType.tkhup, tkh / 2);
-            row.putValue(SInfoResultType.tkhdown, -tkh / 2);
+            row.putValue(SInfoResultType.tkhup, (double) Math.round(tkh / 2));
+            row.putValue(SInfoResultType.tkhdown, (double) -(Math.round(tkh / 2)));
             break;
         }
 
-        final double flowDepthTkh = calculateFlowDepthTkh(tkh, kind, wst, meanBedHeight);
+        final double flowDepthTkh = calculateFlowDepthTkh(tkh, kind, flowDepth);
         row.putValue(SInfoResultType.flowdepthtkh, flowDepthTkh);
 
-        return true;
+        return TkhCalculateState.SUCCESS;
     }
 
     /**
@@ -219,15 +226,15 @@
         return tkh;
     }
 
-    private double calculateFlowDepthTkh(final double tkhValue, final SoilKind tkhKind, final double wst, final double meanBedHeight) {
+    private double calculateFlowDepthTkh(final double tkhValue, final SoilKind tkhKind, final double flowDepth) {
 
         switch (tkhKind) {
         case starr:
-            return wst - (meanBedHeight + tkhValue / 100);
+            return flowDepth - Math.round(tkhValue) / 100.0;
 
         case mobil:
         default:
-            return wst - (meanBedHeight + tkhValue / 200);
+            return flowDepth - Math.round(tkhValue / 2) / 100.0;
         }
     }
 }
\ No newline at end of file
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java	Mon Jul 30 08:00:24 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java	Mon Jul 30 08:03:46 2018 +0200
@@ -34,6 +34,7 @@
 import org.dive4elements.river.artifacts.sinfo.common.RiverInfoProvider;
 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.DischargeValuesFinder;
 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator;
+import org.dive4elements.river.artifacts.sinfo.tkhcalculation.TkhCalculator.TkhCalculateState;
 import org.dive4elements.river.artifacts.sinfo.tkhcalculation.WaterlevelValuesFinder;
 import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo;
 import org.dive4elements.river.artifacts.sinfo.util.CalculationUtils;
@@ -184,7 +185,8 @@
             row.putValue(GeneralResultType.gaugeLabel, riverInfoProvider.findGauge(station));
             row.putValue(GeneralResultType.location, riverInfoProvider.getLocation(station));
 
-            if (tkhCalculator.calculateTkh(station, row))
+            final TkhCalculateState calcState = tkhCalculator.calculateTkh(station, row);
+            if (calcState == TkhCalculateState.SUCCESS)
                 rows.add(row);
         }
 
--- a/artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java	Mon Jul 30 08:00:24 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java	Mon Jul 30 08:03:46 2018 +0200
@@ -97,6 +97,10 @@
     public static final int CSV_DIAGRAM_DATA_MAX_DIGITS = 3;
     public static final int CSV_DIAGRAM_DATA_MIN_DIGITS = 3;
 
+    // S-INFO
+    public static final int FLOWDEPTH_MAX_DIGITS = 2;
+    private static final double FLOWDEPTH_ROUND_MULT = 100.0;
+
     /**
      * Creates a localized NumberFormatter with given range of decimal digits.
      *
@@ -377,7 +381,11 @@
     }
 
     public static NumberFormat getFlowDepth(final CallContext context) {
-        return Formatter.getFormatter(context, 2, 2);
+        return Formatter.getFormatter(context, FLOWDEPTH_MAX_DIGITS, FLOWDEPTH_MAX_DIGITS);
+    }
+
+    public static double roundFlowDepth(final double value) {
+        return Math.round(value * FLOWDEPTH_ROUND_MULT) / FLOWDEPTH_ROUND_MULT;
     }
 
     public static NumberFormat getW(final CallContext context) {

http://dive4elements.wald.intevation.org