[PATCH] Bundu bzws density calculation completed
Wald Commits
scm-commit at wald.intevation.org
Thu Aug 23 10:57:59 CEST 2018
# HG changeset patch
# User mschaefer
# Date 1535014660 -7200
# Node ID fd6621f47a72b5deab6100a67570a6ea83d7b9fd
# Parent 7e1fb8d0cb0da8673cbd2a635ddf938e0c32fe80
Bundu bzws density calculation completed
diff -r 7e1fb8d0cb0d -r fd6621f47a72 artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/BunduResultType.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/BunduResultType.java Wed Aug 22 19:12:51 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/BunduResultType.java Thu Aug 23 10:57:40 2018 +0200
@@ -404,7 +404,7 @@
}
};
- public static final BunduResultType missStationRangeFrom = new BunduResultType(I18NStrings.UNIT_KM, "bundu.export.bezugswst.csv.meta.miss.mass.km_from") {
+ public static final BunduResultType missStationRangeFrom = new BunduResultType(I18NStrings.UNIT_KM, "bundu.export.bezugswst.csv.meta.miss.km_from") {
private static final long serialVersionUID = 1L;
@@ -420,7 +420,7 @@
}
};
- public static final BunduResultType missStationRangeTo = new BunduResultType(I18NStrings.UNIT_KM, "bundu.export.bezugswst.csv.meta.miss.mass.km_to") {
+ public static final BunduResultType missStationRangeTo = new BunduResultType(I18NStrings.UNIT_KM, "bundu.export.bezugswst.csv.meta.miss.km_to") {
private static final long serialVersionUID = 1L;
diff -r 7e1fb8d0cb0d -r fd6621f47a72 artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BedQualityCalculator.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BedQualityCalculator.java Wed Aug 22 19:12:51 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BedQualityCalculator.java Thu Aug 23 10:57:40 2018 +0200
@@ -11,10 +11,14 @@
package org.dive4elements.river.artifacts.bundu.bezugswst;
import java.util.Date;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.TreeMap;
import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.access.BedQualityAccess;
import org.dive4elements.river.artifacts.bundu.BUNDUArtifact;
+import org.dive4elements.river.artifacts.math.Linear;
import org.dive4elements.river.artifacts.model.Calculation;
import org.dive4elements.river.artifacts.model.Calculation.Problem;
import org.dive4elements.river.artifacts.model.CalculationResult;
@@ -35,16 +39,19 @@
private final BUNDUArtifact bundu;
+ private final NavigableMap<Double, Double> densities;
public BedQualityCalculator(final CallContext context, final BUNDUArtifact bundu) {
this.context = context;
this.bundu = bundu;
+ this.densities = new TreeMap<>();
}
+
/**
* Calculates the river bed sublayer densities for an array of kms and a time period of measurements
*/
- public double[][] execute(final Calculation problems, final River river, final double[] kms, final Date startDay, final Date endDay) {
+ public void execute(final Calculation problems, final River river, final double[] kms, final Date startDay, final Date endDay) {
final BedQualityCalculation bqCalc = new BedQualityCalculation();
final BedQualityAccess access = createBqAccess(kms[0], kms[kms.length - 1], startDay, endDay);
final CalculationResult bqCalcResult = bqCalc.calculate(access);
@@ -55,7 +62,52 @@
final BedQualityResult[] results = (BedQualityResult[]) bqCalcResult.getData();
final BedQualityResult result = results[0];
final BedQualityResultValue bqResValue = result.getValue("density", "sublayer");
- return bqResValue.getDataInterpolated(kms);
+ final double[][] kmdensities = bqResValue.getDataInterpolated(kms);
+ this.densities.clear();
+ for (int i = 0; i <= kmdensities[0].length - 1; i++)
+ this.densities.put(Double.valueOf(kmdensities[0][i]), Double.valueOf(kmdensities[1][i]));
+ }
+
+ /**
+ * Searches the density of a station in the active calculation result
+ */
+ public double getDensity(final double station) {
+ return interpolateDensity(station);
+ }
+
+ /**
+ * Searches and interpolates a density value for a km
+ */
+ private double interpolateDensity(final double km) {
+
+ if (this.densities.containsKey(km)) {
+ final Double value = this.densities.get(km);
+ return (value == null) ? Double.NaN : value.doubleValue();
+ }
+
+ final Entry<Double, Double> floorEntry = this.densities.floorEntry(km);
+ final Entry<Double, Double> ceilingEntry = this.densities.ceilingEntry(km);
+
+ if ((floorEntry == null) || (ceilingEntry == null))
+ return Double.NaN;
+
+ final double floorKm = floorEntry.getKey().doubleValue();
+ final double ceilKm = ceilingEntry.getKey().doubleValue();
+
+ // report once if the interpolation distance exceeds 1000m
+ // if ((Math.abs(floorKm - ceilKm) > MAX_DISTANCE_KM) && (this.problems != null)) {
+ // this.problems.addProblem(km, "linearInterpolator.maxdistance", MAX_DISTANCE_KM * 1000);
+ // this.problems = null;
+ // return Double.NaN;
+ // }
+
+ final Double floorHeight = floorEntry.getValue();
+ final Double ceilingHeight = ceilingEntry.getValue();
+
+ if (floorHeight == null || ceilingHeight == null)
+ return Double.NaN;
+
+ return Linear.linear(km, floorKm, ceilKm, floorHeight, ceilingHeight);
}
/**
diff -r 7e1fb8d0cb0d -r fd6621f47a72 artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculation.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculation.java Wed Aug 22 19:12:51 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/bundu/bezugswst/BezugswstCalculation.java Thu Aug 23 10:57:40 2018 +0200
@@ -38,6 +38,7 @@
import org.dive4elements.river.exports.WaterlevelDescriptionBuilder;
import org.dive4elements.river.model.BedHeightValueType;
import org.dive4elements.river.model.River;
+import org.dive4elements.river.utils.DoubleUtil;
import org.dive4elements.river.utils.Formatter;
class BezugswstCalculation {
@@ -120,14 +121,8 @@
// Compute the missing volumes
if (access.isCalculateMissingValue()) {
computeMissingVolumes(problems);
- final BedQualityCalculator bqCalculator = new BedQualityCalculator(this.context, bunduartifact);
- final double[] kms = new double[] { this.missKmFrom.doubleValue(), this.missKmTo.doubleValue() };
- final Calendar endDay = Calendar.getInstance();
- endDay.set(access.getBezugsJahr().intValue(), 11, 31);
- final Calendar startDay = Calendar.getInstance();
- startDay.set(endDay.get(Calendar.YEAR) - 20, 0, 1);
- // TODO final double[][] kmDensities = bqCalculator.execute(problems, river, kms, startDay.getTime(), endDay.getTime());
- computeMissingMasses(problems);
+ final BedQualityCalculator bqCalculator = computeDensities(problems, bunduartifact, access, river);
+ computeMissingMasses(problems, bqCalculator);
}
// Add the result to the results collection
@@ -388,15 +383,33 @@
}
/**
+ * Create a density calculator and compute the densities of the missing volume km range and time period according to the
+ * reference year
+ */
+ private BedQualityCalculator computeDensities(final Calculation problems, final BUNDUArtifact bunduartifact, final BunduAccess access, final River river) {
+ final BedQualityCalculator bqCalculator = new BedQualityCalculator(this.context, bunduartifact);
+ // REMARK 10km tolerance at start and end to enable interpolation there
+ final double[] kms = DoubleUtil.explode(access.getMissingVolFrom().doubleValue() - 10.0, access.getMissingVolTo().doubleValue() + 10.0,
+ access.getStep().doubleValue() / 1000);
+ final Calendar endDay = Calendar.getInstance();
+ endDay.set(access.getBezugsJahr().intValue(), 11, 31);
+ final Calendar startDay = Calendar.getInstance();
+ // TODO Spezialregelung für den Rhein (bis 1999, 2000 bis 2009, ab 2010)
+ startDay.set(endDay.get(Calendar.YEAR) - 20, 0, 1);
+ bqCalculator.execute(problems, river, kms, startDay.getTime(), endDay.getTime());
+ return bqCalculator;
+ }
+
+ /**
* Computes the missing masses
*/
- private void computeMissingMasses(final Calculation problems) {
+ private void computeMissingMasses(final Calculation problems, final BedQualityCalculator densityFinder) {
for (final ResultRow row : this.rows) {
@SuppressWarnings("unchecked")
final List<Double> volumes = (List<Double>) row.getValue(BunduResultType.missVolumeFields);
if ((volumes == null) || Double.isNaN(volumes.get(0)))
continue;
- final double density = getDensity(row.getDoubleValue(GeneralResultType.station));
+ final double density = getDensity(row.getDoubleValue(GeneralResultType.station), densityFinder);
final List<Double> masses = new ArrayList<>();
double kmTotal = 0.0;
for (int j = BedHeightValueType.FIELD_FIRST_INDEX; j <= BedHeightValueType.FIELD_LAST_INDEX; j++) {
@@ -470,8 +483,11 @@
return missRows;
}
- private double getDensity(final double km) {
- return 1.73; // TODO
+ /**
+ * Gets the density of a km from the densities calculation
+ */
+ private double getDensity(final double km, final BedQualityCalculator densityFinder) {
+ return densityFinder.getDensity(km);
}
/**
diff -r 7e1fb8d0cb0d -r fd6621f47a72 artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java
--- a/artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java Wed Aug 22 19:12:51 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/utils/Formatter.java Thu Aug 23 10:57:40 2018 +0200
@@ -449,7 +449,7 @@
}
public static NumberFormat getCurrencyFormat(final CallContext context) {
- final NumberFormat nf = getFormatter(context.getMeta(), 0, 0);
+ final NumberFormat nf = getFormatter(context.getMeta(), 2, 2);
nf.setGroupingUsed(true);
return nf;
}
More information about the Dive4Elements-commits
mailing list