comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhcalculation/TkhCalculator.java @ 8964:45f1ad66560e

Code cleanup concerning calculations: improved error handling; improved interpolation; bed heights are now always used for spatial discretisation
author gernotbelger
date Thu, 29 Mar 2018 15:48:17 +0200
parents 183f42641ab6
children b5600453bb8f
comparison
equal deleted inserted replaced
8963:b98fbd91f64a 8964:45f1ad66560e
8 * documentation coming with Dive4Elements River for details. 8 * documentation coming with Dive4Elements River for details.
9 */ 9 */
10 package org.dive4elements.river.artifacts.sinfo.tkhcalculation; 10 package org.dive4elements.river.artifacts.sinfo.tkhcalculation;
11 11
12 import org.apache.commons.lang.math.DoubleRange; 12 import org.apache.commons.lang.math.DoubleRange;
13 import org.apache.commons.math.ArgumentOutsideDomainException;
14 import org.dive4elements.artifacts.CallContext;
15 import org.dive4elements.river.artifacts.model.Calculation; 13 import org.dive4elements.river.artifacts.model.Calculation;
16 import org.dive4elements.river.artifacts.resources.Resources;
17 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow; 14 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultRow;
18 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType; 15 import org.dive4elements.river.artifacts.sinfo.common.SInfoResultType;
19 import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder; 16 import org.dive4elements.river.artifacts.sinfo.tkhstate.BedHeightsFinder;
20 import org.dive4elements.river.model.River; 17 import org.dive4elements.river.model.River;
21 18
24 */ 21 */
25 public final class TkhCalculator { 22 public final class TkhCalculator {
26 23
27 private static final int VALID_BED_MEASUREMENT_YEARS = 20; 24 private static final int VALID_BED_MEASUREMENT_YEARS = 20;
28 25
29 private final Calculation problems;
30
31 private final String problemLabel;
32
33 private final CallContext context;
34
35 private final BedQualityD50KmValueFinder bedMeasurementsFinder; 26 private final BedQualityD50KmValueFinder bedMeasurementsFinder;
36 27
37 private final SoilKindKmValueFinder soilKindFinder; 28 private final SoilKindKmValueFinder soilKindFinder;
38 29
39 private final BedHeightsFinder bedHeightsProvider; 30 private final BedHeightsFinder bedHeightsProvider;
42 33
43 private final DischargeValuesFinder dischargeProvider; 34 private final DischargeValuesFinder dischargeProvider;
44 35
45 private final FlowVelocityModelKmValueFinder flowVelocitiesFinder; 36 private final FlowVelocityModelKmValueFinder flowVelocitiesFinder;
46 37
47 public static TkhCalculator buildTkhCalculator(final boolean useTkh, final CallContext context, final Calculation problems, final String label, 38 public static TkhCalculator buildTkhCalculator(final boolean useTkh, final Calculation problems, final String label,
48 final River river, final DoubleRange calcRange, final WaterlevelValuesFinder waterlevelProvider, final DischargeValuesFinder dischargeProvider, 39 final River river, final DoubleRange calcRange, final WaterlevelValuesFinder waterlevelProvider, final DischargeValuesFinder dischargeProvider,
49 final BedHeightsFinder bedHeightsProvider) { 40 final BedHeightsFinder bedHeightsProvider) {
50 41
51 if (!useTkh) 42 if (!useTkh)
52 return new TkhCalculator(problems, label, context, null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null); 43 return new TkhCalculator(null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null);
53 44
54 if (!dischargeProvider.isValid()) { 45 if (!dischargeProvider.isValid()) {
55 final String message = Resources.getMsg(context.getMeta(), "sinfo_calc_flow_depth.warning.missingQ", null, label); 46 problems.addProblem("sinfo_calc_flow_depth.warning.missingQ", label);
56 problems.addProblem(message); 47 return new TkhCalculator(null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null);
57 return new TkhCalculator(problems, label, context, null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null);
58 } 48 }
59 49
50 /* access bed quality data */
60 final int soundingYear = bedHeightsProvider.getInfo().getYear(); 51 final int soundingYear = bedHeightsProvider.getInfo().getYear();
61 final BedQualityD50KmValueFinder bedMeasurementsFinder = BedQualityD50KmValueFinder.loadBedMeasurements(river, calcRange, soundingYear, 52 final BedQualityD50KmValueFinder bedMeasurementsFinder = BedQualityD50KmValueFinder.loadBedMeasurements(problems, river, calcRange, soundingYear,
62 VALID_BED_MEASUREMENT_YEARS); 53 VALID_BED_MEASUREMENT_YEARS);
63 54 if (bedMeasurementsFinder == null)
64 if (bedMeasurementsFinder == null) { 55 return new TkhCalculator(null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null);
65 final String message = Resources.getMsg(context.getMeta(), "sinfo_calc_flow_depth.warning.missingD50", null, label); 56
66 problems.addProblem(message); 57 /* access bed soil kind data */
67 return new TkhCalculator(problems, label, context, null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null); 58 final SoilKindKmValueFinder soilKindFinder = SoilKindKmValueFinder.loadValues(problems, river, calcRange);
68 } 59 if (soilKindFinder == null)
69 60 return new TkhCalculator(null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null);
70 // FIXME: wie wird ggf. interpoliert? prüfung ob werte vorhanden?
71 final SoilKindKmValueFinder soilKindFinder = SoilKindKmValueFinder.loadValues(river, calcRange);
72 if (soilKindFinder == null) {
73 final String message = Resources.getMsg(context.getMeta(), "sinfo_calc_flow_depth.warning.missingSoilKind", null, label);
74 problems.addProblem(message);
75 return new TkhCalculator(problems, label, context, null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null);
76 }
77 61
78 final DoubleRange qRange = dischargeProvider.getRange(); 62 final DoubleRange qRange = dischargeProvider.getRange();
79 final FlowVelocityModelKmValueFinder flowVelocitiesFinder = FlowVelocityModelKmValueFinder.loadValues(river, calcRange, qRange); 63 final FlowVelocityModelKmValueFinder flowVelocitiesFinder = FlowVelocityModelKmValueFinder.loadValues(problems, river, calcRange, qRange);
80 if (flowVelocitiesFinder == null) { 64 if (flowVelocitiesFinder == null)
81 final String message = Resources.getMsg(context.getMeta(), "sinfo_calc_flow_depth.warning.missingVelocity", null, label); 65 return new TkhCalculator(null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null);
82 problems.addProblem(message); 66
83 return new TkhCalculator(problems, label, context, null, waterlevelProvider, dischargeProvider, bedHeightsProvider, null, null); 67 return new TkhCalculator(bedMeasurementsFinder, waterlevelProvider, dischargeProvider, bedHeightsProvider, soilKindFinder,
84 }
85
86 return new TkhCalculator(problems, label, context, bedMeasurementsFinder, waterlevelProvider, dischargeProvider, bedHeightsProvider, soilKindFinder,
87 flowVelocitiesFinder); 68 flowVelocitiesFinder);
88 } 69 }
89 70
90 private TkhCalculator(final Calculation problems, final String problemLabel, final CallContext context, 71 private TkhCalculator(final BedQualityD50KmValueFinder bedMeasurementsFinder, final WaterlevelValuesFinder waterlevelProvider,
91 final BedQualityD50KmValueFinder bedMeasurementsFinder, final WaterlevelValuesFinder waterlevelProvider,
92 final DischargeValuesFinder dischargeProvider, final BedHeightsFinder bedHeightsProvider, final SoilKindKmValueFinder soilKindFinder, 72 final DischargeValuesFinder dischargeProvider, final BedHeightsFinder bedHeightsProvider, final SoilKindKmValueFinder soilKindFinder,
93 final FlowVelocityModelKmValueFinder flowVelocitiesFinder) { 73 final FlowVelocityModelKmValueFinder flowVelocitiesFinder) {
94 this.problems = problems;
95 this.problemLabel = problemLabel;
96 this.context = context;
97 this.bedMeasurementsFinder = bedMeasurementsFinder; 74 this.bedMeasurementsFinder = bedMeasurementsFinder;
98 this.waterlevelProvider = waterlevelProvider; 75 this.waterlevelProvider = waterlevelProvider;
99 this.dischargeProvider = dischargeProvider; 76 this.dischargeProvider = dischargeProvider;
100 this.bedHeightsProvider = bedHeightsProvider; 77 this.bedHeightsProvider = bedHeightsProvider;
101 this.soilKindFinder = soilKindFinder; 78 this.soilKindFinder = soilKindFinder;
119 return true; 96 return true;
120 } 97 }
121 98
122 private SoilKind getSoilKind(final double km) { 99 private SoilKind getSoilKind(final double km) {
123 100
124 try { 101 if (this.soilKindFinder == null)
125 if (this.soilKindFinder == null)
126 return null;
127
128 return this.soilKindFinder.findSoilKind(km);
129 }
130 catch (final ArgumentOutsideDomainException e) {
131 // FIXME: cumulate problems to one message?
132 final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingSoilKind", null, this.problemLabel);
133 this.problems.addProblem(km, message);
134 return null; 102 return null;
135 } 103
104 return this.soilKindFinder.findSoilKind(km);
136 } 105 }
137 106
138 private double getBedMeasurement(final double km) { 107 private double getBedMeasurement(final double km) {
139 108 return this.bedMeasurementsFinder.findD50(km);
140 try {
141 return this.bedMeasurementsFinder.findD50(km);
142 }
143 catch (final Exception e) {
144 // FIXME: cumulate problems to one message?
145 final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingD50", null, this.problemLabel);
146 this.problems.addProblem(km, message);
147
148 return Double.NaN;
149 }
150 } 109 }
151 110
152 public void calculateTkh(final double km, final SInfoResultRow row) { 111 public void calculateTkh(final double km, final SInfoResultRow row) {
153 112
154 row.putValue(SInfoResultType.station, km); 113 row.putValue(SInfoResultType.station, km);
176 final double d50 = getBedMeasurement(km); 135 final double d50 = getBedMeasurement(km);
177 if (Double.isNaN(d50)) 136 if (Double.isNaN(d50))
178 return; 137 return;
179 row.putValue(SInfoResultType.d50, d50); 138 row.putValue(SInfoResultType.d50, d50);
180 139
181 if (!this.flowVelocitiesFinder.findKmQValues(km, discharge)) { 140 if (!this.flowVelocitiesFinder.findKmQValues(km, discharge))
182 // TODO: ggf. station in Fehlermeldung? 141 return;
183 final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingVelocity", null, this.problemLabel);
184 this.problems.addProblem(km, message);
185 // FIXME: cumulate problems to one message?
186 return;
187 }
188 142
189 final double velocity = this.flowVelocitiesFinder.getFindVmainFound(); 143 final double velocity = this.flowVelocitiesFinder.getFindVmainFound();
190 row.putValue(SInfoResultType.velocity, velocity); 144 row.putValue(SInfoResultType.velocity, velocity);
191 145
192 final double tau = this.flowVelocitiesFinder.getFindTauFound(); 146 final double tau = this.flowVelocitiesFinder.getFindTauFound();

http://dive4elements.wald.intevation.org