comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java @ 686:3dc61e00385e facets-slt

Merged with trunk and introduced hashing of computed values. flys-artifacts/branches/facets-slt@2126 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 15 Jun 2011 15:28:54 +0000
parents fdc898a134a7
children 06689035024c
comparison
equal deleted inserted replaced
667:434146596838 686:3dc61e00385e
1 package de.intevation.flys.artifacts; 1 package de.intevation.flys.artifacts;
2 2
3 import java.util.List; 3 import java.util.List;
4 import java.util.Set;
5 import java.util.HashSet;
6 import java.util.ArrayList;
7 4
8 import org.w3c.dom.Document; 5 import org.w3c.dom.Document;
9 import org.w3c.dom.Element; 6 import org.w3c.dom.Element;
10 import org.w3c.dom.Node; 7 import org.w3c.dom.Node;
11 8
23 import de.intevation.artifacts.common.utils.XMLUtils; 20 import de.intevation.artifacts.common.utils.XMLUtils;
24 21
25 import de.intevation.flys.model.Gauge; 22 import de.intevation.flys.model.Gauge;
26 import de.intevation.flys.model.River; 23 import de.intevation.flys.model.River;
27 24
25 import de.intevation.flys.artifacts.states.CalculationSelect;
28 import de.intevation.flys.artifacts.states.DefaultState; 26 import de.intevation.flys.artifacts.states.DefaultState;
29 import de.intevation.flys.artifacts.context.FLYSContext; 27 import de.intevation.flys.artifacts.context.FLYSContext;
30 28
29 import de.intevation.flys.artifacts.model.ComputeCallback;
31 import de.intevation.flys.artifacts.model.MainValuesFactory; 30 import de.intevation.flys.artifacts.model.MainValuesFactory;
32 import de.intevation.flys.artifacts.model.WQDay; 31 import de.intevation.flys.artifacts.model.WQDay;
33 import de.intevation.flys.artifacts.model.WQKms; 32 import de.intevation.flys.artifacts.model.WQKms;
34 import de.intevation.flys.artifacts.model.WstValueTable; 33 import de.intevation.flys.artifacts.model.WstValueTable;
35 import de.intevation.flys.artifacts.model.WstValueTable.QPosition;
36 import de.intevation.flys.artifacts.model.WstValueTableFactory; 34 import de.intevation.flys.artifacts.model.WstValueTableFactory;
35 import de.intevation.flys.artifacts.model.Calculation1;
36 import de.intevation.flys.artifacts.model.Calculation2;
37 import de.intevation.flys.artifacts.model.Calculation3;
37 import de.intevation.flys.artifacts.model.Calculation4; 38 import de.intevation.flys.artifacts.model.Calculation4;
38 import de.intevation.flys.artifacts.model.Segment; 39 import de.intevation.flys.artifacts.model.Segment;
39 40
40 import gnu.trove.TDoubleArrayList; 41 import gnu.trove.TDoubleArrayList;
41 42
239 240
240 // 241 //
241 // METHODS FOR RETRIEVING COMPUTED DATA FOR DIFFERENT CHART TYPES 242 // METHODS FOR RETRIEVING COMPUTED DATA FOR DIFFERENT CHART TYPES
242 // 243 //
243 244
245
246 public Object compute() {
247 return compute(hash());
248 }
249
250
251 public Object compute(String hash) {
252 String calc = (String) getData(CalculationSelect.FIELD_MODE).getValue();
253
254 ComputeCallback callback = null;
255
256 if (calc.equals(CalculationSelect.CALCULATION_SURFACE_CURVE)) {
257 callback = createSurfaceCurveCallback();
258 }
259 else if (calc.equals(CalculationSelect.CALCULATION_DURATION_CURVE)) {
260 callback = createDurationCurveCallback();
261 }
262 else if (
263 calc.equals(
264 CalculationSelect.CALCULATION_DISCHARGE_LONGITUDINAL_CURVE))
265 {
266 callback = createDischargeLongitudinalCurveCallback();
267 }
268 else if (calc.equals(CalculationSelect.CALCULATION_DISCHARGE_CURVE)) {
269 callback = createDischargeCurveCallback();
270 }
271 else {
272 return null;
273 }
274
275 return compute(hash, callback);
276 }
277
278
279 protected ComputeCallback createSurfaceCurveCallback() {
280 return new ComputeCallback() {
281 public Object compute() {
282 return getWaterlevelData();
283 }
284 };
285 }
286
287
288 protected ComputeCallback createDurationCurveCallback() {
289 return new ComputeCallback() {
290 public Object compute() {
291 return getDurationCurveData();
292 }
293 };
294 }
295
296
297 protected ComputeCallback createDischargeLongitudinalCurveCallback() {
298 return new ComputeCallback() {
299 public Object compute() {
300 return getDischargeLongitudinalSectionData();
301 }
302 };
303 }
304
305
306 protected ComputeCallback createDischargeCurveCallback() {
307 return new ComputeCallback() {
308 public Object compute() {
309 return getComputedDischargeCurveData();
310 }
311 };
312 }
313
314
244 /** 315 /**
245 * Returns the data that is computed by a waterlevel computation. 316 * Returns the data that is computed by a waterlevel computation.
246 * 317 *
247 * @return an array of data triples that consist of W, Q and Kms. 318 * @return an array of data triples that consist of W, Q and Kms.
248 */ 319 */
275 WstValueTable wst = WstValueTableFactory.getTable(river); 346 WstValueTable wst = WstValueTableFactory.getTable(river);
276 if (wst == null) { 347 if (wst == null) {
277 throw new NullPointerException("No Wst found for selected river."); 348 throw new NullPointerException("No Wst found for selected river.");
278 } 349 }
279 350
280 HashSet<Integer> failed = new HashSet<Integer>();
281
282 WQKms[] results = computeWaterlevelData( 351 WQKms[] results = computeWaterlevelData(
283 kms, qs, wst, river.getKmUp(), failed); 352 kms, qs, ws, wst, river.getKmUp());
284
285 // TODO Introduce a caching mechanism here!
286
287 setWaterlevelNames(
288 results, qSel ? qs : ws, qSel ? "Q" : "W", failed);
289 353
290 return results; 354 return results;
291 } 355 }
292
293
294 /**
295 * Sets the name for waterlevels where each WQKms in <i>r</i> represents a
296 * column.
297 *
298 * @param r The waterlevel columns.
299 * @param v The input values of the computations.
300 * @param wq The WQ mode - can be one of "W" or "Q".
301 */
302 public static void setWaterlevelNames(
303 WQKms[] r,
304 double[] v,
305 String wq,
306 Set failed
307 ) {
308 int pos = 0;
309 for (int i = 0; i < v.length; i++) {
310 if (!failed.contains(i)) {
311 r[pos++].setName(wq + "=" + v[i]);
312 }
313 }
314 }
315
316 356
317 /** 357 /**
318 * Computes the data of a waterlevel computation based on the interpolation 358 * Computes the data of a waterlevel computation based on the interpolation
319 * in WstValueTable. 359 * in WstValueTable.
320 * 360 *
323 * @param wst The WstValueTable used for the interpolation. 363 * @param wst The WstValueTable used for the interpolation.
324 * 364 *
325 * @return an array of data triples that consist of W, Q and Kms. 365 * @return an array of data triples that consist of W, Q and Kms.
326 */ 366 */
327 public static WQKms[] computeWaterlevelData( 367 public static WQKms[] computeWaterlevelData(
328 double[] kms, 368 double [] kms,
329 double[] qs, 369 double [] qs,
370 double [] ws,
330 WstValueTable wst, 371 WstValueTable wst,
331 boolean up, 372 boolean up
332 Set<Integer> failed
333 ) { 373 ) {
334 logger.info("WINFOArtifact.computeWaterlevelData"); 374 logger.info("WINFOArtifact.computeWaterlevelData");
335 375
336 WQKms[] wqkms = new WQKms[qs.length]; 376 Calculation1 calculation = new Calculation1(kms, qs, ws, up);
337 377
338 ArrayList<WQKms> results = new ArrayList<WQKms>(); 378 WQKms[] wqkms = calculation.calculate(wst);
339 379
340 int referenceIndex = up ? 0 : kms.length-1; 380 return wqkms;
341
342 for (int i = 0; i < qs.length; i++) {
343 double [] oqs = new double[kms.length];
344 double [] ows = new double[kms.length];
345 WstValueTable.QPosition qPosition =
346 wst.interpolate(qs[i], kms[referenceIndex], kms, ows, oqs);
347 if (qPosition != null) {
348 results.add(new WQKms(kms, oqs, ows));
349 }
350 else {
351 logger.warn("interpolation failed for q = " + qs[i]);
352 failed.add(i);
353 }
354 }
355
356 return results.toArray(new WQKms[results.size()]);
357 } 381 }
358 382
359 383
360 /** 384 /**
361 * Returns the data that is computed by a duration curve computation. 385 * Returns the data that is computed by a duration curve computation.
387 411
388 WstValueTable wst = WstValueTableFactory.getTable(r); 412 WstValueTable wst = WstValueTableFactory.getTable(r);
389 if (wst == null) { 413 if (wst == null) {
390 throw new NullPointerException("No Wst found for selected river."); 414 throw new NullPointerException("No Wst found for selected river.");
391 } 415 }
392
393 // TODO Introduce a caching mechanism here!
394 416
395 return computeDurationCurveData(g, wst, locations[0]); 417 return computeDurationCurveData(g, wst, locations[0]);
396 } 418 }
397 419
398 420
414 Object[] obj = MainValuesFactory.getDurationCurveData(gauge); 436 Object[] obj = MainValuesFactory.getDurationCurveData(gauge);
415 437
416 int[] days = (int[]) obj[0]; 438 int[] days = (int[]) obj[0];
417 double[] qs = (double[]) obj[1]; 439 double[] qs = (double[]) obj[1];
418 440
419 double[] interpolatedW = new double[qs.length]; 441 Calculation3 calculation = new Calculation3(location, days, qs);
420 interpolatedW = wst.interpolateW(location, qs, interpolatedW); 442
421 443 // TODO: report the errors to the user.
422 WQDay wqday = new WQDay(qs.length); 444 return calculation.calculate(wst);
423
424 for (int i = 0; i < days.length; i++) {
425 wqday.add(days[i], interpolatedW[i], qs[i]);
426 }
427
428 return wqday;
429 } 445 }
430 446
431 447
432 /** 448 /**
433 * Returns the data that is computed by a discharge curve computation. 449 * Returns the data that is computed by a discharge curve computation.
456 throw new NullPointerException("No Wst found for selected river."); 472 throw new NullPointerException("No Wst found for selected river.");
457 } 473 }
458 474
459 WQKms wqkms = computeDischargeCurveData(wst, locations[0]); 475 WQKms wqkms = computeDischargeCurveData(wst, locations[0]);
460 476
461 // TODO Introduce a caching mechanism here!
462
463 setComputedDischargeCurveNames(wqkms, locations[0]);
464
465 return wqkms; 477 return wqkms;
466 }
467
468
469 /**
470 * Sets the name of the computed discharge curve data.
471 *
472 * @param wqkms The computed WQKms object.
473 * @param l The location used for the computation.
474 */
475 public static void setComputedDischargeCurveNames(WQKms wqkms, double l) {
476 wqkms.setName(Double.toString(l));
477 } 478 }
478 479
479 480
480 /** 481 /**
481 * Computes the data used to create computed discharge curves. 482 * Computes the data used to create computed discharge curves.
490 WstValueTable wst, 491 WstValueTable wst,
491 double location) 492 double location)
492 { 493 {
493 logger.info("WINFOArtifact.computeDischargeCurveData"); 494 logger.info("WINFOArtifact.computeDischargeCurveData");
494 495
495 double[][] wqs = wst.interpolateWQ(location); 496 Calculation2 calculation = new Calculation2(location);
496 497
497 if (wqs == null) { 498 WQKms wqkms = calculation.calculate(wst);
498 logger.error("Cannot compute discharge curve data."); 499
499 return null; 500 // TODO: Report errors to the user
500 }
501
502 double[] ws = wqs[0];
503 double[] qs = wqs[1];
504
505 WQKms wqkms = new WQKms(ws.length);
506
507 for (int i = 0; i < ws.length; i++) {
508 wqkms.add(ws[i], qs[i], location);
509 }
510 501
511 return wqkms; 502 return wqkms;
512 } 503 }
513 504
514 private static final double [] getBounds(double [][] segments) { 505 private static final double [] getBounds(double [][] segments) {

http://dive4elements.wald.intevation.org