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 :

http://dive4elements.wald.intevation.org