comparison artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadCalculation.java @ 6381:df1a3826c691

SedimentLoadCalculation: Calculate and set Total Load values ind a brutal range merging manner.
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Fri, 21 Jun 2013 11:41:10 +0200
parents fa8425c8694c
children e6ceab9e3091
comparison
equal deleted inserted replaced
6380:dc23ffb9d82c 6381:df1a3826c691
16 import org.apache.log4j.Logger; 16 import org.apache.log4j.Logger;
17 17
18 import org.dive4elements.river.artifacts.access.SedimentLoadAccess; 18 import org.dive4elements.river.artifacts.access.SedimentLoadAccess;
19 import org.dive4elements.river.artifacts.model.Calculation; 19 import org.dive4elements.river.artifacts.model.Calculation;
20 import org.dive4elements.river.artifacts.model.CalculationResult; 20 import org.dive4elements.river.artifacts.model.CalculationResult;
21 import org.dive4elements.river.artifacts.model.Range;
21 22
22 23
23 /** Calculate sediment load. */ 24 /** Calculate sediment load. */
24 public class SedimentLoadCalculation 25 public class SedimentLoadCalculation
25 extends Calculation 26 extends Calculation
290 } 291 }
291 if (problemThisYear) { 292 if (problemThisYear) {
292 logger.warn("Some problem, not calculating total load."); 293 logger.warn("Some problem, not calculating total load.");
293 return load; 294 return load;
294 } 295 }
295 double nextStep = 0; 296 return partialTotal(load);
296 for(double km : load.getKms()) { 297 }
298
299
300 /** Returns true if all fraction values except SuspSediment are unset. */
301 private boolean hasOnlySuspSediment(SedimentLoadFraction fraction) {
302 return (fraction.getSuspSediment() != 0d &&
303 fraction.getCoarse() == 0d &&
304 fraction.getFineMiddle() == 0d &&
305 fraction.getSand() == 0d &&
306 fraction.getSuspSand() == 0d);
307 }
308
309
310 /** Returns true if all fraction values except SuspSediment are set. */
311 private boolean hasButSuspSediment(SedimentLoadFraction fraction) {
312 return (fraction.getSuspSediment() == 0d &&
313 fraction.getCoarse() != 0d &&
314 fraction.getFineMiddle() != 0d &&
315 fraction.getSand() != 0d &&
316 fraction.getSuspSand() != 0d);
317 }
318
319
320 /** Returns true if all fraction needed for total calculation are set. */
321 private boolean complete(SedimentLoadFraction fraction) {
322 return (fraction.getCoarse() != 0d &&
323 fraction.getFineMiddle() != 0d &&
324 fraction.getSand() != 0d &&
325 fraction.getSuspSand() != 0d &&
326 fraction.getSuspSediment() != 0d);
327 }
328
329
330 /**
331 * Set total values in load.
332 * Therefore, run over the kms and find ranges where either all
333 * or all Geschiebe or just the Schwebstoff fractions are set.
334 * Merge these ranges and add (maybe new) respective fractions to
335 * load.
336 * @param load SedimentLoad to add total values (and ranges) to.
337 * @return input param load.
338 */
339 private SedimentLoad partialTotal(SedimentLoad load) {
340 SedimentLoad fairLoad = load;
341
342 Range lastOtherRange = null;
343 double lastOtherValue = 0d;
344
345 Range lastSuspSedimentRange = null;
346 double lastSuspSedimentValue = 0d;
347
348 for (double km: load.getKms()) {
349 logger.debug ("Trying to add at km " + km);
297 SedimentLoadFraction fraction = load.getFraction(km); 350 SedimentLoadFraction fraction = load.getFraction(km);
298 double total = 0d; 351 if (complete(fraction)) {
299 if ((fraction.getCoarse() <= 0d && load.hasCoarse())){ 352 double total = fraction.getCoarse() +
300 addProblem(km, "missing.data.coarse"); 353 fraction.getFineMiddle() +
301 continue; 354 fraction.getSand() +
302 } 355 fraction.getSuspSand() +
303 if (fraction.getFineMiddle() <= 0d && load.hasFineMiddle()) { 356 fraction.getSuspSediment();
304 addProblem(km, "missing.data.fine_middle"); 357 // Easiest case. Add values up and set'em.
305 continue; 358 if (fraction.getCoarseRange().equals(
306 } 359 fraction.getSuspSedimentRange())) {
307 if (fraction.getSand() <= 0d && load.hasSand()) { 360 lastOtherRange = null;
308 addProblem(km, "missing data.sand"); 361 lastSuspSedimentRange = null;
309 continue; 362 fairLoad.setTotal(km, total, fraction.getCoarseRange());
310 } 363 }
311 if (fraction.getSuspSand() <= 0d && load.hasSuspSand()) { 364 else {
312 addProblem(km, "missing.data.susp_sand"); 365 // Need to split a range.
313 continue; 366 if (fraction.getCoarseRange().getEnd()
314 } 367 < fraction.getSuspSedimentRange().getEnd()) {
315 if (fraction.getSuspSediment() <= 0d && load.hasSuspSediment()) { 368 // Schwebstoff is longer.
316 addProblem(km, "missing.data.susp_sediment"); 369 // Adjust and remember schwebstoffs range and value.
317 continue; 370 lastSuspSedimentRange = (Range) fraction.getSuspSedimentRange().clone();
318 } 371 lastSuspSedimentRange.setStart(fraction.getCoarseRange().getEnd());
319 total += fraction.getCoarse() + 372 lastSuspSedimentValue = fraction.getSuspSediment();
320 fraction.getFineMiddle() + 373 lastOtherRange = null;
321 fraction.getSand() + 374 fairLoad.setTotal(km, total, fraction.getCoarseRange());
322 fraction.getSuspSand() + 375 }
323 fraction.getSuspSediment(); 376 else {
324 load.setTotal(km, total, fraction.getTotalRange()); 377 // Geschiebe is longer.
325 } 378 // Adjust and remember other values.
326 return load; 379 lastOtherRange = (Range) fraction.getSuspSedimentRange().clone();
327 } 380 lastOtherRange.setStart(fraction.getSuspSedimentRange().getEnd());
381 lastOtherValue = (total - fraction.getSuspSediment());
382 lastSuspSedimentRange = null;
383 fairLoad.setTotal(km, total, fraction.getSuspSedimentRange());
384 }
385 }
386 }
387 else if (hasOnlySuspSediment(fraction) && lastOtherRange != null) {
388 // Split stuff.
389 Range suspSedimentRange = fraction.getSuspSedimentRange();
390 // if intersects with last other range, cool! merge and add!
391 if (lastOtherRange.contains(km)) {
392 double maxStart = 0d;
393 double minEnd = 0d;
394 maxStart = Math.max(suspSedimentRange.getStart(),
395 lastOtherRange.getStart());
396
397 minEnd = Math.min(suspSedimentRange.getEnd(),
398 lastOtherRange.getEnd());
399 double total = lastOtherValue + fraction.getSuspSediment();
400 Range totalRange = new Range(maxStart, minEnd);
401 if (suspSedimentRange.getEnd() > lastOtherRange.getEnd()) {
402 lastSuspSedimentRange = (Range) suspSedimentRange.clone();
403 lastSuspSedimentRange.setStart(lastOtherRange.getEnd());
404 lastSuspSedimentValue = fraction.getSuspSediment();
405 lastOtherRange = null;
406 }
407 else {
408 // Other is "longer".
409 lastOtherRange.setStart(suspSedimentRange.getEnd());
410 lastSuspSedimentRange = null;
411 }
412 if (Math.abs(suspSedimentRange.getEnd() - lastOtherRange.getEnd()) < 0.1d) {
413 lastOtherRange = null;
414 lastSuspSedimentRange = null;
415 }
416 fairLoad.setTotal(km, total + fraction.getSuspSediment(), totalRange);
417 }
418 else {
419 lastSuspSedimentRange = suspSedimentRange;
420 lastSuspSedimentValue = fraction.getSuspSediment();
421 lastOtherRange = null;
422 }
423 }
424 else if (hasButSuspSediment(fraction) && lastSuspSedimentRange != null) {
425 // If intersects with last suspsed range, merge and add
426 double total = fraction.getCoarse() +
427 fraction.getFineMiddle() +
428 fraction.getSand() +
429 fraction.getSuspSand() +
430 lastSuspSedimentValue;
431 double maxStart = Math.max(fraction.getCoarseRange().getStart(),
432 lastSuspSedimentRange.getStart());
433 if (lastSuspSedimentRange.contains(km)) {
434 double minEnd = Math.min(fraction.getCoarseRange().getEnd(),
435 lastSuspSedimentRange.getEnd());
436 Range totalRange = new Range(maxStart, minEnd);
437 if (lastSuspSedimentRange.getEnd() > fraction.getCoarseRange().getEnd()) {
438 // SuspSed longer.
439 lastSuspSedimentRange.setStart(fraction.getCoarseRange().getEnd());
440 lastOtherRange = null;
441 }
442 else {
443 // Other longer
444 lastOtherRange = (Range) fraction.getCoarseRange().clone();
445 lastOtherRange.setStart(lastSuspSedimentRange.getEnd());
446 lastSuspSedimentRange = null;
447 lastOtherValue = total - lastSuspSedimentValue;
448 }
449 if (Math.abs(lastSuspSedimentRange.getEnd() - lastOtherRange.getEnd()) < 0.1d) {
450 lastOtherRange = null;
451 lastSuspSedimentRange = null;
452 }
453 fairLoad.setTotal(km, total, totalRange);
454 }
455 else {
456 // Ranges are disjoint.
457 lastOtherRange = fraction.getCoarseRange();
458 lastOtherValue = total - fraction.getSuspSediment();
459 lastSuspSedimentRange = null;
460 }
461 }
462 else {
463 // Some values are missing or no intersection with former values.
464 // Stay as we are.
465 }
466 }
467 return fairLoad;
468 }
469
328 470
329 private SedimentLoad calculateUnit(SedimentLoad load, int year) { 471 private SedimentLoad calculateUnit(SedimentLoad load, int year) {
330 SedimentDensity density = 472 SedimentDensity density =
331 SedimentDensityFactory.getSedimentDensity(river, kmLow, kmUp, year); 473 SedimentDensityFactory.getSedimentDensity(river, kmLow, kmUp, year);
332 for (double km: load.getKms()) { 474 for (double km: load.getKms()) {

http://dive4elements.wald.intevation.org