FixedStepSelector.java
- /* Copyright 2002-2025 CS GROUP
- * Licensed to CS GROUP (CS) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * CS licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.orekit.time;
- import java.util.ArrayList;
- import java.util.List;
- import org.hipparchus.util.FastMath;
- /** Selector generating a continuous stream of dates separated by a constant step.
- * <p>
- * The dates can be aligned to whole steps in some time scale. So for example
- * if a step of 60s is used and the alignment time scale is set to
- * {@link org.orekit.time.TimeScales#getUTC() UTC}, dates will be selected
- * at whole minutes in UTC time.
- * </p>
- * <p>
- * BEWARE! This class stores internally the last selected dates, so it is <em>neither</em>
- * reusable across several {@link org.orekit.estimation.measurements.generation.EventBasedScheduler
- * fixed step} or {@link org.orekit.estimation.measurements.generation.ContinuousScheduler
- * continuous} schedulers, <em>nor</em> thread-safe. A separate selector should be used for each
- * scheduler and for each thread in multi-threading context.
- * </p>
- * @author Luc Maisonobe
- * @since 9.3
- */
- public class FixedStepSelector implements DatesSelector {
- /** Step between two consecutive dates. */
- private final double step;
- /** Alignment time scale (null is alignment is not needed). */
- private final TimeScale alignmentTimeScale;
- /** Last selected date. */
- private AbsoluteDate last;
- /** Simple constructor.
- * @param step step between two consecutive dates (s)
- * @param alignmentTimeScale alignment time scale (null is alignment is not needed)
- */
- public FixedStepSelector(final double step, final TimeScale alignmentTimeScale) {
- this.step = step;
- this.alignmentTimeScale = alignmentTimeScale;
- this.last = null;
- }
- /** {@inheritDoc} */
- @Override
- public List<AbsoluteDate> selectDates(final AbsoluteDate start, final AbsoluteDate end) {
- final double sign = FastMath.copySign(1, end.durationFrom(start));
- final List<AbsoluteDate> selected = new ArrayList<>();
- final boolean reset = last == null || sign * start.durationFrom(last) > step;
- for (AbsoluteDate next = reset ? start : last.shiftedBy(sign * step);
- sign * next.durationFrom(end) <= 0;
- next = last.shiftedBy(sign * step)) {
- if (alignmentTimeScale != null) {
- // align date to time scale
- final double t = next.getComponents(alignmentTimeScale).getTime().getSecondsInLocalDay();
- final double dt = step * FastMath.round(t / step) - t;
- next = next.shiftedBy(dt);
- }
- if (sign * next.durationFrom(start) >= 0) {
- if (sign * next.durationFrom(end) <= 0) {
- // the date is within range, select it
- selected.add(next);
- } else {
- // we have exceeded date range
- break;
- }
- }
- last = next;
- }
- return selected;
- }
- }