Mercurial > dive4elements > river
diff 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 |
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java Wed Mar 28 17:04:20 2018 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/tkhstate/TkhCalculation.java Thu Mar 29 15:48:17 2018 +0200 @@ -16,6 +16,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.TreeSet; import org.apache.commons.lang.math.DoubleRange; import org.apache.commons.lang.math.NumberRange; @@ -65,7 +66,7 @@ /* find relevant bed-heights */ final List<BedHeight> defaultBedHeights = new DefaultBedHeights(river).getBedHeights(problems); - final Collection<BedHeightsFinder> bedHeights = BedHeightsFinder.createTkhBedHeights(calcRange, defaultBedHeights); + final Collection<BedHeightsFinder> bedHeights = BedHeightsFinder.createTkhBedHeights(problems, calcRange, defaultBedHeights); /* misuse winfo-artifact to calculate waterlevels in the same way */ final WINFOArtifact winfo = new WinfoArtifactWrapper(sinfo); @@ -85,17 +86,33 @@ /* for each waterlevel, do a tkh calculation */ final TkhCalculationResults results = new TkhCalculationResults(calcModeLabel, user, riverInfo, calcRange, descriptionHeader); - for (final WQKms wqKms : kms) { + /* determine calculation steps */ + final Collection<Double> allStations = determineCalculationSteps(bedHeights); - final TkhCalculationResult result = calculateResult(calcRange, infoProvider, wqKms, bedHeights, descBuilder, problems); + for (final WQKms wqKms : kms) { + final TkhCalculationResult result = calculateResult(calcRange, allStations, infoProvider, wqKms, bedHeights, descBuilder, problems); if (result != null) - // FIXME: must be sorted by station! results.addResult(result); } return new CalculationResult(results, problems); } + /** + * Calculation steps are simply the union of all stations of all involved bed-height datasets + */ + private Collection<Double> determineCalculationSteps(final Collection<BedHeightsFinder> bedHeights) { + + final Collection<Double> allStations = new TreeSet<>(); + + for (final BedHeightsFinder bedHeight : bedHeights) { + final Collection<Double> stations = bedHeight.getStations(); + allStations.addAll(stations); + } + + return allStations; + } + private WQKms[] calculateWaterlevels(final WINFOArtifact winfo, final Calculation problems) { final CalculationResult waterlevelData = winfo.getWaterlevelData(this.context); @@ -112,12 +129,12 @@ return (WQKms[]) waterlevelData.getData(); } - private TkhCalculationResult calculateResult(final DoubleRange calcRange, final RiverInfoProvider riverInfo, final WQKms wkms, - final Collection<BedHeightsFinder> bedHeights, final WaterlevelDescriptionBuilder descBuilder, final Calculation problems) { + private TkhCalculationResult calculateResult(final DoubleRange calcRange, final Collection<Double> allStations, final RiverInfoProvider riverInfo, + final WQKms wkms, final Collection<BedHeightsFinder> bedHeights, final WaterlevelDescriptionBuilder descBuilder, final Calculation problems) { - // FIXME: wo kommt das her? via winfo kein jahr vorhanden, oder doch? aber soll in metadaten ausgegeben werden... + // We have no wst year as the wst is created by a calculation; we do not need it though final int wspYear = -1; - // FIXME: richtig? vgl. WInfo? + // Remark: showAllGauges only true for Fixierungsanalyse, false for WInfo, so false here as well final boolean showAllGauges = false; final WaterlevelData waterlevel = new WaterlevelData(wkms, wspYear, showAllGauges); @@ -137,14 +154,9 @@ final Collection<SInfoResultRow> rows = new ArrayList<>(); - /* using wst-kms as basis, because we know that they are generated wst's with a fixed km-step */ - // FIXME: das führt dazu, das aktuell die Sohlhöhen beliebig linear interpolierrt werden. ist das immer richtig? z.b. - // bei großen abständen? + for (final Double stationDbl : allStations) { - final int size = wkms.size(); - for (int i = 0; i < size; i++) { - - final double station = wkms.getKm(i); + final double station = stationDbl; /* find the right calculator (i.e. bed height) depending on station, there should only be one maximal */ final TkhCalculator tkhCalculator = findCalculator(calculatorsByRanges, station); @@ -188,15 +200,15 @@ final NumberRange range = new NumberRange(info.getFrom(), info.getTo()); - final WaterlevelValuesFinder waterlevelProvider = WaterlevelValuesFinder.fromKms(wkms); + final WaterlevelValuesFinder waterlevelProvider = WaterlevelValuesFinder.fromKms(problems, wkms); final DischargeValuesFinder dischargeProvider = DischargeValuesFinder.fromKms(wkms); /* initialize tkh calculator */ - final TkhCalculator tkhCalculator = TkhCalculator.buildTkhCalculator(true, this.context, problems, wstLabel, riverInfoProvider.getRiver(), - calcRange, waterlevelProvider, dischargeProvider, bedHeightsProvider); + final TkhCalculator tkhCalculator = TkhCalculator.buildTkhCalculator(true, problems, wstLabel, riverInfoProvider.getRiver(), calcRange, + waterlevelProvider, dischargeProvider, bedHeightsProvider); - if (tkhCalculator != null) { - /* just ignore null ones, problems have already been updated by buildTkhCalculator() */ + if (tkhCalculator.hasTkh()) { + /* just ignore invalid ones, problems have already been updated by buildTkhCalculator() */ calculatorByRanges.put(range, tkhCalculator); } }