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.ArrayList;
20  import java.util.List;
21  import java.util.Map;
22  
23  import org.hipparchus.CalculusFieldElement;
24  import org.hipparchus.analysis.differentiation.Gradient;
25  import org.orekit.errors.OrekitException;
26  import org.orekit.errors.OrekitMessages;
27  import org.orekit.time.AbsoluteDate;
28  import org.orekit.time.FieldAbsoluteDate;
29  import org.orekit.utils.ParameterDriver;
30  import org.orekit.utils.TimeSpanMap;
31  
32  /**
33   * Offset clock model aggregating several other clock models.
34   *
35   * @author Luc Maisonobe
36   * @since 12.1
37   */
38  public class AggregatedClockModel implements ClockModel {
39  
40      /** Underlying clock models. */
41      private final TimeSpanMap<ClockModel> models;
42  
43      /** Simple constructor.
44       * @param models underlying clock models
45       */
46      public AggregatedClockModel(final TimeSpanMap<ClockModel> models) {
47          this.models = models;
48      }
49  
50      /** Get the underlying models.
51       * @return underlying models
52       */
53      public TimeSpanMap<ClockModel> getModels() {
54          return models;
55      }
56  
57      /** {@inheritDoc} */
58      @Override
59      public AbsoluteDate getValidityStart() {
60          return models.getFirstNonNullSpan().getStart();
61      }
62  
63      /** {@inheritDoc} */
64      @Override
65      public AbsoluteDate getValidityEnd() {
66          return models.getLastNonNullSpan().getEnd();
67      }
68  
69      /** {@inheritDoc} */
70      @Override
71      public List<ParameterDriver> getParametersDrivers() {
72          final List<ParameterDriver> drivers = new ArrayList<>();
73          models.forEach(model -> drivers.addAll(model.getParametersDrivers()));
74          return drivers;
75      }
76  
77      /** {@inheritDoc} */
78      @Override
79      public ClockOffset getOffset(final AbsoluteDate date) {
80          return getModel(date).getOffset(date);
81      }
82  
83      /** {@inheritDoc} */
84      @Override
85      public <T extends CalculusFieldElement<T>> FieldClockOffset<T> getFieldOffset(final FieldAbsoluteDate<T> date) {
86          return getModel(date.toAbsoluteDate()).getFieldOffset(date);
87      }
88  
89      /** {@inheritDoc} */
90      @Override
91      public FieldClockModel<Gradient> getFieldModel(final int freeParameters,
92              final Map<String, Integer> indices, final AbsoluteDate date) {
93          return getModel(date).getFieldModel(freeParameters, indices, date);
94      }
95  
96      /**
97       * Get the model valid at specified date.
98       *
99       * @param date date for which model is requested
100      * @return clock model valid at date
101      */
102     private ClockModel getModel(final AbsoluteDate date) {
103         final ClockModel clockModel = models.get(date);
104         if (clockModel == null) {
105             // this may happen if map is limited or not contiguous
106             // typically for models retrieved from SP3Ephemeris
107             throw new OrekitException(OrekitMessages.NO_DATA_GENERATED, date);
108         }
109         return clockModel;
110     }
111 
112 }