comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java @ 3008:9e0500d64524

FixA: Calculate the Delta W/ts + the average Delta W/ts per Q sector per analysis period. flys-artifacts/trunk@4564 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Wed, 30 May 2012 17:59:19 +0000
parents e5e6363e6cba
children 05a3fe8800b3
comparison
equal deleted inserted replaced
3007:d520a0869972 3008:9e0500d64524
7 7
8 import de.intevation.flys.artifacts.model.Calculation; 8 import de.intevation.flys.artifacts.model.Calculation;
9 import de.intevation.flys.artifacts.model.CalculationResult; 9 import de.intevation.flys.artifacts.model.CalculationResult;
10 import de.intevation.flys.artifacts.model.FixingsColumn; 10 import de.intevation.flys.artifacts.model.FixingsColumn;
11 import de.intevation.flys.artifacts.model.FixingsColumnFactory; 11 import de.intevation.flys.artifacts.model.FixingsColumnFactory;
12
13 import de.intevation.flys.artifacts.model.FixingsOverview.AndFilter;
14 import de.intevation.flys.artifacts.model.FixingsOverview.DateRangeFilter;
15 import de.intevation.flys.artifacts.model.FixingsOverview.Fixing;
16 import de.intevation.flys.artifacts.model.FixingsOverview.IdFilter;
17 import de.intevation.flys.artifacts.model.FixingsOverview.KmFilter;
18 import de.intevation.flys.artifacts.model.FixingsOverview.Range;
19 import de.intevation.flys.artifacts.model.FixingsOverview.SectorRangeFilter;
20 import de.intevation.flys.artifacts.model.FixingsOverview.SectorFilter;
21
12 import de.intevation.flys.artifacts.model.FixingsOverview; 22 import de.intevation.flys.artifacts.model.FixingsOverview;
13 import de.intevation.flys.artifacts.model.FixingsOverviewFactory; 23 import de.intevation.flys.artifacts.model.FixingsOverviewFactory;
14 import de.intevation.flys.artifacts.model.Parameters; 24 import de.intevation.flys.artifacts.model.Parameters;
15 25
16 import de.intevation.flys.artifacts.model.FixingsOverview.Range; 26 import de.intevation.flys.utils.DateAverager;
17 import de.intevation.flys.artifacts.model.FixingsOverview.Fixing;
18 import de.intevation.flys.artifacts.model.FixingsOverview.IdFilter;
19 import de.intevation.flys.artifacts.model.FixingsOverview.AndFilter;
20 import de.intevation.flys.artifacts.model.FixingsOverview.DateRangeFilter;
21 import de.intevation.flys.artifacts.model.FixingsOverview.SectorRangeFilter;
22
23 import de.intevation.flys.utils.DoubleUtil; 27 import de.intevation.flys.utils.DoubleUtil;
24 28
25 import java.util.ArrayList; 29 import java.util.ArrayList;
30 import java.util.Date;
31 import java.util.HashMap;
26 import java.util.List; 32 import java.util.List;
33 import java.util.Map;
27 34
28 import org.apache.commons.math.MathException; 35 import org.apache.commons.math.MathException;
29 36
30 import org.apache.commons.math.optimization.fitting.CurveFitter; 37 import org.apache.commons.math.optimization.fitting.CurveFitter;
31 38
330 } 337 }
331 338
332 return deltaWTsKM; 339 return deltaWTsKM;
333 } 340 }
334 341
342 protected List<AnalysisPeriodsKM> calculateAnalysisPeriods(
343 Function function,
344 Parameters parameters,
345 FixingsOverview overview
346 ) {
347 ArrayList<AnalysisPeriodsKM> results
348 = new ArrayList<AnalysisPeriodsKM>(parameters.size());
349
350 Range range = new Range(from, to);
351
352 int kmIndex = parameters.columnIndex("km");
353
354 ColumnCache cc = new ColumnCache();
355
356 double [] wq = new double[2];
357
358 int [] parameterIndices =
359 parameters.columnIndices(function.getParameterNames());
360
361 double [] parameterValues = new double[parameterIndices.length];
362
363 DateAverager dateAverager = new DateAverager();
364
365 for (int row = 0, P = parameters.size(); row < P; ++row) {
366 double km = parameters.get(row, kmIndex);
367 parameters.get(row, parameterIndices, parameterValues);
368
369 // This is the paraterized function for a given km.
370 de.intevation.flys.artifacts.math.Function instance =
371 function.instantiate(parameterValues);
372
373 KmFilter kmFilter = new KmFilter(km);
374
375 for (DateRange analysisPeriod: analysisPeriods) {
376 DateRangeFilter drf = new DateRangeFilter(
377 analysisPeriod.getFrom(),
378 analysisPeriod.getTo());
379
380 // for all Q sectors.
381 for (int qSector = qSectorStart; qSector < qSectorEnd; ++qSector) {
382
383 AndFilter filter = new AndFilter();
384 filter.add(kmFilter);
385 filter.add(new SectorFilter(qSector));
386 filter.add(drf);
387
388 List<Fixing.Column> metas = overview.filter(range, filter);
389
390 if (metas.isEmpty()) {
391 // No fixings for km and analysis period
392 continue;
393 }
394
395 double sumQ = 0.0;
396 double sumW = 0.0;
397
398 List<QWD> qwds = new ArrayList<QWD>(metas.size());
399
400 dateAverager.clear();
401
402 for (Fixing.Column meta: metas) {
403 if (meta.findQSector(km) != qSector) {
404 // Ignore not matching sectors.
405 continue;
406 }
407
408 Column column = cc.getColumn(meta);
409 if (column == null || !column.getWQ(km, wq)) {
410 continue;
411 }
412
413 double fw = instance.value(wq[1]);
414 if (Double.isNaN(fw)) {
415 continue;
416 }
417
418 double dw = (wq[0] - fw)*100.0;
419
420 Date date = column.getDate();
421 String description = column.getDescription();
422
423 QWD qwd = new QWD(wq[1], wq[0], dw, date, description);
424
425 qwds.add(qwd);
426
427 sumW += wq[0];
428 sumQ += wq[1];
429
430 dateAverager.add(date);
431 }
432
433 // Calulate average per Q sector.
434 int N = qwds.size();
435 if (N > 0) {
436 double avgW = sumW / N;
437 double avgQ = sumQ / N;
438
439 double avgFw = instance.value(avgQ);
440 if (!Double.isNaN(avgFw)) {
441 double avgDw = (avgW - avgFw)*100.0;
442 Date avgDate = dateAverager.getAverage();
443
444 String avgDescription = "avg.deltawt." + qSector;
445
446 QWD avgQWD = new QWD(
447 avgQ, avgW, avgDw, avgDate, avgDescription);
448
449 // TODO: Store average value.
450 }
451 else {
452 // TODO: Store
453 }
454 }
455 } // for all Q sectors
456 }
457 }
458
459 return results;
460 }
461
335 /** Helper class to bundle the meta information of a column 462 /** Helper class to bundle the meta information of a column
336 * and the real data. 463 * and the real data.
337 */ 464 */
338 protected static class Column { 465 protected static class Column {
339 466
345 472
346 public Column(Fixing.Column meta, FixingsColumn data) { 473 public Column(Fixing.Column meta, FixingsColumn data) {
347 this.meta = meta; 474 this.meta = meta;
348 this.data = data; 475 this.data = data;
349 } 476 }
477
478 public Date getDate() {
479 return meta.getStartTime();
480 }
481
482 public String getDescription() {
483 return meta.getDescription();
484 }
485
486 public boolean getWQ(double km, double [] wq) {
487 data.getW(km, wq, 0);
488 if (Double.isNaN(wq[0])) return false;
489 wq[1] = data.getQ(km);
490 return !Double.isNaN(wq[1]);
491 }
350 } // class Column 492 } // class Column
493
494
495 /**
496 * Helper class to find the data belonging to meta info more quickly.
497 */
498 public static class ColumnCache {
499
500 protected Map<Integer, Column> columns;
501
502 public ColumnCache() {
503 columns = new HashMap<Integer, Column>();
504 }
505
506 public Column getColumn(Fixing.Column meta) {
507 Integer key = meta.getId();
508 Column column = columns.get(key);
509 if (column == null) {
510 FixingsColumn data = FixingsColumnFactory
511 .getInstance()
512 .getColumnData(meta);
513 if (data != null) {
514 column = new Column(meta, data);
515 columns.put(key, column);
516 }
517 }
518 return column;
519 }
520 } // class ColumnCache
351 521
352 /** Fetch meta and data columns for analysis periods. */ 522 /** Fetch meta and data columns for analysis periods. */
353 protected Column [][] getAnalysisColumns(FixingsOverview overview) { 523 protected Column [][] getAnalysisColumns(FixingsOverview overview) {
354 524
355 boolean debug = log.isDebugEnabled(); 525 boolean debug = log.isDebugEnabled();

http://dive4elements.wald.intevation.org