# HG changeset patch # User Sascha L. Teichmann # Date 1338400759 0 # Node ID 9e0500d645245835e4724529274defbed0e655fc # Parent d520a08699720f7dd435ad51b712ca8ef8458741 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 diff -r d520a0869972 -r 9e0500d64524 flys-artifacts/ChangeLog --- 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 + + * 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: + + 2012-05-30 Sascha L. Teichmann * src/main/java/de/intevation/flys/utils/DateAverager.java: diff -r d520a0869972 -r 9e0500d64524 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsFilterBuilder.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) { diff -r d520a0869972 -r 9e0500d64524 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java --- 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; diff -r d520a0869972 -r 9e0500d64524 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java --- 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 calculateAnalysisPeriods( + Function function, + Parameters parameters, + FixingsOverview overview + ) { + ArrayList results + = new ArrayList(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 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 qwds = new ArrayList(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 columns; + + public ColumnCache() { + columns = new HashMap(); + } + + 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) { diff -r d520a0869972 -r 9e0500d64524 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/QWD.java --- 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; }