comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java @ 451:73bc64c4a7b0

Use new logic to calculate "W für ungleichwertige Abfluesse". Not working yet. flys-artifacts/trunk@1946 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Wed, 18 May 2011 17:37:06 +0000
parents c8bb38115290
children 343f248e4c8c
comparison
equal deleted inserted replaced
450:c8bb38115290 451:73bc64c4a7b0
30 import de.intevation.flys.artifacts.model.MainValuesFactory; 30 import de.intevation.flys.artifacts.model.MainValuesFactory;
31 import de.intevation.flys.artifacts.model.WQCKms; 31 import de.intevation.flys.artifacts.model.WQCKms;
32 import de.intevation.flys.artifacts.model.WQDay; 32 import de.intevation.flys.artifacts.model.WQDay;
33 import de.intevation.flys.artifacts.model.WQKms; 33 import de.intevation.flys.artifacts.model.WQKms;
34 import de.intevation.flys.artifacts.model.WstValueTable; 34 import de.intevation.flys.artifacts.model.WstValueTable;
35 import de.intevation.flys.artifacts.model.WstValueTable.QPosition;
35 import de.intevation.flys.artifacts.model.WstValueTableFactory; 36 import de.intevation.flys.artifacts.model.WstValueTableFactory;
36 37
38 import de.intevation.flys.artifacts.math.LinearRemap;
39
40 import gnu.trove.TDoubleArrayList;
37 41
38 /** 42 /**
39 * The default WINFO artifact. 43 * The default WINFO artifact.
40 * 44 *
41 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> 45 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
470 } 474 }
471 475
472 return wqkms; 476 return wqkms;
473 } 477 }
474 478
475
476 /** 479 /**
477 * Returns the data computed by the discharge longitudinal section 480 * Returns the data computed by the discharge longitudinal section
478 * computation. 481 * computation.
479 * 482 *
480 * @return an array of WQKms object - one object for each given Q value. 483 * @return an array of WQKms object - one object for each given Q value.
481 */ 484 */
482 public WQKms[] getDischargeLongitudinalSectionData() { 485 public WQKms [] getDischargeLongitudinalSectionData() {
486
483 logger.debug("WINFOArtifact.getDischargeLongitudinalSectionData"); 487 logger.debug("WINFOArtifact.getDischargeLongitudinalSectionData");
484 488
485 River river = getRiver(); 489 River river = getRiver();
486 if (river == null) { 490 if (river == null) {
487 logger.error("No river selected."); 491 logger.error("No river selected.");
492 return new WQKms[0];
488 } 493 }
489 494
490 WstValueTable wst = WstValueTableFactory.getTable(river); 495 WstValueTable wst = WstValueTableFactory.getTable(river);
491 if (wst == null) { 496 if (wst == null) {
492 logger.error("No Wst found for selected river."); 497 logger.error("No wst found for selected river.");
493 } 498 return new WQKms[0];
494 499 }
495 double[][] dist = getSplittedDistance(); 500
496 int num = dist != null ? dist.length : 0; 501 double [][] segments = getSplittedDistance();
497 502
498 double[][] allQs = new double[num][]; 503 if (segments.length < 1) {
499 double[][] allWs = new double[num][]; 504 logger.warn("no segments given");
500 WQKms[][] wqkms = new WQKms[num][]; 505 return new WQKms[0];
501 506 }
502 boolean qSel = true; 507
503 508 if (segments.length == 1) {
504 for (int i = 0; i < num; i++) { 509 // fall back to normal "Wasserstand/Wasserspiegellage" calculation
505 double[] kms = getKms(dist[i]); 510 double [] qs = toQs(segments[0]);
506 if (kms == null) { 511 if (qs == null) {
507 // XXX maybe we should cancel this operation here. 512 logger.warn("no qs given");
513 return new WQKms[0];
514 }
515 if (qs.length == 1) {
516 double [] kms = getKms(segments[0]);
517 return computeWaterlevelData(kms, qs, wst);
518 }
519 }
520
521 // more than one segment
522
523 double [] boundKms;
524
525 if (segments.length == 2) {
526 boundKms = new double [] { segments[0][0], segments[1][1] };
527 }
528 else {
529 TDoubleArrayList bounds = new TDoubleArrayList();
530
531 bounds.add(segments[0][0]);
532
533 for (int i = 1; i < segments.length-1; ++i) {
534 double [] segment = segments[i];
535
536 Gauge gauge = river.determineGauge(segment[0], segment[1]);
537
538 if (gauge == null) {
539 logger.warn("no gauge found between " +
540 segment[0] + " and " + segment[1]);
541 bounds.add(0.5*(segment[0] + segment[1]));
542 }
543 else {
544 bounds.add(gauge.getStation().doubleValue());
545 }
546 }
547
548 bounds.add(segments[segments.length-1][1]);
549 boundKms = bounds.toNativeArray();
550 }
551
552 if (logger.isDebugEnabled()) {
553 logger.debug("bound kms: " + joinDoubles(boundKms));
554 }
555
556 double [][] iqs = null;
557
558 for (int i = 0; i < segments.length; ++i) {
559 double [] iqsi = toQs(segments[i]);
560 if (iqsi == null) {
561 logger.warn("iqsi == null");
562 return new WQKms[0];
563 }
564
565 if (iqs == null) {
566 iqs = new double[iqsi.length][boundKms.length];
567 }
568 else if (iqs.length != iqsi.length) {
569 logger.warn("iqsi.logger != iqs.length: "
570 + iqsi.length + " " + iqsi.length);
571 return new WQKms[0];
572 }
573
574 if (logger.isDebugEnabled()) {
575 logger.debug("segments qs[ " + i + "]: " + joinDoubles(iqsi));
576 }
577
578 for (int j = 0; j < iqs.length; ++j) {
579 iqs[j][i] = iqsi[j];
580 }
581 }
582
583 if (logger.isDebugEnabled()) {
584 for (int i = 0; i < iqs.length; ++i) {
585 logger.debug("iqs[" + i + "]: " + joinDoubles(iqs[i]));
586 }
587 }
588
589 double [] boundWs = new double[boundKms.length];
590 double [] boundQs = new double[boundKms.length];
591
592 // XXX: Is there some state missing?
593
594 double [] okms = getExplodedValues(
595 boundKms[0], boundKms[boundKms.length-1], DEFAULT_KM_STEPS);
596
597 ArrayList<WQKms> results = new ArrayList<WQKms>();
598
599 for (int i = 0; i < iqs.length; ++i) {
600 double [] iqsi = iqs[i];
601
602 QPosition qPosition = wst.interpolate(
603 iqsi[0], 0, boundKms, boundWs, boundQs);
604
605 if (qPosition == null) {
606 logger.warn("interpolation failed for " + iqsi[i]);
508 continue; 607 continue;
509 } 608 }
510 609
511 double[] qs = getQs(dist[i]); 610 LinearRemap remap = new LinearRemap();
512 allQs[i] = qs; 611
513 612 for (int j = 1; j < boundKms.length; ++j) {
514 if (qs == null) { 613 remap.add(
515 logger.debug("Determine Q values based on a set of W values."); 614 boundKms[j-1], boundKms[j],
516 qSel = false; 615 boundQs[j-1], iqsi[j-1],
517 616 boundQs[j], iqsi[j]);
518 allWs[i] = getWs(dist[i]); 617 }
519 qs = getQsForWs(allWs[i]); 618
520 } 619 double [] oqs = new double[okms.length];
521 620 double [] ows = new double[okms.length];
522 wqkms[i] = computeWaterlevelData(kms, qs, wst); 621
523 } 622 wst.interpolate(okms, ows, oqs, qPosition, remap);
524 623
525 WQKms[] merged = WQKms.merge(wqkms); 624 BackJumpCorrector bjc = new BackJumpCorrector();
526 int numMerged = merged.length; 625 if (bjc.doCorrection(okms, ows)) {
527 WQKms[] computed = new WQKms[numMerged]; 626 logger.debug("Discharge longitudinal section has backjumps.");
528 627 results.add(new WQCKms(okms, oqs, ows, bjc.getCorrected()));
529 for (int i = 0; i < numMerged; i++) { 628 }
530 computed[i] = computeDischargeLongitudinalSectionData(merged[i]); 629 else {
531 630 results.add(new WQKms(okms, oqs, ows));
532 setDischargeLongitudinalSectionNames( 631 }
533 computed[i], 632 }
534 qSel ? allQs : allWs, 633 // TODO: set names
535 i, 634
536 qSel ? "Q" : "W"); 635 return results.toArray(new WQKms[results.size()]);
537 } 636 }
538 637
539 // TODO Introduce a caching mechanism here! 638 protected static String joinDoubles(double [] x) {
540 639 if (x == null) {
541 return computed; 640 return "null";
641 }
642 StringBuilder sb = new StringBuilder();
643 for (int i = 0; i < x.length; ++i) {
644 if (i > 0) sb.append(", ");
645 sb.append(x[i]);
646 }
647 return sb.toString();
648 }
649
650 protected double [] toQs(double [] range) {
651 double [] qs = getQs(range);
652 if (qs == null) {
653 logger.debug("Determine Q values based on a set of W values.");
654 double [] ws = getWs(range);
655 qs = getQsForWs(ws);
656 }
657 return qs;
542 } 658 }
543 659
544 660
545 /** 661 /**
546 * Sets the name for discharge longitudinal section curves where each WQKms 662 * Sets the name for discharge longitudinal section curves where each WQKms

http://dive4elements.wald.intevation.org