comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java @ 677:a95f34f1f39a

Added error reporting to 'Abflusskurve' calculation. flys-artifacts/trunk@2101 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 10 Jun 2011 14:24:15 +0000
parents c501f27c1f71
children 19a3185822a4
comparison
equal deleted inserted replaced
676:c501f27c1f71 677:a95f34f1f39a
15 import org.apache.commons.math.analysis.interpolation.SplineInterpolator; 15 import org.apache.commons.math.analysis.interpolation.SplineInterpolator;
16 16
17 import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; 17 import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
18 18
19 import org.apache.commons.math.ArgumentOutsideDomainException; 19 import org.apache.commons.math.ArgumentOutsideDomainException;
20
21 import org.apache.commons.math.exception.MathIllegalArgumentException;
20 22
21 public class WstValueTable 23 public class WstValueTable
22 implements Serializable 24 implements Serializable
23 { 25 {
24 private static Logger log = Logger.getLogger(WstValueTable.class); 26 private static Logger log = Logger.getLogger(WstValueTable.class);
142 144
143 public double [][] interpolateWQ( 145 public double [][] interpolateWQ(
144 Row other, 146 Row other,
145 double km, 147 double km,
146 int steps, 148 int steps,
147 WstValueTable table 149 WstValueTable table,
150 Calculation errors
148 ) { 151 ) {
149 int W = Math.min(ws.length, other.ws.length); 152 int W = Math.min(ws.length, other.ws.length);
150 153
151 if (W < 1) { 154 if (W < 1) {
155 if (errors != null) {
156 // TODO: I18N
157 errors.addProblem("no ws found");
158 }
152 return new double[2][0]; 159 return new double[2][0];
153 } 160 }
154 161
155 double factor = Linear.factor(km, this.km, other.km); 162 double factor = Linear.factor(km, this.km, other.km);
156 163
165 double wqs = Linear.weight( 172 double wqs = Linear.weight(
166 factor, 173 factor,
167 table.getQIndex(i, km), 174 table.getQIndex(i, km),
168 table.getQIndex(i, other.km)); 175 table.getQIndex(i, other.km));
169 176
177 if (Double.isNaN(wws) || Double.isNaN(wqs)) {
178 if (errors != null) {
179 // TODO: I18N
180 errors.addProblem(km, "cannot find w or q");
181 }
182 }
183 else {
184 if (wqs < minQ) minQ = wqs;
185 if (wqs > maxQ) maxQ = wqs;
186 }
187
170 splineW[i] = wws; 188 splineW[i] = wws;
171 splineQ[i] = wqs; 189 splineQ[i] = wqs;
172 if (wqs < minQ) minQ = wqs;
173 if (wqs > maxQ) maxQ = wqs;
174 } 190 }
175 191
176 double stepWidth = (maxQ - minQ)/steps; 192 double stepWidth = (maxQ - minQ)/steps;
177 193
178 SplineInterpolator interpolator = new SplineInterpolator(); 194 SplineInterpolator interpolator = new SplineInterpolator();
179 PolynomialSplineFunction spline = 195 PolynomialSplineFunction spline;
180 interpolator.interpolate(splineQ, splineW); 196
197 try {
198 spline = interpolator.interpolate(splineQ, splineW);
199 }
200 catch (MathIllegalArgumentException miae) {
201 if (errors != null) {
202 // TODO: I18N
203 errors.addProblem(km, "spline creation failed");
204 }
205 log.error("spline creation failed");
206 return new double[2][0];
207 }
181 208
182 double [] outWs = new double[steps]; 209 double [] outWs = new double[steps];
183 double [] outQs = new double[steps]; 210 double [] outQs = new double[steps];
211
212 Arrays.fill(outWs, Double.NaN);
213 Arrays.fill(outQs, Double.NaN);
184 214
185 try { 215 try {
186 double q = minQ; 216 double q = minQ;
187 for (int i = 0; i < outWs.length; ++i, q += stepWidth) { 217 for (int i = 0; i < outWs.length; ++i, q += stepWidth) {
188 outWs[i] = spline.value(outQs[i] = q); 218 outWs[i] = spline.value(outQs[i] = q);
189 } 219 }
190 } 220 }
191 catch (ArgumentOutsideDomainException aode) { 221 catch (ArgumentOutsideDomainException aode) {
192 log.error("Spline interpolation failed.", aode); 222 if (errors != null) {
223 // TODO: I18N
224 errors.addProblem(km, "spline interpolation failed");
225 }
226 log.error("spline interpolation failed", aode);
193 } 227 }
194 228
195 return new double [][] { outWs, outQs }; 229 return new double [][] { outWs, outQs };
196 } 230 }
197 231
198 public double [][] interpolateWQ(int steps, WstValueTable table) { 232 public double [][] interpolateWQ(
199 233 int steps,
234 WstValueTable table,
235 Calculation errors
236 ) {
200 int W = ws.length; 237 int W = ws.length;
201 238
202 if (W < 1) { 239 if (W < 1) {
240 if (errors != null) {
241 // TODO: I18N
242 errors.addProblem(km, "no ws found");
243 }
203 return new double[2][0]; 244 return new double[2][0];
204 } 245 }
205 246
206 double [] splineQ = new double[W]; 247 double [] splineQ = new double[W];
207 248
208 double minQ = Double.MAX_VALUE; 249 double minQ = Double.MAX_VALUE;
209 double maxQ = -Double.MAX_VALUE; 250 double maxQ = -Double.MAX_VALUE;
210 251
211 QPosition qPosition = new QPosition();
212
213 for (int i = 0; i < W; ++i) { 252 for (int i = 0; i < W; ++i) {
214 splineQ[i] = table.getQIndex(i, km); 253 double sq = table.getQIndex(i, km);
215 if (splineQ[i] < minQ) minQ = splineQ[i]; 254 if (Double.isNaN(sq)) {
216 if (splineQ[i] > maxQ) maxQ = splineQ[i]; 255 if (errors != null) {
256 // TODO: I18N
257 errors.addProblem(
258 km, "no q found in " + (i+1) + " column");
259 }
260 }
261 else {
262 if (sq < minQ) minQ = sq;
263 if (sq > maxQ) maxQ = sq;
264 }
265 splineQ[i] = sq;
217 } 266 }
218 267
219 double stepWidth = (maxQ - minQ)/steps; 268 double stepWidth = (maxQ - minQ)/steps;
220 269
221 SplineInterpolator interpolator = new SplineInterpolator(); 270 SplineInterpolator interpolator = new SplineInterpolator();
222 271
223 PolynomialSplineFunction spline = 272 PolynomialSplineFunction spline;
224 interpolator.interpolate(splineQ, ws); 273
274 try {
275 spline = interpolator.interpolate(splineQ, ws);
276 }
277 catch (MathIllegalArgumentException miae) {
278 if (errors != null) {
279 // TODO: I18N
280 errors.addProblem(km, "spline creation failed");
281 }
282 log.error("spline creation failed");
283 return new double[2][0];
284 }
225 285
226 double [] outWs = new double[steps]; 286 double [] outWs = new double[steps];
227 double [] outQs = new double[steps]; 287 double [] outQs = new double[steps];
288
289 Arrays.fill(outWs, Double.NaN);
290 Arrays.fill(outQs, Double.NaN);
228 291
229 try { 292 try {
230 double q = minQ; 293 double q = minQ;
231 for (int i = 0; i < outWs.length; ++i, q += stepWidth) { 294 for (int i = 0; i < outWs.length; ++i, q += stepWidth) {
232 outWs[i] = spline.value(outQs[i] = q); 295 outWs[i] = spline.value(outQs[i] = q);
233 } 296 }
234 } 297 }
235 catch (ArgumentOutsideDomainException aode) { 298 catch (ArgumentOutsideDomainException aode) {
236 log.error("Spline interpolation failed.", aode); 299 if (errors != null) {
300 // TODO: I18N
301 errors.addProblem(km, "spline interpolation failed");
302 }
303 log.error("spline interpolation failed.", aode);
237 } 304 }
238 305
239 return new double [][] { outWs, outQs }; 306 return new double [][] { outWs, outQs };
240 } 307 }
241 308
335 402
336 if (rowIndex < 1 || rowIndex >= rows.size()) { 403 if (rowIndex < 1 || rowIndex >= rows.size()) {
337 // do not extrapolate 404 // do not extrapolate
338 Arrays.fill(ws, Double.NaN); 405 Arrays.fill(ws, Double.NaN);
339 if (errors != null) { 406 if (errors != null) {
407 // TODO: I18N
340 errors.addProblem(km, "km not found"); 408 errors.addProblem(km, "km not found");
341 } 409 }
342 } 410 }
343 else { 411 else {
344 Row r1 = rows.get(rowIndex-1); 412 Row r1 = rows.get(rowIndex-1);
349 417
350 return ws; 418 return ws;
351 } 419 }
352 420
353 public double [][] interpolateWQ(double km) { 421 public double [][] interpolateWQ(double km) {
354 return interpolateWQ(km, DEFAULT_Q_STEPS); 422 return interpolateWQ(km, null);
355 } 423 }
356 424
357 public double [][] interpolateWQ(double km, int steps) { 425 public double [][] interpolateWQ(double km, Calculation errors) {
426 return interpolateWQ(km, DEFAULT_Q_STEPS, errors);
427 }
428
429 public double [][] interpolateWQ(double km, int steps, Calculation errors) {
358 430
359 int rowIndex = Collections.binarySearch(rows, new Row(km)); 431 int rowIndex = Collections.binarySearch(rows, new Row(km));
360 432
361 if (rowIndex >= 0) { // direct row match 433 if (rowIndex >= 0) { // direct row match
362 Row row = rows.get(rowIndex); 434 Row row = rows.get(rowIndex);
363 return row.interpolateWQ(steps, this); 435 return row.interpolateWQ(steps, this, errors);
364 } 436 }
365 437
366 rowIndex = -rowIndex -1; 438 rowIndex = -rowIndex -1;
367 439
368 if (rowIndex < 1 || rowIndex >= rows.size()) { 440 if (rowIndex < 1 || rowIndex >= rows.size()) {
369 // do not extrapolate 441 // do not extrapolate
442 if (errors != null) {
443 // TODO: I18N
444 errors.addProblem(km, "km not found");
445 }
370 return new double[2][0]; 446 return new double[2][0];
371 } 447 }
372 448
373 Row r1 = rows.get(rowIndex-1); 449 Row r1 = rows.get(rowIndex-1);
374 Row r2 = rows.get(rowIndex); 450 Row r2 = rows.get(rowIndex);
375 451
376 return r1.interpolateWQ(r2, km, steps, this); 452 return r1.interpolateWQ(r2, km, steps, this, errors);
377 } 453 }
378 454
379 public boolean interpolate( 455 public boolean interpolate(
380 double km, 456 double km,
381 double [] out, 457 double [] out,

http://dive4elements.wald.intevation.org