1   /* Copyright 2002-2025 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.utils;
18  
19  import java.util.List;
20  
21  import org.hipparchus.CalculusFieldElement;
22  import org.hipparchus.Field;
23  import org.hipparchus.util.MathArrays;
24  import org.orekit.errors.UnsupportedParameterException;
25  import org.orekit.time.AbsoluteDate;
26  import org.orekit.time.FieldAbsoluteDate;
27  import org.orekit.utils.TimeSpanMap.Span;
28  
29  /** Provider for {@link ParameterDriver parameters drivers}.
30   * @author Luc Maisonobe
31   * @author Melina Vanel
32   * @author Maxime Journot
33   * @since 11.2
34   */
35  public interface ParameterDriversProvider {
36  
37      /** Find if a parameter driver with a given name already exists in a list of parameter drivers.
38       * @param driversList the list of parameter drivers
39       * @param name the parameter driver's name to filter with
40       * @return true if the name was found, false otherwise
41       * @since 13.0
42       */
43      static boolean findByName(final List<ParameterDriver> driversList, final String name) {
44          for (final ParameterDriver d : driversList) {
45              if (d.getName().equals(name)) {
46                  return true;
47              }
48          }
49          return false;
50      }
51  
52      /** Get the drivers for parameters.
53       * @return drivers for parameters
54       */
55      List<ParameterDriver> getParametersDrivers();
56  
57      /** Get total number of spans for all the parameters driver.
58       * @return total number of span to be estimated
59       * @since 12.0
60       */
61      default int getNbParametersDriversValue() {
62          int totalSpan = 0;
63          final List<ParameterDriver> allParameters = getParametersDrivers();
64          for (ParameterDriver driver : allParameters) {
65              totalSpan += driver.getNbOfValues();
66          }
67          return totalSpan;
68      }
69  
70      /** Get model parameters.
71       * @return model parameters, will throw an
72       * exception if one PDriver has several values driven. If
73       * it's the case (if at least 1 PDriver of the model has several values
74       * driven) the method {@link #getParameters(AbsoluteDate)} must be used.
75       * @since 12.0
76       */
77      default double[] getParameters() {
78  
79          final List<ParameterDriver> drivers = getParametersDrivers();
80          final double[] parameters = new double[drivers.size()];
81          for (int i = 0; i < drivers.size(); ++i) {
82              parameters[i] = drivers.get(i).getValue();
83          }
84          return parameters;
85      }
86  
87      /** Get model parameters.
88       * @param date date at which the parameters want to be known, can
89       * be new AbsoluteDate() if all the parameters have no validity period
90       * that is to say that they have only 1 estimated value over the all
91       * interval
92       * @return model parameters
93       * @since 12.0
94       */
95      default double[] getParameters(AbsoluteDate date) {
96  
97          final List<ParameterDriver> drivers = getParametersDrivers();
98          final double[] parameters = new double[drivers.size()];
99          for (int i = 0; i < drivers.size(); ++i) {
100             parameters[i] = drivers.get(i).getValue(date);
101         }
102         return parameters;
103     }
104 
105     /** Get model parameters, return a list a all span values
106      * of all parameters.
107      * @return model parameters
108      * @since 12.0
109      */
110     default double[] getParametersAllValues() {
111 
112         final List<ParameterDriver> drivers = getParametersDrivers();
113         final int nbParametersValues = getNbParametersDriversValue();
114         final double[] parameters = new double[nbParametersValues];
115         int paramIndex = 0;
116         for (ParameterDriver driver : drivers) {
117             for (Span<Double> span = driver.getValueSpanMap().getFirstSpan(); span != null; span = span.next()) {
118                 parameters[paramIndex++] = span.getData();
119             }
120 
121         }
122         return parameters;
123     }
124 
125     /** Get model parameters.
126      * @param field field to which the elements belong
127      * @param <T> type of the elements
128      * @return model parameters
129      * @since 9.0
130      */
131     default <T extends CalculusFieldElement<T>> T[] getParametersAllValues(final Field<T> field) {
132         final List<ParameterDriver> drivers = getParametersDrivers();
133         final int nbParametersValues = getNbParametersDriversValue();
134         final T[] parameters = MathArrays.buildArray(field, nbParametersValues);
135         int paramIndex = 0;
136         for (ParameterDriver driver : drivers) {
137             for (Span<Double> span = driver.getValueSpanMap().getFirstSpan(); span != null; span = span.next()) {
138                 parameters[paramIndex++] = field.getZero().newInstance(span.getData());
139             }
140         }
141         return parameters;
142     }
143 
144     /** Get model parameters.
145      * @param field field to which the elements belong
146      * @param <T> type of the elements
147      * @return model parameters, will throw an
148      * exception if one PDriver of the has several values driven. If
149      * it's the case (if at least 1 PDriver of the model has several values
150      * driven) the method {@link #getParameters(Field, FieldAbsoluteDate)} must be used.
151      * @since 9.0
152      */
153     default <T extends CalculusFieldElement<T>> T[] getParameters(final Field<T> field) {
154         final List<ParameterDriver> drivers = getParametersDrivers();
155         final T[] parameters = MathArrays.buildArray(field, drivers.size());
156         for (int i = 0; i < drivers.size(); ++i) {
157             parameters[i] = field.getZero().newInstance(drivers.get(i).getValue());
158         }
159         return parameters;
160     }
161 
162     /** Get model parameters.
163      * @param field field to which the elements belong
164      * @param <T> type of the elements
165      * @param date field date at which the parameters want to be known, can
166      * be new AbsoluteDate() if all the parameters have no validity period.
167      * @return model parameters
168      * @since 9.0
169      */
170     default <T extends CalculusFieldElement<T>> T[] getParameters(final Field<T> field, final FieldAbsoluteDate<T> date) {
171         final List<ParameterDriver> drivers = getParametersDrivers();
172         final T[] parameters = MathArrays.buildArray(field, drivers.size());
173         for (int i = 0; i < drivers.size(); ++i) {
174             parameters[i] = field.getZero().newInstance(drivers.get(i).getValue(date.toAbsoluteDate()));
175         }
176         return parameters;
177     }
178 
179     /** Get parameter value from its name.
180      * @param name parameter name
181      * @return parameter value
182      * @since 8.0
183      */
184     default ParameterDriver getParameterDriver(final String name) {
185 
186         for (final ParameterDriver driver : getParametersDrivers()) {
187             if (name.equals(driver.getName())) {
188                 // we have found a parameter with that name
189                 return driver;
190             }
191         }
192         throw new UnsupportedParameterException(name, getParametersDrivers());
193     }
194 
195     /** Check if a parameter is supported.
196      * <p>Supported parameters are those listed by {@link #getParametersDrivers()}.</p>
197      * @param name parameter name to check
198      * @return true if the parameter is supported
199      * @see #getParametersDrivers()
200      * @since 8.0
201      */
202     default boolean isSupported(String name) {
203         for (final ParameterDriver driver : getParametersDrivers()) {
204             if (name.equals(driver.getName())) {
205                 // we have found a parameter with that name
206                 return true;
207             }
208         }
209         // the parameter is not supported
210         return false;
211     }
212 }