Mercurial > dive4elements > river
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(); |