comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation6.java @ 4232:b3aa91e45010

Implemented the Q evaluation mode for historical discharge calculations. Added the calculation itself, created new facets, added themes and improved the chart generator to support the new facets.
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 24 Oct 2012 07:25:35 +0200
parents 1d9c9a3493ea
children 49cb65d5932d
comparison
equal deleted inserted replaced
4231:adcb8aee1910 4232:b3aa91e45010
16 */ 16 */
17 public class Calculation6 extends Calculation { 17 public class Calculation6 extends Calculation {
18 18
19 private static final Logger logger = Logger.getLogger(Calculation6.class); 19 private static final Logger logger = Logger.getLogger(Calculation6.class);
20 20
21 private int mode; 21 private int mode;
22 private long[] timerange; 22 private long[] timerange;
23 private double[] values; 23 private double[] values;
24
25 24
26 public static final int MODE_W = 0; 25 public static final int MODE_W = 0;
27 public static final int MODE_Q = 1; 26 public static final int MODE_Q = 1;
28 27
29 public static final double SCALE = 1d; 28 public static final double SCALE = 1d;
30 29
31
32 public Calculation6(int mode, long[] timerange, double[] values) { 30 public Calculation6(int mode, long[] timerange, double[] values) {
33 this.mode = mode; 31 this.mode = mode;
34 this.timerange = timerange; 32 this.timerange = timerange;
35 this.values = values; 33 this.values = values;
36 } 34 }
37
38 35
39 public CalculationResult calculate(Gauge gauge) { 36 public CalculationResult calculate(Gauge gauge) {
40 if (!checkParameters() || gauge == null) { 37 if (!checkParameters() || gauge == null) {
41 logger.warn("Parameters not valid for calculation."); 38 logger.warn("Parameters not valid for calculation.");
42 39
45 42
46 if (logger.isDebugEnabled()) { 43 if (logger.isDebugEnabled()) {
47 debug(); 44 debug();
48 } 45 }
49 46
50 DischargeTable refTable = fetchReferenceTable(gauge); 47 DischargeTable refTable = fetchReferenceTable(gauge);
51 List<DischargeTable> dts = fetchDischargeTables(gauge); 48 List<DischargeTable> dts = fetchDischargeTables(gauge);
52 49
53 int numTables = dts.size(); 50 int numTables = dts.size();
54 51
55 logger.debug("Take " + numTables + " into account."); 52 logger.debug("Take " + numTables + " into account.");
62 59
63 logger.debug("Number of calculation results: " + wqt.length); 60 logger.debug("Number of calculation results: " + wqt.length);
64 61
65 return new CalculationResult(wqt, this); 62 return new CalculationResult(wqt, this);
66 } 63 }
67
68 64
69 protected boolean checkParameters() { 65 protected boolean checkParameters() {
70 if (!(mode == MODE_W || mode == MODE_Q)) { 66 if (!(mode == MODE_W || mode == MODE_Q)) {
71 logger.warn("Invalid mode '" + mode + "' for calculation."); 67 logger.warn("Invalid mode '" + mode + "' for calculation.");
72 return false; 68 return false;
83 } 79 }
84 80
85 return true; 81 return true;
86 } 82 }
87 83
88
89 protected DischargeTable fetchReferenceTable(Gauge gauge) { 84 protected DischargeTable fetchReferenceTable(Gauge gauge) {
90 return gauge.fetchMasterDischargeTable(); 85 return gauge.fetchMasterDischargeTable();
91 } 86 }
92 87
93
94 protected List<DischargeTable> fetchDischargeTables(Gauge gauge) { 88 protected List<DischargeTable> fetchDischargeTables(Gauge gauge) {
95 List<DischargeTable> relevant = new ArrayList<DischargeTable>(); 89 List<DischargeTable> relevant = new ArrayList<DischargeTable>();
96 List<DischargeTable> all = gauge.getDischargeTables(); 90 List<DischargeTable> all = gauge.getDischargeTables();
97 91
98 for (DischargeTable dt: all) { 92 for (DischargeTable dt : all) {
99 if (isDischargeTableRelevant(dt)) { 93 if (isDischargeTableRelevant(dt)) {
100 relevant.add(dt); 94 relevant.add(dt);
101 } 95 }
102 } 96 }
103 97
104 return relevant; 98 return relevant;
105 } 99 }
106 100
107
108 protected boolean isDischargeTableRelevant(DischargeTable dt) { 101 protected boolean isDischargeTableRelevant(DischargeTable dt) {
109 TimeInterval ti = dt.getTimeInterval(); 102 TimeInterval ti = dt.getTimeInterval();
110 103
111 if (dt.getKind() == Gauge.MASTER_DISCHARGE_TABLE || ti == null) { 104 if (dt.getKind() == Gauge.MASTER_DISCHARGE_TABLE || ti == null) {
112 return false; 105 return false;
113 } 106 }
114 107
115 Date start = ti.getStartTime(); 108 Date start = ti.getStartTime();
116 long startTime = start.getTime(); 109 long startTime = start.getTime();
117 110
118 if (startTime >= timerange[0] && startTime <= timerange[1]) { 111 if (startTime >= timerange[0] && startTime <= timerange[1]) {
119 return true; 112 return true;
120 } 113 }
121 114
122 Date stop = ti.getStopTime(); 115 Date stop = ti.getStopTime();
123 long stopTime = stop != null ? stop.getTime() : -1l; 116 long stopTime = stop != null ? stop.getTime() : -1l;
124 117
125 if (stopTime >= timerange[0] && stopTime <= timerange[1]) { 118 if (stopTime >= timerange[0] && stopTime <= timerange[1]) {
126 return true; 119 return true;
127 } 120 }
129 logger.debug("DischargeTable not in range: " + start + " -> " + stop); 122 logger.debug("DischargeTable not in range: " + start + " -> " + stop);
130 123
131 return false; 124 return false;
132 } 125 }
133 126
134 127 protected WQTimerange[] prepareCalculationData(DischargeTable refTable,
135 protected WQTimerange[] prepareCalculationData( 128 List<DischargeTable> dts) {
136 DischargeTable refTable,
137 List<DischargeTable> dts
138 ) {
139 if (refTable == null) { 129 if (refTable == null) {
140 addProblem("cannot.find.hist.q.reftable"); 130 addProblem("cannot.find.hist.q.reftable");
141 return prepareSimpleData(dts); 131 return prepareSimpleData(dts);
142 } 132 }
143 else { 133 else {
144 return prepareData(refTable, dts); 134 return prepareData(refTable, dts);
145 } 135 }
146 } 136 }
147 137
148
149 protected WQTimerange[] prepareSimpleData(List<DischargeTable> dts) { 138 protected WQTimerange[] prepareSimpleData(List<DischargeTable> dts) {
150 List<WQTimerange> wqts = 139 List<WQTimerange> wqts = new ArrayList<WQTimerange>(values.length);
151 new ArrayList<WQTimerange>(values.length); 140
152 141 for (double value : values) {
153 for (double value: values) {
154 logger.debug("Prepare data for value: " + value); 142 logger.debug("Prepare data for value: " + value);
155 143
156 String name = mode == MODE_W ? "W=" + value : "Q=" + value; 144 String name = mode == MODE_W ? "W=" + value : "Q=" + value;
157 WQTimerange wqt = null; 145 WQTimerange wqt = null;
158 146
159 for (DischargeTable dt: dts) { 147 for (DischargeTable dt : dts) {
160 Date[] ti = prepareTimeInterval(dt); 148 Date[] ti = prepareTimeInterval(dt);
161 Timerange t = new Timerange(ti[0], ti[1]); 149 Timerange t = new Timerange(ti[0], ti[1]);
162 double w; 150 double w;
163 double q; 151 double q;
164 152
165 if (mode == MODE_W) { 153 if (mode == MODE_W) {
166 w = value; 154 w = value;
167 q = findValueForW(dt, w, DischargeTables.HISTORICAL_SCALE); 155 q = findValueForW(dt, w, DischargeTables.HISTORICAL_SCALE);
168 156
172 continue; 160 continue;
173 } 161 }
174 } 162 }
175 else { 163 else {
176 q = value; 164 q = value;
177 w = findValueForQ(dt, q); 165 w = findValueForQ(dt, q, DischargeTables.HISTORICAL_SCALE);
178 } 166 }
179 167
180 logger.debug("Q=" + q + " | W=" + w); 168 logger.debug("Q=" + q + " | W=" + w);
181 169
182 if (wqt == null) { 170 if (wqt == null) {
192 } 180 }
193 181
194 return wqts.toArray(new WQTimerange[wqts.size()]); 182 return wqts.toArray(new WQTimerange[wqts.size()]);
195 } 183 }
196 184
197 185 protected HistoricalWQTimerange[] prepareData(DischargeTable refTable,
198 protected HistoricalWQTimerange[] prepareData( 186 List<DischargeTable> dts) {
199 DischargeTable refTable, 187 List<HistoricalWQTimerange> wqts = new ArrayList<HistoricalWQTimerange>(
200 List<DischargeTable> dts 188 values.length);
201 ) { 189
202 List<HistoricalWQTimerange> wqts = 190 for (double value : values) {
203 new ArrayList<HistoricalWQTimerange>(values.length);
204
205 for (double value: values) {
206 logger.debug("Prepare data plus diff for value: " + value); 191 logger.debug("Prepare data plus diff for value: " + value);
207 192
208 String name = mode == MODE_W ? "W=" + value : "Q=" + value; 193 String name = mode == MODE_W ? "W=" + value : "Q=" + value;
209 HistoricalWQTimerange wqt = null; 194 HistoricalWQTimerange wqt = null;
210 195
211 double ref; 196 double ref;
212 double diff; 197 double diff;
213 198
214 if (refTable != null && mode == MODE_W) { 199 if (refTable != null && mode == MODE_W) {
215 ref = findValueForW(refTable, value, DischargeTables.MASTER_SCALE); 200 ref = findValueForW(refTable, value,
201 DischargeTables.MASTER_SCALE);
216 } 202 }
217 else if (refTable != null) { 203 else if (refTable != null) {
218 ref = findValueForQ(refTable, value); 204 ref = findValueForQ(refTable, value,
205 DischargeTables.MASTER_SCALE);
219 } 206 }
220 else { 207 else {
221 ref = Double.NaN; 208 ref = Double.NaN;
222 } 209 }
223 210
224 for (DischargeTable dt: dts) { 211 for (DischargeTable dt : dts) {
225 Date[] ti = prepareTimeInterval(dt); 212 Date[] ti = prepareTimeInterval(dt);
226 213
227 Timerange t = new Timerange(ti[0] ,ti[1]); 214 Timerange t = new Timerange(ti[0], ti[1]);
228 double w; 215 double w;
229 double q; 216 double q;
230 217
231 if (mode == MODE_W) { 218 if (mode == MODE_W) {
232 w = value; 219 w = value;
233 q = findValueForW(dt, w, DischargeTables.HISTORICAL_SCALE); 220 q = findValueForW(dt, w, DischargeTables.HISTORICAL_SCALE);
234 221
235 if (Double.isNaN(q)) { 222 if (Double.isNaN(q)) {
236 logger.warn("Cannot find Q for W: " + w); 223 logger.warn("Cannot find Q for W: " + w);
237 addProblem("cannot.find.hist.q.for.w", w, ti[0], ti[1]); 224 addProblem("cannot.find.hist.q.for.w", w, ti[0], ti[1]);
238 continue; 225 continue;
239 } 226 }
240 227
241 diff = ref-q; 228 diff = ref - q;
242 } 229 }
243 else { 230 else {
244 q = value; 231 q = value;
245 w = findValueForQ(dt, q); 232 w = findValueForQ(dt, q, DischargeTables.HISTORICAL_SCALE);
246 diff = ref-w; 233
234 if (Double.isNaN(w)) {
235 logger.warn("Cannot find W for Q: " + q);
236 addProblem("cannot.find.hist.w.for.q", q, ti[0], ti[1]);
237 continue;
238 }
239 diff = ref - w;
247 } 240 }
248 241
249 logger.debug("Q=" + q + " | W=" + w + " | Ref = " + ref); 242 logger.debug("Q=" + q + " | W=" + w + " | Ref = " + ref);
250 243
251 if (wqt == null) { 244 if (wqt == null) {
258 if (wqt != null) { 251 if (wqt != null) {
259 wqts.add(wqt); 252 wqts.add(wqt);
260 } 253 }
261 } 254 }
262 255
263 return (HistoricalWQTimerange[]) 256 return (HistoricalWQTimerange[]) wqts
264 wqts.toArray(new HistoricalWQTimerange[wqts.size()]); 257 .toArray(new HistoricalWQTimerange[wqts.size()]);
265 } 258 }
266
267 259
268 protected Date[] prepareTimeInterval(DischargeTable dt) { 260 protected Date[] prepareTimeInterval(DischargeTable dt) {
269 TimeInterval ti = dt.getTimeInterval(); 261 TimeInterval ti = dt.getTimeInterval();
270 262
271 Date start = ti.getStartTime(); 263 Date start = ti.getStartTime();
272 Date end = ti.getStopTime(); 264 Date end = ti.getStopTime();
273 265
274 if (end == null) { 266 if (end == null) {
275 logger.warn("TimeInterval has no stop time set!"); 267 logger.warn("TimeInterval has no stop time set!");
276 268
277 end = new Date(); 269 end = new Date();
278 } 270 }
279 271
280 return new Date[] { start, end }; 272 return new Date[] { start, end };
281 } 273 }
282 274
283
284 protected double findValueForW(DischargeTable dt, double w, double scale) { 275 protected double findValueForW(DischargeTable dt, double w, double scale) {
285 double[][] vs = DischargeTables.loadDischargeTableValues(dt, scale); 276 double[][] vs = DischargeTables.loadDischargeTableValues(dt, scale);
286 double [] qs = DischargeTables.getQsForW(vs, w); 277 double[] qs = DischargeTables.getQsForW(vs, w);
287 return qs.length == 0 ? Double.NaN : qs[0]; 278 return qs.length == 0 ? Double.NaN : qs[0];
288 } 279 }
289 280
290 281 protected double findValueForQ(DischargeTable dt, double q, double scale) {
291 protected double findValueForQ(DischargeTable dt, double q) { 282 double[][] vs = DischargeTables.loadDischargeTableValues(dt, scale);
292 double[][] vs = DischargeTables.loadDischargeTableValues(dt, SCALE); 283 double[] ws = DischargeTables.getWsForQ(vs, q);
293 logger.warn("TODO: IMPLEMENT ME!"); 284
294 285 return ws.length == 0 ? Double.NaN : ws[0];
295 return 10; 286 }
296 }
297
298 287
299 /** 288 /**
300 * Writes the parameters used for this calculation to logger. 289 * Writes the parameters used for this calculation to logger.
301 */ 290 */
302 public void debug() { 291 public void debug() {
303 StringBuilder sb = new StringBuilder(); 292 StringBuilder sb = new StringBuilder();
304 for (double value: values) { 293 for (double value : values) {
305 sb.append(String.valueOf(value) + " "); 294 sb.append(String.valueOf(value) + " ");
306 } 295 }
307 296
308 logger.debug("========== Calculation6 =========="); 297 logger.debug("========== Calculation6 ==========");
309 logger.debug(" Mode: " + mode); 298 logger.debug(" Mode: " + mode);

http://dive4elements.wald.intevation.org