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 java.util.Map;
20  
21  import org.hipparchus.CalculusFieldElement;
22  import org.hipparchus.analysis.differentiation.Gradient;
23  import org.orekit.time.AbsoluteDate;
24  import org.orekit.time.FieldAbsoluteDate;
25  import org.orekit.utils.ParameterDriver;
26  import org.orekit.utils.ParameterDriversProvider;
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 parameter term names.
35       * This creates the list of parameter driver terms that are accepted
36       * @param count the count of the term name being request
37       * @return clock term name
38       */
39      default String getAcceptedTermName(final Integer count) {
40          final String[] regularNames = {"-clock-bias", "-clock-drift", "-clock-acceleration"};
41          if (count < 3) {
42              return regularNames[count];
43          }
44          return "-clock-term-" + count;
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 field clock offset at date.
73       * @param <T> type of the field elements
74       * @param date date at which offset is requested
75       * @return field clock offset
76       */
77      <T extends CalculusFieldElement<T>> FieldClockOffset<T> getFieldOffset(FieldAbsoluteDate<T> date);
78  
79      /** Get the parameter driver for the clock bias.
80       * <p>
81       * The bias represents the constant offset of the clock from the reference time scale.
82       * For a polynomial clock model of the form offset(t) = a₀ + a₁·t + a₂·t² + ...,
83       * the bias driver corresponds to the a₀ coefficient.
84       * </p>
85       * @return parameter driver for clock bias, or null if not available
86       * @since 14.0
87       */
88      default ParameterDriver getBiasDriver() {
89          return getParameterDriverWithSubstring(getAcceptedTermName(0));
90      }
91  
92      /** Get the parameter driver for the clock rate (drift).
93       * <p>
94       * The rate represents the linear drift of the clock offset over time.
95       * For a polynomial clock model of the form offset(t) = a₀ + a₁·t + a₂·t² + ...,
96       * the rate driver corresponds to the a₁ coefficient. The rate is expressed
97       * in seconds of offset per second of elapsed time (dimensionless).
98       * </p>
99       * @return parameter driver for clock rate, or null if not available
100      * @since 14.0
101      */
102     default ParameterDriver getRateDriver() {
103         return getParameterDriverWithSubstring(getAcceptedTermName(1));
104     }
105 
106     /** Get the parameter driver for the clock acceleration.
107      * <p>
108      * The acceleration represents the quadratic component of the clock offset over time.
109      * For a polynomial clock model of the form offset(t) = a₀ + a₁·t + a₂·t² + ...,
110      * the acceleration driver corresponds to the a₂ coefficient. The acceleration
111      * is expressed in seconds of offset per second squared of elapsed time.
112      * </p>
113      * @return parameter driver for clock acceleration, or null if not available
114      * @since 14.0
115      */
116     default ParameterDriver getAccelerationDriver() {
117         return getParameterDriverWithSubstring(getAcceptedTermName(2));
118     }
119 
120     /** Get the parameter driver for a given index.
121      * <p>
122      * This gets the desired term value for the given integer.
123      * For example, if the fifth term counting up from bias being zero is desired.
124      * For all parameters without the standard naming convention, other methods
125      * of retrieval are required.
126      * </p>
127      * @param term the driver term parameter index requested
128      * @return parameter driver for clock acceleration, or null if not available
129      * @since 14.0
130      */
131     default ParameterDriver getParameterDriverTerm(final Integer term) {
132         return switch (term) {
133             case 0 -> getBiasDriver();
134             case 1 -> getRateDriver();
135             case 2 -> getAccelerationDriver();
136             default -> getParameterDriver(getAcceptedTermName(term));
137         };
138     }
139 
140     /**
141      * Convert to field model.
142      * @param freeParameters total number of free parameters in the gradient
143      * @param indices indices of the differentiation parameters in derivatives computations,
144      * must be span name and not driver name
145      * @param date date at which model must be valid
146      * @return converted clock model
147      */
148     FieldClockModel<Gradient> getFieldModel(int freeParameters, Map<String, Integer> indices, AbsoluteDate date);
149 
150 }