Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.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 |
---|---|
14 import java.util.HashMap; | 14 import java.util.HashMap; |
15 import java.util.List; | 15 import java.util.List; |
16 import java.util.Map; | 16 import java.util.Map; |
17 import java.util.Map.Entry; | 17 import java.util.Map.Entry; |
18 import java.util.Set; | 18 import java.util.Set; |
19 import java.util.TreeSet; | |
19 | 20 |
20 import org.apache.commons.lang.math.DoubleRange; | 21 import org.apache.commons.lang.math.DoubleRange; |
21 import org.apache.commons.lang.math.NumberRange; | 22 import org.apache.commons.lang.math.NumberRange; |
22 import org.dive4elements.artifacts.CallContext; | 23 import org.dive4elements.artifacts.CallContext; |
23 import org.dive4elements.river.artifacts.WINFOArtifact; | 24 import org.dive4elements.river.artifacts.WINFOArtifact; |
63 | 64 |
64 final Calculation problems = new Calculation(); | 65 final Calculation problems = new Calculation(); |
65 | 66 |
66 /* find relevant bed-heights */ | 67 /* find relevant bed-heights */ |
67 final List<BedHeight> defaultBedHeights = new DefaultBedHeights(river).getBedHeights(problems); | 68 final List<BedHeight> defaultBedHeights = new DefaultBedHeights(river).getBedHeights(problems); |
68 final Collection<BedHeightsFinder> bedHeights = BedHeightsFinder.createTkhBedHeights(calcRange, defaultBedHeights); | 69 final Collection<BedHeightsFinder> bedHeights = BedHeightsFinder.createTkhBedHeights(problems, calcRange, defaultBedHeights); |
69 | 70 |
70 /* misuse winfo-artifact to calculate waterlevels in the same way */ | 71 /* misuse winfo-artifact to calculate waterlevels in the same way */ |
71 final WINFOArtifact winfo = new WinfoArtifactWrapper(sinfo); | 72 final WINFOArtifact winfo = new WinfoArtifactWrapper(sinfo); |
72 | 73 |
73 /* calculate waterlevels */ | 74 /* calculate waterlevels */ |
83 final String descriptionHeader = descBuilder.getColumnHeader(); | 84 final String descriptionHeader = descBuilder.getColumnHeader(); |
84 | 85 |
85 /* for each waterlevel, do a tkh calculation */ | 86 /* for each waterlevel, do a tkh calculation */ |
86 final TkhCalculationResults results = new TkhCalculationResults(calcModeLabel, user, riverInfo, calcRange, descriptionHeader); | 87 final TkhCalculationResults results = new TkhCalculationResults(calcModeLabel, user, riverInfo, calcRange, descriptionHeader); |
87 | 88 |
89 /* determine calculation steps */ | |
90 final Collection<Double> allStations = determineCalculationSteps(bedHeights); | |
91 | |
88 for (final WQKms wqKms : kms) { | 92 for (final WQKms wqKms : kms) { |
89 | 93 final TkhCalculationResult result = calculateResult(calcRange, allStations, infoProvider, wqKms, bedHeights, descBuilder, problems); |
90 final TkhCalculationResult result = calculateResult(calcRange, infoProvider, wqKms, bedHeights, descBuilder, problems); | |
91 if (result != null) | 94 if (result != null) |
92 // FIXME: must be sorted by station! | |
93 results.addResult(result); | 95 results.addResult(result); |
94 } | 96 } |
95 | 97 |
96 return new CalculationResult(results, problems); | 98 return new CalculationResult(results, problems); |
99 } | |
100 | |
101 /** | |
102 * Calculation steps are simply the union of all stations of all involved bed-height datasets | |
103 */ | |
104 private Collection<Double> determineCalculationSteps(final Collection<BedHeightsFinder> bedHeights) { | |
105 | |
106 final Collection<Double> allStations = new TreeSet<>(); | |
107 | |
108 for (final BedHeightsFinder bedHeight : bedHeights) { | |
109 final Collection<Double> stations = bedHeight.getStations(); | |
110 allStations.addAll(stations); | |
111 } | |
112 | |
113 return allStations; | |
97 } | 114 } |
98 | 115 |
99 private WQKms[] calculateWaterlevels(final WINFOArtifact winfo, final Calculation problems) { | 116 private WQKms[] calculateWaterlevels(final WINFOArtifact winfo, final Calculation problems) { |
100 | 117 |
101 final CalculationResult waterlevelData = winfo.getWaterlevelData(this.context); | 118 final CalculationResult waterlevelData = winfo.getWaterlevelData(this.context); |
110 } | 127 } |
111 | 128 |
112 return (WQKms[]) waterlevelData.getData(); | 129 return (WQKms[]) waterlevelData.getData(); |
113 } | 130 } |
114 | 131 |
115 private TkhCalculationResult calculateResult(final DoubleRange calcRange, final RiverInfoProvider riverInfo, final WQKms wkms, | 132 private TkhCalculationResult calculateResult(final DoubleRange calcRange, final Collection<Double> allStations, final RiverInfoProvider riverInfo, |
116 final Collection<BedHeightsFinder> bedHeights, final WaterlevelDescriptionBuilder descBuilder, final Calculation problems) { | 133 final WQKms wkms, final Collection<BedHeightsFinder> bedHeights, final WaterlevelDescriptionBuilder descBuilder, final Calculation problems) { |
117 | 134 |
118 // FIXME: wo kommt das her? via winfo kein jahr vorhanden, oder doch? aber soll in metadaten ausgegeben werden... | 135 // We have no wst year as the wst is created by a calculation; we do not need it though |
119 final int wspYear = -1; | 136 final int wspYear = -1; |
120 // FIXME: richtig? vgl. WInfo? | 137 // Remark: showAllGauges only true for Fixierungsanalyse, false for WInfo, so false here as well |
121 final boolean showAllGauges = false; | 138 final boolean showAllGauges = false; |
122 final WaterlevelData waterlevel = new WaterlevelData(wkms, wspYear, showAllGauges); | 139 final WaterlevelData waterlevel = new WaterlevelData(wkms, wspYear, showAllGauges); |
123 | 140 |
124 final RiverInfoProvider riverInfoProvider = riverInfo.forWaterlevel(waterlevel); | 141 final RiverInfoProvider riverInfoProvider = riverInfo.forWaterlevel(waterlevel); |
125 | 142 |
135 return null; | 152 return null; |
136 } | 153 } |
137 | 154 |
138 final Collection<SInfoResultRow> rows = new ArrayList<>(); | 155 final Collection<SInfoResultRow> rows = new ArrayList<>(); |
139 | 156 |
140 /* using wst-kms as basis, because we know that they are generated wst's with a fixed km-step */ | 157 for (final Double stationDbl : allStations) { |
141 // FIXME: das führt dazu, das aktuell die Sohlhöhen beliebig linear interpolierrt werden. ist das immer richtig? z.b. | 158 |
142 // bei großen abständen? | 159 final double station = stationDbl; |
143 | |
144 final int size = wkms.size(); | |
145 for (int i = 0; i < size; i++) { | |
146 | |
147 final double station = wkms.getKm(i); | |
148 | 160 |
149 /* find the right calculator (i.e. bed height) depending on station, there should only be one maximal */ | 161 /* find the right calculator (i.e. bed height) depending on station, there should only be one maximal */ |
150 final TkhCalculator tkhCalculator = findCalculator(calculatorsByRanges, station); | 162 final TkhCalculator tkhCalculator = findCalculator(calculatorsByRanges, station); |
151 if (tkhCalculator == null) | 163 if (tkhCalculator == null) |
152 continue; | 164 continue; |
186 | 198 |
187 final BedHeightInfo info = bedHeightsProvider.getInfo(); | 199 final BedHeightInfo info = bedHeightsProvider.getInfo(); |
188 | 200 |
189 final NumberRange range = new NumberRange(info.getFrom(), info.getTo()); | 201 final NumberRange range = new NumberRange(info.getFrom(), info.getTo()); |
190 | 202 |
191 final WaterlevelValuesFinder waterlevelProvider = WaterlevelValuesFinder.fromKms(wkms); | 203 final WaterlevelValuesFinder waterlevelProvider = WaterlevelValuesFinder.fromKms(problems, wkms); |
192 final DischargeValuesFinder dischargeProvider = DischargeValuesFinder.fromKms(wkms); | 204 final DischargeValuesFinder dischargeProvider = DischargeValuesFinder.fromKms(wkms); |
193 | 205 |
194 /* initialize tkh calculator */ | 206 /* initialize tkh calculator */ |
195 final TkhCalculator tkhCalculator = TkhCalculator.buildTkhCalculator(true, this.context, problems, wstLabel, riverInfoProvider.getRiver(), | 207 final TkhCalculator tkhCalculator = TkhCalculator.buildTkhCalculator(true, problems, wstLabel, riverInfoProvider.getRiver(), calcRange, |
196 calcRange, waterlevelProvider, dischargeProvider, bedHeightsProvider); | 208 waterlevelProvider, dischargeProvider, bedHeightsProvider); |
197 | 209 |
198 if (tkhCalculator != null) { | 210 if (tkhCalculator.hasTkh()) { |
199 /* just ignore null ones, problems have already been updated by buildTkhCalculator() */ | 211 /* just ignore invalid ones, problems have already been updated by buildTkhCalculator() */ |
200 calculatorByRanges.put(range, tkhCalculator); | 212 calculatorByRanges.put(range, tkhCalculator); |
201 } | 213 } |
202 } | 214 } |
203 | 215 |
204 return calculatorByRanges; | 216 return calculatorByRanges; |