changeset 3008:9e0500d64524

FixA: Calculate the Delta W/ts + the average Delta W/ts per Q sector per analysis period. flys-artifacts/trunk@4564 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Wed, 30 May 2012 17:59:19 +0000
parents d520a0869972
children 4dda67a893da
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsFilterBuilder.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/QWD.java
diffstat 5 files changed, 244 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Wed May 30 17:01:54 2012 +0000
+++ b/flys-artifacts/ChangeLog	Wed May 30 17:59:19 2012 +0000
@@ -1,3 +1,25 @@
+2012-05-30	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java:
+	  Calculate the Delta W/ts + 
+	  the average Delta W/ts per Q sector per analysis period.
+	  !!! Very complicated stuff !!!
+	  TODO:
+	  - Store results into the new data structures AnalysisPeriod and
+	    AnalysisPeriods.
+	  - Remove the old DeltaWTsKM and DeltaWT.
+	  - Adjust the facets and the export.
+
+	* src/main/java/de/intevation/flys/artifacts/model/fixings/QWD.java:
+	  Added convinience constructor.
+
+	* src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java:
+	  Added sector filter.
+
+	* src/main/java/de/intevation/flys/artifacts/model/FixingsFilterBuilder.java:
+	  Expose the new sector filter to the fixing overview service. Syntax:
+	  <sector value="<value>"/>
+
 2012-05-30	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/utils/DateAverager.java:
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsFilterBuilder.java	Wed May 30 17:01:54 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsFilterBuilder.java	Wed May 30 17:59:19 2012 +0000
@@ -11,6 +11,7 @@
 import de.intevation.flys.artifacts.model.FixingsOverview.NotFilter;
 import de.intevation.flys.artifacts.model.FixingsOverview.OrFilter;
 import de.intevation.flys.artifacts.model.FixingsOverview.Range;
+import de.intevation.flys.artifacts.model.FixingsOverview.SectorFilter;
 import de.intevation.flys.artifacts.model.FixingsOverview.SectorRangeFilter;
 
 import java.text.ParsePosition;
@@ -198,6 +199,17 @@
                     }
                 }
             }
+            else if ("sector".equals(name)) {
+                String value = element.getAttribute("value").trim();
+                if (value.length() > 0) {
+                    try {
+                        filters.add(new SectorFilter(Integer.parseInt(value)));
+                    }
+                    catch (NumberFormatException nfe) {
+                        log.warn(nfe);
+                    }
+                }
+            }
             else if ("position".equals(name)) {
                 String km = element.getAttribute("km").trim();
                 if (km.length() > 0) {
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java	Wed May 30 17:01:54 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java	Wed May 30 17:59:19 2012 +0000
@@ -855,6 +855,25 @@
         }
     } // class DateRangeFilter
 
