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";

http://dive4elements.wald.intevation.org