comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/FlowDepthCalculation.java @ 8901:0a900d605d52

S-INFO Flowdepth work on TKH calculation
author mschaefer
date Thu, 22 Feb 2018 17:04:06 +0100
parents d32c22fc686c
children 37ff7f435912
comparison
equal deleted inserted replaced
8900:d32c22fc686c 8901:0a900d605d52
25 import org.dive4elements.river.artifacts.BedHeightsArtifact; 25 import org.dive4elements.river.artifacts.BedHeightsArtifact;
26 import org.dive4elements.river.artifacts.model.Calculation; 26 import org.dive4elements.river.artifacts.model.Calculation;
27 import org.dive4elements.river.artifacts.model.CalculationResult; 27 import org.dive4elements.river.artifacts.model.CalculationResult;
28 import org.dive4elements.river.artifacts.model.DateRange; 28 import org.dive4elements.river.artifacts.model.DateRange;
29 import org.dive4elements.river.artifacts.model.LocationProvider; 29 import org.dive4elements.river.artifacts.model.LocationProvider;
30 import org.dive4elements.river.artifacts.model.WQKms; 30 import org.dive4elements.river.artifacts.model.QKms;
31 import org.dive4elements.river.artifacts.model.WKms; 31 import org.dive4elements.river.artifacts.model.WKms;
32 import org.dive4elements.river.artifacts.resources.Resources; 32 import org.dive4elements.river.artifacts.resources.Resources;
33 import org.dive4elements.river.artifacts.sinfo.SINFOArtifact; 33 import org.dive4elements.river.artifacts.sinfo.SINFOArtifact;
34 import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthAccess.DifferencesPair; 34 import org.dive4elements.river.artifacts.sinfo.flowdepth.FlowDepthAccess.DifferencesPair;
35 import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo; 35 import org.dive4elements.river.artifacts.sinfo.util.BedHeightInfo;
109 /* access real input data from database */ 109 /* access real input data from database */
110 final String soundingId = diffPair.getSoundingId(); 110 final String soundingId = diffPair.getSoundingId();
111 final String wstId = diffPair.getWstId(); 111 final String wstId = diffPair.getWstId();
112 112
113 final BedHeight bedHeight = loadBedHeight(soundingId); 113 final BedHeight bedHeight = loadBedHeight(soundingId);
114 final BedHeight bedHeight = loadBedHeight(soundingId);
115 if (bedHeight == null) { 114 if (bedHeight == null) {
116 final String message = Resources.format(this.context.getMeta(), "Failed to access sounding with id '{0}'", soundingId); 115 final String message = Resources.format(this.context.getMeta(), "Failed to access sounding with id '{0}'", soundingId);
117 problems.addProblem(message); 116 problems.addProblem(message);
118 return null; 117 return null;
119 } 118 }
131 final String soundingLabel = bedHeight.getDescription(); 130 final String soundingLabel = bedHeight.getDescription();
132 final String label = String.format("%s - %s", wspLabel, soundingLabel); 131 final String label = String.format("%s - %s", wspLabel, soundingLabel);
133 132
134 checkYearDifference(label, waterlevel, bedHeight, problems); 133 checkYearDifference(label, waterlevel, bedHeight, problems);
135 checkWaterlevelDiscretisation(wstKms, calcRange, problems); 134 checkWaterlevelDiscretisation(wstKms, calcRange, problems);
136 // TODO: prüfen, ob sohlhöen die calcRange abdecken/überschneiden 135 // TODO: prüfen, ob sohlhöhen die calcRange abdecken/überschneiden
137 136
138 /* re-determine the reference gauge, in the same way as the WaterlevelArtifact would do it */ 137 /* re-determine the reference gauge, in the same way as the WaterlevelArtifact would do it */
139 final String notinrange = Resources.getMsg(this.context.getMeta(), CSV_NOT_IN_GAUGE_RANGE, CSV_NOT_IN_GAUGE_RANGE); 138 final String notinrange = Resources.getMsg(this.context.getMeta(), CSV_NOT_IN_GAUGE_RANGE, CSV_NOT_IN_GAUGE_RANGE);
140 139
141 final Gauge refGauge = waterlevel.findReferenceGauge(river); 140 final Gauge refGauge = waterlevel.findReferenceGauge(river);
145 final int wspYear = waterlevel.getYear(); 144 final int wspYear = waterlevel.getYear();
146 final WstInfo wstInfo = new WstInfo(wspLabel, wspYear, refGaugeName); 145 final WstInfo wstInfo = new WstInfo(wspLabel, wspYear, refGaugeName);
147 146
148 final FlowDepthCalculationResult resultData = new FlowDepthCalculationResult(label, wstInfo, sounding); 147 final FlowDepthCalculationResult resultData = new FlowDepthCalculationResult(label, wstInfo, sounding);
149 148
150 // FIXME: nur prüfen/beschaffen wenn TKH Berechnung aktiv 149 boolean doCalcTkh = useTkh;
151 /* Abflusswerte vorhanden? */ 150 if (doCalcTkh && !(wstKms instanceof QKms)) {
152 if (!(wstKms instanceof WQKms)) {
153 final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingQ", null, label); 151 final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingQ", null, label);
154 problems.addProblem(message); 152 problems.addProblem(message);
155 // TODO: keine Berechnung TKH 153 doCalcTkh = false;
156 } 154 }
157 155
158 BedQualityD50KmValueFinder bedMeasurementsFinder = null; 156 BedQualityD50KmValueFinder bedMeasurementsFinder = null;
159 if (useTkh) 157 if (doCalcTkh)
160 bedMeasurementsFinder = loadBedMeasurements(river, calcRange, sounding.getYear()); 158 bedMeasurementsFinder = loadBedMeasurements(river, calcRange, sounding.getYear().intValue());
161 // FIXME: prüfung ob (genug) werte vorhanden sind? was sind genau die kriterien? falls nein, problem hinzufügen und keine
162 // berechnung tkh
163 159
164 final String bedHeightLabel = bedHeight.getDescription(); 160 final String bedHeightLabel = bedHeight.getDescription();
165 final String wstLabel = wstKms.getName(); 161 final String wstLabel = wstKms.getName();
166 162
167 final UnivariateRealFunction wstInterpolator = DoubleUtil.getLinearInterpolator(wstKms.allKms(), wstKms.allWs()); 163 final UnivariateRealFunction wstInterpolator = DoubleUtil.getLinearInterpolator(wstKms.allKms(), wstKms.allWs());
168 UnivariateRealFunction qInterpolator = null; 164 UnivariateRealFunction qInterpolator = null;
169 DoubleRange qRange = null; 165 DoubleRange qRange = null;
170 if (useTkh && (wstKms instanceof WQKms)) { 166 if (doCalcTkh) {
171 qInterpolator = DoubleUtil.getLinearInterpolator(((WQKms) wstKms).allKms(), ((WQKms) wstKms).allQs()); 167 qInterpolator = DoubleUtil.getLinearInterpolator(((QKms) wstKms).allKms(), ((QKms) wstKms).allQs());
172 qRange = new DoubleRange( ((WQKms) wstKms).allQs().min(), ((WQKms) wstKms).allQs().max()); 168 qRange = new DoubleRange( ((QKms) wstKms).allQs().min(), ((QKms) wstKms).allQs().max());
173 } 169 }
174 170
175 // FIXME: sort by station first, but in what direction? 171 // FIXME: sort by station first, but in what direction?
176 // FIXME: using river.getKmUp()? 172 // FIXME: using river.getKmUp()?
177 final List<BedHeightValue> values = bedHeight.getValues(); 173 final List<BedHeightValue> values = bedHeight.getValues();
180 Collections.sort(sortedValues, new BedHeightStationComparator()); 176 Collections.sort(sortedValues, new BedHeightStationComparator());
181 177
182 // FIXME: wie wird ggf. interpoliert? prüfung ob werte vorhanden? 178 // FIXME: wie wird ggf. interpoliert? prüfung ob werte vorhanden?
183 /* SoilKind lastKind = SoilKind.mobil; */ 179 /* SoilKind lastKind = SoilKind.mobil; */
184 SoilKindKmValueFinder soilKindFinder = null; 180 SoilKindKmValueFinder soilKindFinder = null;
185 if (useTkh) { 181 if (doCalcTkh) {
186 soilKindFinder = new SoilKindKmValueFinder(); 182 soilKindFinder = new SoilKindKmValueFinder();
187 soilKindFinder.loadValues(river, calcRange); 183 soilKindFinder.loadValues(river, calcRange);
188 } 184 }
189 185
190 FlowVelocityModelKmValueFinder flowVelocitiesFinder = null; 186 FlowVelocityModelKmValueFinder flowVelocitiesFinder = null;
191 if (useTkh) { 187 if (doCalcTkh) {
192 flowVelocitiesFinder = new FlowVelocityModelKmValueFinder(); 188 flowVelocitiesFinder = new FlowVelocityModelKmValueFinder();
193 flowVelocitiesFinder.loadValues(river, calcRange, qRange); 189 flowVelocitiesFinder.loadValues(river, calcRange, qRange);
194 } 190 }
195 191
196 for (final BedHeightValue bedHeightValue : sortedValues) { 192 for (final BedHeightValue bedHeightValue : sortedValues) {
204 continue; 200 continue;
205 201
206 final double km = station; 202 final double km = station;
207 final double meanBedHeight = meanBedHeightDbl; 203 final double meanBedHeight = meanBedHeightDbl;
208 204
209 if (!calcRange.containsDouble(km))
210 continue;
211 if (!calcRange.containsDouble(km)) 205 if (!calcRange.containsDouble(km))
212 continue; 206 continue;
213 207
214 try { 208 try {
215 // FIXME: check out of range 209 // FIXME: check out of range
225 else 219 else
226 discharge = Double.NaN; 220 discharge = Double.NaN;
227 221
228 // FIXME: calculate tkh 222 // FIXME: calculate tkh
229 double tkh = 0; 223 double tkh = 0;
230 if (useTkh) { 224 if (doCalcTkh) {
231 double d50 = 0; 225 double d50 = bedMeasurementsFinder.findD50(km);
232 try { 226 if (Double.isNaN(d50)) {
233 d50 = bedMeasurementsFinder.findD50(km);
234 } catch (Exception e) {
235 final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingD50", null, label); 227 final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingD50", null, label);
236 problems.addProblem(km, message); 228 problems.addProblem(km, message);
237 //FIXME: cumulate problems 229 //FIXME: cumulate problems to one message?
238 } 230 }
239 if (flowVelocitiesFinder.findKmQValues(km, discharge)) { 231 if (!Double.isNaN(d50)) {
240 tkh = calculateTkh(wst - meanBedHeight, flowVelocitiesFinder.getFindVmainFound(), d50, flowVelocitiesFinder.getFindTauFound()); 232 if (flowVelocitiesFinder.findKmQValues(km, discharge)) {
241 log.debug(String.format("calculateTkh km %.3f q %.0f w %.2f mbh %.2f vm %.1f tau %.1f d50(mm) %.1f tkh(cm) %.1f", 233 tkh = calculateTkh(wst - meanBedHeight, flowVelocitiesFinder.getFindVmainFound(), d50, flowVelocitiesFinder.getFindTauFound());
242 km, discharge, wst, meanBedHeight, flowVelocitiesFinder.getFindVmainFound(), flowVelocitiesFinder.getFindTauFound(), d50*1000, tkh)); 234 /* log.debug(String.format("calculateTkh km %.3f q %.0f w %.2f mbh %.2f vm %.1f tau %.1f d50(mm) %.1f tkh(cm) %.1f",
235 km, discharge, wst, meanBedHeight, flowVelocitiesFinder.getFindVmainFound(), flowVelocitiesFinder.getFindTauFound(), d50*1000, tkh)); */
236 }
237 else {
238 final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingQ", null, label);
239 problems.addProblem(km, message);
240 //FIXME: cumulate problems to one message?
241 }
243 } 242 }
244 else 243 else
245 tkh = Double.NaN; 244 tkh = Double.NaN;
246 } 245 }
247 246
248 // Soil kind 247 // Soil kind
249 SoilKind kind = SoilKind.starr; 248 SoilKind kind = SoilKind.mobil;
250 if (useTkh) { 249 if (doCalcTkh) {
251 try { 250 try {
252 kind = soilKindFinder.findSoilKind(km); 251 kind = soilKindFinder.findSoilKind(km);
253 } catch (Exception e) { 252 } catch (Exception e) {
254 final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingSoilKind", null, label); 253 final String message = Resources.getMsg(this.context.getMeta(), "sinfo_calc_flow_depth.warning.missingSoilKind", null, label);
255 problems.addProblem(km, message); 254 problems.addProblem(km, message);
256 //FIXME: cumulate problems 255 //FIXME: cumulate problems to one message?
257 } 256 }
258 } 257 }
259 258
260 /* // REMARK: bissl spielerei zum testen damit die sohlart nicht zu schnell wechselt 259 /* // REMARK: bissl spielerei zum testen damit die sohlart nicht zu schnell wechselt
261 SoilKind kind; 260 SoilKind kind;

http://dive4elements.wald.intevation.org