Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java @ 4255:670e98f5a441
Fixed leak while merging facets.
The ThemeList that is used by OutputHelper to sort the
Facets for an Output now uses a list to store the ManagedFacets.
The correct order is made up by sorting the List using
Collections.sort() function of the Java JDK. Therfore, the
ManagedFacet class implements the Comparable interface. The
return value of its compareTo(other) method depends on the
value of the 'position' field.
author | Ingo Weinzierl <weinzierl.ingo@googlemail.com> |
---|---|
date | Thu, 25 Oct 2012 14:01:46 +0200 |
parents | a16837d73130 |
children |
line wrap: on
line source
package de.intevation.flys.artifacts.model.fixings; import de.intevation.flys.artifacts.access.FixAnalysisAccess; import de.intevation.flys.artifacts.math.fitting.Function; import de.intevation.flys.artifacts.model.CalculationResult; import de.intevation.flys.artifacts.model.DateRange; import de.intevation.flys.artifacts.model.FixingsOverview.AndFilter; import de.intevation.flys.artifacts.model.FixingsOverview.DateRangeFilter; import de.intevation.flys.artifacts.model.FixingsOverview.Fixing.Filter; import de.intevation.flys.artifacts.model.FixingsOverview.Fixing; import de.intevation.flys.artifacts.model.FixingsOverview.IdsFilter; import de.intevation.flys.artifacts.model.FixingsOverview.KmFilter; import de.intevation.flys.artifacts.model.FixingsOverview.SectorFilter; import de.intevation.flys.artifacts.model.FixingsOverview; import de.intevation.flys.artifacts.model.Parameters; import de.intevation.flys.artifacts.model.Range; import de.intevation.flys.utils.DateAverager; import de.intevation.flys.utils.KMIndex; import gnu.trove.TIntIntHashMap; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.commons.math.stat.descriptive.moment.StandardDeviation; import org.apache.log4j.Logger; public class FixAnalysisCalculation extends FixCalculation { private static Logger log = Logger.getLogger(FixAnalysisCalculation.class); protected DateRange referencePeriod; protected DateRange [] analysisPeriods; public FixAnalysisCalculation() { } public FixAnalysisCalculation(FixAnalysisAccess access) { super(access); DateRange referencePeriod = access.getReferencePeriod(); DateRange [] analysisPeriods = access.getAnalysisPeriods(); if (referencePeriod == null) { addProblem("fix.missing.reference.period"); } if (analysisPeriods == null || analysisPeriods.length < 1) { addProblem("fix.missing.analysis.periods"); } if (!hasProblems()) { this.referencePeriod = referencePeriod; this.analysisPeriods = analysisPeriods; } } @Override public CalculationResult innerCalculate( FixingsOverview overview, Function func ) { ColumnCache cc = new ColumnCache(); FitResult fitResult = doFitting(overview, cc, func); if (fitResult == null) { return new CalculationResult(this); } KMIndex<AnalysisPeriod []> analysisPeriods = calculateAnalysisPeriods( func, fitResult.getParameters(), overview, cc); analysisPeriods.sort(); FixAnalysisResult far = new FixAnalysisResult( fitResult.getParameters(), fitResult.getReferenced(), fitResult.getOutliers(), analysisPeriods); return new CalculationResult(far, this); } @Override protected Filter createFilter() { Filter ids = super.createFilter(); DateRangeFilter rdf = new DateRangeFilter( referencePeriod.getFrom(), referencePeriod.getTo()); return new AndFilter().add(rdf).add(ids); } protected KMIndex<AnalysisPeriod []> calculateAnalysisPeriods( Function function, Parameters parameters, FixingsOverview overview, ColumnCache cc ) { Range range = new Range(from, to); int kmIndex = parameters.columnIndex("km"); int maxQIndex = parameters.columnIndex("max_q"); double [] wq = new double[2]; int [] parameterIndices = parameters.columnIndices(function.getParameterNames()); double [] parameterValues = new double[parameterIndices.length]; DateAverager dateAverager = new DateAverager(); KMIndex<AnalysisPeriod []> results = new KMIndex<AnalysisPeriod []>(parameters.size()); IdsFilter idsFilter = new IdsFilter(events); TIntIntHashMap [] col2indices = new TIntIntHashMap[analysisPeriods.length]; for (int i = 0; i < analysisPeriods.length; ++i) { col2indices[i] = new TIntIntHashMap(); } for (int row = 0, R = parameters.size(); row < R; ++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); ArrayList<AnalysisPeriod> periodResults = new ArrayList<AnalysisPeriod>(analysisPeriods.length); for (int ap = 0; ap < analysisPeriods.length; ++ap) { DateRange analysisPeriod = analysisPeriods[ap]; TIntIntHashMap col2index = col2indices[ap]; DateRangeFilter drf = new DateRangeFilter( analysisPeriod.getFrom(), analysisPeriod.getTo()); QWD [] qSectorAverages = new QWD[4]; double [] qSectorStdDevs = new double[4]; ArrayList<QWD> allQWDs = new ArrayList<QWD>(); // for all Q sectors. for (int qSector = qSectorStart; qSector < qSectorEnd; ++qSector) { Filter filter = new AndFilter() .add(kmFilter) .add(new SectorFilter(qSector)) .add(drf) .add(idsFilter); 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; StandardDeviation stdDev = new StandardDeviation(); 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.getQW(km, wq)) { continue; } double fw = instance.value(wq[1]); if (Double.isNaN(fw)) { continue; } double dw = (wq[0] - fw)*100.0; stdDev.increment(dw); Date date = column.getDate(); String description = column.getDescription(); QWD qwd = new QWD( wq[1], wq[0], description, date, true, dw, getIndex(col2index, column.getIndex())); qwds.add(qwd); sumW += wq[0]; sumQ += wq[1]; dateAverager.add(date); } // Calulate average per Q sector. int N = qwds.size(); if (N > 0) { allQWDs.addAll(qwds); 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, avgDescription, avgDate, true, avgDw, 0); qSectorAverages[qSector] = avgQWD; } qSectorStdDevs[qSector] = stdDev.getResult(); } else { qSectorStdDevs[qSector] = Double.NaN; } } // for all Q sectors QWD [] aqwds = allQWDs.toArray(new QWD[allQWDs.size()]); AnalysisPeriod periodResult = new AnalysisPeriod( analysisPeriod, aqwds, qSectorAverages, qSectorStdDevs); periodResults.add(periodResult); } double maxQ = -Double.MAX_VALUE; for (AnalysisPeriod ap: periodResults) { double q = ap.getMaxQ(); if (q > maxQ) { maxQ = q; } } double oldMaxQ = parameters.get(row, maxQIndex); if (oldMaxQ < maxQ) { parameters.set(row, maxQIndex, maxQ); } results.add(km, periodResults.toArray( new AnalysisPeriod[periodResults.size()])); } return results; } private static final int getIndex(TIntIntHashMap map, int colIdx) { if (map.containsKey(colIdx)) { return map.get(colIdx); } int index = map.size(); map.put(colIdx, index); return index; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :