comparison artifacts/src/main/java/org/dive4elements/river/artifacts/services/DynamicMainValuesService.java @ 9395:0255c51283a4

Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
author mschaefer
date Mon, 13 Aug 2018 09:16:44 +0200
parents e4a6679b868f
children 6ebc9357550c
comparison
equal deleted inserted replaced
9394:439699ff9b2d 9395:0255c51283a4
7 */ 7 */
8 8
9 package org.dive4elements.river.artifacts.services; 9 package org.dive4elements.river.artifacts.services;
10 10
11 import java.math.BigDecimal; 11 import java.math.BigDecimal;
12 import java.math.MathContext;
12 import java.math.RoundingMode; 13 import java.math.RoundingMode;
13 import java.util.ArrayList; 14 import java.util.ArrayList;
14 import java.util.Calendar; 15 import java.util.Calendar;
15 import java.util.Date; 16 import java.util.Date;
16 import java.util.List; 17 import java.util.List;
178 final double mq = DoubleUtil.sum(mqs.toNativeArray()) / mqs.size(); 179 final double mq = DoubleUtil.sum(mqs.toNativeArray()) / mqs.size();
179 mainValues.add(createMainValue(gauge, fetchNamedQMainValue("MQ", session), mq, timeperiod)); 180 mainValues.add(createMainValue(gauge, fetchNamedQMainValue("MQ", session), mq, timeperiod));
180 final double mhq = DoubleUtil.sum(mhqs.toNativeArray()) / mhqs.size(); 181 final double mhq = DoubleUtil.sum(mhqs.toNativeArray()) / mhqs.size();
181 mainValues.add(createMainValue(gauge, fetchNamedQMainValue("MHQ", session), mhq, timeperiod)); 182 mainValues.add(createMainValue(gauge, fetchNamedQMainValue("MHQ", session), mhq, timeperiod));
182 183
183 // Compute hq5 184 // Compute hq5 - obsolete
184 mhqs.sort(); 185 // mhqs.sort();
185 final double hq5 = mhqs.get((int) Math.ceil(4 * mhqs.size() / 5)); 186 // final double hq5 = mhqs.get((int) Math.ceil(4 * mhqs.size() / 5));
186 mainValues.add(createMainValue(gauge, fetchNamedQMainValue("HQ5", session), hq5, timeperiod)); 187 // mainValues.add(createMainValue(gauge, fetchNamedQMainValue("HQ5", session), hq5, timeperiod));
188
189 // Add HSQ-II from the gauge's main values
190 final MainValue hsq2 = fetchHsqII(gauge, session);
191 if (hsq2 != null)
192 mainValues.add(hsq2);
187 193
188 // Query the gauge's daily Q values and build a list sorted by ascending Q 194 // Query the gauge's daily Q values and build a list sorted by ascending Q
189 final TDoubleArrayList qs = new TDoubleArrayList(); 195 final TDoubleArrayList qs = new TDoubleArrayList();
190 for (final DailyDischargeValue qdv : qdvs) 196 for (final DailyDischargeValue qdv : qdvs)
191 qs.add(qdv.getDischarge().doubleValue()); 197 qs.add(qdv.getDischarge().doubleValue());
194 // Step through the sorted Q list and get the duration discharges 200 // Step through the sorted Q list and get the duration discharges
195 final int yearCnt = DateUtils.getYearFromDate(endTime) - DateUtils.getYearFromDate(startTime) + 1; 201 final int yearCnt = DateUtils.getYearFromDate(endTime) - DateUtils.getYearFromDate(startTime) + 1;
196 double glq20 = Double.NaN; 202 double glq20 = Double.NaN;
197 for (int i = 0, k = 0; (i <= 364) && (k <= qs.size() - 1); i++, k += yearCnt) { 203 for (int i = 0, k = 0; (i <= 364) && (k <= qs.size() - 1); i++, k += yearCnt) {
198 final NamedMainValue nmv = fetchNamedQMainValue(i, session, mainValues.get(0).getMainValue().getType()); 204 final NamedMainValue nmv = fetchNamedQMainValue(i, session, mainValues.get(0).getMainValue().getType());
199 if (nmv != null) 205 if (nmv != null) {
200 mainValues.add(createMainValue(gauge, nmv, getDurationQ(qs, k), timeperiod)); 206 final double q = getDurationQ(qs, k);
201 if (i == 20) 207 mainValues.add(createMainValue(gauge, nmv, q, timeperiod));
202 glq20 = qs.get(k); 208 if (i == 20)
209 glq20 = q;
210 }
203 } 211 }
204 mainValues.add(createMainValue(gauge, fetchNamedQMainValue("GlQ", session), glq20, timeperiod)); 212 mainValues.add(createMainValue(gauge, fetchNamedQMainValue("GlQ", session), glq20, timeperiod));
205 } 213 }
206 214
207 /** 215 /**
214 cb.setTime(b); 222 cb.setTime(b);
215 return (ca.get(Calendar.YEAR) == cb.get(Calendar.YEAR)); 223 return (ca.get(Calendar.YEAR) == cb.get(Calendar.YEAR));
216 } 224 }
217 225
218 /** 226 /**
227 * Fetches the gauge's HSQ-II from the database, or returns null
228 */
229 private MainValue fetchHsqII(final Gauge gauge, final Session session) {
230 final NamedMainValue nmv = NamedMainValue.fetchByNameAndType("HSQ-II", MainValueTypeKey.UNKNOWN.getName(), session);
231 if (nmv == null)
232 return null;
233 final List<MainValue> mvs = gauge.getMainValues();
234 for (final MainValue mv : mvs) {
235 if (mv.getMainValue().getId() == nmv.getId())
236 return mv;
237 }
238 return null;
239 }
240
241 /**
219 * Fetches a named main Q value from the database, if existing 242 * Fetches a named main Q value from the database, if existing
220 */ 243 */
221 private NamedMainValue fetchNamedQMainValue(final String name, final Session session) { 244 private NamedMainValue fetchNamedQMainValue(final String name, final Session session) {
222 final NamedMainValue nmv = NamedMainValue.fetchByNameAndType(name, MainValueTypeKey.Q.getName(), session); 245 final NamedMainValue nmv = NamedMainValue.fetchByNameAndType(name, MainValueTypeKey.Q.getName(), session);
223 if (nmv != null) 246 if (nmv != null)
245 268
246 /** 269 /**
247 * Gets the q from a list at a list position, or the next larger q if the immediate successors are equal 270 * Gets the q from a list at a list position, or the next larger q if the immediate successors are equal
248 */ 271 */
249 private double getDurationQ(final TDoubleArrayList qs, final int i) { 272 private double getDurationQ(final TDoubleArrayList qs, final int i) {
250 for (int j = i; j + 1 <= qs.size() - 1; j++) 273 if (i == 0)
251 if (qs.get(j + 1) > qs.get(j) + 0.001) 274 return qs.getQuick(0);
252 return qs.get(j); 275 for (int j = i; j <= qs.size() - 1; j++) {
253 // TODO Increment q on third significant digit 276 if (qs.getQuick(j) > qs.getQuick(j - 1) + 0.001)
254 return qs.get(qs.size() - 1); 277 return qs.getQuick(j);
278 }
279 // Identical values at end of list: increment q on third significant digit
280 final MathContext mc = new MathContext(3, RoundingMode.FLOOR);
281 BigDecimal qplus = BigDecimal.valueOf(qs.getQuick(qs.size() - 1));
282 qplus = qplus.round(mc).add(BigDecimal.ONE.scaleByPowerOfTen(-qplus.scale()));
283 return qplus.doubleValue();
255 } 284 }
256 } 285 }

http://dive4elements.wald.intevation.org