1 package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 import fr.ifremer.tutti.persistence.entities.data.CopyIndividualObservationMode;
28 import fr.ifremer.tutti.type.WeightUnit;
29 import org.apache.commons.lang3.tuple.Pair;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32
33 import java.util.Objects;
34
35
36
37
38
39
40
41
42
43 public class IndividualObservationToFrequencyEngine {
44
45
46 private static final Log log = LogFactory.getLog(IndividualObservationToFrequencyEngine.class);
47
48
49
50
51 private final SpeciesFrequencyTableModel frequencyTableModel;
52
53 private final WeightUnit individualObservationWeightUnit;
54 private final WeightUnit frequencyWeightUnit;
55
56 public IndividualObservationToFrequencyEngine(SpeciesFrequencyUIModel speciesFrequencyUIModel) {
57 this.individualObservationWeightUnit = speciesFrequencyUIModel.getIndividualObservationWeightUnit();
58 this.frequencyWeightUnit = speciesFrequencyUIModel.getWeightUnit();
59 this.frequencyTableModel = speciesFrequencyUIModel.getFrequencyTableModel();
60 }
61
62 public boolean computeFrequencyUpdate(CopyIndividualObservationMode copyIndividualObservationMode,
63 IndividualObservationBatchRowState oldState,
64 IndividualObservationBatchRowState newState) {
65
66 switch (copyIndividualObservationMode) {
67
68 case ALL:
69 computeFrequencyUpdateForSizeAndWeight(oldState, newState);
70
71 break;
72
73 case SIZE:
74 computeFrequencyUpdateForSizeOnly(oldState, newState);
75
76 break;
77
78 case NOTHING:
79
80 break;
81
82 default:
83 throw new IllegalStateException("Can't come here");
84
85 }
86
87 return oldState.isValid() != newState.isValid();
88
89 }
90
91 public void computeFrequencyUpdateForSizeOnly(IndividualObservationBatchRowState oldState, IndividualObservationBatchRowState newState) {
92
93 Objects.requireNonNull(oldState);
94 Objects.requireNonNull(newState);
95
96 Float oldSize = oldState.getSize();
97 Float newSize = newState.getSize();
98 boolean sizeChanged = !Objects.equals(oldSize, newSize);
99
100 if (sizeChanged) {
101
102 Float decrementSize = null;
103 Float incrementSize = null;
104
105 if (oldState.isValid()) {
106 decrementSize = oldSize;
107 }
108
109 if (newState.isValid()) {
110 incrementSize = newSize;
111 }
112
113 apply(decrementSize, incrementSize, null, null);
114
115 }
116
117 }
118
119 public void computeFrequencyUpdateForSizeAndWeight(IndividualObservationBatchRowState oldState, IndividualObservationBatchRowState newState) {
120
121 Objects.requireNonNull(oldState);
122 Objects.requireNonNull(newState);
123
124 Float newSize = newState.getSize();
125 Float oldSize = oldState.getSize();
126 boolean sizeChanged = !Objects.equals(oldSize, newSize);
127
128 Float newWeight = newState.getWeight();
129 Float oldWeight = oldState.getWeight();
130 boolean weightChanged = !Objects.equals(oldWeight, newWeight);
131
132 if (!sizeChanged && !weightChanged) {
133
134
135 return;
136
137 }
138
139 boolean oldStateValid = oldState.isValid();
140 boolean newStateValid = newState.isValid();
141
142 Float decrementSize = null;
143 Float incrementSize = null;
144
145 Pair<Float, Float> substractWeight = null;
146 Pair<Float, Float> addWeight = null;
147
148 if (sizeChanged) {
149
150 if (oldStateValid) {
151
152 decrementSize = oldSize;
153 substractWeight = Pair.of(oldSize, oldWeight);
154
155 }
156
157 if (newStateValid) {
158
159 incrementSize = newSize;
160 addWeight = Pair.of(newSize, newWeight);
161
162 }
163
164 }
165
166 if (weightChanged) {
167
168
169
170 Float weightToAdd;
171
172 if (oldStateValid && newStateValid) {
173
174 weightToAdd = newWeight - oldWeight;
175
176 } else if (oldStateValid) {
177
178 decrementSize = oldSize;
179 weightToAdd = -oldWeight;
180
181 } else if (newStateValid) {
182
183 incrementSize = newSize;
184 weightToAdd = newWeight;
185
186 } else {
187
188 weightToAdd = 0f;
189
190 }
191
192 if (individualObservationWeightUnit.isNotNullNorZero(weightToAdd)) {
193
194 if (individualObservationWeightUnit.isGreaterThanZero(weightToAdd)) {
195
196
197 addWeight = Pair.of(newSize, weightToAdd);
198
199 } else {
200
201
202 substractWeight = Pair.of(newSize, -weightToAdd);
203
204 }
205
206 }
207
208 }
209
210 apply(decrementSize, incrementSize, substractWeight, addWeight);
211
212 }
213
214 private void apply(Float lengthStepToDecrement, Float lengthStepToIncrement, Pair<Float, Float> substractWeight, Pair<Float, Float> addWeight) {
215
216 if (lengthStepToDecrement != null) {
217
218 if (log.isInfoEnabled()) {
219 log.info("Decrements frequency rows number for length class: " + lengthStepToDecrement);
220 }
221 frequencyTableModel.decrementFrequencyRowsNumbers(lengthStepToDecrement);
222
223 }
224
225 if (lengthStepToIncrement != null) {
226
227 if (log.isInfoEnabled()) {
228 log.info("Increments frequency rows number for length class: " + lengthStepToIncrement);
229 }
230 frequencyTableModel.incrementFrequencyRowsNumbers(lengthStepToIncrement);
231
232 }
233
234 if (substractWeight != null) {
235
236 float weight = substractWeight.getValue();
237 float weightToRemove = frequencyTableModel.convertWeightFromIndividualObservation(weight);
238 Float lengthClass = substractWeight.getKey();
239 if (log.isInfoEnabled()) {
240 log.info("Substract weight: " + weightToRemove + frequencyWeightUnit.getShortLabel() + " for length class: " + lengthClass);
241 }
242 frequencyTableModel.removeWeightToFrequencyRow(lengthClass, weightToRemove);
243
244 }
245
246 if (addWeight != null) {
247
248 float weight = addWeight.getValue();
249 float weightToAdd = frequencyTableModel.convertWeightFromIndividualObservation(weight);
250 Float lengthClass = addWeight.getKey();
251 if (log.isInfoEnabled()) {
252 log.info("Add weight: " + weightToAdd + frequencyWeightUnit.getShortLabel() + " for length class: " + lengthClass);
253 }
254 frequencyTableModel.addWeightToFrequencyRow(lengthClass, weightToAdd);
255
256 }
257
258 }
259
260 }