comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java @ 655:913b52064449

Refactored version of "Berechnung 4" flys-artifacts/trunk@2053 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sun, 05 Jun 2011 18:24:46 +0000
parents 44175d4720f8
children fdc898a134a7
comparison
equal deleted inserted replaced
654:bbc966c81809 655:913b52064449
26 import de.intevation.flys.model.Gauge; 26 import de.intevation.flys.model.Gauge;
27 import de.intevation.flys.model.River; 27 import de.intevation.flys.model.River;
28 28
29 import de.intevation.flys.artifacts.states.DefaultState; 29 import de.intevation.flys.artifacts.states.DefaultState;
30 import de.intevation.flys.artifacts.context.FLYSContext; 30 import de.intevation.flys.artifacts.context.FLYSContext;
31 import de.intevation.flys.artifacts.math.BackJumpCorrector; 31
32 import de.intevation.flys.artifacts.model.MainValuesFactory; 32 import de.intevation.flys.artifacts.model.MainValuesFactory;
33 import de.intevation.flys.artifacts.model.WQCKms;
34 import de.intevation.flys.artifacts.model.WQDay; 33 import de.intevation.flys.artifacts.model.WQDay;
35 import de.intevation.flys.artifacts.model.WQKms; 34 import de.intevation.flys.artifacts.model.WQKms;
36 import de.intevation.flys.artifacts.model.WstValueTable; 35 import de.intevation.flys.artifacts.model.WstValueTable;
37 import de.intevation.flys.artifacts.model.WstValueTable.QPosition; 36 import de.intevation.flys.artifacts.model.WstValueTable.QPosition;
38 import de.intevation.flys.artifacts.model.WstValueTableFactory; 37 import de.intevation.flys.artifacts.model.WstValueTableFactory;
39 38 import de.intevation.flys.artifacts.model.Calculation4;
40 import de.intevation.flys.artifacts.math.LinearRemap; 39 import de.intevation.flys.artifacts.model.Segment;
41 40
42 import gnu.trove.TDoubleArrayList; 41 import gnu.trove.TDoubleArrayList;
43 42
44 /** 43 /**
45 * The default WINFO artifact. 44 * The default WINFO artifact.
581 if (river == null) { 580 if (river == null) {
582 logger.error("No river selected."); 581 logger.error("No river selected.");
583 return new WQKms[0]; 582 return new WQKms[0];
584 } 583 }
585 584
586 boolean kmUp = river.getKmUp(); 585 WstValueTable table = WstValueTableFactory.getTable(river);
587 586 if (table == null) {
588 WstValueTable wst = WstValueTableFactory.getTable(river);
589 if (wst == null) {
590 logger.error("No wst found for selected river."); 587 logger.error("No wst found for selected river.");
591 return new WQKms[0]; 588 return new WQKms[0];
592 } 589 }
593 590
594 double [][] segments = getRanges(); 591 List<Segment> segments = getSegments();
595 592
596 if (logger.isDebugEnabled()) { 593 if (segments == null) {
597 logger.debug("segments ----------------- enter"); 594 logger.error("Cannot create segments.");
598 for (double [] segment: segments) {
599 logger.debug(" " + joinDoubles(segment));
600 }
601 logger.debug("segments ----------------- leave");
602 }
603
604 if (segments.length < 1) {
605 logger.warn("no segments given");
606 return new WQKms[0]; 595 return new WQKms[0];
607 } 596 }
608 597
609 if (segments.length == 1) { 598 double [] range = getFromToStep();
610 // fall back to normal "Wasserstand/Wasserspiegellage" calculation 599
611 double [] qs = toQs(segments[0]); 600 if (range == null) {
612 if (qs == null) { 601 logger.error("Cannot figure out range.");
613 logger.warn("no qs given"); 602 return new WQKms[0];
614 return new WQKms[0]; 603 }
615 } 604
616 if (qs.length == 1) { 605 Calculation4 calc4 = new Calculation4(segments, river, isQ());
617 double [] kms = getKms(segments[0]); 606
618 HashSet<Integer> failed = new HashSet<Integer>(); 607 WQKms [] results = calc4.calculate(table, range[0], range[1], range[2]);
619 WQKms [] results = computeWaterlevelData 608
620 (kms, qs, wst, kmUp, failed); 609 return results;
621 setWaterlevelNames(
622 results, qs, isQ() ? "Q" : "W", failed);
623 return results;
624 }
625 }
626
627 // more than one segment
628
629 double [] boundKms = extractBoundsKm(river, segments);
630
631
632 if (logger.isDebugEnabled()) {
633 logger.debug("bound kms: " + joinDoubles(boundKms));
634 }
635
636 double [][] iqs = null;
637
638 for (int i = 0; i < segments.length; ++i) {
639 double [] iqsi = toQs(segments[i]);
640 if (iqsi == null) {
641 logger.warn("iqsi == null");
642 return new WQKms[0];
643 }
644
645 if (iqs == null) {
646 iqs = new double[iqsi.length][boundKms.length];
647 }
648 else if (iqs.length != iqsi.length) {
649 logger.warn("iqsi.logger != iqs.length: "
650 + iqsi.length + " " + iqsi.length);
651 return new WQKms[0];
652 }
653
654 if (logger.isDebugEnabled()) {
655 logger.debug("segments qs[ " + i + "]: " + joinDoubles(iqsi));
656 }
657
658 for (int j = 0; j < iqs.length; ++j) {
659 iqs[j][i] = iqsi[j];
660 }
661 }
662
663 if (logger.isDebugEnabled()) {
664 for (int i = 0; i < iqs.length; ++i) {
665 logger.debug("iqs[" + i + "]: " + joinDoubles(iqs[i]));
666 }
667 }
668
669 double [] boundWs = new double[boundKms.length];
670 double [] boundQs = new double[boundKms.length];
671
672 double [] okms = getKms(new double [] {
673 boundKms[0], boundKms[boundKms.length-1] });
674
675 ArrayList<WQKms> results = new ArrayList<WQKms>();
676
677 int referenceIndex = kmUp ? 0 : boundKms.length-1;
678
679 HashSet<Integer> failed = new HashSet<Integer>();
680
681 for (int i = 0; i < iqs.length; ++i) {
682 double [] iqsi = iqs[i];
683
684 QPosition qPosition = wst.interpolate(
685 iqsi[0],
686 boundKms[referenceIndex],
687 boundKms, boundWs, boundQs);
688
689 if (qPosition == null) {
690 logger.warn("interpolation failed for " + iqsi[i]);
691 failed.add(i);
692 continue;
693 }
694
695 LinearRemap remap = new LinearRemap();
696
697 for (int j = 1; j < boundKms.length; ++j) {
698 remap.add(
699 boundKms[j-1], boundKms[j],
700 boundQs[j-1], iqsi[j-1],
701 boundQs[j], iqsi[j]);
702 }
703
704 double [] oqs = new double[okms.length];
705 double [] ows = new double[okms.length];
706
707 wst.interpolate(okms, ows, oqs, qPosition, remap);
708
709 BackJumpCorrector bjc = new BackJumpCorrector();
710 if (bjc.doCorrection(okms, ows)) {
711 logger.debug("Discharge longitudinal section has backjumps.");
712 results.add(new WQCKms(okms, oqs, ows, bjc.getCorrected()));
713 }
714 else {
715 results.add(new WQKms(okms, oqs, ows));
716 }
717 }
718
719 WQKms [] wqkms = results.toArray(new WQKms[results.size()]);
720
721 setDischargeLongitudinalSectionNames(
722 wqkms, iqs, isQ() ? "Q" : "W", failed);
723
724 return wqkms;
725 }
726
727 protected static String joinDoubles(double [] x) {
728 if (x == null) {
729 return "";
730 }
731 StringBuilder sb = new StringBuilder();
732 for (int i = 0; i < x.length; ++i) {
733 if (i > 0) sb.append(", ");
734 sb.append(x[i]);
735 }
736 return sb.toString();
737 }
738
739 protected double [] toQs(double [] range) {
740 double [] qs = getQs(range);
741 if (qs == null) {
742 logger.debug("Determine Q values based on a set of W values.");
743 double [] ws = getWs(range);
744 qs = getQsForWs(ws);
745 }
746 return qs;
747 }
748
749
750 /**
751 * Sets the name for discharge longitudinal section curves where each WQKms
752 * in <i>r</i> represents a column.
753 */
754 public static void setDischargeLongitudinalSectionNames(
755 WQKms [] wqkms,
756 double [][] iqs,
757 String wq,
758 Set<Integer> failed
759 ) {
760 logger.debug("WINFOArtifact.setDischargeLongitudinalSectionNames");
761
762 // TODO: I18N
763
764 int pos = 0;
765
766 for (int j = 0; j < iqs.length; ++j) {
767 if (failed.contains(j)) {
768 continue;
769 }
770 StringBuilder sb = new StringBuilder(wq)
771 .append(" benutzerdefiniert (");
772
773 double [] iqsi = iqs[j];
774 for (int i = 0; i < iqsi.length; i++) {
775 if (i > 0) {
776 sb.append("; ");
777 }
778 sb.append(iqsi[i]);
779 }
780 sb.append(")");
781
782 wqkms[pos++].setName(sb.toString());
783 }
784 } 610 }
785 } 611 }
786 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : 612 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org