comparison artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java @ 9316:72b3270e1568

U-Info salix line with regional and supraregional scenario calculation and chart display
author mschaefer
date Thu, 26 Jul 2018 17:28:32 +0200
parents 9a9f076d5716
children a978b601a034
comparison
equal deleted inserted replaced
9315:2ff46d921917 9316:72b3270e1568
11 11
12 import java.util.ArrayList; 12 import java.util.ArrayList;
13 import java.util.HashMap; 13 import java.util.HashMap;
14 import java.util.List; 14 import java.util.List;
15 import java.util.Map; 15 import java.util.Map;
16 import java.util.Map.Entry;
16 import java.util.NavigableMap; 17 import java.util.NavigableMap;
17 18
18 import org.dive4elements.artifacts.CallContext; 19 import org.dive4elements.artifacts.CallContext;
19 import org.dive4elements.river.artifacts.WINFOArtifact; 20 import org.dive4elements.river.artifacts.WINFOArtifact;
20 import org.dive4elements.river.artifacts.access.ComputationRangeAccess; 21 import org.dive4elements.river.artifacts.access.ComputationRangeAccess;
54 55
55 private Calculation problems; 56 private Calculation problems;
56 57
57 private WstValueTable wst; 58 private WstValueTable wst;
58 59
60 /**
61 * List of delta-w (may be 0) mapped by km range
62 */
59 private NavigableMap<Double, List<Double>> rangeScenarios; 63 private NavigableMap<Double, List<Double>> rangeScenarios;
60 64
61 65
62 public SalixLineCalculator(final CallContext context, final RiverInfoProvider riverInfoProvider) { 66 public SalixLineCalculator(final CallContext context, final RiverInfoProvider riverInfoProvider) {
63 this.context = context; 67 this.context = context;
70 74
71 /** 75 /**
72 * Calculate the salix line result rows 76 * Calculate the salix line result rows
73 */ 77 */
74 public void execute(final Calculation problems, final UINFOArtifact uinfo, final NavigableMap<Double, List<Double>> rangeScenarios, 78 public void execute(final Calculation problems, final UINFOArtifact uinfo, final NavigableMap<Double, List<Double>> rangeScenarios,
75 final ScenarioType scenarioType, final SalixLineCalculationResults results) { 79 final ScenarioType scenarioType, final String[] scenarioLabels, final SalixLineCalculationResults results) {
76 80
77 this.problems = problems; 81 this.problems = problems;
78 this.wst = WstValueTableFactory.getTable(this.riverInfoProvider.getRiver()); 82 this.wst = WstValueTableFactory.getTable(this.riverInfoProvider.getRiver());
79 this.rangeScenarios = rangeScenarios; 83 this.rangeScenarios = rangeScenarios;
80 84
85 winfo.addStringData("ld_step", "100"); 89 winfo.addStringData("ld_step", "100");
86 for (final double station : new ComputationRangeAccess(winfo).getKms()) { 90 for (final double station : new ComputationRangeAccess(winfo).getKms()) {
87 this.rows.add(createRow(station)); 91 this.rows.add(createRow(station));
88 } 92 }
89 if (scenarioType == ScenarioType.REGIONAL) 93 if (scenarioType == ScenarioType.REGIONAL)
90 results.addResult(new SalixLineCalculationRegionalResult("Salix", null, this.rows), problems); 94 results.addResult(new SalixLineCalculationRegionalResult("Salix", scenarioLabels, this.rows), problems);
91 else if (scenarioType == ScenarioType.SUPRAREGIONAL) 95 else if (scenarioType == ScenarioType.SUPRAREGIONAL)
92 results.addResult(new SalixLineCalculationSupraRegionalResult("Salix", null, this.rows), problems); 96 results.addResult(new SalixLineCalculationSupraRegionalResult("Salix", this.rows), problems);
93 else if (scenarioType == ScenarioType.HISTORICAL) 97 else if (scenarioType == ScenarioType.HISTORICAL)
94 results.addResult(new SalixLineCalculationHistoricalResult("Salix", null, this.rows), problems); 98 results.addResult(new SalixLineCalculationHistoricalResult("Salix", this.rows), problems);
95 else 99 else
96 results.addResult(new SalixLineCalculationNoScenarioResult("Salix", null, this.rows), problems); 100 results.addResult(new SalixLineCalculationNoScenarioResult("Salix", this.rows), problems);
97 } 101 }
98 102
99 /** 103 /**
100 * Fetch MW, MNW and MHW of all gauges and determine the wst QPosition for each one 104 * Fetch MW, MNW and MHW of all gauges and determine the wst QPosition for each one
101 */ 105 */
126 * Create a result row for a station and its gauge, and add w-q-values as selected 130 * Create a result row for a station and its gauge, and add w-q-values as selected
127 */ 131 */
128 private ResultRow createRow(final double station) { 132 private ResultRow createRow(final double station) {
129 133
130 final ResultRow row = ResultRow.create(); 134 final ResultRow row = ResultRow.create();
135 // Find station's gauge
131 final Gauge gauge = this.riverInfoProvider.getGauge(station, true); 136 final Gauge gauge = this.riverInfoProvider.getGauge(station, true);
132 row.putValue(GeneralResultType.station, station); 137 row.putValue(GeneralResultType.station, station);
138 // Interpolate mnw, mw, and mhw
133 final double mnw = interpolateW(station, this.gaugeMnwPos.get(gauge)); 139 final double mnw = interpolateW(station, this.gaugeMnwPos.get(gauge));
134 final double mw = interpolateW(station, this.gaugeMwPos.get(gauge)); 140 final double mw = interpolateW(station, this.gaugeMwPos.get(gauge));
135 final double mhw = interpolateW(station, this.gaugeMhwPos.get(gauge)); 141 final double mhw = interpolateW(station, this.gaugeMhwPos.get(gauge));
136 row.putValue(SInfoResultType.waterlevel, mnw); 142 row.putValue(SInfoResultType.waterlevel, mnw);
137 row.putValue(SInfoResultType.waterlevel1, mw); 143 row.putValue(SInfoResultType.waterlevel1, mw);
138 row.putValue(SInfoResultType.waterlevel2, mhw); 144 row.putValue(SInfoResultType.waterlevel2, mhw);
145 // Calc salix-line and mw-mnw
139 row.putValue(UInfoResultType.salixline, calcSalix(mhw, mw)); 146 row.putValue(UInfoResultType.salixline, calcSalix(mhw, mw));
140 row.putValue(UInfoResultType.salix_delta_mw, calcMwmnw(mw, mnw)); 147 row.putValue(UInfoResultType.salix_delta_mw, calcMwmnw(mw, mnw));
148 // Calc scenario values (always all scenario types set, Result variant extracts the fields needed)
149 final List<SalixScenario> scenarios = new ArrayList<>();
150 final double[] deltaws = getDeltaWs(station);
151 for (int i = 0; i <= deltaws.length - 1; i++) {
152 if (Math.abs(deltaws[i]) < 0.0001) {
153 row.putValue(UInfoResultType.salix_line_scenario, Double.NaN);
154 row.putValue(UInfoResultType.salix_line_scenario_dwspl, 0); // TODO NaN when changed from int to double
155 }
156 else {
157 final double salix = calcSalix(mhw, mw + deltaws[i]);
158 row.putValue(UInfoResultType.salix_line_scenario, salix);
159 row.putValue(UInfoResultType.salix_line_scenario_dwspl, (int) (deltaws[i] * 100));
160 scenarios.add(new SalixScenario((int) (deltaws[i] * 100), salix));
161 }
162 }
163 row.putValue(UInfoResultType.customMultiRowColSalixRegionalValue_Dwspl, scenarios);
141 return row; 164 return row;
142 } 165 }
143 166
144 /** 167 /**
145 * Interpolates the W for a station with a fixed (virtual) wst column position 168 * Interpolates the W for a station with a fixed (virtual) wst column position
162 * Calculates the inverse MW-MNW difference 185 * Calculates the inverse MW-MNW difference
163 */ 186 */
164 private double calcMwmnw(final double mw, final double mnw) { 187 private double calcMwmnw(final double mw, final double mnw) {
165 return mnw - mw; 188 return mnw - mw;
166 } 189 }
190
191 /**
192 * Gets the station-specific list of delta-ws of the active scenario, at least with one 0 item in any case
193 */
194 private double[] getDeltaWs(final double station) {
195 final Entry<Double, List<Double>> stationScenarios = this.rangeScenarios.floorEntry(station);
196 if (stationScenarios == null)
197 return new double[] { 0.0 };
198 else {
199 final double[] deltaws = new double[stationScenarios.getValue().size()];
200 for (int i = 0; i <= stationScenarios.getValue().size() - 1; i++)
201 deltaws[i] = stationScenarios.getValue().get(i);
202 return deltaws;
203 }
204 }
167 } 205 }

http://dive4elements.wald.intevation.org