1   /* Copyright 2022-2026 Thales Alenia Space
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.time.clocks;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.hipparchus.analysis.differentiation.Gradient;
21  import org.orekit.time.AbsoluteDate;
22  import org.orekit.utils.drivers.ParameterDriver;
23  import org.orekit.utils.drivers.ParameterDriversProvider;
24  
25  import java.util.Map;
26  import java.util.function.DoubleFunction;
27  
28  /** Offset clock model.
29   * @author Luc Maisonobe
30   * @since 12.1
31   */
32  public interface ClockModel extends ParameterDriversProvider {
33  
34      /** Get the accepted suffix for parameter names.
35       * This creates the list of parameter driver terms that are accepted
36       * @param term the driver term parameter index requested
37       * @return clock term suffix
38       */
39      default String getAcceptedTermSuffix(final int term) {
40          return switch (term) {
41              case 0 -> "-clock-bias";
42              case 1 -> "-clock-drift";
43              case 2 -> "-clock-acceleration";
44              default -> "-clock-term-" + term;
45          };
46      }
47  
48      /** Get validity start.
49       * @return model validity start
50       */
51      AbsoluteDate getValidityStart();
52  
53      /** Get validity end.
54       * @return model validity end
55       */
56      AbsoluteDate getValidityEnd();
57  
58      /** Get the clock offset at date.
59       * @param date date at which offset is requested
60       * @return clock offset at specified date
61       */
62      ClockOffset getOffset(AbsoluteDate date);
63  
64      /** Get the clock offset value at date.
65       * @param date date at which offset value is requested
66       * @return clock offset value
67       */
68      default double getOffsetValue(final AbsoluteDate date) {
69          return getOffset(date).getValue(date);
70      }
71  
72      /** Get the parameter driver for the clock bias.
73       * <p>
74       * The bias represents the constant offset of the clock from the reference time scale.
75       * For a polynomial clock model of the form offset(t) = a₀ + a₁·t + a₂·t² + ...,
76       * the bias driver corresponds to the a₀ coefficient.
77       * </p>
78       * @return parameter driver for clock bias, or null if not available
79       * @since 14.0
80       */
81      default ParameterDriver getBiasDriver() {
82          return getParameterDriverWithSubstring(getAcceptedTermSuffix(0));
83      }
84  
85      /** Get the parameter driver for the clock rate (drift).
86       * <p>
87       * The rate represents the linear drift of the clock offset over time.
88       * For a polynomial clock model of the form offset(t) = a₀ + a₁·t + a₂·t² + ...,
89       * the rate driver corresponds to the a₁ coefficient. The rate is expressed
90       * in seconds of offset per second of elapsed time (dimensionless).
91       * </p>
92       * @return parameter driver for clock rate, or null if not available
93       * @since 14.0
94       */
95      default ParameterDriver getRateDriver() {
96          return getParameterDriverWithSubstring(getAcceptedTermSuffix(1));
97      }
98  
99      /** Get the parameter driver for the clock acceleration.
100      * <p>
101      * The acceleration represents the quadratic component of the clock offset over time.
102      * For a polynomial clock model of the form offset(t) = a₀ + a₁·t + a₂·t² + ...,
103      * the acceleration driver corresponds to the a₂ coefficient. The acceleration
104      * is expressed in seconds of offset per second squared of elapsed time.
105      * </p>
106      * @return parameter driver for clock acceleration, or null if not available
107      * @since 14.0
108      */
109     default ParameterDriver getAccelerationDriver() {
110         return getParameterDriverWithSubstring(getAcceptedTermSuffix(2));
111     }
112 
113     /** Get the parameter driver for a given index.
114      * <p>
115      * This gets the desired term value for the given integer.
116      * For example, if the fifth term counting up from bias being zero is desired.
117      * For all parameters without the standard naming convention, other methods
118      * of retrieval are required.
119      * </p>
120      * @param term the driver term parameter index requested
121      * @return parameter driver for clock acceleration, or null if not available
122      * @since 14.0
123      */
124     default ParameterDriver getParameterDriverTerm(final int term) {
125         return switch (term) {
126             case 0 -> getBiasDriver();
127             case 1 -> getRateDriver();
128             case 2 -> getAccelerationDriver();
129             default -> getParameterDriver(getAcceptedTermSuffix(term));
130         };
131     }
132 
133     /**
134      * Convert to field model.
135      * @param <T> type of the field elements
136      * @param converter converter to field elements
137      * @return field version of the instance
138      * @since 14.0
139      */
140     <T extends CalculusFieldElement<T>> FieldClockModel<T> toField(DoubleFunction<T> converter);
141 
142     /**
143      * Convert to gradient model.
144      * @param freeParameters total number of free parameters in the gradient
145      * @param indices indices of the differentiation parameters in derivatives computations,
146      * must be span name and not driver name
147      * @return converted clock model
148      */
149     FieldClockModel<Gradient> toGradient(int freeParameters, Map<String, Integer> indices);
150 
151 }