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.indicator;
18  
19  import java.util.ArrayList;
20  import java.util.List;
21  import java.util.Optional;
22  
23  import fr.inrae.agroclim.indicators.exception.IndicatorsException;
24  import fr.inrae.agroclim.indicators.exception.type.ComputationErrorType;
25  import fr.inrae.agroclim.indicators.model.Parameter;
26  import fr.inrae.agroclim.indicators.model.data.DailyData;
27  import fr.inrae.agroclim.indicators.model.data.Resource;
28  import fr.inrae.agroclim.indicators.util.Doublet;
29  import jakarta.xml.bind.annotation.XmlAccessType;
30  import jakarta.xml.bind.annotation.XmlAccessorType;
31  import jakarta.xml.bind.annotation.XmlElement;
32  import lombok.EqualsAndHashCode;
33  import lombok.Getter;
34  import lombok.Setter;
35  
36  /**
37   * Compute the number of period (nbDays) matching the criteria.
38   *
39   * @author jucufi
40   */
41  @XmlAccessorType(XmlAccessType.FIELD)
42  @EqualsAndHashCode(
43          callSuper = true,
44          of = {"nbDays"}
45          )
46  public final class NumberOfWaves extends SimpleIndicatorWithCriteria implements Detailable {
47      /**
48       * UUID for Serializable.
49       */
50      private static final long serialVersionUID = 6030595237342422011L;
51  
52      /**
53       * Tag name.
54       */
55      static final String NB_OF_DAYS = "nbDays";
56  
57      /**
58       * Number of step (day or hour) per wave.
59       */
60      @XmlElement(required = true)
61      @Getter
62      @Setter
63      private Integer nbDays;
64  
65      /**
66       * Constructor.
67       */
68      public NumberOfWaves() {
69          super();
70      }
71  
72      @Override
73      public NumberOfWaves clone() throws CloneNotSupportedException {
74          final NumberOfWaves clone = (NumberOfWaves) super.clone();
75          clone.nbDays = nbDays;
76          return clone;
77      }
78  
79      @Override
80      public double computeSingleValue(final Resource<? extends DailyData> climatic) throws IndicatorsException {
81          if (getCriteria() == null) {
82              throw new IndicatorsException(ComputationErrorType.CRITERIA_NULL);
83          }
84          if (nbDays == null) {
85              throw new IndicatorsException(ComputationErrorType.WRONG_DEFINITION, "nbDays must not be null!");
86          }
87          int index = 0;
88          int nb = 0;
89          boolean resultCriteria;
90  
91          for (final DailyData data : climatic.getData()) {
92              resultCriteria = getCriteria().eval(data);
93              if (resultCriteria) {
94                  index += 1;
95              } else {
96                  index = 0;
97              }
98  
99              if (index >= nbDays) {
100                 nb += 1;
101                 index = 0;
102             }
103 
104         }
105         return nb;
106     }
107 
108     @Override
109     public List<Doublet<Parameter, Number>> getParameterDefaults() {
110         if (getParameters() == null) {
111             return List.of();
112         }
113         final List<Doublet<Parameter, Number>> val = new ArrayList<>();
114         if (getCriteria() != null && getCriteria().getParameterDefaults() != null) {
115             val.addAll(getCriteria().getParameterDefaults());
116         }
117         final Optional<Parameter> found = getParameters().stream() //
118                 .filter(a -> NB_OF_DAYS.equals(a.getAttribute())) //
119                 .findFirst();
120         if (found.isPresent()) {
121             val.add(Doublet.of(found.get(), nbDays));
122         }
123         return val;
124     }
125 
126 }