# HG changeset patch # User Sascha L. Teichmann # Date 1405681408 -7200 # Node ID cd35b76f1ef8d8774dcce8768eea4327f9589361 # Parent db4e6bd367a67e0d5849ae6f67ae3c9ce68a7772 Sediment load. More off year based calculations. diff -r db4e6bd367a6 -r cd35b76f1ef8 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataCalculation.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataCalculation.java Fri Jul 18 12:22:51 2014 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataCalculation.java Fri Jul 18 13:03:28 2014 +0200 @@ -9,6 +9,7 @@ import java.util.List; import java.util.Set; +import java.util.TreeSet; import org.dive4elements.river.artifacts.access.SedimentLoadAccess; import org.dive4elements.river.artifacts.model.Calculation; @@ -18,6 +19,10 @@ import org.dive4elements.river.artifacts.model.minfo.SedimentLoadData; import org.dive4elements.river.artifacts.model.minfo.SedimentLoadData.Value; import org.dive4elements.river.artifacts.model.minfo.SedimentLoadData.Station; +import org.dive4elements.river.artifacts.model.minfo.SedimentLoadDataValueFilter.And; +import org.dive4elements.river.artifacts.model.minfo.SedimentLoadDataValueFilter.IsEpoch; +import org.dive4elements.river.artifacts.model.minfo.SedimentLoadDataValueFilter.Not; +import org.dive4elements.river.artifacts.model.minfo.SedimentLoadDataValueFilter.TimeRangeIntersects; import org.dive4elements.river.model.River; import org.dive4elements.river.utils.DoubleUtil; @@ -83,6 +88,43 @@ SedimentLoadData.GF_SUSP_SEDIMENT }; + public static final class GrainFraction { + private String description; + private int [] grainFractions; + + public GrainFraction(String description, int [] grainFractions) { + this.description = description; + this.grainFractions = grainFractions; + } + public static final GrainFraction make(String description, int [] grainFractions) { + return new GrainFraction(description, grainFractions); + } + + public String getDescription() { + return description; + } + + public int [] getGrainFractions() { + return grainFractions; + } + } // class GrainFraction + + public static final GrainFraction [] GRAIN_FRACTIONS = { + // TODO: i18n + GrainFraction.make("minfo.total.load.flys", TOTAL_LOAD_FLYS), + GrainFraction.make("minfo.bed.load.flys", BED_LOAD_FLYS), + GrainFraction.make("minfo.bed.load.susp.sand.flys", BED_LOAD_SUSP_SAND_FLYS), + GrainFraction.make("minfo.total.load.bfg", TOTAL_LOAD_BFG), + GrainFraction.make("minfo.bed.load.bfg", BED_LOAD_BFG), + GrainFraction.make("minfo.suspended.load.bfg", SUSPENDED_LOAD_BFG), + GrainFraction.make("minfo.coarse.flys", COARSE_FLYS), + GrainFraction.make("minfo.fine.middle.flys", FINE_MIDDLE_FLYS), + GrainFraction.make("minfo.sand.flys", SAND_FLYS) , + GrainFraction.make("minfo.susp.sand.flys", SUSP_SAND_FLYS), + GrainFraction.make("minfo.susp.sand.bed.flys", SUSP_SAND_BED_FLYS), + GrainFraction.make("minfo.susp.sediment.flys", SUSP_SEDIMENT_FLYS), + }; + public static final class Sum implements Value.Visitor { private int n; @@ -124,8 +166,8 @@ private String river; private String yearEpoch; private String unit; - private int [][] epoch; - private int [] period; + private int [][] epochs; + private int [] years; private double from; private double to; @@ -140,17 +182,17 @@ String yearEpoch = access.getYearEpoch(); String unit = access.getUnit(); - int [] period = null; - int [][] epoch = null; + int [] years = null; + int [][] epochs = null; double from = access.getUpperKM(); double to = access.getLowerKM(); if (yearEpoch.equals("year")) { - period = access.getPeriod(); + years = access.getPeriod(); } else if (yearEpoch.equals("epoch") || yearEpoch.equals("off_epoch")) { - epoch = access.getEpochs(); + epochs = access.getEpochs(); } else { addProblem("minfo.missing.year_epoch"); @@ -161,7 +203,7 @@ addProblem("minfo.missing.river"); } - if (period == null && epoch == null) { + if (years == null && epochs == null) { addProblem("minfo.missing.time"); } @@ -169,13 +211,18 @@ this.river = river; this.yearEpoch = yearEpoch; this.unit = unit; - this.period = period; - this.epoch = epoch; + this.years = years; + this.epochs = epochs; this.from = from; this.to = to; return internalCalculate(); } + return error(null); + } + + private CalculationResult error(String msg) { + if (msg != null) addProblem(msg); return new CalculationResult(this); } @@ -185,13 +232,45 @@ if ("off_epoch".equals(yearEpoch)) return calculateOffEpochs(); // TODO: i18n - addProblem("minfo.sediment.load.unknown.calc.mode"); - - return new CalculationResult(this); + return error("minfo.sediment.load.unknown.calc.mode"); } private CalculationResult calculateYears() { - // TODO: Implement me! + boolean isKmUp = isKmUp(); + SedimentLoadData sld = + SedimentLoadDataFactory.INSTANCE.getSedimentLoadData(river); + if (sld == null) { + // TODO: i18n + return error("minfo.sediment.load.no.data"); + } + + Set missingFractions = new TreeSet(); + + Not notEpochs = new Not(IsEpoch.INSTANCE); + + Sum sum = new Sum(); + + for (int year: years) { + Value.Filter filter = new And() + .add(notEpochs) + .add(new TimeRangeIntersects(year)); + + for (GrainFraction gf: GRAIN_FRACTIONS) { + double [][] result = sum( + sld, gf.getGrainFractions(), filter, sum, isKmUp, + missingFractions); + + if (result[0].length == 0 || DoubleUtil.isNaN(result[1])) { + // TODO: resolve i18n + addProblem("minfo.sediment.load.no.fractions", + gf.getDescription()); + continue; + } + // TODO: Generate result data set for calculation. + } + } + // TODO: Generate messages for missing fractions. + return null; } diff -r db4e6bd367a6 -r cd35b76f1ef8 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataFactory.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataFactory.java Fri Jul 18 12:22:51 2014 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataFactory.java Fri Jul 18 13:03:28 2014 +0200 @@ -50,10 +50,13 @@ "WHERE r.name = :river " + "ORDER BY sl.id"; + public static final SedimentLoadDataFactory INSTANCE = + new SedimentLoadDataFactory(); + private SedimentLoadDataFactory() { } - public SedimentLoadData getSedimentLoadData(String river) { + public synchronized SedimentLoadData getSedimentLoadData(String river) { boolean debug = log.isDebugEnabled(); if (debug) { diff -r db4e6bd367a6 -r cd35b76f1ef8 artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataValueFilter.java --- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataValueFilter.java Fri Jul 18 12:22:51 2014 +0200 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataValueFilter.java Fri Jul 18 13:03:28 2014 +0200 @@ -20,6 +20,20 @@ private SedimentLoadDataValueFilter() { } + public static final class Not implements Filter { + + private Filter parent; + + public Not(Filter parent) { + this.parent = parent; + } + + @Override + public boolean accept(Value value) { + return !parent.accept(value); + } + } // class Not + public static abstract class Composite implements Filter { protected List filters; @@ -27,8 +41,9 @@ filters = new ArrayList(); } - public void add(Filter filter) { + public Composite add(Filter filter) { filters.add(filter); + return this; } } @@ -98,6 +113,10 @@ private Date a; private Date b; + public TimeRangeIntersects(int year) { + this(year, year); + } + public TimeRangeIntersects(int startYear, int endYear) { this(firstJan(Math.min(startYear, endYear)), lastDec(Math.max(startYear, endYear)));