diff flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java @ 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 e5e6363e6cba
children 05a3fe8800b3
line wrap: on
line diff
--- 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) {
 

http://dive4elements.wald.intevation.org