1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package fr.inrae.agroclim.indicators.model.criteria;
18
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Objects;
23 import java.util.Optional;
24
25 import fr.inrae.agroclim.indicators.exception.IndicatorsException;
26 import fr.inrae.agroclim.indicators.model.Parameter;
27 import fr.inrae.agroclim.indicators.model.data.DailyData;
28 import fr.inrae.agroclim.indicators.model.data.Variable;
29 import fr.inrae.agroclim.indicators.model.data.climate.ClimaticDailyData;
30 import fr.inrae.agroclim.indicators.util.Doublet;
31 import jakarta.xml.bind.annotation.XmlElement;
32 import jakarta.xml.bind.annotation.XmlRootElement;
33 import jakarta.xml.bind.annotation.XmlTransient;
34 import jakarta.xml.bind.annotation.XmlType;
35 import lombok.EqualsAndHashCode;
36 import lombok.Getter;
37 import lombok.Setter;
38 import lombok.ToString;
39 import lombok.extern.log4j.Log4j2;
40
41
42
43
44
45
46
47
48
49
50
51 @XmlRootElement
52 @XmlType(propOrder = {"inferiorToThreshold", "strict", "operator", "threshold", "noThreshold"})
53 @ToString
54 @Log4j2
55 @EqualsAndHashCode(callSuper = true, of = {"noThreshold", "operator", "threshold"})
56 public final class SimpleCriteria extends VariableCriteria {
57
58
59
60 private static final long serialVersionUID = -4284278102762199667L;
61
62
63
64
65 private static final String THRESHOLD = "threshold";
66
67
68
69
70 @XmlTransient
71 private boolean inferiorToThreshold = true;
72
73
74
75
76 @XmlElement
77 @Getter
78 @Setter
79 private boolean noThreshold = false;
80
81
82
83
84 @XmlElement
85 @Getter
86 @Setter
87 private RelationalOperator operator = RelationalOperator.LT;
88
89
90
91
92 @XmlTransient
93 private boolean strict = true;
94
95
96
97
98 @XmlElement
99 @Getter
100 private double threshold;
101
102
103
104
105 public SimpleCriteria() {
106 super();
107 }
108
109
110
111
112
113
114
115
116
117
118
119 public SimpleCriteria(final String variable, final RelationalOperator op, final double thr) {
120 setOperator(op);
121 setVariable(Variable.getByName(variable));
122 setThreshold(thr);
123 }
124
125 @Override
126 public SimpleCriteria clone() {
127 final SimpleCriteria clone = new SimpleCriteria();
128 clone.threshold = threshold;
129 clone.setVariable(getVariable());
130 clone.inferiorToThreshold = inferiorToThreshold;
131 clone.strict = strict;
132 clone.noThreshold = noThreshold;
133 clone.operator = operator;
134 if (getParameters() != null) {
135 clone.setParameters(getParameters());
136 }
137 return clone;
138 }
139
140 @Override
141 public boolean eval(final DailyData dailydata) throws IndicatorsException {
142 if (dailydata == null) {
143 return false;
144 }
145 if (isNoThreshold()) {
146 return true;
147 }
148 final double val = getValueOf(dailydata);
149 return operator.eval(val, getThreshold());
150 }
151
152
153
154
155
156
157
158
159 public String getFormula(final ClimaticDailyData data) throws IndicatorsException {
160 final StringBuilder sb = new StringBuilder();
161 sb.append(getValueOf(data));
162 sb.append(" ");
163 sb.append(operator.getRepr());
164 sb.append(" ");
165 sb.append(getThreshold());
166 return sb.toString();
167 }
168
169 @Override
170 public List<Doublet<Parameter, Number>> getParameterDefaults() {
171 if (getParameters() == null) {
172 return List.of();
173 }
174 final Optional<Parameter> found = getParameters().stream()
175 .filter(a -> THRESHOLD.equals(a.getAttribute()))
176 .findFirst();
177 if (found.isEmpty()) {
178 return List.of();
179 }
180 return List.of(Doublet.of(found.get(), threshold));
181 }
182
183 @Override
184 public Map<String, Double> getParametersValues() {
185 final Map<String, Double> val = new HashMap<>();
186
187 if (getParameters() == null) {
188 return val;
189 }
190 for (final Parameter param : getParameters()) {
191 if (Objects.equals(param.getAttribute(), THRESHOLD)) {
192 val.put(param.getId(), threshold);
193 }
194 }
195 return val;
196 }
197
198
199
200
201
202 @Deprecated(forRemoval = true)
203 public Boolean isInferiorToThreshold() {
204 return null;
205 }
206
207
208
209
210
211 @Deprecated(forRemoval = true)
212 public Boolean isStrict() {
213 return null;
214 }
215
216 @Override
217 public void removeParameter(final Parameter param) {
218 if (this.getParameters() != null) {
219 this.getParameters().remove(param);
220 }
221 }
222
223
224
225
226 @XmlElement
227 public void setInferiorToThreshold(final Boolean value) {
228 this.inferiorToThreshold = value;
229 setOperator();
230 }
231
232
233
234
235 private void setOperator() {
236 if (this.inferiorToThreshold) {
237 if (strict) {
238 operator = RelationalOperator.LT;
239 } else {
240 operator = RelationalOperator.LE;
241 }
242 } else {
243 if (strict) {
244 operator = RelationalOperator.GT;
245 } else {
246 operator = RelationalOperator.GE;
247 }
248 }
249 }
250
251 @Override
252 public void setParametersValues(final Map<String, Double> values) {
253
254 if (getParameters() == null || values == null || values.isEmpty()) {
255 return;
256 }
257 for (final Parameter param : getParameters()) {
258 if (Objects.equals(param.getAttribute(), THRESHOLD)) {
259 final String id = param.getId();
260 if (values.containsKey(id) && values.get(id) != null) {
261 if (values.get(id) == null) {
262 LOGGER.error("Strange, value of parameter {} is null!", id);
263 } else {
264 setThreshold(values.get(id));
265 }
266 }
267 } else {
268 LOGGER.error("Attribute {} not handled!", param.getAttribute());
269 }
270 }
271 }
272
273
274
275
276 @XmlElement
277 public void setStrict(final Boolean value) {
278 this.strict = value;
279 setOperator();
280 }
281
282
283
284
285 public void setThreshold(final double value) {
286 final double old = threshold;
287 threshold = value;
288 getPropertySupport().firePropertyChange(THRESHOLD, old, value);
289 }
290
291 @Override
292 public String toStringTree(final String ident) {
293 final StringBuilder sb = new StringBuilder();
294 sb.append(ident).append(" class: ").append(getClass().getName())
295 .append("\n");
296 sb.append(ident).append(" operator: ")
297 .append(operator.getRepr()).append("\n");
298 sb.append(ident).append(" noThreshold: ").append(noThreshold)
299 .append("\n");
300 sb.append(ident).append(" threshold: ").append(threshold)
301 .append("\n");
302 sb.append(ident).append(" variable: ").append(getVariable())
303 .append("\n");
304 return sb.toString();
305 }
306 }