LazyLoadedEop.java

  1. /* Contributed in the public domain.
  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.frames;

  18. import java.util.ArrayList;
  19. import java.util.HashMap;
  20. import java.util.List;
  21. import java.util.Map;
  22. import java.util.SortedSet;
  23. import java.util.TreeSet;
  24. import java.util.function.Supplier;

  25. import org.orekit.data.DataProvidersManager;
  26. import org.orekit.errors.OrekitException;
  27. import org.orekit.time.ChronologicalComparator;
  28. import org.orekit.time.TimeScale;
  29. import org.orekit.time.TimeScales;
  30. import org.orekit.utils.Constants;
  31. import org.orekit.utils.IERSConventions;

  32. /**
  33.  * Loads Earth Orientation Parameters (EOP) from a configured set of {@link
  34.  * EOPHistoryLoader}s on demand. Methods are synchronized so it is safe for access from
  35.  * multiple threads.
  36.  *
  37.  * @author Guylaine Prat
  38.  * @author Luc Maisonobe
  39.  * @author Pascal Parraud
  40.  * @author Evan Ward
  41.  * @see LazyLoadedFrames
  42.  * @see FramesFactory
  43.  * @since 10.1
  44.  */
  45. public class LazyLoadedEop {

  46.     /** Provides access to the EOP data files. */
  47.     private final DataProvidersManager dataProvidersManager;
  48.     /** Loaders for Earth Orientation parameters. */
  49.     private final Map<IERSConventions, List<EOPHistoryLoader>> eopHistoryLoaders;
  50.     /** Threshold for EOP continuity. */
  51.     private double eopContinuityThreshold;

  52.     /**
  53.      * Create a new instance for loading EOP data from multiple {@link
  54.      * EOPHistoryLoader}s.
  55.      *
  56.      * @param dataProvidersManager provides access to the needed EOP data files.
  57.      */
  58.     public LazyLoadedEop(final DataProvidersManager dataProvidersManager) {
  59.         this.dataProvidersManager = dataProvidersManager;
  60.         this.eopHistoryLoaders = new HashMap<>();
  61.         this.eopContinuityThreshold = 5 * Constants.JULIAN_DAY;
  62.     }

  63.     /**
  64.      * Get the data providers manager for this instance.
  65.      *
  66.      * @return the provider of EOP data files.
  67.      */
  68.     public DataProvidersManager getDataProvidersManager() {
  69.         return dataProvidersManager;
  70.     }

  71.     /**
  72.      * Add the default loaders EOP history (IAU 1980 precession/nutation).
  73.      * <p>
  74.      * The default loaders look for IERS EOP C04 and bulletins B files. They correspond to
  75.      * {@link IERSConventions#IERS_1996 IERS 1996} conventions.
  76.      * </p>
  77.      *
  78.      * @param rapidDataColumnsSupportedNames regular expression for supported rapid data
  79.      *                                       columns EOP files names (may be null if the
  80.      *                                       default IERS file names are used)
  81.      * @param rapidDataXMLSupportedNames     regular expression for supported rapid data
  82.      *                                       XML EOP files names (may be null if the
  83.      *                                       default IERS file names are used)
  84.      * @param eopC04SupportedNames           regular expression for supported EOP C04
  85.      *                                       files names (may be null if the default IERS
  86.      *                                       file names are used)
  87.      * @param bulletinBSupportedNames        regular expression for supported bulletin B
  88.      *                                       files names (may be null if the default IERS
  89.      *                                       file names are used)
  90.      * @param bulletinASupportedNames        regular expression for supported bulletin A
  91.      *                                       files names (may be null if the default IERS
  92.      *                                       file names are used)
  93.      * @param utcSupplier                    UTC time scale supplier. Value is not
  94.      *                                       accessed until attempting to load EOP.
  95.      * @see <a href="http://hpiers.obspm.fr/eoppc/eop/eopc04/">IERS EOP C04 files</a>
  96.      * @see #addEOPHistoryLoader(IERSConventions, EOPHistoryLoader)
  97.      * @see #clearEOPHistoryLoaders()
  98.      * @see #addDefaultEOP2000HistoryLoaders(String, String, String, String, String, Supplier)
  99.      */
  100.     public void addDefaultEOP1980HistoryLoaders(final String rapidDataColumnsSupportedNames,
  101.                                                 final String rapidDataXMLSupportedNames,
  102.                                                 final String eopC04SupportedNames,
  103.                                                 final String bulletinBSupportedNames,
  104.                                                 final String bulletinASupportedNames,
  105.                                                 final Supplier<TimeScale> utcSupplier) {
  106.         final String rapidColNames =
  107.                 (rapidDataColumnsSupportedNames == null) ?
  108.                         FramesFactory.RAPID_DATA_PREDICTION_COLUMNS_1980_FILENAME :
  109.                         rapidDataColumnsSupportedNames;
  110.         addEOPHistoryLoader(IERSConventions.IERS_1996,
  111.                 new RapidDataAndPredictionColumnsLoader(false, rapidColNames,
  112.                         dataProvidersManager, utcSupplier));
  113.         final String rapidXmlNames =
  114.                 (rapidDataXMLSupportedNames == null) ?
  115.                         FramesFactory.RAPID_DATA_PREDICTION_XML_1980_FILENAME :
  116.                         rapidDataXMLSupportedNames;
  117.         addEOPHistoryLoader(IERSConventions.IERS_1996,
  118.                 new RapidDataAndPredictionXMLLoader(rapidXmlNames, dataProvidersManager,
  119.                         utcSupplier));
  120.         final String eopcNames =
  121.                 (eopC04SupportedNames == null) ?
  122.                         FramesFactory.EOPC04_1980_FILENAME : eopC04SupportedNames;
  123.         addEOPHistoryLoader(IERSConventions.IERS_1996,
  124.                 new EOPC04FilesLoader(eopcNames, dataProvidersManager, utcSupplier));
  125.         final String bulBNames =
  126.                 (bulletinBSupportedNames == null) ?
  127.                         FramesFactory.BULLETINB_1980_FILENAME : bulletinBSupportedNames;
  128.         addEOPHistoryLoader(IERSConventions.IERS_1996,
  129.                 new BulletinBFilesLoader(bulBNames, dataProvidersManager, utcSupplier));
  130.         final String bulANames =
  131.                 (bulletinASupportedNames == null) ?
  132.                         FramesFactory.BULLETINA_FILENAME : bulletinASupportedNames;
  133.         addEOPHistoryLoader(IERSConventions.IERS_1996,
  134.                 new BulletinAFilesLoader(bulANames, dataProvidersManager, utcSupplier));
  135.     }

  136.     /**
  137.      * Add the default loaders for EOP history (IAU 2000/2006 precession/nutation).
  138.      * <p>
  139.      * The default loaders look for IERS EOP C04 and bulletins B files. They correspond to
  140.      * both {@link IERSConventions#IERS_2003 IERS 2003} and {@link
  141.      * IERSConventions#IERS_2010 IERS 2010} conventions.
  142.      * </p>
  143.      *
  144.      * @param rapidDataColumnsSupportedNames regular expression for supported rapid data
  145.      *                                       columns EOP files names (may be null if the
  146.      *                                       default IERS file names are used)
  147.      * @param rapidDataXMLSupportedNames     regular expression for supported rapid data
  148.      *                                       XML EOP files names (may be null if the
  149.      *                                       default IERS file names are used)
  150.      * @param eopC04SupportedNames           regular expression for supported EOP C04
  151.      *                                       files names (may be null if the default IERS
  152.      *                                       file names are used)
  153.      * @param bulletinBSupportedNames        regular expression for supported bulletin B
  154.      *                                       files names (may be null if the default IERS
  155.      *                                       file names are used)
  156.      * @param bulletinASupportedNames        regular expression for supported bulletin A
  157.      *                                       files names (may be null if the default IERS
  158.      *                                       file names are used)
  159.      * @param utcSupplier                    UTC time scale supplier. Value is not
  160.      *                                       accessed until attempting to load EOP.
  161.      * @see <a href="http://hpiers.obspm.fr/eoppc/eop/eopc04/">IERS EOP C04 files</a>
  162.      * @see #addEOPHistoryLoader(IERSConventions, EOPHistoryLoader)
  163.      * @see #clearEOPHistoryLoaders()
  164.      * @see #addDefaultEOP1980HistoryLoaders(String, String, String, String, String, Supplier)
  165.      */
  166.     public void addDefaultEOP2000HistoryLoaders(final String rapidDataColumnsSupportedNames,
  167.                                                 final String rapidDataXMLSupportedNames,
  168.                                                 final String eopC04SupportedNames,
  169.                                                 final String bulletinBSupportedNames,
  170.                                                 final String bulletinASupportedNames,
  171.                                                 final Supplier<TimeScale> utcSupplier) {
  172.         final String rapidColNames =
  173.                 (rapidDataColumnsSupportedNames == null) ?
  174.                         FramesFactory.RAPID_DATA_PREDICITON_COLUMNS_2000_FILENAME :
  175.                         rapidDataColumnsSupportedNames;
  176.         addEOPHistoryLoader(IERSConventions.IERS_2003,
  177.                 new RapidDataAndPredictionColumnsLoader(
  178.                         true, rapidColNames, dataProvidersManager, utcSupplier));
  179.         addEOPHistoryLoader(IERSConventions.IERS_2010,
  180.                 new RapidDataAndPredictionColumnsLoader(
  181.                         true, rapidColNames, dataProvidersManager, utcSupplier));
  182.         final String rapidXmlNames =
  183.                 (rapidDataXMLSupportedNames == null) ?
  184.                         FramesFactory.RAPID_DATA_PREDICITON_XML_2000_FILENAME :
  185.                         rapidDataXMLSupportedNames;
  186.         addEOPHistoryLoader(IERSConventions.IERS_2003,
  187.                 new RapidDataAndPredictionXMLLoader(
  188.                         rapidXmlNames, dataProvidersManager, utcSupplier));
  189.         addEOPHistoryLoader(IERSConventions.IERS_2010,
  190.                 new RapidDataAndPredictionXMLLoader(
  191.                         rapidXmlNames, dataProvidersManager, utcSupplier));
  192.         final String eopcNames =
  193.                 (eopC04SupportedNames == null) ?
  194.                         FramesFactory.EOPC04_2000_FILENAME : eopC04SupportedNames;
  195.         addEOPHistoryLoader(IERSConventions.IERS_2003,
  196.                 new EOPC04FilesLoader(eopcNames, dataProvidersManager, utcSupplier));
  197.         addEOPHistoryLoader(IERSConventions.IERS_2010,
  198.                 new EOPC04FilesLoader(eopcNames, dataProvidersManager, utcSupplier));
  199.         final String bulBNames =
  200.                 (bulletinBSupportedNames == null) ?
  201.                         FramesFactory.BULLETINB_2000_FILENAME : bulletinBSupportedNames;
  202.         addEOPHistoryLoader(IERSConventions.IERS_2003,
  203.                 new BulletinBFilesLoader(bulBNames, dataProvidersManager, utcSupplier));
  204.         addEOPHistoryLoader(IERSConventions.IERS_2010,
  205.                 new BulletinBFilesLoader(bulBNames, dataProvidersManager, utcSupplier));
  206.         final String bulANames =
  207.                 (bulletinASupportedNames == null) ?
  208.                         FramesFactory.BULLETINA_FILENAME : bulletinASupportedNames;
  209.         addEOPHistoryLoader(IERSConventions.IERS_2003,
  210.                 new BulletinAFilesLoader(bulANames, dataProvidersManager, utcSupplier));
  211.         addEOPHistoryLoader(IERSConventions.IERS_2010,
  212.                 new BulletinAFilesLoader(bulANames, dataProvidersManager, utcSupplier));
  213.     }

  214.     /**
  215.      * Add a loader for Earth Orientation Parameters history.
  216.      *
  217.      * @param conventions IERS conventions to which EOP history applies
  218.      * @param loader      custom loader to add for the EOP history
  219.      * @see #addDefaultEOP1980HistoryLoaders(String, String, String, String, String, Supplier)
  220.      * @see #clearEOPHistoryLoaders()
  221.      */
  222.     public void addEOPHistoryLoader(final IERSConventions conventions, final EOPHistoryLoader loader) {
  223.         synchronized (eopHistoryLoaders) {
  224.             if (!eopHistoryLoaders.containsKey(conventions)) {
  225.                 eopHistoryLoaders.put(conventions, new ArrayList<>());
  226.             }
  227.             eopHistoryLoaders.get(conventions).add(loader);
  228.         }
  229.     }

  230.     /**
  231.      * Clear loaders for Earth Orientation Parameters history.
  232.      *
  233.      * @see #addEOPHistoryLoader(IERSConventions, EOPHistoryLoader)
  234.      * @see #addDefaultEOP1980HistoryLoaders(String, String, String, String, String, Supplier)
  235.      */
  236.     public void clearEOPHistoryLoaders() {
  237.         synchronized (eopHistoryLoaders) {
  238.             eopHistoryLoaders.clear();
  239.         }
  240.     }

  241.     /**
  242.      * Set the threshold to check EOP continuity.
  243.      * <p>
  244.      * The default threshold (used if this method is never called) is 5 Julian days. If
  245.      * after loading EOP entries some holes between entries exceed this threshold, an
  246.      * exception will be triggered.
  247.      * </p>
  248.      * <p>
  249.      * One case when calling this method is really useful is for applications that use a
  250.      * single Bulletin A, as these bulletins have a roughly one month wide hole for the
  251.      * first bulletin of each month, which contains older final data in addition to the
  252.      * rapid data and the predicted data.
  253.      * </p>
  254.      *
  255.      * @param threshold threshold to use for checking EOP continuity (in seconds)
  256.      */
  257.     public void setEOPContinuityThreshold(final double threshold) {
  258.         eopContinuityThreshold = threshold;
  259.     }

  260.     /**
  261.      * Get Earth Orientation Parameters history.
  262.      * <p>
  263.      * If no {@link EOPHistoryLoader} has been added by calling {@link
  264.      * #addEOPHistoryLoader(IERSConventions, EOPHistoryLoader) addEOPHistoryLoader} or if
  265.      * {@link #clearEOPHistoryLoaders() clearEOPHistoryLoaders} has been called
  266.      * afterwards, the {@link #addDefaultEOP1980HistoryLoaders(String, String, String,
  267.      * String, String, Supplier)} and {@link #addDefaultEOP2000HistoryLoaders(String,
  268.      * String, String, String, String, Supplier)} methods will be called automatically
  269.      * with supported file names parameters all set to null, in order to get the default
  270.      * loaders configuration.
  271.      * </p>
  272.      *
  273.      * @param conventions conventions for which EOP history is requested
  274.      * @param simpleEOP   if true, tidal effects are ignored when interpolating EOP
  275.      * @param timeScales  to use when loading EOP and computing corrections.
  276.      * @return Earth Orientation Parameters history
  277.      */
  278.     public EOPHistory getEOPHistory(final IERSConventions conventions,
  279.                                     final boolean simpleEOP,
  280.                                     final TimeScales timeScales) {

  281.         synchronized (eopHistoryLoaders) {

  282.             if (eopHistoryLoaders.isEmpty()) {
  283.                 // set up using default loaders
  284.                 final Supplier<TimeScale> utcSupplier = timeScales::getUTC;
  285.                 addDefaultEOP2000HistoryLoaders(null, null, null, null, null, utcSupplier);
  286.                 addDefaultEOP1980HistoryLoaders(null, null, null, null, null, utcSupplier);
  287.             }

  288.             // TimeStamped based set needed to remove duplicates
  289.             OrekitException pendingException = null;
  290.             final SortedSet<EOPEntry> data = new TreeSet<>(new ChronologicalComparator());

  291.             // try to load canonical data if available
  292.             if (eopHistoryLoaders.containsKey(conventions)) {
  293.                 for (final EOPHistoryLoader loader : eopHistoryLoaders.get(conventions)) {
  294.                     try {
  295.                         loader.fillHistory(
  296.                                 conventions.getNutationCorrectionConverter(timeScales),
  297.                                 data);
  298.                     } catch (OrekitException oe) {
  299.                         pendingException = oe;
  300.                     }
  301.                 }
  302.             }

  303.             if (data.isEmpty() && pendingException != null) {
  304.                 throw pendingException;
  305.             }

  306.             final EOPHistory history =
  307.                     new EOPHistory(conventions, data, simpleEOP, timeScales);
  308.             history.checkEOPContinuity(eopContinuityThreshold);
  309.             return history;

  310.         }

  311.     }

  312. }