Mercurial > dive4elements > river
comparison flys-artifacts/src/main/java/org/dive4elements/river/artifacts/model/fixings/FixAnalysisCalculation.java @ 5831:bd047b71ab37
Repaired internal references
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Thu, 25 Apr 2013 12:06:39 +0200 |
parents | flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/fixings/FixAnalysisCalculation.java@a16837d73130 |
children |
comparison
equal
deleted
inserted
replaced
5830:160f53ee0870 | 5831:bd047b71ab37 |
---|---|
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 : |