FixedStepSelector.java

  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.time;

  18. import java.util.ArrayList;
  19. import java.util.List;

  20. import org.hipparchus.util.FastMath;

  21. /** Selector generating a continuous stream of dates separated by a constant step.
  22.  * <p>
  23.  * The dates can be aligned to whole steps in some time scale. So for example
  24.  * if a step of 60s is used and the alignment time scale is set to
  25.  * {@link org.orekit.time.TimeScales#getUTC() UTC}, dates will be selected
  26.  * at whole minutes in UTC time.
  27.  * </p>
  28.  * <p>
  29.  * BEWARE! This class stores internally the last selected dates, so it is <em>neither</em>
  30.  * reusable across several {@link org.orekit.estimation.measurements.generation.EventBasedScheduler
  31.  * fixed step} or {@link org.orekit.estimation.measurements.generation.ContinuousScheduler
  32.  * continuous} schedulers, <em>nor</em> thread-safe. A separate selector should be used for each
  33.  * scheduler and for each thread in multi-threading context.
  34.  * </p>
  35.  * @author Luc Maisonobe
  36.  * @since 9.3
  37.  */
  38. public class FixedStepSelector implements DatesSelector {

  39.     /** Step between two consecutive dates. */
  40.     private final double step;

  41.     /** Alignment time scale (null is alignment is not needed). */
  42.     private final TimeScale alignmentTimeScale;

  43.     /** Last selected date. */
  44.     private AbsoluteDate last;

  45.     /** Simple constructor.
  46.      * @param step step between two consecutive dates (s)
  47.      * @param alignmentTimeScale alignment time scale (null is alignment is not needed)
  48.      */
  49.     public FixedStepSelector(final double step, final TimeScale alignmentTimeScale) {
  50.         this.step               = step;
  51.         this.alignmentTimeScale = alignmentTimeScale;
  52.         this.last               = null;
  53.     }

  54.     /** {@inheritDoc} */
  55.     @Override
  56.     public List<AbsoluteDate> selectDates(final AbsoluteDate start, final AbsoluteDate end) {

  57.         final double sign = FastMath.copySign(1, end.durationFrom(start));
  58.         final List<AbsoluteDate> selected = new ArrayList<>();

  59.         final boolean reset = last == null || sign * start.durationFrom(last) > step;
  60.         for (AbsoluteDate next = reset ? start : last.shiftedBy(sign * step);
  61.              sign * next.durationFrom(end) <= 0;
  62.              next = last.shiftedBy(sign * step)) {

  63.             if (alignmentTimeScale != null) {
  64.                 // align date to time scale
  65.                 final double t  = next.getComponents(alignmentTimeScale).getTime().getSecondsInLocalDay();
  66.                 final double dt = step * FastMath.round(t / step) - t;
  67.                 next = next.shiftedBy(dt);
  68.             }

  69.             if (sign * next.durationFrom(start) >= 0) {
  70.                 if (sign * next.durationFrom(end) <= 0) {
  71.                     // the date is within range, select it
  72.                     selected.add(next);
  73.                 } else {
  74.                     // we have exceeded date range
  75.                     break;
  76.                 }
  77.             }
  78.             last = next;

  79.         }

  80.         return selected;

  81.     }

  82. }