Mercurial > dive4elements > river
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 : |