Mercurial > dive4elements > river
comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/BedQualityD50KmValueFinder.java @ 8901:0a900d605d52
S-INFO Flowdepth work on TKH calculation
author | mschaefer |
---|---|
date | Thu, 22 Feb 2018 17:04:06 +0100 |
parents | 89f3c5462a16 |
children | 37ff7f435912 |
comparison
equal
deleted
inserted
replaced
8900:d32c22fc686c | 8901:0a900d605d52 |
---|---|
16 import org.apache.commons.lang.math.DoubleRange; | 16 import org.apache.commons.lang.math.DoubleRange; |
17 import org.apache.commons.math.ArgumentOutsideDomainException; | 17 import org.apache.commons.math.ArgumentOutsideDomainException; |
18 import org.apache.commons.math.analysis.interpolation.LinearInterpolator; | 18 import org.apache.commons.math.analysis.interpolation.LinearInterpolator; |
19 import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; | 19 import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction; |
20 import org.apache.log4j.Logger; | 20 import org.apache.log4j.Logger; |
21 import org.dive4elements.river.artifacts.math.Utils; | |
21 import org.dive4elements.river.artifacts.model.DateRange; | 22 import org.dive4elements.river.artifacts.model.DateRange; |
22 import org.dive4elements.river.backend.SedDBSessionHolder; | 23 import org.dive4elements.river.backend.SedDBSessionHolder; |
23 import org.dive4elements.river.model.River; | 24 import org.dive4elements.river.model.River; |
25 import org.dive4elements.river.utils.DoubleUtil; | |
24 import org.hibernate.SQLQuery; | 26 import org.hibernate.SQLQuery; |
25 import org.hibernate.Session; | 27 import org.hibernate.Session; |
26 import org.hibernate.type.StandardBasicTypes; | 28 import org.hibernate.type.StandardBasicTypes; |
27 | 29 |
30 import gnu.trove.TDoubleArrayList; | |
31 | |
28 /** | 32 /** |
29 * Searchable sorted km array with parallel bed measurements value array and linear interpolation for km and d50 between the array elements. | 33 * Searchable sorted km array with parallel bed measurements value array and linear interpolation for km and d50 between the array elements.<br /> |
34 * <br /> | |
35 * See comment of SQL command on how the values are filtered and aggregated. | |
36 * | |
30 * @author Matthias Schäfer | 37 * @author Matthias Schäfer |
31 * | 38 * |
32 */ | 39 */ |
33 public class BedQualityD50KmValueFinder { | 40 public class BedQualityD50KmValueFinder { |
34 | 41 |
152 + " GROUP BY t.km" | 159 + " GROUP BY t.km" |
153 + " ORDER BY t.km"; | 160 + " ORDER BY t.km"; |
154 private static final String[] SQL_BED_D50_SELECT_ALIAS = {"km", "mindate", "maxdate", "cnt", "mindepth", "maxdepth", "d50"}; | 161 private static final String[] SQL_BED_D50_SELECT_ALIAS = {"km", "mindate", "maxdate", "cnt", "mindepth", "maxdepth", "d50"}; |
155 | 162 |
156 /** | 163 /** |
157 * Real linear interpolator for kms and d50 values | 164 * Kms of the loaded river range |
158 */ | 165 */ |
159 private PolynomialSplineFunction interpolator; | 166 private TDoubleArrayList kms; |
167 | |
168 /** | |
169 * D50 for each km in kms | |
170 */ | |
171 private TDoubleArrayList values; | |
172 | |
160 | 173 |
161 /***** METHODS *****/ | 174 /***** METHODS *****/ |
162 | 175 |
163 /** | 176 /** |
164 * Returns the d50 value interpolated according to a km | 177 * Returns the d50 value interpolated according to a km |
165 * @throws ArgumentOutsideDomainException | 178 * @return d50 (mm) of the km, or NaN |
166 */ | 179 */ |
167 public double findD50(double km) throws ArgumentOutsideDomainException { | 180 public double findD50(double km) throws ArgumentOutsideDomainException { |
168 return interpolator.value(km); | 181 if ((kms == null) || (kms.size() == 0)) |
182 return Double.NaN; | |
183 int i = kms.binarySearch(km); | |
184 if (i >= 0) | |
185 return values.get(i); | |
186 i = -i - 1; | |
187 if ((i - 1 >= 0) && Utils.epsilonEquals(km, kms.get(i - 1), 0.0001)) | |
188 return values.get(i - 1); | |
189 else if ((i >= 0) && (i <= kms.size() - 1) && Utils.epsilonEquals(km, kms.get(i), 0.0001)) | |
190 return values.get(i); | |
191 else | |
192 return Double.NaN; | |
169 } | 193 } |
170 | 194 |
171 /** | 195 /** |
172 * Loads the range of the river's kms with their associated values. | 196 * Loads the range of the river's kms with their associated values. |
173 * @return Whether the load has been successful | 197 * @return Whether the load has been successful |
189 sqlQuery.setDouble("tokm", kmRange.getMaximumDouble()); | 213 sqlQuery.setDouble("tokm", kmRange.getMaximumDouble()); |
190 sqlQuery.setDate("fromdate", dateRange.getFrom()); | 214 sqlQuery.setDate("fromdate", dateRange.getFrom()); |
191 sqlQuery.setDate("todate", dateRange.getTo()); | 215 sqlQuery.setDate("todate", dateRange.getTo()); |
192 @SuppressWarnings("unchecked") | 216 @SuppressWarnings("unchecked") |
193 final List<Object[]> rows = sqlQuery.list(); | 217 final List<Object[]> rows = sqlQuery.list(); |
194 final double[] kms = new double[rows.size()]; | 218 kms = new TDoubleArrayList(); |
195 final double[] values = new double[rows.size()]; | 219 values = new TDoubleArrayList(); |
196 D50Measurement measurement; | 220 D50Measurement measurement; |
197 int i = -1; | |
198 for (Object[] row : rows) { | 221 for (Object[] row : rows) { |
199 measurement = new D50Measurement(row, SQL_BED_D50_SELECT_ALIAS); | 222 measurement = new D50Measurement(row, SQL_BED_D50_SELECT_ALIAS); |
200 i++; | 223 kms.add(measurement.getKm()); |
201 kms[i] = measurement.getKm(); | 224 values.add(measurement.getD50()); |
202 values[i] = measurement.getD50(); | 225 log.debug(String.format("loadValues km %.3f d50(mm) %.1f count %d", kms.get(kms.size()-1), values.get(values.size()-1), measurement.getCnt())); |
203 log.debug(String.format("loadValues km %.3f d50(mm) %.1f count %d", kms[i], values[i], measurement.getCnt())); | 226 } |
204 } | |
205 interpolator = new LinearInterpolator().interpolate(kms, values); | |
206 return true; | 227 return true; |
207 } | 228 } |
208 | 229 |
209 } | 230 } |