comparison artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/salix/SalixLineCalculator.java @ 9321:a978b601a034

Salix: Fixed ArrrayoutOfBoundsException; minor cleanup
author gernotbelger
date Fri, 27 Jul 2018 10:25:09 +0200
parents 72b3270e1568
children b3d3c958a594
comparison
equal deleted inserted replaced
9320:61e6d158a20f 9321:a978b601a034
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.Map.Entry;
17 import java.util.NavigableMap; 17 import java.util.NavigableMap;
18 18
19 import org.dive4elements.artifacts.CallContext;
20 import org.dive4elements.river.artifacts.WINFOArtifact; 19 import org.dive4elements.river.artifacts.WINFOArtifact;
21 import org.dive4elements.river.artifacts.access.ComputationRangeAccess; 20 import org.dive4elements.river.artifacts.access.ComputationRangeAccess;
22 import org.dive4elements.river.artifacts.common.GeneralResultType; 21 import org.dive4elements.river.artifacts.common.GeneralResultType;
23 import org.dive4elements.river.artifacts.common.ResultRow; 22 import org.dive4elements.river.artifacts.common.ResultRow;
24 import org.dive4elements.river.artifacts.model.Calculation; 23 import org.dive4elements.river.artifacts.model.Calculation;
39 /** 38 /**
40 * Calculation of the result rows of the u-info salix line calc mode 39 * Calculation of the result rows of the u-info salix line calc mode
41 * 40 *
42 * @author Matthias Schäfer 41 * @author Matthias Schäfer
43 */ 42 */
44 public class SalixLineCalculator { 43 final class SalixLineCalculator {
45 44
46 private final List<ResultRow> rows = new ArrayList<>(); 45 private final List<ResultRow> rows = new ArrayList<>();
47 46
48 private final RiverInfoProvider riverInfoProvider; 47 private final RiverInfoProvider riverInfoProvider;
49
50 private final CallContext context;
51 48
52 private final Map<Gauge, QPosition> gaugeMwPos; 49 private final Map<Gauge, QPosition> gaugeMwPos;
53 private final Map<Gauge, QPosition> gaugeMnwPos; 50 private final Map<Gauge, QPosition> gaugeMnwPos;
54 private final Map<Gauge, QPosition> gaugeMhwPos; 51 private final Map<Gauge, QPosition> gaugeMhwPos;
55 52
56 private Calculation problems; 53 private Calculation problems;
57 54
58 private WstValueTable wst; 55 private WstValueTable wst;
59 56
60 /** 57 public SalixLineCalculator(final RiverInfoProvider riverInfoProvider) {
61 * List of delta-w (may be 0) mapped by km range
62 */
63 private NavigableMap<Double, List<Double>> rangeScenarios;
64
65
66 public SalixLineCalculator(final CallContext context, final RiverInfoProvider riverInfoProvider) {
67 this.context = context;
68 this.riverInfoProvider = riverInfoProvider; 58 this.riverInfoProvider = riverInfoProvider;
69 this.gaugeMwPos = new HashMap<>(); 59 this.gaugeMwPos = new HashMap<>();
70 this.gaugeMnwPos = new HashMap<>(); 60 this.gaugeMnwPos = new HashMap<>();
71 this.gaugeMhwPos = new HashMap<>(); 61 this.gaugeMhwPos = new HashMap<>();
72 } 62 }
73
74 63
75 /** 64 /**
76 * Calculate the salix line result rows 65 * Calculate the salix line result rows
77 */ 66 */
78 public void execute(final Calculation problems, final UINFOArtifact uinfo, final NavigableMap<Double, List<Double>> rangeScenarios, 67 public void execute(final Calculation problems, final UINFOArtifact uinfo, final NavigableMap<Double, List<Double>> rangeScenarios,
79 final ScenarioType scenarioType, final String[] scenarioLabels, final SalixLineCalculationResults results) { 68 final ScenarioType scenarioType, final String[] scenarioLabels, final SalixLineCalculationResults results) {
80 69
81 this.problems = problems; 70 this.problems = problems;
82 this.wst = WstValueTableFactory.getTable(this.riverInfoProvider.getRiver()); 71 this.wst = WstValueTableFactory.getTable(this.riverInfoProvider.getRiver());
83 this.rangeScenarios = rangeScenarios;
84 72
85 fetchGaugeMainValuePositions(); 73 fetchGaugeMainValuePositions();
86 74
87 final WINFOArtifact winfo = new WinfoArtifactWrapper(uinfo); 75 final WINFOArtifact winfo = new WinfoArtifactWrapper(uinfo);
88 winfo.addStringData("ld_mode", "distance"); 76 winfo.addStringData("ld_mode", "distance");
89 winfo.addStringData("ld_step", "100"); 77 winfo.addStringData("ld_step", "100");
90 for (final double station : new ComputationRangeAccess(winfo).getKms()) { 78 for (final double station : new ComputationRangeAccess(winfo).getKms()) {
91 this.rows.add(createRow(station)); 79 this.rows.add(createRow(station, rangeScenarios));
92 } 80 }
93 if (scenarioType == ScenarioType.REGIONAL) 81 if (scenarioType == ScenarioType.REGIONAL)
94 results.addResult(new SalixLineCalculationRegionalResult("Salix", scenarioLabels, this.rows), problems); 82 results.addResult(new SalixLineCalculationRegionalResult("Salix", scenarioLabels, this.rows), problems);
95 else if (scenarioType == ScenarioType.SUPRAREGIONAL) 83 else if (scenarioType == ScenarioType.SUPRAREGIONAL)
96 results.addResult(new SalixLineCalculationSupraRegionalResult("Salix", this.rows), problems); 84 results.addResult(new SalixLineCalculationSupraRegionalResult("Salix", this.rows), problems);
126 } 114 }
127 } 115 }
128 116
129 /** 117 /**
130 * Create a result row for a station and its gauge, and add w-q-values as selected 118 * Create a result row for a station and its gauge, and add w-q-values as selected
119 *
120 * @param rangeScenarios2
131 */ 121 */
132 private ResultRow createRow(final double station) { 122 private ResultRow createRow(final double station, final NavigableMap<Double, List<Double>> rangeScenarios) {
133 123
134 final ResultRow row = ResultRow.create(); 124 final ResultRow row = ResultRow.create();
135 // Find station's gauge 125 // Find station's gauge
136 final Gauge gauge = this.riverInfoProvider.getGauge(station, true); 126 final Gauge gauge = this.riverInfoProvider.getGauge(station, true);
137 row.putValue(GeneralResultType.station, station); 127 row.putValue(GeneralResultType.station, station);
145 // Calc salix-line and mw-mnw 135 // Calc salix-line and mw-mnw
146 row.putValue(UInfoResultType.salixline, calcSalix(mhw, mw)); 136 row.putValue(UInfoResultType.salixline, calcSalix(mhw, mw));
147 row.putValue(UInfoResultType.salix_delta_mw, calcMwmnw(mw, mnw)); 137 row.putValue(UInfoResultType.salix_delta_mw, calcMwmnw(mw, mnw));
148 // Calc scenario values (always all scenario types set, Result variant extracts the fields needed) 138 // Calc scenario values (always all scenario types set, Result variant extracts the fields needed)
149 final List<SalixScenario> scenarios = new ArrayList<>(); 139 final List<SalixScenario> scenarios = new ArrayList<>();
150 final double[] deltaws = getDeltaWs(station); 140 final double[] deltaws = getDeltaWs(station, rangeScenarios);
151 for (int i = 0; i <= deltaws.length - 1; i++) { 141 for (int i = 0; i <= deltaws.length - 1; i++) {
152 if (Math.abs(deltaws[i]) < 0.0001) { 142 if (Math.abs(deltaws[i]) < 0.0001) {
153 row.putValue(UInfoResultType.salix_line_scenario, Double.NaN); 143 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 144 row.putValue(UInfoResultType.salix_line_scenario_dwspl, 0); // TODO NaN when changed from int to double
155 } 145 /* always need to add a member, so the exporter will produce empty columns */
156 else { 146 scenarios.add(null);
147 } else {
157 final double salix = calcSalix(mhw, mw + deltaws[i]); 148 final double salix = calcSalix(mhw, mw + deltaws[i]);
158 row.putValue(UInfoResultType.salix_line_scenario, salix); 149 row.putValue(UInfoResultType.salix_line_scenario, salix);
159 row.putValue(UInfoResultType.salix_line_scenario_dwspl, (int) (deltaws[i] * 100)); 150 row.putValue(UInfoResultType.salix_line_scenario_dwspl, (int) (deltaws[i] * 100));
160 scenarios.add(new SalixScenario((int) (deltaws[i] * 100), salix)); 151 scenarios.add(new SalixScenario((int) (deltaws[i] * 100), salix));
161 } 152 }
168 * Interpolates the W for a station with a fixed (virtual) wst column position 159 * Interpolates the W for a station with a fixed (virtual) wst column position
169 */ 160 */
170 private double interpolateW(final double station, final QPosition qPosition) { 161 private double interpolateW(final double station, final QPosition qPosition) {
171 if (qPosition != null) 162 if (qPosition != null)
172 return this.wst.interpolateW(station, qPosition, this.problems); 163 return this.wst.interpolateW(station, qPosition, this.problems);
173 else 164
174 return Double.NaN; 165 return Double.NaN;
175 } 166 }
176 167
177 /** 168 /**
178 * Calculates the salix value 169 * Calculates the salix value
179 */ 170 */
188 return mnw - mw; 179 return mnw - mw;
189 } 180 }
190 181
191 /** 182 /**
192 * Gets the station-specific list of delta-ws of the active scenario, at least with one 0 item in any case 183 * Gets the station-specific list of delta-ws of the active scenario, at least with one 0 item in any case
184 *
185 * @param rangeScenarios
193 */ 186 */
194 private double[] getDeltaWs(final double station) { 187 private double[] getDeltaWs(final double station, final NavigableMap<Double, List<Double>> rangeScenarios) {
195 final Entry<Double, List<Double>> stationScenarios = this.rangeScenarios.floorEntry(station); 188 final Entry<Double, List<Double>> stationScenarios = rangeScenarios.floorEntry(station);
196 if (stationScenarios == null) 189 if (stationScenarios == null)
197 return new double[] { 0.0 }; 190 return new double[] { 0.0 };
198 else { 191
199 final double[] deltaws = new double[stationScenarios.getValue().size()]; 192 final double[] deltaws = new double[stationScenarios.getValue().size()];
200 for (int i = 0; i <= stationScenarios.getValue().size() - 1; i++) 193 for (int i = 0; i <= stationScenarios.getValue().size() - 1; i++)
201 deltaws[i] = stationScenarios.getValue().get(i); 194 deltaws[i] = stationScenarios.getValue().get(i);
202 return deltaws; 195 return deltaws;
203 }
204 } 196 }
205 } 197 }

http://dive4elements.wald.intevation.org