1 package fr.ifremer.tutti.service.export;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import com.google.common.base.Predicate;
26 import com.google.common.collect.Lists;
27 import com.google.common.collect.Maps;
28 import com.google.common.collect.Multimap;
29 import fr.ifremer.tutti.persistence.entities.data.BatchContainer;
30 import fr.ifremer.tutti.persistence.entities.data.CatchBatch;
31 import fr.ifremer.tutti.persistence.entities.data.FishingOperation;
32 import fr.ifremer.tutti.persistence.entities.data.MarineLitterBatch;
33 import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch;
34 import fr.ifremer.tutti.persistence.entities.data.SpeciesBatchFrequency;
35 import fr.ifremer.tutti.persistence.entities.referential.Species;
36 import fr.ifremer.tutti.service.PersistenceService;
37 import fr.ifremer.tutti.service.catches.WeightComputingService;
38 import fr.ifremer.tutti.util.Numbers;
39 import org.apache.commons.collections4.CollectionUtils;
40
41 import java.util.Collection;
42 import java.util.List;
43 import java.util.Map;
44
45
46
47
48
49
50
51
52
53 public class ExportCatchContext {
54
55 final FishingOperation fishingOperation;
56
57 final CatchBatch catchBatch;
58
59 final BatchContainer<SpeciesBatch> rootSpeciesBatch;
60
61 final BatchContainer<SpeciesBatch> rootBenthosBatch;
62
63 final BatchContainer<MarineLitterBatch> marineLitterBatches;
64
65 final Multimap<Species, SpeciesBatchFrequency> speciesFrequencies;
66
67 final Multimap<Species, SpeciesBatchFrequency> benthosFrequencies;
68
69 final Predicate<SpeciesBatch> vracPredicate;
70
71 public static ExportCatchContext newExportContext(PersistenceService persistenceService,
72 WeightComputingService weightComputingService,
73 Integer fishingOperationId,
74 boolean loadFrequencies) {
75
76 FishingOperation fishingOperation =
77 persistenceService.getFishingOperation(fishingOperationId);
78
79 CatchBatch catchBatch =
80 persistenceService.getCatchBatchFromFishingOperation(fishingOperationId);
81
82 BatchContainer<SpeciesBatch> rootSpeciesBatch =
83 weightComputingService.getComputedSpeciesBatches(fishingOperationId);
84
85 BatchContainer<SpeciesBatch> rootBenthosBatch =
86 weightComputingService.getComputedBenthosBatches(fishingOperationId);
87
88 BatchContainer<MarineLitterBatch> marineLitterBatches =
89 weightComputingService.getComputedMarineLitterBatches(
90 fishingOperationId,
91 catchBatch.getMarineLitterTotalWeight());
92 weightComputingService.computeCatchBatchWeights(catchBatch,
93 rootSpeciesBatch,
94 rootBenthosBatch,
95 marineLitterBatches);
96
97 Multimap<Species, SpeciesBatchFrequency> speciesFrequencies;
98 Multimap<Species, SpeciesBatchFrequency> benthosFrequencies;
99
100 if (loadFrequencies) {
101
102 speciesFrequencies = persistenceService.getAllSpeciesBatchFrequencyForBatch(rootSpeciesBatch);
103 benthosFrequencies = persistenceService.getAllBenthosBatchFrequencyForBatch(rootBenthosBatch);
104 } else {
105 speciesFrequencies = null;
106 benthosFrequencies = null;
107 }
108
109 Predicate<SpeciesBatch> vracPredicate = persistenceService.getVracBatchPredicate();
110
111 return new ExportCatchContext(vracPredicate,
112 fishingOperation,
113 catchBatch,
114 rootSpeciesBatch,
115 speciesFrequencies,
116 rootBenthosBatch,
117 benthosFrequencies,
118 marineLitterBatches);
119
120 }
121
122 private ExportCatchContext(Predicate<SpeciesBatch> vracPredicate,
123 FishingOperation fishingOperation,
124 CatchBatch catchBatch,
125 BatchContainer<SpeciesBatch> rootSpeciesBatch,
126 Multimap<Species, SpeciesBatchFrequency> speciesFrequencies,
127 BatchContainer<SpeciesBatch> rootBenthosBatch,
128 Multimap<Species, SpeciesBatchFrequency> benthosFrequencies,
129 BatchContainer<MarineLitterBatch> marineLitterBatches) {
130 this.vracPredicate = vracPredicate;
131 this.fishingOperation = fishingOperation;
132 this.catchBatch = catchBatch;
133 this.rootSpeciesBatch = rootSpeciesBatch;
134 this.speciesFrequencies = speciesFrequencies;
135 this.benthosFrequencies = benthosFrequencies;
136 this.rootBenthosBatch = rootBenthosBatch;
137 this.marineLitterBatches = marineLitterBatches;
138 }
139
140 public FishingOperation getFishingOperation() {
141 return fishingOperation;
142 }
143
144 public float getCatchTotalWeight() {
145 return Numbers.getValueOrComputedValue(
146 catchBatch.getCatchTotalWeight(),
147 catchBatch.getCatchTotalComputedWeight());
148 }
149
150 public float getCatchTotalSortedWeight() {
151 return catchBatch.getSpeciesTotalSampleSortedComputedWeight() +
152 catchBatch.getBenthosTotalSampleSortedComputedWeight() +
153 catchBatch.getSpeciesTotalUnsortedComputedWeight() +
154 catchBatch.getBenthosTotalUnsortedComputedWeight();
155 }
156
157 public float getSpeciesTotalSortedWeight() {
158 return Numbers.getValueOrComputedValue(
159 catchBatch.getSpeciesTotalSortedWeight(),
160 catchBatch.getSpeciesTotalSortedComputedWeight());
161 }
162
163 public float getBenthosTotalSortedWeight() {
164 return Numbers.getValueOrComputedValue(
165 catchBatch.getBenthosTotalSortedWeight(),
166 catchBatch.getBenthosTotalSortedComputedWeight());
167 }
168
169 public boolean withSpeciesBatches() {
170 return rootSpeciesBatch != null && !rootSpeciesBatch.isEmptyChildren();
171 }
172
173 public boolean withBenthosBatches() {
174 return rootBenthosBatch != null && !rootBenthosBatch.isEmptyChildren();
175 }
176
177 public boolean withSpeciesFrequencies() {
178 return speciesFrequencies != null && !speciesFrequencies.isEmpty();
179 }
180
181 public boolean withBenthosFrequencies() {
182 return benthosFrequencies != null && !benthosFrequencies.isEmpty();
183 }
184
185 public List<ExportBatchEntry> getSpeciesBatchEntry(boolean computeNumber) {
186 List<ExportBatchEntry> catchList = Lists.newArrayList();
187
188 if (withSpeciesBatches()) {
189
190 boolean withFrequencies = withSpeciesFrequencies();
191
192 Map<Species, ExportBatchEntry> catches = Maps.newLinkedHashMap();
193
194
195 float rate = getSpeciesElevationRate();
196
197 List<SpeciesBatch> batches = rootSpeciesBatch.getChildren();
198 for (SpeciesBatch batch : batches) {
199
200 ExportBatchEntry aCatch = createExportBatchCatch(
201 batch,
202 catches,
203 rate,
204 computeNumber);
205
206 if (withFrequencies) {
207 addFrequencies(aCatch, speciesFrequencies);
208 }
209 }
210 catchList.addAll(catches.values());
211 }
212 return catchList;
213 }
214
215 public List<ExportBatchEntry> getBenthosBatchEntry(boolean computeNumber) {
216 List<ExportBatchEntry> catchList = Lists.newArrayList();
217
218 if (withBenthosBatches()) {
219
220 boolean withFrequencies = withBenthosFrequencies();
221
222 Map<Species, ExportBatchEntry> catches = Maps.newLinkedHashMap();
223
224
225 float rate = getBenthosElevationRate();
226
227 List<SpeciesBatch> batches = rootBenthosBatch.getChildren();
228 for (SpeciesBatch batch : batches) {
229
230 ExportBatchEntry aCatch = createExportBatchCatch(
231 batch,
232 catches,
233 rate,
234 computeNumber);
235
236 if (withFrequencies) {
237 addFrequencies(aCatch, benthosFrequencies);
238 }
239 }
240
241 catchList.addAll(catches.values());
242 }
243 return catchList;
244 }
245
246 public ExportBatchEntry getInertAndLivingNotItemizedCatch() {
247
248 ExportBatchEntry result = new ExportBatchEntry(null);
249
250 float speciesRatio = getSpeciesElevationRate();
251 float benthosRatio = getBenthosElevationRate();
252
253 Float speciesInterWeight = Numbers.getValueOrComputedValue(
254 catchBatch.getSpeciesTotalInertWeight(),
255 catchBatch.getSpeciesTotalInertComputedWeight());
256
257 if (speciesInterWeight != null) {
258 result.addSortedWeight(speciesInterWeight);
259 result.addTotalWeight(speciesInterWeight * speciesRatio);
260 }
261
262 Float speciesLivingNotItemizedWeigth = Numbers.getValueOrComputedValue(
263 catchBatch.getSpeciesTotalLivingNotItemizedWeight(),
264 catchBatch.getSpeciesTotalLivingNotItemizedComputedWeight());
265
266 if (speciesLivingNotItemizedWeigth != null) {
267 result.addSortedWeight(speciesLivingNotItemizedWeigth);
268 result.addTotalWeight(speciesLivingNotItemizedWeigth * speciesRatio);
269 }
270
271 Float benthosInterWeight = Numbers.getValueOrComputedValue(
272 catchBatch.getBenthosTotalInertWeight(),
273 catchBatch.getBenthosTotalInertComputedWeight());
274
275 if (benthosInterWeight != null) {
276 result.addSortedWeight(benthosInterWeight);
277 result.addTotalWeight(benthosInterWeight * benthosRatio);
278 }
279
280 Float benthosLivingNotItemizedWeight = Numbers.getValueOrComputedValue(
281 catchBatch.getBenthosTotalLivingNotItemizedWeight(),
282 catchBatch.getBenthosTotalLivingNotItemizedComputedWeight());
283
284 if (benthosLivingNotItemizedWeight != null) {
285 result.addSortedWeight(benthosLivingNotItemizedWeight);
286 result.addTotalWeight(benthosLivingNotItemizedWeight * benthosRatio);
287 }
288
289 return result;
290 }
291
292 public boolean isVracBatch(SpeciesBatch batch) {
293 return vracPredicate.apply(batch);
294 }
295
296 protected float getSpeciesElevationRate() {
297
298 float globalRatio = catchBatch.getCatchTotalSortedComputedWeight() / catchBatch.getCatchTotalSortedSortedComputedWeight();
299
300 float speciesTotalSortedWeight = getSpeciesTotalSortedWeight();
301
302
303 float result = globalRatio * speciesTotalSortedWeight;
304 if (catchBatch.getSpeciesTotalSampleSortedComputedWeight() > 0) {
305 result /= catchBatch.getSpeciesTotalSampleSortedComputedWeight();
306 }
307 return result;
308 }
309
310 protected float getBenthosElevationRate() {
311
312 float globalRatio = catchBatch.getCatchTotalSortedComputedWeight() / catchBatch.getCatchTotalSortedSortedComputedWeight();
313
314 float benthosTotalSortedWeight = getBenthosTotalSortedWeight();
315
316
317 float result = globalRatio * benthosTotalSortedWeight;
318 if (catchBatch.getBenthosTotalSampleSortedComputedWeight() > 0) {
319 result /= catchBatch.getBenthosTotalSampleSortedComputedWeight();
320 }
321 return result;
322 }
323
324 protected ExportBatchEntry createExportBatchCatch(SpeciesBatch batch,
325 Map<Species, ExportBatchEntry> catches,
326 float ratio,
327 boolean computeNumber) {
328
329 Species species = batch.getSpecies();
330
331 ExportBatchEntry ktch = catches.get(species);
332 if (ktch == null) {
333 ktch = new ExportBatchEntry(batch);
334 catches.put(species, ktch);
335 }
336
337 float sortedWeight = Numbers.getValueOrComputedValue(
338 batch.getSampleCategoryWeight(),
339 batch.getSampleCategoryComputedWeight());
340
341 ktch.addSortedWeight(sortedWeight);
342
343 boolean isVracBatch = isVracBatch(batch);
344 float speciesTotalWeight = sortedWeight;
345 if (isVracBatch) {
346 speciesTotalWeight *= ratio;
347 }
348 ktch.addTotalWeight(speciesTotalWeight);
349
350 if (computeNumber) {
351 float number = Math.round(computeNumber(batch, 1.0f));
352 if (isVracBatch) {
353 number *= ratio;
354 }
355 ktch.addNumber(Math.round(number));
356 }
357 return ktch;
358 }
359
360 protected float computeNumber(SpeciesBatch batch, float rf) {
361 float result;
362
363 float weight = Numbers.getValueOrComputedValue(
364 batch.getSampleCategoryWeight(),
365 batch.getSampleCategoryComputedWeight());
366
367 if (batch.isChildBatchsEmpty()) {
368
369
370
371 Integer number = Numbers.getValueOrComputedValue(
372 batch.getNumber(),
373 batch.getComputedNumber());
374 if (number == null) {
375
376
377 number = 0;
378 }
379
380
381 Float subweight = Numbers.getValueOrComputedValue(
382 batch.getWeight(),
383 batch.getComputedWeight());
384
385 if (subweight != null) {
386
387
388 rf *= weight / subweight;
389 }
390
391 result = number.floatValue() * rf;
392 } else {
393
394
395 float totalWeight = 0.f;
396 for (SpeciesBatch child : batch.getChildBatchs()) {
397 totalWeight += Numbers.getValueOrComputedValue(
398 child.getSampleCategoryWeight(),
399 child.getSampleCategoryComputedWeight());
400 }
401
402 result = 0f;
403
404 float rf2 = rf * weight / totalWeight;
405
406 for (SpeciesBatch child : batch.getChildBatchs()) {
407
408 result += computeNumber(child, rf2);
409 }
410
411 }
412 return result;
413 }
414
415 protected <F extends SpeciesBatchFrequency> void addFrequencies(ExportBatchEntry aCatch,
416 Multimap<Species, F> frequencies) {
417 Species species = aCatch.getBatch().getSpecies();
418 Collection<F> batchFrequencies = frequencies.get(species);
419 if (CollectionUtils.isNotEmpty(batchFrequencies)) {
420 for (F batchFrequency : batchFrequencies) {
421 Integer number = batchFrequency.getNumber();
422 Float lengthStep = batchFrequency.getLengthStep();
423 aCatch.addFrequency(lengthStep, number);
424 }
425 }
426 }
427 }