Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java @ 2744:c1f2e792704a
FixA: Calculate Delta W/t, too.
flys-artifacts/trunk@4479 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 23 May 2012 18:27:45 +0000 |
parents | a441be7f1589 |
children | cbb513a8f548 |
comparison
equal
deleted
inserted
replaced
2743:10e6400d4166 | 2744:c1f2e792704a |
---|---|
11 import de.intevation.flys.artifacts.model.FixingsColumnFactory; | 11 import de.intevation.flys.artifacts.model.FixingsColumnFactory; |
12 import de.intevation.flys.artifacts.model.FixingsOverview; | 12 import de.intevation.flys.artifacts.model.FixingsOverview; |
13 import de.intevation.flys.artifacts.model.FixingsOverviewFactory; | 13 import de.intevation.flys.artifacts.model.FixingsOverviewFactory; |
14 import de.intevation.flys.artifacts.model.Parameters; | 14 import de.intevation.flys.artifacts.model.Parameters; |
15 | 15 |
16 import de.intevation.flys.artifacts.model.FixingsOverview.Range; | |
16 import de.intevation.flys.artifacts.model.FixingsOverview.Fixing; | 17 import de.intevation.flys.artifacts.model.FixingsOverview.Fixing; |
17 import de.intevation.flys.artifacts.model.FixingsOverview.IdFilter; | 18 import de.intevation.flys.artifacts.model.FixingsOverview.IdFilter; |
19 import de.intevation.flys.artifacts.model.FixingsOverview.Fixing.Filter; | |
20 import de.intevation.flys.artifacts.model.FixingsOverview.AndFilter; | |
21 import de.intevation.flys.artifacts.model.FixingsOverview.DateRangeFilter; | |
22 import de.intevation.flys.artifacts.model.FixingsOverview.SectorRangeFilter; | |
18 | 23 |
19 import de.intevation.flys.utils.DoubleUtil; | 24 import de.intevation.flys.utils.DoubleUtil; |
20 | 25 |
21 import java.util.ArrayList; | 26 import java.util.ArrayList; |
22 import java.util.List; | 27 import java.util.List; |
28 import java.util.Date; | |
23 | 29 |
24 import org.apache.commons.math.MathException; | 30 import org.apache.commons.math.MathException; |
25 | 31 |
26 import org.apache.commons.math.optimization.fitting.CurveFitter; | 32 import org.apache.commons.math.optimization.fitting.CurveFitter; |
27 | 33 |
32 public class FixCalculation | 38 public class FixCalculation |
33 extends Calculation | 39 extends Calculation |
34 { | 40 { |
35 private static Logger logger = Logger.getLogger(FixCalculation.class); | 41 private static Logger logger = Logger.getLogger(FixCalculation.class); |
36 | 42 |
37 protected String river; | 43 protected String river; |
38 protected double from; | 44 protected double from; |
39 protected double to; | 45 protected double to; |
40 protected double step; | 46 protected double step; |
41 protected boolean preprocessing; | 47 protected boolean preprocessing; |
42 protected String function; | 48 protected String function; |
43 protected int [] events; | 49 protected int [] events; |
50 protected long [][] analysisPeriods; | |
51 protected int qSectorStart; | |
52 protected int qSectorEnd; | |
44 | 53 |
45 public FixCalculation() { | 54 public FixCalculation() { |
46 } | 55 } |
47 | 56 |
48 public FixCalculation(FixationArtifactAccess access) { | 57 public FixCalculation(FixationArtifactAccess access) { |
49 | 58 |
50 String river = access.getRiver(); | 59 String river = access.getRiver(); |
51 Double from = access.getFrom(); | 60 Double from = access.getFrom(); |
52 Double to = access.getTo(); | 61 Double to = access.getTo(); |
53 Double step = access.getStep(); | 62 Double step = access.getStep(); |
54 String function = access.getFunction(); | 63 String function = access.getFunction(); |
55 int [] events = access.getEvents(); | 64 int [] events = access.getEvents(); |
65 long [][] analysisPeriods = access.getAnalysisPeriods(); | |
66 Integer qSectorStart = access.getQSectorStart(); | |
67 Integer qSectorEnd = access.getQSectorEnd(); | |
56 | 68 |
57 if (river == null) { | 69 if (river == null) { |
58 // TODO: i18n | 70 // TODO: i18n |
59 addProblem("fix.missing.river"); | 71 addProblem("fix.missing.river"); |
60 } | 72 } |
82 if (events == null || events.length < 1) { | 94 if (events == null || events.length < 1) { |
83 // TODO: i18n | 95 // TODO: i18n |
84 addProblem("fix.missing.events"); | 96 addProblem("fix.missing.events"); |
85 } | 97 } |
86 | 98 |
99 if (analysisPeriods == null || analysisPeriods.length < 1) { | |
100 // TODO: i18n | |
101 addProblem("fix.missing.analysis.periods"); | |
102 } | |
103 | |
104 if (qSectorStart == null) { | |
105 // TODO: i18n | |
106 addProblem("fix.missing.qstart.sector"); | |
107 } | |
108 | |
109 if (qSectorEnd == null) { | |
110 // TODO: i18n | |
111 addProblem("fix.missing.qend.sector"); | |
112 } | |
113 | |
87 if (!hasProblems()) { | 114 if (!hasProblems()) { |
88 this.river = river; | 115 this.river = river; |
89 this.from = from; | 116 this.from = from; |
90 this.to = to; | 117 this.to = to; |
91 this.step = step; | 118 this.step = step; |
92 this.function = function; | 119 this.function = function; |
93 this.events = events; | 120 this.events = events; |
121 this.analysisPeriods = analysisPeriods; | |
122 this.qSectorStart = qSectorStart; | |
123 this.qSectorEnd = qSectorEnd; | |
94 } | 124 } |
95 } | 125 } |
96 | 126 |
97 public CalculationResult calculate() { | 127 public CalculationResult calculate() { |
98 | 128 |
190 // TODO: i18n | 220 // TODO: i18n |
191 addProblem("fix.invalid.values"); | 221 addProblem("fix.invalid.values"); |
192 results.removeNaNs(); | 222 results.removeNaNs(); |
193 } | 223 } |
194 | 224 |
195 // TODO: Calculate Delta W/t, too. | 225 // Calculate Delta W/t |
196 return new CalculationResult(results, this); | 226 List<DeltaWT> deltaWTs = calculateDeltaWTs( |
227 func, | |
228 overview, | |
229 results); | |
230 | |
231 // TODO: Add km indexed structure for deltaWTs | |
232 | |
233 return new CalculationResult(deltaWTs, this); | |
234 } | |
235 | |
236 public List<DeltaWT> calculateDeltaWTs( | |
237 Function function, | |
238 FixingsOverview overview, | |
239 Parameters results | |
240 ) { | |
241 List<DeltaWT> deltaWTs = new ArrayList<DeltaWT>(); | |
242 | |
243 Column [][] analysisColumns = getAnalysisColumns(overview); | |
244 | |
245 int [] parameterIndices = | |
246 results.columnIndices(function.getParameterNames()); | |
247 | |
248 double [] parameterValues = | |
249 new double[parameterIndices.length]; | |
250 | |
251 double [] ow = new double[1]; | |
252 | |
253 for (int i = 0, N = results.size(); i < N; ++i) { | |
254 double km = results.get(i, "km"); | |
255 results.get(i, parameterIndices, parameterValues); | |
256 | |
257 // This is the paraterized function for a given km. | |
258 de.intevation.flys.artifacts.math.Function instance = | |
259 function.instantiate(parameterValues); | |
260 | |
261 // Evaluate all columns for all analysis periods. | |
262 for (int j = 0; j < analysisColumns.length; ++j) { | |
263 Column [] periodColumns = analysisColumns[j]; | |
264 | |
265 for (int k = 0; k < periodColumns.length; ++k) { | |
266 Column pc = periodColumns[k]; | |
267 | |
268 // Q from real data. | |
269 double q = pc.data.getQ(km); | |
270 if (Double.isNaN(q)) { | |
271 continue; | |
272 } | |
273 | |
274 // Calculate W from function. | |
275 double nw = instance.value(q); | |
276 if (Double.isNaN(nw)) { | |
277 continue; | |
278 } | |
279 | |
280 // W from real data. | |
281 pc.data.getW(km, ow); | |
282 | |
283 if (Double.isNaN(ow[0])) { | |
284 continue; | |
285 } | |
286 | |
287 double deltaW = ow[0] - nw; | |
288 | |
289 DeltaWT deltaWT = new DeltaWT( | |
290 deltaW, | |
291 pc.meta.getStartTime(), | |
292 pc.meta.getDescription()); | |
293 | |
294 deltaWTs.add(deltaWT); | |
295 } | |
296 } | |
297 } | |
298 | |
299 return deltaWTs; | |
300 } | |
301 | |
302 /** Helper class to bundle the meta information of a column | |
303 * and the real data. | |
304 */ | |
305 protected static class Column { | |
306 | |
307 protected Fixing.Column meta; | |
308 protected FixingsColumn data; | |
309 | |
310 public Column() { | |
311 } | |
312 | |
313 public Column(Fixing.Column meta, FixingsColumn data) { | |
314 this.meta = meta; | |
315 this.data = data; | |
316 } | |
317 } // class Column | |
318 | |
319 /** Fetch meta and data columns for analysis periods. */ | |
320 protected Column [][] getAnalysisColumns(FixingsOverview overview) { | |
321 | |
322 Column columns [][] = new Column[analysisPeriods.length][]; | |
323 | |
324 Range range = new Range(from, to); | |
325 SectorRangeFilter sectorRangeFilter = | |
326 new SectorRangeFilter(qSectorStart, qSectorEnd); | |
327 | |
328 FixingsColumnFactory fcf = FixingsColumnFactory.getInstance(); | |
329 | |
330 for (int i = 0; i < columns.length; ++i) { | |
331 | |
332 // Construct filter for period. | |
333 long [] period = analysisPeriods[i]; | |
334 | |
335 AndFilter filter = new AndFilter(); | |
336 | |
337 DateRangeFilter dateRangeFilter = | |
338 new DateRangeFilter( | |
339 new Date(period[0]), | |
340 new Date(period[1])); | |
341 | |
342 filter.add(dateRangeFilter); | |
343 filter.add(sectorRangeFilter); | |
344 | |
345 List<Fixing.Column> metaCols = overview.filter(range, filter); | |
346 | |
347 ArrayList<Column> cols = new ArrayList<Column>(metaCols.size()); | |
348 | |
349 // Only use columns which have data. | |
350 for (Fixing.Column meta: metaCols) { | |
351 FixingsColumn data = fcf.getColumnData(meta); | |
352 if (data != null) { | |
353 cols.add(new Column(meta, data)); | |
354 } | |
355 } | |
356 columns[i] = cols.toArray(new Column[cols.size()]); | |
357 } | |
358 | |
359 return columns; | |
197 } | 360 } |
198 | 361 |
199 protected static String [] createColumnNames(String [] parameters) { | 362 protected static String [] createColumnNames(String [] parameters) { |
200 String [] result = new String[parameters.length + 1]; | 363 String [] result = new String[parameters.length + 1]; |
201 result[0] = "km"; | 364 result[0] = "km"; |