Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataCalculation.java @ 8067:6d24ba2ac964
Sediment load: refactored epoch calculation to not average over all but per year.
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Thu, 31 Jul 2014 17:04:41 +0200 |
parents | fe5ef780f8b1 |
children | 9ecd6267323b |
comparison
equal
deleted
inserted
replaced
8066:fe5ef780f8b1 | 8067:6d24ba2ac964 |
---|---|
5 * and comes with ABSOLUTELY NO WARRANTY! Check out the | 5 * and comes with ABSOLUTELY NO WARRANTY! Check out the |
6 * documentation coming with Dive4Elements River for details. | 6 * documentation coming with Dive4Elements River for details. |
7 */ | 7 */ |
8 package org.dive4elements.river.artifacts.model.minfo; | 8 package org.dive4elements.river.artifacts.model.minfo; |
9 | 9 |
10 import java.util.ArrayList; | |
10 import java.util.List; | 11 import java.util.List; |
12 import java.util.Map; | |
11 import java.util.Set; | 13 import java.util.Set; |
14 import java.util.TreeMap; | |
12 import java.util.TreeSet; | 15 import java.util.TreeSet; |
13 | 16 |
14 import org.dive4elements.river.artifacts.access.SedimentLoadAccess; | 17 import org.dive4elements.river.artifacts.access.SedimentLoadAccess; |
15 import org.dive4elements.river.artifacts.model.Calculation; | 18 import org.dive4elements.river.artifacts.model.Calculation; |
16 import org.dive4elements.river.artifacts.model.CalculationResult; | 19 import org.dive4elements.river.artifacts.model.CalculationResult; |
152 sum += value.getValue(); | 155 sum += value.getValue(); |
153 ++n; | 156 ++n; |
154 } | 157 } |
155 } // class Sum | 158 } // class Sum |
156 | 159 |
157 public static final class Avg extends Sum { | |
158 public Avg() { | |
159 } | |
160 | |
161 @Override | |
162 public double getSum() { | |
163 return n == 0 ? 0.0 : sum/(double)n; | |
164 } | |
165 } // class Sum | |
166 | |
167 | |
168 private String river; | 160 private String river; |
169 private String yearEpoch; | 161 private String yearEpoch; |
170 private String unit; | 162 private String unit; |
171 private int [][] epochs; | 163 private int [][] epochs; |
172 private int [] years; | 164 private int [] years; |
297 SedimentLoadDataResult sldr = new SedimentLoadDataResult(); | 289 SedimentLoadDataResult sldr = new SedimentLoadDataResult(); |
298 | 290 |
299 boolean isKmUp = isKmUp(); | 291 boolean isKmUp = isKmUp(); |
300 Set<Integer> missingFractions = new TreeSet<Integer>(); | 292 Set<Integer> missingFractions = new TreeSet<Integer>(); |
301 | 293 |
294 SedimentDensity sd = getSedimentDensity(); | |
295 | |
302 // They are not epochs, they are single years! | 296 // They are not epochs, they are single years! |
303 Not notEpochs = new Not(IsEpoch.INSTANCE); | 297 Not notEpochs = new Not(IsEpoch.INSTANCE); |
304 | 298 |
305 for (int [] epoch: epochs) { | 299 for (int [] epoch: epochs) { |
306 Value.Filter filter = new And() | 300 List<double [][]> results = new ArrayList<double [][]>(); |
307 .add(notEpochs) | 301 |
308 .add(new TimeRangeIntersects(epoch[0], epoch[1])); | 302 int min = Math.min(epoch[0], epoch[1]); |
309 | 303 int max = Math.max(epoch[0], epoch[1]); |
310 Avg avg = new Avg(); | 304 |
311 | 305 for (int year = min; year <= max; ++year) { |
312 for (GrainFraction gf: GRAIN_FRACTIONS) { | 306 Value.Filter filter = new And() |
313 double [][] result = sum( | 307 .add(notEpochs) |
314 sld, gf.getGrainFractions(), filter, avg, isKmUp, | 308 .add(new TimeRangeIntersects(year)); |
315 missingFractions); | 309 |
316 | 310 Sum sum = new Sum(); |
317 if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) { | 311 |
318 // TODO: resolve i18n | 312 for (GrainFraction gf: GRAIN_FRACTIONS) { |
319 addProblem("minfo.sediment.load.no.fractions", | 313 double [][] result = sum( |
320 gf.getDescription()); | 314 sld, gf.getGrainFractions(), filter, sum, isKmUp, |
321 continue; | 315 missingFractions); |
322 } | 316 |
323 // TODO: Optionally transform units. | 317 if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) { |
324 SedimentLoadDataResult.Fraction sldrf = | 318 // TODO: resolve i18n |
325 new SedimentLoadDataResult.Fraction(gf.getDescription(), result); | 319 addProblem("minfo.sediment.load.no.fractions", |
326 sldr.addFraction(sldrf); | 320 gf.getDescription()); |
321 continue; | |
322 } | |
323 | |
324 transformT2M3(sd, year, result); | |
325 results.add(result); | |
326 } | |
327 } | 327 } |
328 | |
329 double [][] result = average(results); | |
330 // TODO: Optionally transform units. | |
331 SedimentLoadDataResult.Fraction sldrf = | |
332 new SedimentLoadDataResult.Fraction("TODO: nice description", result); | |
333 sldr.addFraction(sldrf); | |
328 } | 334 } |
329 // TODO: Generate messages for missing fractions. | 335 // TODO: Generate messages for missing fractions. |
330 return new CalculationResult(sldr, this); | 336 return new CalculationResult(sldr, this); |
331 } | 337 } |
332 | 338 |
450 | 456 |
451 // TODO: Handle 'virtual' measument stations 'from' and 'to'. | 457 // TODO: Handle 'virtual' measument stations 'from' and 'to'. |
452 | 458 |
453 return result; | 459 return result; |
454 } | 460 } |
461 | |
462 private static final class XSum { | |
463 private double sum; | |
464 private int n; | |
465 public XSum() { | |
466 } | |
467 public void add(double v) { | |
468 sum += v; | |
469 ++n; | |
470 } | |
471 public double avg() { | |
472 return sum/n; | |
473 } | |
474 } | |
475 | |
476 private static double [][] average(List<double [][]> data) { | |
477 | |
478 TreeMap<Double, XSum> map = new TreeMap<Double, XSum>(); | |
479 | |
480 for (double [][] pair: data) { | |
481 double [] kms = pair[0]; | |
482 double [] vs = pair[1]; | |
483 for (int i = 0; i < kms.length; ++i) { | |
484 double km = kms[i]; | |
485 double v = vs[i]; | |
486 if (Double.isNaN(km) || Double.isNaN(v)) { | |
487 continue; | |
488 } | |
489 XSum xsum = map.get(km); | |
490 if (xsum == null) { | |
491 map.put(km, xsum = new XSum()); | |
492 } | |
493 xsum.add(v); | |
494 } | |
495 } | |
496 | |
497 double [][] result = new double[2][map.size()]; | |
498 int i = 0; | |
499 for (Map.Entry<Double, XSum> entry: map.entrySet()) { | |
500 result[i][0] = entry.getKey(); | |
501 result[i][1] = entry.getValue().avg(); | |
502 ++i; | |
503 } | |
504 | |
505 return null; | |
506 } | |
507 | |
455 } | 508 } |
456 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : | 509 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : |