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