comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation4.java @ 3468:f37e7e8907cb

merged flys-artifacts/2.8.1
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:39 +0200
parents 22790758b132
children 39885bdfc6fc
comparison
equal deleted inserted replaced
3387:5ffad8bde8ad 3468:f37e7e8907cb
1 package de.intevation.flys.artifacts.model;
2
3 import de.intevation.flys.artifacts.math.BackJumpCorrector;
4 import de.intevation.flys.artifacts.math.Function;
5 import de.intevation.flys.artifacts.math.Identity;
6 import de.intevation.flys.artifacts.math.Linear;
7
8 import de.intevation.flys.artifacts.model.WstValueTable.QPosition;
9
10 import de.intevation.flys.model.River;
11
12 import de.intevation.flys.utils.DoubleUtil;
13
14 import java.util.Arrays;
15 import java.util.List;
16
17 import org.apache.log4j.Logger;
18
19 public class Calculation4
20 extends Calculation
21 {
22 private static Logger logger = Logger.getLogger(Calculation4.class);
23
24 public static final double MINIMAL_STEP_WIDTH = 1e-5;
25
26 protected List<Segment> segments;
27
28 protected boolean isQ;
29
30 public Calculation4() {
31 }
32
33 public Calculation4(List<Segment> segments, River river, boolean isQ) {
34
35 this.segments = segments;
36 this.isQ = isQ;
37
38 Segment.setReferencePointConvertQ(segments, river, isQ, this);
39 }
40
41 public CalculationResult calculate(
42 WstValueTable table,
43 double from, double to, double step
44 ) {
45 boolean debug = logger.isDebugEnabled();
46
47 if (debug) {
48 logger.debug(
49 "calculate from " + from + " to " + to + " step " + step);
50 logger.debug("# segments: " + segments.size());
51 for (Segment segment: segments) {
52 logger.debug(" " + segment);
53 }
54 }
55
56 if (segments.isEmpty()) {
57 logger.debug("no segments found");
58 addProblem("no.segments.found");
59 return new CalculationResult(new WQKms[0], this);
60 }
61
62 int numResults = segments.get(0).values.length;
63
64 if (numResults < 1) {
65 logger.debug("no values given");
66 addProblem("no.values.given");
67 return new CalculationResult(new WQKms[0], this);
68 }
69
70
71 WQKms [] results = new WQKms[numResults];
72 for (int i = 0; i < results.length; ++i) {
73 results[i] = new WQKms();
74 }
75
76 if (Math.abs(step) < MINIMAL_STEP_WIDTH) {
77 step = MINIMAL_STEP_WIDTH;
78 }
79
80 if (from > to) {
81 step = -step;
82 }
83
84 QPosition [] qPositions = new QPosition[numResults];
85
86 Function [] functions = new Function[numResults];
87
88 double [] out = new double[2];
89
90 Segment sentinel = new Segment(Double.MAX_VALUE);
91 Segment s1 = sentinel, s2 = sentinel;
92
93 for (double pos = from;
94 from < to ? pos <= to : pos >= to;
95 pos = DoubleUtil.round(pos + step)
96 ) {
97 if (pos < s1.referencePoint || pos > s2.referencePoint) {
98 if (debug) {
99 logger.debug("need to find new interval for " + pos);
100 }
101 // find new interval
102 if (pos <= segments.get(0).referencePoint) {
103 // before first segment -> "gleichwertig"
104 if (debug) {
105 logger.debug("before first segment -> gleichwertig");
106 }
107 Segment first = segments.get(0);
108 double [] values = first.values;
109 double refPos = first.referencePoint;
110 for (int i = 0; i < qPositions.length; ++i) {
111 qPositions[i] = table.getQPosition(
112 refPos, values[i]);
113 }
114 sentinel.setReferencePoint(-Double.MAX_VALUE);
115 s1 = sentinel;
116 s2 = segments.get(0);
117 Arrays.fill(functions, Identity.IDENTITY);
118 }
119 else if (pos >= segments.get(segments.size()-1).referencePoint) {
120 // after last segment -> "gleichwertig"
121 if (debug) {
122 logger.debug("after last segment -> gleichwertig");
123 }
124 Segment last = segments.get(segments.size()-1);
125 double [] values = last.values;
126 double refPos = last.referencePoint;
127 for (int i = 0; i < qPositions.length; ++i) {
128 qPositions[i] = table.getQPosition(
129 refPos, values[i]);
130 }
131 sentinel.setReferencePoint(Double.MAX_VALUE);
132 s1 = last;
133 s2 = sentinel;
134 Arrays.fill(functions, Identity.IDENTITY);
135 }
136 else { // "ungleichwertig"
137 // find matching interval
138 if (debug) {
139 logger.debug("in segments -> ungleichwertig");
140 }
141 s1 = s2 = null;
142 for (int i = 1, N = segments.size(); i < N; ++i) {
143 Segment si1 = segments.get(i-1);
144 Segment si = segments.get(i);
145 if (debug) {
146 logger.debug("check " + pos + " in " +
147 si1.referencePoint + " - " + si.referencePoint);
148 }
149 if (pos >= si1.referencePoint
150 && pos <= si. referencePoint) {
151 s1 = si1;
152 s2 = si;
153 break;
154 }
155 }
156
157 if (s1 == null) {
158 throw new IllegalStateException("no interval found");
159 }
160
161 Segment anchor, free;
162
163 if (from > to) { anchor = s1; free = s2; }
164 else { anchor = s2; free = s1; }
165
166 // build transforms based on "gleichwertiger" phase
167 for (int i = 0; i < qPositions.length; ++i) {
168 QPosition qi = table.getQPosition(
169 anchor.referencePoint,
170 anchor.values[i]);
171
172 if ((qPositions[i] = qi) == null) {
173 addProblem(pos, "cannot.find.q", anchor.values[i]);
174 functions[i] = Identity.IDENTITY;
175 }
176 else {
177 double qA = table.getQ(qi, anchor.referencePoint);
178 double qF = table.getQ(qi, free .referencePoint);
179
180 functions[i] = Double.isNaN(qA) || Double.isNaN(qF)
181 ? Identity.IDENTITY
182 : new Linear(
183 qA, qF,
184 anchor.values[i], free.values[i]);
185
186 if (debug) {
187 logger.debug(
188 anchor.referencePoint + ": " +
189 qA + " -> " + functions[i].value(qA) +
190 " / " + free.referencePoint + ": " +
191 qF + " -> " + functions[i].value(qF));
192 }
193 }
194 } // build transforms
195 } // "ungleichwertiges" interval
196 } // find matching interval
197
198 for (int i = 0; i < qPositions.length; ++i) {
199 QPosition qPosition = qPositions[i];
200
201 if (qPosition == null) {
202 continue;
203 }
204
205 if (table.interpolate(pos, out, qPosition, functions[i])) {
206 results[i].add(out[0], out[1], pos);
207 }
208 else {
209 addProblem(pos, "cannot.interpolate.w.q");
210 }
211 }
212 }
213
214 // Backjump correction
215 for (int i = 0; i < results.length; ++i) {
216 BackJumpCorrector bjc = new BackJumpCorrector();
217
218 double [] ws = results[i].getWs();
219 double [] kms = results[i].getKms();
220
221 if (bjc.doCorrection(kms, ws, this)) {
222 results[i] = new WQCKms(results[i], bjc.getCorrected());
223 }
224 }
225
226 // name the curves
227 for (int i = 0; i < results.length; ++i) {
228 results[i].setName(createName(i));
229 }
230
231 return new CalculationResult(results, this);
232 }
233
234 protected String createName(int index) {
235 // TODO: i18n
236 StringBuilder sb = new StringBuilder(isQ ? "Q" : "W");
237 sb.append(" benutzerdefiniert (");
238 for (int i = 0, N = segments.size(); i < N; ++i) {
239 if (i > 0) {
240 sb.append("; ");
241 }
242 Segment segment = segments.get(i);
243 sb.append((segment.backup != null
244 ? segment.backup
245 : segment.values)[index]);
246 }
247 sb.append(')');
248 return sb.toString();
249 }
250 }
251 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org