# HG changeset patch # User Sascha L. Teichmann # Date 1337797665 0 # Node ID c1f2e792704a92a7d3b059f2faf3a66e1ee3f468 # Parent 10e6400d41667109bc0ee72ba8247808c93a553f FixA: Calculate Delta W/t, too. flys-artifacts/trunk@4479 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 10e6400d4166 -r c1f2e792704a flys-artifacts/ChangeLog --- a/flys-artifacts/ChangeLog Wed May 23 13:48:20 2012 +0000 +++ b/flys-artifacts/ChangeLog Wed May 23 18:27:45 2012 +0000 @@ -14,6 +14,26 @@ 2012-05-23 Raimund Renkert + * src/main/java/de/intevation/flys/artifacts/math/fitting/Function.java: + Allow instantiation of a function with concrete parameters. + + * src/main/java/de/intevation/flys/artifacts/model/Parameters.java: + Enable indexed access to parameter names. + + * src/main/java/de/intevation/flys/artifacts/model/fixings/FitResult.java: + New. Bundles the results of the fitting. + + * src/main/java/de/intevation/flys/artifacts/model/fixings/DeltaWT.java: + New. Stores results of Delta W/t calcs. + + * src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java: + Calculate Delta W/t s, too. + + * src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java: + Make component filters ('and', 'or') more easy to construct. + +2012-05-23 Raimund Renkert + * src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java, src/main/java/de/intevation/flys/themes/ThemeFactory.java: Improved startup performance. diff -r 10e6400d4166 -r c1f2e792704a flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/fitting/Function.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/fitting/Function.java Wed May 23 13:48:20 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/fitting/Function.java Wed May 23 18:27:45 2012 +0000 @@ -1,5 +1,7 @@ package de.intevation.flys.artifacts.math.fitting; +import org.apache.commons.math.FunctionEvaluationException; + import org.apache.commons.math.optimization.fitting.ParametricRealFunction; import de.intevation.flys.utils.DoubleUtil; @@ -53,5 +55,22 @@ public double [] getInitialGuess() { return initialGuess; } + + public de.intevation.flys.artifacts.math.Function instantiate( + final double [] parameters + ) { + return new de.intevation.flys.artifacts.math.Function() { + + @Override + public double value(double x) { + try { + return Function.this.value(x, parameters); + } + catch (FunctionEvaluationException fee) { + return Double.NaN; + } + } + }; + } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 10e6400d4166 -r c1f2e792704a 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 23 13:48:20 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java Wed May 23 18:27:45 2012 +0000 @@ -748,13 +748,24 @@ public static abstract class ComponentFilter implements Fixing.Filter { protected List children; + public ComponentFilter() { + children = new ArrayList(); + } + public ComponentFilter(List children) { this.children = children; } + + public void add(Fixing.Filter filter) { + children.add(filter); + } } // class ComponentFilter public static class OrFilter extends ComponentFilter { + public OrFilter() { + } + public OrFilter(List children) { super(children); } @@ -772,6 +783,9 @@ public static class AndFilter extends ComponentFilter { + public AndFilter() { + } + public AndFilter(List children) { super(children); } diff -r 10e6400d4166 -r c1f2e792704a flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Parameters.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Parameters.java Wed May 23 13:48:20 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Parameters.java Wed May 23 18:27:45 2012 +0000 @@ -77,5 +77,22 @@ public void removeNaNs() { W.removeNaNs(columns); } + + public int [] columnIndices(String [] columns) { + int [] indices = new int[columns.length]; + for (int i = 0; i < columns.length; ++i) { + indices[i] = columnIndex(columns[i]); + } + return indices; + } + + public void get(int row, int [] columnIndices, double [] values) { + for (int i = 0; i < columnIndices.length; ++i) { + int index = columnIndices[i]; + values[i] = index >= 0 && index < columns.length + ? columns[index].getQuick(row) + : Double.NaN; + } + } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 10e6400d4166 -r c1f2e792704a flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/DeltaWT.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/DeltaWT.java Wed May 23 18:27:45 2012 +0000 @@ -0,0 +1,47 @@ +package de.intevation.flys.artifacts.model.fixings; + +import java.io.Serializable; + +import java.util.Date; + +public class DeltaWT +implements Serializable +{ + protected double deltaW; + protected Date date; + protected String description; + + public DeltaWT() { + } + + public DeltaWT(double deltaW, Date date, String description) { + this.deltaW = deltaW; + this.date = date; + this.description = description; + } + + public double getDeltaW() { + return deltaW; + } + + public void setDeltaW(double deltaW) { + this.deltaW = deltaW; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 10e6400d4166 -r c1f2e792704a flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FitResult.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FitResult.java Wed May 23 18:27:45 2012 +0000 @@ -0,0 +1,39 @@ +package de.intevation.flys.artifacts.model.fixings; + +import de.intevation.flys.artifacts.model.Parameters; + +import java.io.Serializable; + +import java.util.List; + +public class FitResult +implements Serializable +{ + protected Parameters parameters; + protected List deltaWTs; + + public FitResult() { + } + + public FitResult(Parameters parameters, List deltaWTs) { + this.parameters = parameters; + this.deltaWTs = deltaWTs; + } + + public Parameters getParameters() { + return parameters; + } + + public void setParameters(Parameters parameters) { + this.parameters = parameters; + } + + public List getDeltaWTs() { + return deltaWTs; + } + + public void setDeltaWTs(List deltaWTs) { + this.deltaWTs = deltaWTs; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 10e6400d4166 -r c1f2e792704a 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 23 13:48:20 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java Wed May 23 18:27:45 2012 +0000 @@ -13,13 +13,19 @@ 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.Fixing.Filter; +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.DoubleUtil; import java.util.ArrayList; import java.util.List; +import java.util.Date; import org.apache.commons.math.MathException; @@ -34,25 +40,31 @@ { private static Logger logger = Logger.getLogger(FixCalculation.class); - protected String river; - protected double from; - protected double to; - protected double step; - protected boolean preprocessing; - protected String function; - protected int [] events; + protected String river; + protected double from; + protected double to; + protected double step; + protected boolean preprocessing; + protected String function; + protected int [] events; + protected long [][] analysisPeriods; + protected int qSectorStart; + protected int qSectorEnd; public FixCalculation() { } public FixCalculation(FixationArtifactAccess access) { - String river = access.getRiver(); - Double from = access.getFrom(); - Double to = access.getTo(); - Double step = access.getStep(); - String function = access.getFunction(); - int [] events = access.getEvents(); + String river = access.getRiver(); + Double from = access.getFrom(); + Double to = access.getTo(); + Double step = access.getStep(); + String function = access.getFunction(); + int [] events = access.getEvents(); + long [][] analysisPeriods = access.getAnalysisPeriods(); + Integer qSectorStart = access.getQSectorStart(); + Integer qSectorEnd = access.getQSectorEnd(); if (river == null) { // TODO: i18n @@ -84,13 +96,31 @@ addProblem("fix.missing.events"); } + if (analysisPeriods == null || analysisPeriods.length < 1) { + // TODO: i18n + addProblem("fix.missing.analysis.periods"); + } + + if (qSectorStart == null) { + // TODO: i18n + addProblem("fix.missing.qstart.sector"); + } + + if (qSectorEnd == null) { + // TODO: i18n + addProblem("fix.missing.qend.sector"); + } + if (!hasProblems()) { - this.river = river; - this.from = from; - this.to = to; - this.step = step; - this.function = function; - this.events = events; + this.river = river; + this.from = from; + this.to = to; + this.step = step; + this.function = function; + this.events = events; + this.analysisPeriods = analysisPeriods; + this.qSectorStart = qSectorStart; + this.qSectorEnd = qSectorEnd; } } @@ -192,8 +222,141 @@ results.removeNaNs(); } - // TODO: Calculate Delta W/t, too. - return new CalculationResult(results, this); + // Calculate Delta W/t + List deltaWTs = calculateDeltaWTs( + func, + overview, + results); + + // TODO: Add km indexed structure for deltaWTs + + return new CalculationResult(deltaWTs, this); + } + + public List calculateDeltaWTs( + Function function, + FixingsOverview overview, + Parameters results + ) { + List deltaWTs = new ArrayList(); + + Column [][] analysisColumns = getAnalysisColumns(overview); + + int [] parameterIndices = + results.columnIndices(function.getParameterNames()); + + double [] parameterValues = + new double[parameterIndices.length]; + + double [] ow = new double[1]; + + for (int i = 0, N = results.size(); i < N; ++i) { + double km = results.get(i, "km"); + results.get(i, parameterIndices, parameterValues); + + // This is the paraterized function for a given km. + de.intevation.flys.artifacts.math.Function instance = + function.instantiate(parameterValues); + + // Evaluate all columns for all analysis periods. + for (int j = 0; j < analysisColumns.length; ++j) { + Column [] periodColumns = analysisColumns[j]; + + for (int k = 0; k < periodColumns.length; ++k) { + Column pc = periodColumns[k]; + + // Q from real data. + double q = pc.data.getQ(km); + if (Double.isNaN(q)) { + continue; + } + + // Calculate W from function. + double nw = instance.value(q); + if (Double.isNaN(nw)) { + continue; + } + + // W from real data. + pc.data.getW(km, ow); + + if (Double.isNaN(ow[0])) { + continue; + } + + double deltaW = ow[0] - nw; + + DeltaWT deltaWT = new DeltaWT( + deltaW, + pc.meta.getStartTime(), + pc.meta.getDescription()); + + deltaWTs.add(deltaWT); + } + } + } + + return deltaWTs; + } + + /** Helper class to bundle the meta information of a column + * and the real data. + */ + protected static class Column { + + protected Fixing.Column meta; + protected FixingsColumn data; + + public Column() { + } + + public Column(Fixing.Column meta, FixingsColumn data) { + this.meta = meta; + this.data = data; + } + } // class Column + + /** Fetch meta and data columns for analysis periods. */ + protected Column [][] getAnalysisColumns(FixingsOverview overview) { + + Column columns [][] = new Column[analysisPeriods.length][]; + + Range range = new Range(from, to); + SectorRangeFilter sectorRangeFilter = + new SectorRangeFilter(qSectorStart, qSectorEnd); + + FixingsColumnFactory fcf = FixingsColumnFactory.getInstance(); + + for (int i = 0; i < columns.length; ++i) { + + // Construct filter for period. + long [] period = analysisPeriods[i]; + + AndFilter filter = new AndFilter(); + + DateRangeFilter dateRangeFilter = + new DateRangeFilter( + new Date(period[0]), + new Date(period[1])); + + filter.add(dateRangeFilter); + filter.add(sectorRangeFilter); + + List metaCols = overview.filter(range, filter); + + ArrayList cols = new ArrayList(metaCols.size()); + + // Only use columns which have data. + for (Fixing.Column meta: metaCols) { + FixingsColumn data = fcf.getColumnData(meta); + if (data != null) { + cols.add(new Column(meta, data)); + } + } + columns[i] = cols.toArray(new Column[cols.size()]); + } + + return columns; } protected static String [] createColumnNames(String [] parameters) {