comparison artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataCalculation.java @ 8193:8d447516b7dd

Sum up fractions from stations and previous stations according to respective validity model.
author Tom Gottfried <tom@intevation.de>
date Thu, 04 Sep 2014 17:33:01 +0200
parents 76e1e9d81ce2
children 59e50aa0c6c2
comparison
equal deleted inserted replaced
8192:adbf980004c0 8193:8d447516b7dd
15 import java.util.TreeSet; 15 import java.util.TreeSet;
16 16
17 import org.dive4elements.river.artifacts.access.SedimentLoadAccess; 17 import org.dive4elements.river.artifacts.access.SedimentLoadAccess;
18 import org.dive4elements.river.artifacts.model.Calculation; 18 import org.dive4elements.river.artifacts.model.Calculation;
19 import org.dive4elements.river.artifacts.model.CalculationResult; 19 import org.dive4elements.river.artifacts.model.CalculationResult;
20 import org.dive4elements.river.artifacts.model.RiverFactory;
21 import org.apache.log4j.Logger; 20 import org.apache.log4j.Logger;
22 import org.dive4elements.river.artifacts.model.minfo.SedimentLoadData.Value; 21 import org.dive4elements.river.artifacts.model.minfo.SedimentLoadData.Value;
23 import org.dive4elements.river.artifacts.model.minfo.SedimentLoadData.Station; 22 import org.dive4elements.river.artifacts.model.minfo.SedimentLoadData.Station;
24 import org.dive4elements.river.artifacts.model.minfo.SedimentLoadDataValueFilter.And; 23 import org.dive4elements.river.artifacts.model.minfo.SedimentLoadDataValueFilter.And;
25 import org.dive4elements.river.artifacts.model.minfo.SedimentLoadDataValueFilter.IsEpoch; 24 import org.dive4elements.river.artifacts.model.minfo.SedimentLoadDataValueFilter.IsEpoch;
95 return description; 94 return description;
96 } 95 }
97 96
98 public int [] getGrainFractions() { 97 public int [] getGrainFractions() {
99 return grainFractions; 98 return grainFractions;
99 }
100
101 public int getStationType() {
102 return SedimentLoadData.measurementStationType(
103 SedimentLoadData.grainFractionIndex(this.description));
100 } 104 }
101 } // class LoadSum 105 } // class LoadSum
102 106
103 public static final LoadSum [] LOAD_SUMS = { 107 public static final LoadSum [] LOAD_SUMS = {
104 // Names are alignt to the grain_fractions table 108 // Names are alignt to the grain_fractions table
221 return error("minfo.sediment.load.no.data"); 225 return error("minfo.sediment.load.no.data");
222 } 226 }
223 227
224 SedimentLoadDataResult sldr = new SedimentLoadDataResult(); 228 SedimentLoadDataResult sldr = new SedimentLoadDataResult();
225 229
226 boolean isKmUp = isKmUp();
227 Set<Integer> missingFractions = new TreeSet<Integer>(); 230 Set<Integer> missingFractions = new TreeSet<Integer>();
228 231
229 Not notEpochs = new Not(IsEpoch.INSTANCE); 232 Not notEpochs = new Not(IsEpoch.INSTANCE);
230 233
231 Sum sum = new Sum(); 234 Sum sum = new Sum();
241 String period = Integer.toString(year); 244 String period = Integer.toString(year);
242 245
243 for (LoadSum ls: LOAD_SUMS) { 246 for (LoadSum ls: LOAD_SUMS) {
244 247
245 double [][] result = sum( 248 double [][] result = sum(
246 sld, ls.getGrainFractions(), filter, sum, isKmUp, 249 sld, ls.getGrainFractions(), ls.getStationType(),
247 missingFractions); 250 filter, sum, missingFractions);
248 251
249 if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) { 252 if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) {
250 // TODO: resolve i18n 253 // TODO: resolve i18n
251 addProblem("minfo.sediment.load.no.fractions", 254 addProblem("minfo.sediment.load.no.fractions",
252 ls.getDescription()); 255 ls.getDescription());
263 266
264 } 267 }
265 // TODO: Generate messages for missing fractions. 268 // TODO: Generate messages for missing fractions.
266 return new CalculationResult(sldr, this); 269 return new CalculationResult(sldr, this);
267 } 270 }
268
269 271
270 private CalculationResult calculateEpochs() { 272 private CalculationResult calculateEpochs() {
271 SedimentLoadData sld = 273 SedimentLoadData sld =
272 SedimentLoadDataFactory.INSTANCE.getSedimentLoadData(river); 274 SedimentLoadDataFactory.INSTANCE.getSedimentLoadData(river);
273 if (sld == null) { 275 if (sld == null) {
275 return error("minfo.sediment.load.no.data"); 277 return error("minfo.sediment.load.no.data");
276 } 278 }
277 279
278 SedimentLoadDataResult sldr = new SedimentLoadDataResult(); 280 SedimentLoadDataResult sldr = new SedimentLoadDataResult();
279 281
280 boolean isKmUp = isKmUp();
281 Set<Integer> missingFractions = new TreeSet<Integer>(); 282 Set<Integer> missingFractions = new TreeSet<Integer>();
282 283
283 Sum sum = new Sum(); 284 Sum sum = new Sum();
284 285
285 SedimentDensity sd = getSedimentDensity(); 286 SedimentDensity sd = getSedimentDensity();
301 for (int year = min; year <= max; ++year) { 302 for (int year = min; year <= max; ++year) {
302 Value.Filter filter = new And(notEpochs) 303 Value.Filter filter = new And(notEpochs)
303 .add(new TimeRangeIntersects(year)); 304 .add(new TimeRangeIntersects(year));
304 305
305 double [][] result = sum( 306 double [][] result = sum(
306 sld, ls.getGrainFractions(), filter, sum, isKmUp, 307 sld, ls.getGrainFractions(), ls.getStationType(),
307 missingFractions); 308 filter, sum, missingFractions);
308 309
309 if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) { 310 if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) {
310 // TODO: resolve i18n 311 // TODO: resolve i18n
311 addProblem("minfo.sediment.load.no.fractions", 312 addProblem("minfo.sediment.load.no.fractions",
312 ls.getDescription()); 313 ls.getDescription());
340 341
341 SedimentLoadDataResult sldr = new SedimentLoadDataResult(); 342 SedimentLoadDataResult sldr = new SedimentLoadDataResult();
342 343
343 SedimentDensity sd = getSedimentDensity(); 344 SedimentDensity sd = getSedimentDensity();
344 345
345 boolean isKmUp = isKmUp();
346 Set<Integer> missingFractions = new TreeSet<Integer>(); 346 Set<Integer> missingFractions = new TreeSet<Integer>();
347 347
348 for (int [] epoch: epochs) { 348 for (int [] epoch: epochs) {
349 Value.Filter filter = new And(IsOfficial.INSTANCE) 349 Value.Filter filter = new And(IsOfficial.INSTANCE)
350 .add(new TimeRangeIntersects(epoch[0], epoch[1])); 350 .add(new TimeRangeIntersects(epoch[0], epoch[1]));
356 356
357 Sum sum = new Sum(); 357 Sum sum = new Sum();
358 358
359 for (LoadSum ls: LOAD_SUMS) { 359 for (LoadSum ls: LOAD_SUMS) {
360 double [][] result = sum( 360 double [][] result = sum(
361 sld, ls.getGrainFractions(), filter, sum, isKmUp, 361 sld, ls.getGrainFractions(), ls.getStationType(),
362 missingFractions); 362 filter, sum, missingFractions);
363 363
364 if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) { 364 if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) {
365 // TODO: resolve i18n 365 // TODO: resolve i18n
366 addProblem("minfo.sediment.load.no.fractions", 366 addProblem("minfo.sediment.load.no.fractions",
367 ls.getDescription()); 367 ls.getDescription());
373 sldr.addFraction(sldrf); 373 sldr.addFraction(sldrf);
374 } 374 }
375 } 375 }
376 // TODO: Generate messages for missing fractions. 376 // TODO: Generate messages for missing fractions.
377 return new CalculationResult(sldr, this); 377 return new CalculationResult(sldr, this);
378 }
379
380 /** Figure out flow direction of river. */
381 private final boolean isKmUp() {
382 River r = RiverFactory.getRiver(river);
383 if (r == null) {
384 addProblem("minfo.missing.river");
385 return true;
386 }
387 return r.getKmUp();
388 } 378 }
389 379
390 private final boolean inM3() { 380 private final boolean inM3() {
391 return unit.equals("m3_per_a"); 381 return unit.equals("m3_per_a");
392 } 382 }
413 } 403 }
414 404
415 public double[][] sum( 405 public double[][] sum(
416 SedimentLoadData sld, 406 SedimentLoadData sld,
417 int [] grainFractions, 407 int [] grainFractions,
408 int lsSType,
418 Value.Filter filter, 409 Value.Filter filter,
419 Sum sum, 410 Sum sum,
420 boolean isKMUp,
421 Set<Integer> missingFractions 411 Set<Integer> missingFractions
422 ) { 412 ) {
423 List<Station> stations = sld.findStations(from, to); 413 List<Station> stations = sld.findStations(from, to);
424 414
425 double [] values = new double[grainFractions.length]; 415 double [] values = new double[grainFractions.length];
426 416
427 double [][] result = new double[2][stations.size()]; 417 double [][] result = new double[2][stations.size()];
428 418
429 for (int j = 0, S = stations.size(); j < S; ++j) { 419 for (int j = 0, S = stations.size(); j < S; ++j) {
430 Station station = stations.get(j); 420 Station station = stations.get(j);
421 int sType = station.getType();
422
431 for (int i = 0; i < grainFractions.length; ++i) { 423 for (int i = 0; i < grainFractions.length; ++i) {
432 int gf = grainFractions[i]; 424 int gf = grainFractions[i];
425 int gfSType = SedimentLoadData.measurementStationType(gf);
426
433 sum.reset(); 427 sum.reset();
428
429 // Add current single fraction at current station
434 station.filterGrainFraction(gf, filter, sum); 430 station.filterGrainFraction(gf, filter, sum);
435 if (sum.getN() == 0) { // No values found 431
436 int msType = SedimentLoadData.measurementStationType(gf); 432 if (gfSType == Station.UNKNOWN) {
437 // Station of right fraction type already? No: take previous. 433 log.error("No measurement station type defined for " +
438 if (!station.isType(msType)) { 434 "fraction-index" + gf);
439 Station prev = station.prevByType(msType, isKMUp); 435 }
436 else {
437 if (lsSType != Station.BED_LOAD &&
438 lsSType != Station.SUSPENDED &&
439 (sType == Station.BED_LOAD ||
440 sType == Station.SUSPENDED) &&
441 sum.getN() == 0) {
442 /* In case the station-type of the load sum is
443 a combined type and we are at non-combined station:
444 we need to add values from previous station of
445 the other type for fractions not given here. */
446 int otherType = sType == Station.BED_LOAD ?
447 Station.SUSPENDED : Station.BED_LOAD;
448 Station prev = station.prevByType(otherType);
440 if (prev != null) { 449 if (prev != null) {
441 prev.filterGrainFraction(gf, filter, sum); 450 prev.filterGrainFraction(gf, filter, sum);
442 } 451 }
443 } 452 }
444 } 453 }

http://dive4elements.wald.intevation.org