comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation6.java @ 3318:dbe2f85bf160

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

http://dive4elements.wald.intevation.org