+    public static class SectorFilter implements Fixing.Filter {
+
+        protected int sector;
+
+        public SectorFilter(int sector) {
+            this.sector = sector;
+        }
+
+        @Override
+        public boolean accept(Fixing.Column column) {
+            for (SectorRange s: column.getSectors()) {
+                if (s.getSector() == sector) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    } // class SectorFilter
+
     public static class SectorRangeFilter implements Fixing.Filter {
 
         protected int min;
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java	Wed May 30 17:01:54 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java	Wed May 30 17:59:19 2012 +0000
@@ -9,21 +9,28 @@
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.FixingsColumn;
 import de.intevation.flys.artifacts.model.FixingsColumnFactory;
+
+import de.intevation.flys.artifacts.model.FixingsOverview.AndFilter;
+import de.intevation.flys.artifacts.model.FixingsOverview.DateRangeFilter;
+import de.intevation.flys.artifacts.model.FixingsOverview.Fixing;
+import de.intevation.flys.artifacts.model.FixingsOverview.IdFilter;
+import de.intevation.flys.artifacts.model.FixingsOverview.KmFilter;
+import de.intevation.flys.artifacts.model.FixingsOverview.Range;
+import de.intevation.flys.artifacts.model.FixingsOverview.SectorRangeFilter;
+import de.intevation.flys.artifacts.model.FixingsOverview.SectorFilter;
+
 import de.intevation.flys.artifacts.model.FixingsOverview;
 import de.intevation.flys.artifacts.model.FixingsOverviewFactory;
 import de.intevation.flys.artifacts.model.Parameters;
 
-import de.intevation.flys.artifacts.model.FixingsOverview.Range;
-import de.intevation.flys.artifacts.model.FixingsOverview.Fixing;
-import de.intevation.flys.artifacts.model.FixingsOverview.IdFilter;
-import de.intevation.flys.artifacts.model.FixingsOverview.AndFilter;
-import de.intevation.flys.artifacts.model.FixingsOverview.DateRangeFilter;
-import de.intevation.flys.artifacts.model.FixingsOverview.SectorRangeFilter;
-
+import de.intevation.flys.utils.DateAverager;
 import de.intevation.flys.utils.DoubleUtil;
 
 import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.commons.math.MathException;
 
@@ -332,6 +339,126 @@
         return deltaWTsKM;
     }
 
+    protected List<AnalysisPeriodsKM> calculateAnalysisPeriods(
+        Function        function,
+        Parameters      parameters,
+        FixingsOverview overview
+    ) {
+        ArrayList<AnalysisPeriodsKM> results
+            = new ArrayList<AnalysisPeriodsKM>(parameters.size());
+
+        Range range = new Range(from, to);
+
+        int kmIndex = parameters.columnIndex("km");
+
+        ColumnCache cc = new ColumnCache();
+
+        double [] wq = new double[2];
+
+        int [] parameterIndices = 
+            parameters.columnIndices(function.getParameterNames());
+
+        double [] parameterValues = new double[parameterIndices.length];
+
+        DateAverager dateAverager = new DateAverager();
+
+        for (int row = 0, P = parameters.size(); row < P; ++row) {
+            double km = parameters.get(row, kmIndex);
+            parameters.get(row, parameterIndices, parameterValues);
+
+            // This is the paraterized function for a given km.
+            de.intevation.flys.artifacts.math.Function instance =
+                function.instantiate(parameterValues);
+
+            KmFilter kmFilter = new KmFilter(km);
+
+            for (DateRange analysisPeriod: analysisPeriods) {
+                DateRangeFilter drf = new DateRangeFilter(
+                    analysisPeriod.getFrom(),
+                    analysisPeriod.getTo());
+
+                // for all Q sectors.
+                for (int qSector = qSectorStart; qSector < qSectorEnd; ++qSector) {
+
+                    AndFilter filter = new AndFilter();
+                    filter.add(kmFilter);
+                    filter.add(new SectorFilter(qSector));
+                    filter.add(drf);
+
+                    List<Fixing.Column> metas = overview.filter(range, filter);
+
+                    if (metas.isEmpty()) {
+                        // No fixings for km and analysis period
+                        continue;
+                    }
+
+                    double sumQ = 0.0;
+                    double sumW = 0.0;
+
+                    List<QWD> qwds = new ArrayList<QWD>(metas.size());
+
+                    dateAverager.clear();
+
+                    for (Fixing.Column meta: metas) {
+                        if (meta.findQSector(km) != qSector) {
+                            // Ignore not matching sectors.
+                            continue;
+                        }
+
+                        Column column = cc.getColumn(meta);
+                        if (column == null || !column.getWQ(km, wq)) {
+                            continue;
+                        }
+
+                        double fw = instance.value(wq[1]);
+                        if (Double.isNaN(fw)) {
+                            continue;
+                        }
+
+                        double dw = (wq[0] - fw)*100.0;
+
+                        Date date = column.getDate();
+                        String description = column.getDescription();
+
+                        QWD qwd = new QWD(wq[1], wq[0], dw, date, description);
+
+                        qwds.add(qwd);
+
+                        sumW += wq[0];
+                        sumQ += wq[1];
+
+                        dateAverager.add(date);
+                    }
+
+                    // Calulate average per Q sector.
+                    int N = qwds.size();
+                    if (N > 0) {
+                        double avgW = sumW / N;
+                        double avgQ = sumQ / N;
+
+                        double avgFw = instance.value(avgQ);
+                        if (!Double.isNaN(avgFw)) {
+                            double avgDw = (avgW - avgFw)*100.0;
+                            Date avgDate = dateAverager.getAverage();
+
+                            String avgDescription = "avg.deltawt." + qSector;
+
+                            QWD avgQWD = new QWD(
+                                avgQ, avgW, avgDw, avgDate, avgDescription);
+
+                            // TODO: Store average value.
+                        }
+                        else {
+                            // TODO: Store
+                        }
+                    }
+                } // for all Q sectors
+            }
+        }
+
+        return results;
+    }
+
     /** Helper class to bundle the meta information of a column 
      *  and the real data.
      */
@@ -347,8 +474,51 @@
             this.meta = meta;
             this.data = data;
         }
+
+        public Date getDate() {
+            return meta.getStartTime();
+        }
+
+        public String getDescription() {
+            return meta.getDescription();
+        }
+
+        public boolean getWQ(double km, double [] wq) {
+            data.getW(km, wq, 0);
+            if (Double.isNaN(wq[0])) return false;
+            wq[1] = data.getQ(km);
+            return !Double.isNaN(wq[1]);
+        }
     } // class Column
 
+
+    /**
+     * Helper class to find the data belonging to meta info more quickly.
+     */
+    public static class ColumnCache {
+
+        protected Map<Integer, Column> columns;
+
+        public ColumnCache() {
+            columns = new HashMap<Integer, Column>();
+        }
+
+        public Column getColumn(Fixing.Column meta) {
+            Integer key = meta.getId();
+            Column column = columns.get(key);
+            if (column == null) {
+                FixingsColumn data = FixingsColumnFactory
+                    .getInstance()
+                    .getColumnData(meta);
+                if (data != null) {
+                    column = new Column(meta, data);
+                    columns.put(key, column);
+                }
+            }
+            return column;
+        }
+    } // class ColumnCache
+
     /** Fetch meta and data columns for analysis periods. */
     protected Column [][] getAnalysisColumns(FixingsOverview overview) {
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/QWD.java	Wed May 30 17:01:54 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/QWD.java	Wed May 30 17:59:19 2012 +0000
@@ -16,6 +16,20 @@
     public QWD() {
     }
 
+    public QWD(
+        double q,
+        double w,
+        double deltaW,
+        Date   date,
+        String description
+    ) {
+        this.q           = q;
+        this.w           = q;
+        this.deltaW      = deltaW;
+        this.date        = date;
+        this.description = description;
+    }
+
     public double getQ() {
         return q;
     }

http://dive4elements.wald.intevation.org