changeset 8055:cd35b76f1ef8

Sediment load. More off year based calculations.
author Sascha L. Teichmann <teichmann@intevation.de>
date Fri, 18 Jul 2014 13:03:28 +0200 (2014-07-18)
parents db4e6bd367a6
children d86cc6a17b7a
files artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataCalculation.java artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataFactory.java artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadDataValueFilter.java
diffstat 3 files changed, 116 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- 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<Integer> missingFractions = new TreeSet<Integer>();
+
+        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;
     }
 
--- 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) {
--- 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<Filter> filters;
 
@@ -27,8 +41,9 @@
             filters = new ArrayList<Filter>();
         }
 
-        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)));

http://dive4elements.wald.intevation.org