AbstractSolarActivityData.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.models.earth.atmosphere.data;
- import org.hipparchus.exception.DummyLocalizable;
- import org.orekit.data.DataProvidersManager;
- import org.orekit.data.DataSource;
- import org.orekit.errors.OrekitException;
- import org.orekit.errors.OrekitMessages;
- import org.orekit.models.earth.atmosphere.DTM2000InputParameters;
- import org.orekit.models.earth.atmosphere.NRLMSISE00InputParameters;
- import org.orekit.time.AbsoluteDate;
- import org.orekit.time.TimeScale;
- import org.orekit.time.TimeStamped;
- import org.orekit.utils.GenericTimeStampedCache;
- import org.orekit.utils.ImmutableTimeStampedCache;
- import org.orekit.utils.TimeStampedGenerator;
- import java.io.BufferedInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.text.ParseException;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.List;
- import java.util.function.Function;
- import java.util.stream.Collectors;
- /**
- * Abstract class for solar activity data.
- *
- * @param <L> type of the line parameters
- * @param <D> type of the solar activity data loader
- *
- * @author Vincent Cucchietti
- * @since 12.0
- */
- public abstract class AbstractSolarActivityData<L extends AbstractSolarActivityDataLoader.LineParameters, D extends AbstractSolarActivityDataLoader<L>>
- implements DTM2000InputParameters, NRLMSISE00InputParameters {
- /** Size of the list. */
- protected static final int N_NEIGHBORS = 2;
- /** Serializable UID. */
- private static final long serialVersionUID = 8804818166227680449L;
- /** Weather data thread safe cache. */
- private final transient GenericTimeStampedCache<L> cache;
- /** Supported names. */
- private final String supportedNames;
- /** UTC time scale. */
- private final TimeScale utc;
- /** First available date. */
- private final AbsoluteDate firstDate;
- /** Last available date. */
- private final AbsoluteDate lastDate;
- /**
- * @param supportedNames regular expression for supported AGI/CSSI space weather files names
- * @param loader data loader
- * @param dataProvidersManager provides access to auxiliary data files.
- * @param utc UTC time scale
- * @param maxSlots maximum number of independent cached time slots in the
- * {@link GenericTimeStampedCache time-stamped cache}
- * @param maxSpan maximum duration span in seconds of one slot in the {@link GenericTimeStampedCache time-stamped cache}
- * @param maxInterval time interval above which a new slot is created in the
- * {@link GenericTimeStampedCache time-stamped cache}
- * @param minimumStep overriding minimum step designed for non-homogeneous tabulated values. To be used for example when
- * caching monthly tabulated values. May be null.
- */
- protected AbstractSolarActivityData(final String supportedNames, final D loader,
- final DataProvidersManager dataProvidersManager, final TimeScale utc,
- final int maxSlots, final double maxSpan, final double maxInterval,
- final double minimumStep) {
- // Load data
- dataProvidersManager.feed(supportedNames, loader);
- // Create thread safe cache
- this.cache = new GenericTimeStampedCache<>(N_NEIGHBORS, maxSlots, maxSpan, maxInterval,
- new SolarActivityGenerator(loader.getDataSet()), minimumStep);
- // Initialise fields
- this.supportedNames = supportedNames;
- this.utc = utc;
- this.firstDate = loader.getMinDate();
- this.lastDate = loader.getMaxDate();
- }
- /**
- * Simple constructor.
- *
- * @param source source for the data
- * @param loader data loader
- * @param utc UTC time scale
- * @param maxSlots maximum number of independent cached time slots in the
- * {@link GenericTimeStampedCache time-stamped cache}
- * @param maxSpan maximum duration span in seconds of one slot in the {@link GenericTimeStampedCache time-stamped cache}
- * @param maxInterval time interval above which a new slot is created in the
- * {@link GenericTimeStampedCache time-stamped cache}
- * @param minimumStep overriding minimum step designed for non-homogeneous tabulated values. To be used for example when
- * caching monthly tabulated values. May be null.
- *
- * @since 12.0
- */
- public AbstractSolarActivityData(final DataSource source, final D loader, final TimeScale utc, final int maxSlots,
- final double maxSpan, final double maxInterval, final double minimumStep) {
- try {
- // Load file
- try (InputStream is = source.getOpener().openStreamOnce();
- BufferedInputStream bis = new BufferedInputStream(is)) {
- loader.loadData(bis, source.getName());
- }
- // Create thread safe cache
- this.cache = new GenericTimeStampedCache<>(N_NEIGHBORS, maxSlots, maxSpan, maxInterval,
- new SolarActivityGenerator(loader.getDataSet()), minimumStep);
- // Initialise fields
- this.supportedNames = source.getName();
- this.utc = utc;
- this.firstDate = loader.getMinDate();
- this.lastDate = loader.getMaxDate();
- }
- catch (IOException | ParseException ioe) {
- throw new OrekitException(ioe, new DummyLocalizable(ioe.getMessage()));
- }
- }
- /**
- * Performs a linear interpolation between two values The weights are computed from the time delta between previous date,
- * current date, next date.
- *
- * @param date current date
- * @param solarActivityToDoubleMapper mapping function taking solar activity as input and returning a double
- *
- * @return the value interpolated for the current date
- */
- protected double getLinearInterpolation(final AbsoluteDate date, final Function<L, Double> solarActivityToDoubleMapper) {
- // Create solar activity around current date
- final LocalSolarActivity localSolarActivity = new LocalSolarActivity(date);
- // Extract values
- return getLinearInterpolation(localSolarActivity, solarActivityToDoubleMapper);
- }
- /**
- * Performs a linear interpolation between two values The weights are computed from the time delta between previous date,
- * current date, next date.
- *
- * @param localSolarActivity solar activity around current date
- * @param solarActivityToDoubleMapper mapping function taking solar activity as input and returning a double
- *
- * @return the value interpolated for the current date
- */
- protected double getLinearInterpolation(final LocalSolarActivity localSolarActivity,
- final Function<L, Double> solarActivityToDoubleMapper) {
- // Extract values
- final L previousParameters = localSolarActivity.getPreviousParam();
- final double previousValue = solarActivityToDoubleMapper.apply(previousParameters);
- final L nextParameters = localSolarActivity.getNextParam();
- final double nextValue = solarActivityToDoubleMapper.apply(nextParameters);
- // Perform a linear interpolation
- final AbsoluteDate previousDate = localSolarActivity.getPreviousParam().getDate();
- final AbsoluteDate currentDate = localSolarActivity.getNextParam().getDate();
- final double dt = currentDate.durationFrom(previousDate);
- final AbsoluteDate date = localSolarActivity.getDate();
- final double previousWeight = currentDate.durationFrom(date) / dt;
- final double nextWeight = date.durationFrom(previousDate) / dt;
- // Returns the data interpolated at the date
- return previousValue * previousWeight + nextValue * nextWeight;
- }
- /**
- * Get underlying cache.
- *
- * @return cache
- */
- public GenericTimeStampedCache<L> getCache() {
- return cache;
- }
- /**
- * Get the supported names regular expression.
- *
- * @return the supported names.
- */
- public String getSupportedNames() {
- return supportedNames;
- }
- /**
- * Get the UTC timescale.
- *
- * @return UTC timescale
- */
- public TimeScale getUTC() {
- return utc;
- }
- /** {@inheritDoc} */
- @Override
- public AbsoluteDate getMinDate() {
- return firstDate;
- }
- /** {@inheritDoc} */
- @Override
- public AbsoluteDate getMaxDate() {
- return lastDate;
- }
- /** Container for weather parameters around current date. Allows for thread safe use. */
- protected class LocalSolarActivity implements TimeStamped {
- /** Date. */
- private final AbsoluteDate currentDate;
- /** Previous parameters. */
- private final L previousParam;
- /** Next parameters. */
- private final L nextParam;
- /**
- * Constructor.
- *
- * @param date current date
- */
- public LocalSolarActivity(final AbsoluteDate date) {
- // Asked date is before earliest available data
- if (date.durationFrom(firstDate) < 0) {
- throw new OrekitException(OrekitMessages.OUT_OF_RANGE_EPHEMERIDES_DATE_BEFORE, date, firstDate, lastDate,
- firstDate.durationFrom(date));
- }
- // Asked date is after latest available data
- if (date.durationFrom(lastDate) > 0) {
- throw new OrekitException(OrekitMessages.OUT_OF_RANGE_EPHEMERIDES_DATE_AFTER, date, firstDate, lastDate,
- date.durationFrom(lastDate));
- }
- final List<L> neighbours = cache.getNeighbors(date).collect(Collectors.toList());
- this.currentDate = date;
- this.previousParam = neighbours.get(0);
- this.nextParam = neighbours.get(1);
- }
- /** @return current date */
- public AbsoluteDate getDate() {
- return currentDate;
- }
- /** @return previous parameters */
- public L getPreviousParam() {
- return previousParam;
- }
- /** @return next parameters */
- public L getNextParam() {
- return nextParam;
- }
- }
- /** Generator used in the weather data cache. */
- protected class SolarActivityGenerator implements TimeStampedGenerator<L> {
- /**
- * Default time step to shift the date.
- * <p>
- * It is used so that, in the case where the earliest date is exactly at noon, we do not get the following interval
- * [previous day; current day] but rather the expected interval [current day; next day]
- */
- private static final double STEP = 1;
- /** Data set. */
- private final ImmutableTimeStampedCache<L> data;
- /**
- * Constructor.
- *
- * @param dataSet weather data
- */
- protected SolarActivityGenerator(final Collection<L> dataSet) {
- this.data = new ImmutableTimeStampedCache<>(N_NEIGHBORS, dataSet);
- }
- /** {@inheritDoc} */
- @Override
- public List<L> generate(final AbsoluteDate existingDate, final AbsoluteDate date) {
- // No prior data in the cache
- if (existingDate == null) {
- return data.getNeighbors(date).collect(Collectors.toList());
- }
- // Prior data in the cache, fill with data between date and existing date
- if (date.isBefore(existingDate)) {
- return generateDataFromEarliestToLatestDates(date, existingDate);
- }
- return generateDataFromEarliestToLatestDates(existingDate, date);
- }
- /**
- * Generate a list of parameters between earliest and latest dates.
- *
- * @param earliest earliest date
- * @param latest latest date
- *
- * @return list of parameters between earliest and latest dates
- */
- public List<L> generateDataFromEarliestToLatestDates(final AbsoluteDate earliest, final AbsoluteDate latest) {
- /* Gives first two parameters bracketing the earliest date
- * A date shifted by step is used so that, in the case where the earliest date is exactly noon, we do not get the
- * following interval [previous day; current day] but rather the expected interval [current day; next day] */
- List<L> neighbours = data.getNeighbors(earliest.shiftedBy(STEP)).collect(Collectors.toList());
- // Get next parameter until it brackets the latest date
- AbsoluteDate latestNeighbourDate = neighbours.get(1).getDate();
- final List<L> params = new ArrayList<>(neighbours);
- while (latestNeighbourDate.isBefore(latest)) {
- neighbours = data.getNeighbors(latestNeighbourDate.shiftedBy(STEP)).collect(Collectors.toList());
- params.add(neighbours.get(1));
- latestNeighbourDate = neighbours.get(1).getDate();
- }
- return params;
- }
- }
- }