Mercurial > dive4elements > river
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); |