comparison artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixAnalysisCalculation.java @ 5838:5aa05a7a34b7

Rename modules to more fitting names.
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 15:23:37 +0200
parents flys-artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixAnalysisCalculation.java@bd047b71ab37
children 4897a58c8746
comparison
equal deleted inserted replaced
5837:d9901a08d0a6 5838:5aa05a7a34b7
1 package org.dive4elements.river.artifacts.model.fixings;
2
3 import org.dive4elements.river.artifacts.access.FixAnalysisAccess;
4
5 import org.dive4elements.river.artifacts.math.fitting.Function;
6
7 import org.dive4elements.river.artifacts.model.CalculationResult;
8 import org.dive4elements.river.artifacts.model.DateRange;
9
10 import org.dive4elements.river.artifacts.model.FixingsOverview.AndFilter;
11 import org.dive4elements.river.artifacts.model.FixingsOverview.DateRangeFilter;
12
13 import org.dive4elements.river.artifacts.model.FixingsOverview.Fixing.Filter;
14
15 import org.dive4elements.river.artifacts.model.FixingsOverview.Fixing;
16 import org.dive4elements.river.artifacts.model.FixingsOverview.IdsFilter;
17 import org.dive4elements.river.artifacts.model.FixingsOverview.KmFilter;
18 import org.dive4elements.river.artifacts.model.FixingsOverview.SectorFilter;
19
20 import org.dive4elements.river.artifacts.model.FixingsOverview;
21 import org.dive4elements.river.artifacts.model.Parameters;
22 import org.dive4elements.river.artifacts.model.Range;
23
24 import org.dive4elements.river.utils.DateAverager;
25 import org.dive4elements.river.utils.KMIndex;
26
27 import gnu.trove.TIntIntHashMap;
28
29 import java.util.ArrayList;
30 import java.util.Date;
31 import java.util.List;
32
33 import org.apache.commons.math.stat.descriptive.moment.StandardDeviation;
34
35 import org.apache.log4j.Logger;
36
37 public class FixAnalysisCalculation
38 extends FixCalculation
39 {
40 private static Logger log = Logger.getLogger(FixAnalysisCalculation.class);
41
42 protected DateRange referencePeriod;
43 protected DateRange [] analysisPeriods;
44
45 public FixAnalysisCalculation() {
46 }
47
48 public FixAnalysisCalculation(FixAnalysisAccess access) {
49 super(access);
50
51 DateRange referencePeriod = access.getReferencePeriod();
52 DateRange [] analysisPeriods = access.getAnalysisPeriods();
53
54 if (referencePeriod == null) {
55 addProblem("fix.missing.reference.period");
56 }
57
58 if (analysisPeriods == null || analysisPeriods.length < 1) {
59 addProblem("fix.missing.analysis.periods");
60 }
61
62 if (!hasProblems()) {
63 this.referencePeriod = referencePeriod;
64 this.analysisPeriods = analysisPeriods;
65 }
66 }
67
68 @Override
69 public CalculationResult innerCalculate(
70 FixingsOverview overview,
71 Function func
72 ) {
73 ColumnCache cc = new ColumnCache();
74
75 FitResult fitResult = doFitting(overview, cc, func);
76
77 if (fitResult == null) {
78 return new CalculationResult(this);
79 }
80
81 KMIndex<AnalysisPeriod []> analysisPeriods =
82 calculateAnalysisPeriods(
83 func,
84 fitResult.getParameters(),
85 overview,
86 cc);
87
88 analysisPeriods.sort();
89
90 FixAnalysisResult far = new FixAnalysisResult(
91 fitResult.getParameters(),
92 fitResult.getReferenced(),
93 fitResult.getOutliers(),
94 analysisPeriods);
95
96 return new CalculationResult(far, this);
97 }
98
99 @Override
100 protected Filter createFilter() {
101 Filter ids = super.createFilter();
102 DateRangeFilter rdf = new DateRangeFilter(
103 referencePeriod.getFrom(),
104 referencePeriod.getTo());
105 return new AndFilter().add(rdf).add(ids);
106 }
107
108 protected KMIndex<AnalysisPeriod []> calculateAnalysisPeriods(
109 Function function,
110 Parameters parameters,
111 FixingsOverview overview,
112 ColumnCache cc
113 ) {
114 Range range = new Range(from, to);
115
116 int kmIndex = parameters.columnIndex("km");
117 int maxQIndex = parameters.columnIndex("max_q");
118
119 double [] wq = new double[2];
120
121 int [] parameterIndices =
122 parameters.columnIndices(function.getParameterNames());
123
124 double [] parameterValues = new double[parameterIndices.length];
125
126 DateAverager dateAverager = new DateAverager();
127
128 KMIndex<AnalysisPeriod []> results =
129 new KMIndex<AnalysisPeriod []>(parameters.size());
130
131 IdsFilter idsFilter = new IdsFilter(events);
132
133 TIntIntHashMap [] col2indices =
134 new TIntIntHashMap[analysisPeriods.length];
135
136 for (int i = 0; i < analysisPeriods.length; ++i) {
137 col2indices[i] = new TIntIntHashMap();
138 }
139
140 for (int row = 0, R = parameters.size(); row < R; ++row) {
141 double km = parameters.get(row, kmIndex);
142 parameters.get(row, parameterIndices, parameterValues);
143
144 // This is the paraterized function for a given km.
145 org.dive4elements.river.artifacts.math.Function instance =
146 function.instantiate(parameterValues);
147
148 KmFilter kmFilter = new KmFilter(km);
149
150 ArrayList<AnalysisPeriod> periodResults =
151 new ArrayList<AnalysisPeriod>(analysisPeriods.length);
152
153 for (int ap = 0; ap < analysisPeriods.length; ++ap) {
154 DateRange analysisPeriod = analysisPeriods[ap];
155 TIntIntHashMap col2index = col2indices[ap];
156
157 DateRangeFilter drf = new DateRangeFilter(
158 analysisPeriod.getFrom(),
159 analysisPeriod.getTo());
160
161 QWD [] qSectorAverages = new QWD[4];
162 double [] qSectorStdDevs = new double[4];
163
164 ArrayList<QWD> allQWDs = new ArrayList<QWD>();
165
166 // for all Q sectors.
167 for (int qSector = qSectorStart; qSector < qSectorEnd; ++qSector) {
168
169 Filter filter = new AndFilter()
170 .add(kmFilter)
171 .add(new SectorFilter(qSector))
172 .add(drf)
173 .add(idsFilter);
174
175 List<Fixing.Column> metas = overview.filter(range, filter);
176
177 if (metas.isEmpty()) {
178 // No fixings for km and analysis period
179 continue;
180 }
181
182 double sumQ = 0.0;
183 double sumW = 0.0;
184
185 StandardDeviation stdDev = new StandardDeviation();
186
187 List<QWD> qwds = new ArrayList<QWD>(metas.size());
188
189 dateAverager.clear();
190
191 for (Fixing.Column meta: metas) {
192 if (meta.findQSector(km) != qSector) {
193 // Ignore not matching sectors.
194 continue;
195 }
196
197 Column column = cc.getColumn(meta);
198 if (column == null || !column.getQW(km, wq)) {
199 continue;
200 }
201
202 double fw = instance.value(wq[1]);
203 if (Double.isNaN(fw)) {
204 continue;
205 }
206
207 double dw = (wq[0] - fw)*100.0;
208
209 stdDev.increment(dw);
210
211 Date date = column.getDate();
212 String description = column.getDescription();
213
214 QWD qwd = new QWD(
215 wq[1], wq[0],
216 description,
217 date, true,
218 dw, getIndex(col2index, column.getIndex()));
219
220 qwds.add(qwd);
221
222 sumW += wq[0];
223 sumQ += wq[1];
224
225 dateAverager.add(date);
226 }
227
228 // Calulate average per Q sector.
229 int N = qwds.size();
230 if (N > 0) {
231 allQWDs.addAll(qwds);
232 double avgW = sumW / N;
233 double avgQ = sumQ / N;
234
235 double avgFw = instance.value(avgQ);
236 if (!Double.isNaN(avgFw)) {
237 double avgDw = (avgW - avgFw)*100.0;
238 Date avgDate = dateAverager.getAverage();
239
240 String avgDescription = "avg.deltawt." + qSector;
241
242 QWD avgQWD = new QWD(
243 avgQ, avgW, avgDescription, avgDate, true, avgDw, 0);
244
245 qSectorAverages[qSector] = avgQWD;
246 }
247 qSectorStdDevs[qSector] = stdDev.getResult();
248 }
249 else {
250 qSectorStdDevs[qSector] = Double.NaN;
251 }
252 } // for all Q sectors
253
254 QWD [] aqwds = allQWDs.toArray(new QWD[allQWDs.size()]);
255
256 AnalysisPeriod periodResult = new AnalysisPeriod(
257 analysisPeriod,
258 aqwds,
259 qSectorAverages,
260 qSectorStdDevs);
261 periodResults.add(periodResult);
262 }
263
264 double maxQ = -Double.MAX_VALUE;
265 for (AnalysisPeriod ap: periodResults) {
266 double q = ap.getMaxQ();
267 if (q > maxQ) {
268 maxQ = q;
269 }
270 }
271
272 double oldMaxQ = parameters.get(row, maxQIndex);
273 if (oldMaxQ < maxQ) {
274 parameters.set(row, maxQIndex, maxQ);
275 }
276
277 results.add(km, periodResults.toArray(
278 new AnalysisPeriod[periodResults.size()]));
279 }
280
281 return results;
282 }
283
284 private static final int getIndex(TIntIntHashMap map, int colIdx) {
285 if (map.containsKey(colIdx)) {
286 return map.get(colIdx);
287 }
288 int index = map.size();
289 map.put(colIdx, index);
290 return index;
291 }
292 }
293 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org