comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepthdev/FlowDepthDevelopmentCalculation.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 c40db8e8dcae
children b5600453bb8f
comparison
equal deleted inserted replaced
8963:b98fbd91f64a 8964:45f1ad66560e
9 */ 9 */
10 package org.dive4elements.river.artifacts.sinfo.flowdepthdev; 10 package org.dive4elements.river.artifacts.sinfo.flowdepthdev;
11 11
12 import java.util.ArrayList; 12 import java.util.ArrayList;
13 import java.util.Collection; 13 import java.util.Collection;
14 import java.util.TreeSet;
14 15
15 import org.apache.commons.lang.math.DoubleRange; 16 import org.apache.commons.lang.math.DoubleRange;
16 import org.dive4elements.artifacts.CallContext; 17 import org.dive4elements.artifacts.CallContext;
17 import org.dive4elements.river.artifacts.model.Calculation; 18 import org.dive4elements.river.artifacts.model.Calculation;
18 import org.dive4elements.river.artifacts.model.CalculationResult; 19 import org.dive4elements.river.artifacts.model.CalculationResult;
77 78
78 private FlowDepthDevelopmentCalculationResult calculateResult(final DoubleRange calcRange, final WstSoundingIdPair currentPair, 79 private FlowDepthDevelopmentCalculationResult calculateResult(final DoubleRange calcRange, final WstSoundingIdPair currentPair,
79 final WstSoundingIdPair histPair, final Calculation problems, final RiverInfoProvider infoProvider) { 80 final WstSoundingIdPair histPair, final Calculation problems, final RiverInfoProvider infoProvider) {
80 81
81 /* access real input data from database */ 82 /* access real input data from database */
82 final WaterlevelData currentWaterlevel = loadWaterlevel(currentPair, problems); 83 final WaterlevelData currentWaterlevel = loadWaterlevel(currentPair, calcRange, problems);
83 if (currentWaterlevel == null) 84 if (currentWaterlevel == null)
84 return null; 85 return null;
85 86
86 final WaterlevelData historicalWaterlevel = loadWaterlevel(histPair, problems); 87 final WaterlevelData historicalWaterlevel = loadWaterlevel(histPair, calcRange, problems);
87 if (historicalWaterlevel == null) 88 if (historicalWaterlevel == null)
88 return null; 89 return null;
89 90
90 final BedHeightsFinder currentSounding = loadBedHeight(currentPair, calcRange, problems); 91 final BedHeightsFinder currentSounding = loadBedHeight(currentPair, calcRange, problems);
91 if (currentSounding == null) 92 if (currentSounding == null)
110 111
111 // FIXME: distinguish error messages 112 // FIXME: distinguish error messages
112 FlowDepthUtils.checkYearDifference("", currentWstYear, currentSoundingYear, problems); 113 FlowDepthUtils.checkYearDifference("", currentWstYear, currentSoundingYear, problems);
113 FlowDepthUtils.checkYearDifference("", historicalWstYear, historicalSoundingYear, problems); 114 FlowDepthUtils.checkYearDifference("", historicalWstYear, historicalSoundingYear, problems);
114 115
115 // checkWaterlevelDiscretisation(wstKms, calcRange, problems);
116 // TODO: prüfen, ob sohlhöhen die calcRange abdecken/überschneiden
117
118 /* re-determine the reference gauge, in the same way as the WaterlevelArtifact would do it */ 116 /* re-determine the reference gauge, in the same way as the WaterlevelArtifact would do it */
119 final RiverInfoProvider currentRiverInfoProvider = infoProvider.forWaterlevel(currentWaterlevel); 117 final RiverInfoProvider currentRiverInfoProvider = infoProvider.forWaterlevel(currentWaterlevel);
120 final RiverInfoProvider histRiverInfoProvider = infoProvider.forWaterlevel(historicalWaterlevel); 118 final RiverInfoProvider histRiverInfoProvider = infoProvider.forWaterlevel(historicalWaterlevel);
121 119
122 final WstInfo currentWstInfo = new WstInfo(currentWaterlevel.getName(), currentWstYear, currentRiverInfoProvider.getReferenceGauge()); 120 final WstInfo currentWstInfo = new WstInfo(currentWaterlevel.getName(), currentWstYear, currentRiverInfoProvider.getReferenceGauge());
123 final WstInfo historicalWstInfo = new WstInfo(historicalWaterlevel.getName(), historicalWstYear, histRiverInfoProvider.getReferenceGauge()); 121 final WstInfo historicalWstInfo = new WstInfo(historicalWaterlevel.getName(), historicalWstYear, histRiverInfoProvider.getReferenceGauge());
124 122
125 final WKms currentWkms = currentWaterlevel.getWkms(); 123 final WKms currentWkms = currentWaterlevel.getWkms();
126 final WaterlevelValuesFinder currentWstProvider = WaterlevelValuesFinder.fromKms(currentWkms); 124 final WaterlevelValuesFinder currentWstProvider = WaterlevelValuesFinder.fromKms(problems, currentWkms);
127 // final DischargeValuesFinder currentDischargeProvider = DischargeValuesFinder.fromKms(currentWkms);
128 125
129 final WKms historicalWkms = historicalWaterlevel.getWkms(); 126 final WKms historicalWkms = historicalWaterlevel.getWkms();
130 final WaterlevelValuesFinder historicalWstProvider = WaterlevelValuesFinder.fromKms(historicalWkms); 127 final WaterlevelValuesFinder historicalWstProvider = WaterlevelValuesFinder.fromKms(problems, historicalWkms);
131 // final DischargeValuesFinder historicalDischargeProvider = DischargeValuesFinder.fromKms(historicalWkms);
132 128
133 final int currentMeanYear = (currentWstYear + currentSoundingYear) / 2; 129 final int currentMeanYear = (currentWstYear + currentSoundingYear) / 2;
134 final int historcialMeanYear = (historicalWstYear + historicalSoundingYear) / 2; 130 final int historcialMeanYear = (historicalWstYear + historicalSoundingYear) / 2;
135 131
136 // final String waterlevelLabel = waterlevel.getName();
137 // final String soundingLabel = buildSoundingLabel(minBedHeight, maxBedHeight);
138
139 final double diffYear = currentMeanYear - historcialMeanYear; 132 final double diffYear = currentMeanYear - historcialMeanYear;
140 133
141 /* real calculation loop */ 134 /* real calculation loop */
142 final Collection<SInfoResultRow> rows = new ArrayList<>(); 135 final Collection<SInfoResultRow> rows = new ArrayList<>();
143 136
144 // FIXME: determine what is the spatial discretisation that we will use... 137 final Collection<Double> stations = determineCalculationSteps(currentSounding, historicalSounding);
145 final double[] allKms = currentWkms.allKms().toNativeArray(); 138 for (final double station : stations) {
146 for (final double station : allKms) {
147 if (calcRange.containsDouble(station)) { 139 if (calcRange.containsDouble(station)) {
148 140
149 final double currentWst = currentWstProvider.getWaterlevel(station); 141 final double currentWst = currentWstProvider.getWaterlevel(station);
150 // final double currentDischarge = currentDischargeProvider.getDischarge(station);
151 final double currentBedHeight = currentSounding.getMeanBedHeight(station); 142 final double currentBedHeight = currentSounding.getMeanBedHeight(station);
152 143
153 final double historicalWst = historicalWstProvider.getWaterlevel(station); 144 final double historicalWst = historicalWstProvider.getWaterlevel(station);
154 // final double historicalDischarge = historicalDischargeProvider.getDischarge(station);
155 final double historicalBedHeight = historicalSounding.getMeanBedHeight(station); 145 final double historicalBedHeight = historicalSounding.getMeanBedHeight(station);
156 146
157 final double diffWst = (currentWst - historicalWst) * 100; 147 final double diffWst = (currentWst - historicalWst) * 100;
158 final double diffBedHeight = (currentBedHeight - historicalBedHeight) * 100; 148 final double diffBedHeight = (currentBedHeight - historicalBedHeight) * 100;
159 149
184 174
185 return new FlowDepthDevelopmentCalculationResult(label, currentWstInfo, historicalWstInfo, currentSoundingInfo, historicalSoundingInfo, 175 return new FlowDepthDevelopmentCalculationResult(label, currentWstInfo, historicalWstInfo, currentSoundingInfo, historicalSoundingInfo,
186 rows); 176 rows);
187 } 177 }
188 178
179 /**
180 * Calculation steps are simply the union of all stations of all involved bed-height datasets
181 */
182 private Collection<Double> determineCalculationSteps(final BedHeightsFinder currentSounding, final BedHeightsFinder historicalSounding) {
183
184 final Collection<Double> allStations = new TreeSet<>();
185
186 allStations.addAll(currentSounding.getStations());
187 allStations.addAll(historicalSounding.getStations());
188
189 return allStations;
190 }
191
189 private String buildLabel(final WaterlevelData currentWaterlevel, final BedHeightInfo currentSounding, final WaterlevelData historicalWaterlevel, 192 private String buildLabel(final WaterlevelData currentWaterlevel, final BedHeightInfo currentSounding, final WaterlevelData historicalWaterlevel,
190 final BedHeightInfo historicalSounding) { 193 final BedHeightInfo historicalSounding) {
191 194
192 return new StringBuilder(). // 195 return new StringBuilder(). //
193 append(currentWaterlevel.getName()). // 196 append(currentWaterlevel.getName()). //
199 append(historicalSounding.getDescription()). // 202 append(historicalSounding.getDescription()). //
200 toString(); 203 toString();
201 } 204 }
202 205
203 /* REMARK: fetch ALL wst kms, because we need to determine the original reference gauge */ 206 /* REMARK: fetch ALL wst kms, because we need to determine the original reference gauge */
204 private WaterlevelData loadWaterlevel(final WstSoundingIdPair pair, final Calculation problems) { 207 private WaterlevelData loadWaterlevel(final WstSoundingIdPair pair, final DoubleRange calcRange, final Calculation problems) {
205 final String wstId = pair.getWstId(); 208 final String wstId = pair.getWstId();
206 return new WaterlevelFetcher().findWaterlevel(this.context, wstId, Double.NaN, Double.NaN, problems); 209 return new WaterlevelFetcher().findWaterlevel(this.context, wstId, calcRange, problems);
207 } 210 }
208 211
209 private BedHeightsFinder loadBedHeight(final WstSoundingIdPair pair, final DoubleRange calcRange, final Calculation problems) { 212 private BedHeightsFinder loadBedHeight(final WstSoundingIdPair pair, final DoubleRange calcRange, final Calculation problems) {
210 final String soundingId = pair.getSoundingId(); 213 final String soundingId = pair.getSoundingId();
211 return BedHeightsFinder.forId(this.context, soundingId, calcRange, problems); 214 return BedHeightsFinder.forId(this.context, soundingId, calcRange, problems);

http://dive4elements.wald.intevation.org