Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/common/GaugeDurationValuesFinder.java @ 9358:8eddc2393750
Fixed: S-Info flood duration Q-D interpolation for non monotonous Q values, NaN instead of -1 in error cases
author | mschaefer |
---|---|
date | Wed, 01 Aug 2018 13:20:38 +0200 |
parents | 9b16f58c62a7 |
children |
comparison
equal
deleted
inserted
replaced
9357:5ce50640688c | 9358:8eddc2393750 |
---|---|
11 | 11 |
12 import org.apache.commons.lang.math.DoubleRange; | 12 import org.apache.commons.lang.math.DoubleRange; |
13 import org.apache.commons.math.FunctionEvaluationException; | 13 import org.apache.commons.math.FunctionEvaluationException; |
14 import org.apache.commons.math.analysis.UnivariateRealFunction; | 14 import org.apache.commons.math.analysis.UnivariateRealFunction; |
15 import org.apache.commons.math.analysis.interpolation.LinearInterpolator; | 15 import org.apache.commons.math.analysis.interpolation.LinearInterpolator; |
16 import org.apache.log4j.Logger; | |
16 import org.dive4elements.river.artifacts.model.Calculation; | 17 import org.dive4elements.river.artifacts.model.Calculation; |
17 import org.dive4elements.river.model.Gauge; | 18 import org.dive4elements.river.model.Gauge; |
18 import org.dive4elements.river.model.MainValue; | 19 import org.dive4elements.river.model.MainValue; |
19 import org.dive4elements.river.model.MainValueType.MainValueTypeKey; | 20 import org.dive4elements.river.model.MainValueType.MainValueTypeKey; |
20 | 21 |
28 */ | 29 */ |
29 public final class GaugeDurationValuesFinder { | 30 public final class GaugeDurationValuesFinder { |
30 | 31 |
31 /***** FIELDS *****/ | 32 /***** FIELDS *****/ |
32 | 33 |
33 // private static Logger log = Logger.getLogger(GaugeDurationValuesFinder.class); | 34 private static Logger log = Logger.getLogger(GaugeDurationValuesFinder.class); |
34 | 35 |
35 private final Gauge gauge; | 36 private final Gauge gauge; |
36 | 37 |
37 private Calculation problems; | 38 private Calculation problems; |
38 | 39 |
55 final TDoubleArrayList durs = new TDoubleArrayList(); | 56 final TDoubleArrayList durs = new TDoubleArrayList(); |
56 for (final MainValue v : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.DURATION)) { | 57 for (final MainValue v : MainValue.getValuesOfGaugeAndType(gauge, MainValueTypeKey.DURATION)) { |
57 qs.add(v.getValue().doubleValue()); | 58 qs.add(v.getValue().doubleValue()); |
58 durs.add(Integer.valueOf(v.getMainValue().getName()).doubleValue()); | 59 durs.add(Integer.valueOf(v.getMainValue().getName()).doubleValue()); |
59 } | 60 } |
61 // Merge out-of-order Qs | |
62 final TDoubleArrayList q1s = new TDoubleArrayList(); | |
63 final TDoubleArrayList dur1s = new TDoubleArrayList(); | |
64 boolean writeWarn = true; | |
65 int cnt = 0; | |
66 int i = -1; | |
67 while ((i + 1) <= qs.size() - 1) { | |
68 i++; | |
69 if ((i == 0) || (qs.getQuick(i - 1) < qs.getQuick(i) - 0.001)) { | |
70 q1s.add(qs.getQuick(i)); | |
71 dur1s.add(durs.getQuick(i)); | |
72 cnt = 1; | |
73 } | |
74 else { | |
75 q1s.set(q1s.size() - 1, (q1s.getQuick(q1s.size() - 1) * cnt + qs.getQuick(i)) / (cnt + 1)); | |
76 dur1s.set(dur1s.size() - 1, (dur1s.getQuick(dur1s.size() - 1) * cnt + durs.getQuick(i)) / (cnt + 1)); | |
77 cnt++; | |
78 if (writeWarn) { | |
79 log.warn("Nicht streng monotone Q in D(Q) des Pegels " + gauge.getName()); | |
80 writeWarn = false; | |
81 } | |
82 } | |
83 } | |
60 // Build the duration-by-Q interpolator | 84 // Build the duration-by-Q interpolator |
61 try { | 85 try { |
62 this.qInterpolator = new LinearInterpolator().interpolate(qs.toNativeArray(), durs.toNativeArray()); | 86 this.qInterpolator = new LinearInterpolator().interpolate(q1s.toNativeArray(), dur1s.toNativeArray()); |
63 this.qRange = new DoubleRange(qs.get(0), qs.get(qs.size() - 1)); | 87 this.qRange = new DoubleRange(q1s.getQuick(0), q1s.getQuick(q1s.size() - 1)); |
64 } | 88 } |
65 catch (final Exception e) { | 89 catch (final Exception e) { |
66 this.qInterpolator = null; | 90 this.qInterpolator = null; |
67 this.qRange = null; | 91 this.qRange = null; |
68 } | 92 } |
74 qs.add(v.getValue().doubleValue()); | 98 qs.add(v.getValue().doubleValue()); |
75 } | 99 } |
76 // Build the Q-by-duration interpolator | 100 // Build the Q-by-duration interpolator |
77 try { | 101 try { |
78 this.durInterpolator = new LinearInterpolator().interpolate(durs.toNativeArray(), qs.toNativeArray()); | 102 this.durInterpolator = new LinearInterpolator().interpolate(durs.toNativeArray(), qs.toNativeArray()); |
79 this.durRange = new DoubleRange(durs.get(0), durs.get(durs.size() - 1)); | 103 this.durRange = new DoubleRange(durs.getQuick(0), durs.getQuick(durs.size() - 1)); |
80 } | 104 } |
81 catch (final Exception e) { | 105 catch (final Exception e) { |
82 this.durInterpolator = null; | 106 this.durInterpolator = null; |
83 this.durRange = null; | 107 this.durRange = null; |
84 } | 108 } |
132 } | 156 } |
133 | 157 |
134 /** | 158 /** |
135 * Duration for a discharge | 159 * Duration for a discharge |
136 * | 160 * |
137 * @return duration, or 0 for Q less than all, or 365 for duration greater then all, or -1 in case of exception | 161 * @return duration, or 0 for Q less than all, or 365 for duration greater then all, or NaN in case of missing |
162 * interpolator or exception | |
138 */ | 163 */ |
139 public double getDuration(final double q) { | 164 public double getDuration(final double q) { |
140 try { | 165 try { |
141 if (this.qInterpolator == null) | 166 if (this.qInterpolator == null) |
142 return -1; | 167 return Double.NaN; |
143 else if (q < this.qRange.getMinimumDouble()) | 168 else if (q < this.qRange.getMinimumDouble()) |
144 return 0; | 169 return 0; |
145 else if (q > this.qRange.getMaximumDouble()) | 170 else if (q > this.qRange.getMaximumDouble()) |
146 return 365; | 171 return 365; |
147 else | 172 else |
148 return this.qInterpolator.value(q); | 173 return this.qInterpolator.value(q); |
149 } | 174 } |
150 catch (@SuppressWarnings("unused") final FunctionEvaluationException e) { | 175 catch (@SuppressWarnings("unused") final FunctionEvaluationException e) { |
151 // ignore exception because this can/will happen regularly | 176 // ignore exception because this can/will happen regularly |
152 return -1; | 177 return Double.NaN; |
153 } | 178 } |
154 } | 179 } |
155 } | 180 } |