Mercurial > dive4elements > river
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 : |