annotate artifacts/src/main/java/org/dive4elements/river/artifacts/services/DynamicMainValuesService.java @ 9396:6ebc9357550c

Fixed: bundu bzws start year plus one
author mschaefer
date Mon, 13 Aug 2018 17:15:05 +0200
parents 0255c51283a4
children bc9a45d2b1fa
rev   line source
9288
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
1 /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
2 * Software engineering by Intevation GmbH
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
3 *
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
4 * This file is Free Software under the GNU AGPL (>=v3)
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
5 * and comes with ABSOLUTELY NO WARRANTY! Check out the
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
6 * documentation coming with Dive4Elements River for details.
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
7 */
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
8
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
9 package org.dive4elements.river.artifacts.services;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
10
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
11 import java.math.BigDecimal;
9395
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
12 import java.math.MathContext;
9392
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
13 import java.math.RoundingMode;
9288
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
14 import java.util.ArrayList;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
15 import java.util.Calendar;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
16 import java.util.Date;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
17 import java.util.List;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
18
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
19 import org.dive4elements.artifacts.CallMeta;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
20 import org.dive4elements.artifacts.GlobalContext;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
21 import org.dive4elements.artifacts.common.ArtifactNamespaceContext;
9392
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
22 import org.dive4elements.artifacts.common.utils.DateUtils;
9288
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
23 import org.dive4elements.artifacts.common.utils.XMLUtils;
9392
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
24 import org.dive4elements.river.backend.SessionHolder;
9288
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
25 import org.dive4elements.river.model.Gauge;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
26 import org.dive4elements.river.model.MainValue;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
27 import org.dive4elements.river.model.MainValueType;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
28 import org.dive4elements.river.model.MainValueType.MainValueTypeKey;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
29 import org.dive4elements.river.model.NamedMainValue;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
30 import org.dive4elements.river.model.OfficialLine;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
31 import org.dive4elements.river.model.River;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
32 import org.dive4elements.river.model.TimeInterval;
9392
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
33 import org.dive4elements.river.model.sinfo.DailyDischargeValue;
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
34 import org.dive4elements.river.model.sinfo.DailyDischargeValue.OrderByField;
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
35 import org.dive4elements.river.utils.DoubleUtil;
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
36 import org.hibernate.Session;
9288
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
37 import org.w3c.dom.Document;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
38
9392
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
39 import gnu.trove.TDoubleArrayList;
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
40
9288
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
41 /**
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
42 * This service returns the main values of a river's gauge based on the start
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
43 * and end point of the river.
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
44 *
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
45 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
46 */
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
47 public class DynamicMainValuesService extends AbstractMainValuesService {
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
48
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
49 private static final long serialVersionUID = 1L;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
50
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
51 private static final String XPATH_START_YEAR = "/art:mainvalues/art:startYear/text()";
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
52
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
53 private static final String XPATH_END_YEAR = "/art:mainvalues/art:endYear/text()";
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
54
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
55 @Override
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
56 public Document doProcess(final Document data, final GlobalContext context, final CallMeta callMeta) {
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
57 try {
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
58
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
59 final River river = getRequestedRiver(data);
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
60 final Gauge gauge = getRequestedGauge(data, river);
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
61 final Date startTime = getRequestedStartYear(data);
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
62 final Date endTime = getRequestedEndYear(data);
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
63
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
64 final List<MainValue> mainValues = getMainValues(river, gauge, startTime, endTime);
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
65
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
66 return buildDocument(river, gauge, mainValues, context);
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
67 }
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
68 catch (final MainValuesServiceException e) {
9392
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
69 // e.printStackTrace();
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
70 return error(e.getMessage());
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
71 }
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
72 catch (final Exception e) {
9288
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
73 e.printStackTrace();
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
74 return error(e.getMessage());
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
75 }
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
76 }
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
77
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
78 private Date getRequestedStartYear(final Document data) throws MainValuesServiceException {
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
79
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
80 final String startStr = XMLUtils.xpathString(data, XPATH_START_YEAR, ArtifactNamespaceContext.INSTANCE);
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
81
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
82 if (startStr == null)
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
83 throw new MainValuesServiceException("no start year");
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
84
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
85 try {
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
86 final int year = Integer.parseInt(startStr);
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
87 final Calendar cal = Calendar.getInstance();
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
88 cal.clear();
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
89 cal.set(year, 0, 1);
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
90 return cal.getTime();
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
91 }
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
92 catch (final NumberFormatException e) {
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
93 e.printStackTrace();
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
94 throw new MainValuesServiceException("invalid start year");
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
95 }
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
96 }
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
97
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
98 private Date getRequestedEndYear(final Document data) throws MainValuesServiceException {
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
99
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
100 final String endStr = XMLUtils.xpathString(data, XPATH_END_YEAR, ArtifactNamespaceContext.INSTANCE);
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
101
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
102 if (endStr == null)
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
103 throw new MainValuesServiceException("no end year");
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
104
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
105 try {
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
106 final int year = Integer.parseInt(endStr);
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
107 final Calendar cal = Calendar.getInstance();
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
108 cal.clear();
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
109 cal.set(year, 11, 31);
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
110 return cal.getTime();
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
111 }
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
112 catch (final NumberFormatException e) {
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
113 e.printStackTrace();
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
114 throw new MainValuesServiceException("invalid end year");
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
115 }
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
116 }
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
117
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
118 /**
9392
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
119 * Computes a gauge's main values for a period of time based on its daily discharges stored in the database
9288
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
120 */
9392
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
121 protected List<MainValue> getMainValues(final River river, final Gauge gauge, final Date startTime, final Date endTime) throws MainValuesServiceException {
9288
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
122
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
123 final List<MainValue> mainValues = new ArrayList<>();
9392
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
124 computeMainDischargeValues(gauge, startTime, endTime, mainValues);
9288
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
125 return mainValues;
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
126 }
9392
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
127
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
128 /**
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
129 * Computes mnq, mq, mhq, hq5 and q(d=0..364) and adds them to a MainValue list
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
130 */
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
131 private void computeMainDischargeValues(final Gauge gauge, final Date startTime, final Date endTime, final List<MainValue> mainValues)
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
132 throws MainValuesServiceException {
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
133
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
134 // Query the gauge's daily Q values
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
135 final List<DailyDischargeValue> qdvs = DailyDischargeValue.getValues(gauge, startTime, endTime, OrderByField.DAY);
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
136 if (qdvs.isEmpty())
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
137 throw new MainValuesServiceException("no daily discharge values for gauge " + gauge.getName() + " in the requested time period");
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
138 // return; // TODO Fehlermeldung
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
139
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
140 // Build yearly aggregates
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
141 final TDoubleArrayList mnqs = new TDoubleArrayList();
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
142 final TDoubleArrayList mqs = new TDoubleArrayList();
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
143 int mqcnt = 0;
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
144 final TDoubleArrayList mhqs = new TDoubleArrayList();
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
145 for (int i = 0, j = 0; i <= qdvs.size() - 1; i++) {
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
146 final DailyDischargeValue qdv = qdvs.get(i);
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
147 if ((i >= 1) && isSameQYear(qdv.getDay(), qdvs.get(i - 1).getDay())) {
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
148 // Continue aggregating the values of the current year
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
149 mnqs.set(j, Math.min(mnqs.get(j), qdv.getDischarge().doubleValue()));
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
150 mhqs.set(j, Math.max(mhqs.get(j), qdv.getDischarge().doubleValue()));
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
151 mqs.set(j, mqs.get(j) + qdv.getDischarge().doubleValue());
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
152 mqcnt++;
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
153 if (i == qdvs.size() - 1)
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
154 mqs.set(j, mqs.get(j) / mqcnt);
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
155 }
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
156 else {
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
157 // Complete mq aggregation
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
158 if (mqcnt >= 1) {
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
159 mqs.set(j, mqs.get(j) / mqcnt);
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
160 j++;
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
161 }
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
162 // Start next year
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
163 mnqs.add(qdv.getDischarge().doubleValue());
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
164 mhqs.add(qdv.getDischarge().doubleValue());
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
165 mqs.add(qdv.getDischarge().doubleValue());
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
166 mqcnt = 1;
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
167 }
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
168 }
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
169
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
170 // Compute arithmetic means of the yearly values
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
171 final Session session = SessionHolder.HOLDER.get();
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
172 final TimeInterval timeperiod = new TimeInterval(startTime, endTime);
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
173 final double mnq = DoubleUtil.sum(mnqs.toNativeArray()) / mnqs.size();
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
174 mainValues.add(createMainValue(gauge, fetchNamedQMainValue("MNQ", session), mnq, timeperiod));
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
175 final double mq = DoubleUtil.sum(mqs.toNativeArray()) / mqs.size();
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
176 mainValues.add(createMainValue(gauge, fetchNamedQMainValue("MQ", session), mq, timeperiod));
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
177 final double mhq = DoubleUtil.sum(mhqs.toNativeArray()) / mhqs.size();
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
178 mainValues.add(createMainValue(gauge, fetchNamedQMainValue("MHQ", session), mhq, timeperiod));
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
179
9395
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
180 // Compute hq5 - obsolete
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
181 // mhqs.sort();
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
182 // final double hq5 = mhqs.get((int) Math.ceil(4 * mhqs.size() / 5));
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
183 // mainValues.add(createMainValue(gauge, fetchNamedQMainValue("HQ5", session), hq5, timeperiod));
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
184
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
185 // Add HSQ-II from the gauge's main values
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
186 final MainValue hsq2 = fetchHsqII(gauge, session);
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
187 if (hsq2 != null)
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
188 mainValues.add(hsq2);
9392
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
189
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
190 // Query the gauge's daily Q values and build a list sorted by ascending Q
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
191 final TDoubleArrayList qs = new TDoubleArrayList();
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
192 for (final DailyDischargeValue qdv : qdvs)
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
193 qs.add(qdv.getDischarge().doubleValue());
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
194 qs.sort();
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
195
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
196 // Step through the sorted Q list and get the duration discharges
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
197 final int yearCnt = DateUtils.getYearFromDate(endTime) - DateUtils.getYearFromDate(startTime) + 1;
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
198 double glq20 = Double.NaN;
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
199 for (int i = 0, k = 0; (i <= 364) && (k <= qs.size() - 1); i++, k += yearCnt) {
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
200 final NamedMainValue nmv = fetchNamedQMainValue(i, session, mainValues.get(0).getMainValue().getType());
9395
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
201 if (nmv != null) {
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
202 final double q = getDurationQ(qs, k);
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
203 mainValues.add(createMainValue(gauge, nmv, q, timeperiod));
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
204 if (i == 20)
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
205 glq20 = q;
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
206 }
9392
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
207 }
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
208 mainValues.add(createMainValue(gauge, fetchNamedQMainValue("GlQ", session), glq20, timeperiod));
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
209 }
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
210
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
211 /**
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
212 * Checks year equality of two dates (calendar year)
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
213 */
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
214 private boolean isSameQYear(final Date a, final Date b) {
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
215 final Calendar ca = Calendar.getInstance();
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
216 ca.setTime(a);
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
217 final Calendar cb = Calendar.getInstance();
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
218 cb.setTime(b);
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
219 return (ca.get(Calendar.YEAR) == cb.get(Calendar.YEAR));
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
220 }
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
221
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
222 /**
9395
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
223 * Fetches the gauge's HSQ-II from the database, or returns null
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
224 */
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
225 private MainValue fetchHsqII(final Gauge gauge, final Session session) {
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
226 final NamedMainValue nmv = NamedMainValue.fetchByNameAndType("HSQ-II", MainValueTypeKey.UNKNOWN.getName(), session);
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
227 if (nmv == null)
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
228 return null;
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
229 final List<MainValue> mvs = gauge.getMainValues();
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
230 for (final MainValue mv : mvs) {
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
231 if (mv.getMainValue().getId() == nmv.getId())
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
232 return mv;
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
233 }
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
234 return null;
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
235 }
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
236
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
237 /**
9392
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
238 * Fetches a named main Q value from the database, if existing
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
239 */
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
240 private NamedMainValue fetchNamedQMainValue(final String name, final Session session) {
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
241 final NamedMainValue nmv = NamedMainValue.fetchByNameAndType(name, MainValueTypeKey.Q.getName(), session);
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
242 if (nmv != null)
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
243 nmv.setOfficialLines(new ArrayList<OfficialLine>());
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
244 return nmv;
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
245 }
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
246
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
247 /**
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
248 * Fetches a named main Q(duration) value from the database, if existing
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
249 */
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
250 private NamedMainValue fetchNamedQMainValue(final int days, final Session session, final MainValueType qType) {
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
251 final NamedMainValue nmv = NamedMainValue.fetchByNameAndType(Integer.toString(days), MainValueTypeKey.DURATION.getName(), session);
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
252 // final NamedMainValue nmv = new NamedMainValue(Integer.toString(days), qType);
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
253 if (nmv != null)
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
254 nmv.setOfficialLines(new ArrayList<OfficialLine>());
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
255 return nmv;
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
256 }
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
257
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
258 /**
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
259 * Creates a main value for a main value name
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
260 */
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
261 private MainValue createMainValue(final Gauge gauge, final NamedMainValue nmv, final double value, final TimeInterval timeperiod) {
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
262 return new MainValue(gauge, nmv, BigDecimal.valueOf(value).setScale(0, RoundingMode.HALF_EVEN), timeperiod); // TODO Scale per Formatter-Konstante o.ä.
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
263 }
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
264
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
265 /**
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
266 * Gets the q from a list at a list position, or the next larger q if the immediate successors are equal
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
267 */
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
268 private double getDurationQ(final TDoubleArrayList qs, final int i) {
9395
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
269 if (i == 0)
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
270 return qs.getQuick(0);
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
271 for (int j = i; j <= qs.size() - 1; j++) {
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
272 if (qs.getQuick(j) > qs.getQuick(j - 1) + 0.001)
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
273 return qs.getQuick(j);
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
274 }
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
275 // Identical values at end of list: increment q on third significant digit
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
276 final MathContext mc = new MathContext(3, RoundingMode.FLOOR);
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
277 BigDecimal qplus = BigDecimal.valueOf(qs.getQuick(qs.size() - 1));
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
278 qplus = qplus.round(mc).add(BigDecimal.ONE.scaleByPowerOfTen(-qplus.scale()));
0255c51283a4 Bundu dynamix main value calculation: added hsq-ii, removed hq5, correction of duration q calculation
mschaefer
parents: 9392
diff changeset
279 return qplus.doubleValue();
9392
e4a6679b868f Implemented first approach of bundu dynamic main value calculation
mschaefer
parents: 9288
diff changeset
280 }
9288
82c67b859aa7 bundu.bezugswst worklflow incl. service impl for mainValues to be calculated
gernotbelger
parents:
diff changeset
281 }

http://dive4elements.wald.intevation.org