BaseParameterDriversSequenceBuilder.java
/* Copyright 2022-2026 Luc Maisonobe
* 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.utils.drivers;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.TimeInterval;
import org.orekit.utils.TimeSpanMap;
/** Builder for {@link ParameterDriversSequence}.
* @param <T> type of the elements
* @param <P> type of the parameter driver
* @param <O> type of the parameter observer
* @param <S> type of the parameters drivers sequence
* @param <B> type of the parameters drivers sequence builder
* @author Luc Maisonobe
* @since 14.0
*/
public abstract class BaseParameterDriversSequenceBuilder<T,
P extends BaseParameterDriver<P, O>,
O extends BaseParameterObserver<P, O>,
S extends BaseParameterDriversSequence<P, O>,
B extends BaseParameterDriversSequenceBuilder<T, P, O, S, B>> {
/** Prefix for drivers limited to one time span. */
public static final String SPAN_PREFIX = "span-";
/** Base name of the parameters. */
private final String baseName;
/** Parameters scaling factor. */
private final double scale;
/** Minimum value. */
private final double minValue;
/** Maximum value. */
private final double maxValue;
/** Reference values. */
private final TimeSpanMap<T> spans;
/** Constructor for an initially empty builder.
* <p>
* The builder {@link #build() build()} method cannot be called right after construction.
* Some reference values must be set before, either by calling the
* {@link #addReferenceValue(Object) addReferenceValue(referenceValue)} method once, or by
* calling the {@link #addReferenceValue(Object, AbsoluteDate, AbsoluteDate)
* addReferenceValue(referenceValue, earliestValidityDate, latestValidityDate)} method as many times
* as needed to cover the usage range before the {@link #build() build()} method can be called.
* </p>
* @param baseName base name of the parameters
* @param scale scaling factor to convert the parameters value to
* non-dimensional (typically set to the expected standard deviation
* of the parameter), it must be non-zero
* @param minValue minimum value allowed
* @param maxValue maximum value allowed
* @param defaultValue default value valid throughout timeline
*/
protected BaseParameterDriversSequenceBuilder(final String baseName, final double scale,
final double minValue, final double maxValue,
final T defaultValue) {
this.baseName = baseName;
this.scale = scale;
this.minValue = minValue;
this.maxValue = maxValue;
this.spans = new TimeSpanMap<>(defaultValue);
}
/** Add a reference value throughout timeline.
* <p>
* Calling this method is equivalent to call
* {@code addReferenceValue(referenceValue, AbsoluteDate.PAST_INFINITY, AbsoluteDate.FUTURE_INFINITY)}.
* </p>
* @param referenceValue reference value
* @return the instance itself, allowing use of the fluent interface pattern
*/
public B addReferenceValue(final T referenceValue) {
return addReferenceValue(referenceValue, AbsoluteDate.PAST_INFINITY, AbsoluteDate.FUTURE_INFINITY);
}
/** Add a reference value valid for a time span.
* @param referenceValue reference value
* @param earliestValidityDate date after which the coefficient is valid
* @param latestValidityDate date before which the coefficient is valid
* @return the instance itself, allowing use of the fluent interface pattern
*/
public B addReferenceValue(final T referenceValue,
final AbsoluteDate earliestValidityDate,
final AbsoluteDate latestValidityDate) {
spans.addValidBetween(referenceValue, earliestValidityDate, latestValidityDate);
@SuppressWarnings("unchecked")
final B self = (B) this;
return self;
}
/** Build a {@link BaseParameterDriversSequence}.
* <p>
* If only one reference value has been set, its name will be the base name set at construction.
* If several reference values have been set, their names will be built by concatenating together
* {@link #SPAN_PREFIX}, followed by the base name set at construction, followed by a single "-",
* and finally appending the index of the parameter driver, counting from 0.
* </p>
* @return built sequence
*/
public S build() {
TimeSpanMap.Span<T> current;
try {
current = spans.getFirstNonNullSpan();
} catch (OrekitException oe) {
// user did not call addReferenceValue
throw new OrekitException(oe, OrekitMessages.NO_REFERENCE_VALUES_SET);
}
// check if there is one or several reference values
final boolean oneValueOnly = current == spans.getLastNonNullSpan();
final TimeSpanMap<P> drivers = new TimeSpanMap<>(null);
// build the drivers
int index = 0;
while (current != null) {
// safety check
if (current.getData() == null) {
if (current.next() == null) {
// null data after the sequence is OK
break;
} else {
// null date in the middle of the sequence
throw new OrekitException(OrekitMessages.MISSING_REFERENCE_VALUE,
current.getStart(), current.getEnd());
}
}
// build the name of the driver, using a chronological index if needed
final String name = oneValueOnly ? baseName : SPAN_PREFIX + baseName + "-" + index++;
// create the driver
final P driver = buildDriver(name, current.getData(), scale, minValue, maxValue,
TimeInterval.of(current.getStart(), current.getEnd(), false));
// add it to the map
drivers.addValidBetween(driver, current.getStart(), current.getEnd());
// prepare handling of next reference value
current = current.next();
}
return buildSequence(drivers);
}
/** Build a parameter driver.
* @param name name of the parameter
* @param referenceValue reference value of the parameter
* @param scaleFactor scaling factor to convert the parameters value to non-dimensional (typically set to the
* expected standard deviation of the parameter), it must be non-zero
* @param min minimum value allowed
* @param max maximum value allowed
* @param validity validity interval
* @return built parameter driver
*/
protected abstract P buildDriver(String name, T referenceValue, double scaleFactor,
double min, double max, TimeInterval validity);
/** Build a sequence.
* @param drivers drivers sequence
* @return built sequence
*/
protected abstract S buildSequence(TimeSpanMap<P> drivers);
}