Mercurial > dive4elements > river
diff flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixCalculation.java @ 2744:c1f2e792704a
FixA: Calculate Delta W/t, too.
flys-artifacts/trunk@4479 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Wed, 23 May 2012 18:27:45 +0000 |
parents | a441be7f1589 |
children | cbb513a8f548 |
line wrap: on
line diff
--- 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<DeltaWT> deltaWTs = calculateDeltaWTs( + func, + overview, + results); + + // TODO: Add km indexed structure for deltaWTs + + return new CalculationResult(deltaWTs, this); + } + + public List<DeltaWT> calculateDeltaWTs( + Function function, + FixingsOverview overview, + Parameters results + ) { + List<DeltaWT> deltaWTs = new ArrayList<DeltaWT>(); + + 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<Fixing.Column> metaCols = overview.filter(range, filter); + + ArrayList<Column> cols = new ArrayList<Column>(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) {