View Javadoc
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  }