1 /*
2 * This file is part of Indicators.
3 *
4 * Indicators is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * Indicators is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Indicators. If not, see <https://www.gnu.org/licenses/>.
16 */
17 package fr.inrae.agroclim.indicators.model.data.phenology;
18
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Objects;
24
25 import lombok.Getter;
26 import lombok.Setter;
27
28 /**
29 * Calculator to add relative stages.
30 *
31 * Last changed : $Date$
32 *
33 * @author $Author$
34 * @version $Revision$
35 */
36 public final class RelativeAnnualStageCalculator {
37
38 /**
39 * Relative number of days for each stage to build.
40 */
41 @Setter
42 private List<StageDelta> deltas;
43
44 /**
45 * Stages to handle.
46 */
47 @Getter
48 @Setter
49 private List<AnnualStageData> annualStageDatas;
50
51 /**
52 * Compute new stage and return all stages.
53 *
54 * @return all stages
55 */
56 public List<AnnualStageData> load() {
57 Map<Integer, AnnualStageData> annuallyData = new HashMap<>();
58 annualStageDatas.forEach(annualStageData -> {
59 int year = annualStageData.getYear();
60 if (!annuallyData.containsKey(year)) {
61 annuallyData.put(year, annualStageData);
62 } else {
63 throw new RuntimeException("Year " + year + " already set!");
64 }
65 });
66 annualStageDatas.forEach(annualStageData -> {
67 int year = annualStageData.getYear();
68 List<Stage> stages = new ArrayList<>(annualStageData.getStages());
69
70 stages.forEach(stage -> {
71 final String name = stage.getName();
72 deltas.forEach(stageDelta -> {
73 Integer delta = stageDelta.getDays();
74 if (delta == null || delta == 0) {
75 return;
76 }
77 String stageName = stageDelta.getStage();
78 if (!Objects.equals(name, stageName)) {
79 return;
80 }
81 int doy = stage.getValue() + delta;
82 if (doy <= 0) {
83 doy = 0;
84 }
85 if (delta > 0) {
86 stageName = stage.getName() + "+" + delta;
87 } else if (delta < 0) {
88 stageName = stage.getName() + delta;
89 }
90 annuallyData.get(year).add(stageName, doy);
91 });
92 });
93 });
94 List<AnnualStageData> data = new ArrayList<>();
95 data.addAll(annuallyData.values());
96 return data;
97 }
98
99 }