comparison artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataCalculation.java @ 8066:fe5ef780f8b1

Sediment load: fetch sediment density for transforming t/a to m^3/a.
author Sascha L. Teichmann <teichmann@intevation.de>
date Wed, 30 Jul 2014 19:26:20 +0200
parents 8489565ff563
children 6d24ba2ac964
comparison
equal deleted inserted replaced
8065:fdb26fe898dc 8066:fe5ef780f8b1
252 252
253 Not notEpochs = new Not(IsEpoch.INSTANCE); 253 Not notEpochs = new Not(IsEpoch.INSTANCE);
254 254
255 Sum sum = new Sum(); 255 Sum sum = new Sum();
256 256
257 SedimentDensity sd = getSedimentDensity();
258
257 for (int year: years) { 259 for (int year: years) {
258 Value.Filter filter = new And() 260 Value.Filter filter = new And()
259 .add(notEpochs) 261 .add(notEpochs)
260 .add(new TimeRangeIntersects(year)); 262 .add(new TimeRangeIntersects(year));
261 263
262 for (GrainFraction gf: GRAIN_FRACTIONS) { 264 for (GrainFraction gf: GRAIN_FRACTIONS) {
263 double [][] result = sum( 265 double [][] result = sum(
264 sld, gf.getGrainFractions(), filter, sum, isKmUp, 266 sld, gf.getGrainFractions(), filter, sum, isKmUp,
267 missingFractions);
268
269 if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) {
270 // TODO: resolve i18n
271 addProblem("minfo.sediment.load.no.fractions",
272 gf.getDescription());
273 continue;
274 }
275
276 transformT2M3(sd, year, result);
277
278 SedimentLoadDataResult.Fraction sldrf =
279 new SedimentLoadDataResult.Fraction(gf.getDescription(), result);
280
281 sldr.addFraction(sldrf);
282 }
283 }
284 // TODO: Generate messages for missing fractions.
285 return new CalculationResult(sldr, this);
286 }
287
288
289 private CalculationResult calculateEpochs() {
290 SedimentLoadData sld =
291 SedimentLoadDataFactory.INSTANCE.getSedimentLoadData(river);
292 if (sld == null) {
293 // TODO: i18n
294 return error("minfo.sediment.load.no.data");
295 }
296
297 SedimentLoadDataResult sldr = new SedimentLoadDataResult();
298
299 boolean isKmUp = isKmUp();
300 Set<Integer> missingFractions = new TreeSet<Integer>();
301
302 // They are not epochs, they are single years!
303 Not notEpochs = new Not(IsEpoch.INSTANCE);
304
305 for (int [] epoch: epochs) {
306 Value.Filter filter = new And()
307 .add(notEpochs)
308 .add(new TimeRangeIntersects(epoch[0], epoch[1]));
309
310 Avg avg = new Avg();
311
312 for (GrainFraction gf: GRAIN_FRACTIONS) {
313 double [][] result = sum(
314 sld, gf.getGrainFractions(), filter, avg, isKmUp,
265 missingFractions); 315 missingFractions);
266 316
267 if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) { 317 if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) {
268 // TODO: resolve i18n 318 // TODO: resolve i18n
269 addProblem("minfo.sediment.load.no.fractions", 319 addProblem("minfo.sediment.load.no.fractions",
278 } 328 }
279 // TODO: Generate messages for missing fractions. 329 // TODO: Generate messages for missing fractions.
280 return new CalculationResult(sldr, this); 330 return new CalculationResult(sldr, this);
281 } 331 }
282 332
283 private CalculationResult calculateEpochs() { 333 private CalculationResult calculateOffEpochs() {
284 SedimentLoadData sld = 334 SedimentLoadData sld =
285 SedimentLoadDataFactory.INSTANCE.getSedimentLoadData(river); 335 SedimentLoadDataFactory.INSTANCE.getSedimentLoadData(river);
286 if (sld == null) { 336 if (sld == null) {
287 // TODO: i18n 337 // TODO: i18n
288 return error("minfo.sediment.load.no.data"); 338 return error("minfo.sediment.load.no.data");
291 SedimentLoadDataResult sldr = new SedimentLoadDataResult(); 341 SedimentLoadDataResult sldr = new SedimentLoadDataResult();
292 342
293 boolean isKmUp = isKmUp(); 343 boolean isKmUp = isKmUp();
294 Set<Integer> missingFractions = new TreeSet<Integer>(); 344 Set<Integer> missingFractions = new TreeSet<Integer>();
295 345
296 // They are not epochs, they are single years!
297 Not notEpochs = new Not(IsEpoch.INSTANCE);
298
299 for (int [] epoch: epochs) { 346 for (int [] epoch: epochs) {
300 Value.Filter filter = new And() 347 Value.Filter filter = new And()
301 .add(notEpochs) 348 .add(IsOfficial.INSTANCE)
302 .add(new TimeRangeIntersects(epoch[0], epoch[1])); 349 .add(new TimeRangeIntersects(epoch[0], epoch[1]));
303 350
304 Avg avg = new Avg(); 351 Sum sum = new Sum();
305 352
306 for (GrainFraction gf: GRAIN_FRACTIONS) { 353 for (GrainFraction gf: GRAIN_FRACTIONS) {
307 double [][] result = sum( 354 double [][] result = sum(
308 sld, gf.getGrainFractions(), filter, avg, isKmUp, 355 sld, gf.getGrainFractions(), filter, sum, isKmUp,
309 missingFractions); 356 missingFractions);
310 357
311 if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) { 358 if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) {
312 // TODO: resolve i18n 359 // TODO: resolve i18n
313 addProblem("minfo.sediment.load.no.fractions", 360 addProblem("minfo.sediment.load.no.fractions",
322 } 369 }
323 // TODO: Generate messages for missing fractions. 370 // TODO: Generate messages for missing fractions.
324 return new CalculationResult(sldr, this); 371 return new CalculationResult(sldr, this);
325 } 372 }
326 373
327 private CalculationResult calculateOffEpochs() {
328 SedimentLoadData sld =
329 SedimentLoadDataFactory.INSTANCE.getSedimentLoadData(river);
330 if (sld == null) {
331 // TODO: i18n
332 return error("minfo.sediment.load.no.data");
333 }
334
335 SedimentLoadDataResult sldr = new SedimentLoadDataResult();
336
337 boolean isKmUp = isKmUp();
338 Set<Integer> missingFractions = new TreeSet<Integer>();
339
340 for (int [] epoch: epochs) {
341 Value.Filter filter = new And()
342 .add(IsOfficial.INSTANCE)
343 .add(new TimeRangeIntersects(epoch[0], epoch[1]));
344
345 Sum sum = new Sum();
346
347 for (GrainFraction gf: GRAIN_FRACTIONS) {
348 double [][] result = sum(
349 sld, gf.getGrainFractions(), filter, sum, isKmUp,
350 missingFractions);
351
352 if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) {
353 // TODO: resolve i18n
354 addProblem("minfo.sediment.load.no.fractions",
355 gf.getDescription());
356 continue;
357 }
358 // TODO: Optionally transform units.
359 SedimentLoadDataResult.Fraction sldrf =
360 new SedimentLoadDataResult.Fraction(gf.getDescription(), result);
361 sldr.addFraction(sldrf);
362 }
363 }
364 // TODO: Generate messages for missing fractions.
365 return new CalculationResult(sldr, this);
366 }
367
368 /** Figure out flow direction of river. */ 374 /** Figure out flow direction of river. */
369 private boolean isKmUp() { 375 private boolean isKmUp() {
370 River r = RiverFactory.getRiver(river); 376 River r = RiverFactory.getRiver(river);
371 if (r == null) { 377 if (r == null) {
372 addProblem("minfo.missing.river"); 378 addProblem("minfo.missing.river");
373 return true; 379 return true;
374 } 380 }
375 return r.getKmUp(); 381 return r.getKmUp();
382 }
383
384 private final boolean inM3() {
385 return unit.equals("m3_per_a");
386 }
387
388 private SedimentDensity getSedimentDensity() {
389 return inM3()
390 ? SedimentDensityFactory.getSedimentDensity(river, from, to)
391 : null;
392 }
393
394 private static void transformT2M3(SedimentDensity sd, int year, double [][] data) {
395 if (sd == null) {
396 return;
397 }
398 double [] kms = data[0];
399 double [] values = data[1];
400 for (int i = 0; i < kms.length; ++i) {
401 if (Double.isNaN(kms[i]) || Double.isNaN(kms[i])) {
402 continue;
403 }
404 double density = sd.getDensity(kms[i], year);
405 values[i] /= density;
406 }
376 } 407 }
377 408
378 public double[][] sum( 409 public double[][] sum(
379 SedimentLoadData sld, 410 SedimentLoadData sld,
380 int [] grainFractions, 411 int [] grainFractions,

http://dive4elements.wald.intevation.org