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