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.estimation.measurements.generation;
18  
19  import java.util.List;
20  import java.util.Map;
21  import java.util.SortedSet;
22  import java.util.TreeSet;
23  import java.util.function.Predicate;
24  
25  import org.orekit.estimation.measurements.EstimatedMeasurementBase;
26  import org.orekit.estimation.measurements.ObservableSatellite;
27  import org.orekit.estimation.measurements.ObservedMeasurement;
28  import org.orekit.propagation.sampling.OrekitStepInterpolator;
29  import org.orekit.time.AbsoluteDate;
30  import org.orekit.time.DatesSelector;
31  
32  
33  /** Base implementation of {@link Scheduler} managing {@link DatesSelector dates selection}.
34   * @param <T> the type of the measurement
35   * @author Luc Maisonobe
36   * @since 9.3
37   */
38  public abstract class AbstractScheduler<T extends ObservedMeasurement<T>> implements Scheduler<T> {
39  
40      /** Builder for individual measurements. */
41      private final MeasurementBuilder<T> builder;
42  
43      /** Selector for dates. */
44      private final DatesSelector selector;
45  
46      /** Predicate for a posteriori filtering of generated measurements.
47       * @since 13.0
48       */
49      private final Predicate<EstimatedMeasurementBase<T>> filter;
50  
51      /** Simple constructor.
52       * @param builder builder for individual measurements
53       * @param selector selector for dates
54       * @param filter predicate for a posteriori filtering of generated measurements
55       *               (measurements are accepted if the predicates evaluates to {@code true})
56       * @since 13.0
57       */
58      protected AbstractScheduler(final MeasurementBuilder<T> builder,
59                                  final DatesSelector selector,
60                                  final Predicate<EstimatedMeasurementBase<T>> filter) {
61          this.builder  = builder;
62          this.selector = selector;
63          this.filter   = filter;
64      }
65  
66      /** {@inheritDoc}
67       * <p>
68       * This implementation initialize the measurement builder.
69       * </p>
70       */
71      @Override
72      public void init(final AbsoluteDate start, final AbsoluteDate end) {
73          builder.init(start, end);
74      }
75  
76      /** {@inheritDoc} */
77      @Override
78      public MeasurementBuilder<T> getBuilder() {
79          return builder;
80      }
81  
82      /** Get the dates selector.
83       * @return dates selector
84       */
85      public DatesSelector getSelector() {
86          return selector;
87      }
88  
89      /** {@inheritDoc} */
90      @Override
91      public SortedSet<EstimatedMeasurementBase<T>> generate(final Map<ObservableSatellite, OrekitStepInterpolator> interpolators) {
92  
93          // select dates in the current step, using arbitrarily first interpolator
94          // as all interpolators cover the same range
95          final Map.Entry<ObservableSatellite, OrekitStepInterpolator> first = interpolators.entrySet().iterator().next();
96          final List<AbsoluteDate> dates = getSelector().selectDates(first.getValue().getPreviousState().getDate(),
97                                                                     first.getValue().getCurrentState().getDate());
98  
99          // generate measurements when feasible
100         final SortedSet<EstimatedMeasurementBase<T>> measurements = new TreeSet<>();
101         for (final AbsoluteDate date : dates) {
102             if (measurementIsFeasible(date)) {
103                 // a measurement is feasible at this date
104                 final EstimatedMeasurementBase<T> built = getBuilder().build(date, interpolators);
105                 if (filter.test(built)) {
106                     // add the generated measurement is the filters accepts it
107                     measurements.add(built);
108                 }
109             }
110         }
111 
112         return measurements;
113 
114     }
115 
116     /** Check if a measurement is feasible at some date.
117      * @param date date to check
118      * @return true if measurement if feasible
119      * @since 12.0
120      */
121     protected abstract boolean measurementIsFeasible(AbsoluteDate date);
122 
123 }