FixedStepSelector.java

  1. /* Copyright 2002-2019 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (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.TimeScalesFactory#getUTC() UTC}, dates will be selected
  26.  * at whole minutes in UTC time.
  27.  * </p>
  28.  * <p>
  29.  * This class stores internally the last selected dates, so it is <em>not</em>
  30.  * thread-safe. A separate selector should be used for each thread in multi-threading
  31.  * context.
  32.  * </p>
  33.  * @author Luc Maisonobe
  34.  * @since 9.3
  35.  */
  36. public class FixedStepSelector implements DatesSelector {

  37.     /** Step between two consecutive dates. */
  38.     private final double step;

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

  41.     /** Last selected date. */
  42.     private AbsoluteDate last;

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

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

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

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

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

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

  77.         }

  78.         return selected;

  79.     }

  80. }