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.     /** Degree for EOP interpolation.
  53.      * @since 12.0
  54.      */
  55.     private int interpolationDegree;

  56.     /**
  57.      * Create a new instance for loading EOP data from multiple {@link
  58.      * EopHistoryLoader}s.
  59.      *
  60.      * @param dataProvidersManager provides access to the needed EOP data files.
  61.      */
  62.     public LazyLoadedEop(final DataProvidersManager dataProvidersManager) {
  63.         this.dataProvidersManager   = dataProvidersManager;
  64.         this.eopHistoryLoaders      = new HashMap<>();
  65.         this.eopContinuityThreshold = 5 * Constants.JULIAN_DAY;
  66.         this.interpolationDegree    = EOPHistory.DEFAULT_INTERPOLATION_DEGREE;
  67.     }

  68.     /**
  69.      * Get the data providers manager for this instance.
  70.      *
  71.      * @return the provider of EOP data files.
  72.      */
  73.     public DataProvidersManager getDataProvidersManager() {
  74.         return dataProvidersManager;
  75.     }

  76.     /**
  77.      * Add the default loaders EOP history (IAU 1980 precession/nutation).
  78.      * <p>
  79.      * The default loaders look for IERS EOP C04 and bulletins B files. They correspond to
  80.      * {@link IERSConventions#IERS_1996 IERS 1996} conventions.
  81.      * </p>
  82.      *
  83.      * @param rapidDataColumnsSupportedNames regular expression for supported rapid data
  84.      *                                       columns EOP files names (may be null if the
  85.      *                                       default IERS file names are used)
  86.      * @param xmlSupportedNames              regular expression for supported XML EOP
  87.      *                                       files names (may be null if the
  88.      *                                       default IERS file names are used)
  89.      * @param eopC04SupportedNames           regular expression for supported EOP C04
  90.      *                                       files names (may be null if the default IERS
  91.      *                                       file names are used)
  92.      * @param bulletinBSupportedNames        regular expression for supported bulletin B
  93.      *                                       files names (may be null if the default IERS
  94.      *                                       file names are used)
  95.      * @param bulletinASupportedNames        regular expression for supported bulletin A
  96.      *                                       files names (may be null if the default IERS
  97.      *                                       file names are used)
  98.      * @param csvSupportedNames              regular expression for supported csv files names
  99.      *                                       (may be null if the default IERS file names are used)
  100.      * @param utcSupplier                    UTC time scale supplier. Value is not
  101.      *                                       accessed until attempting to load EOP.
  102.      * @see <a href="https://datacenter.iers.org/products/eop/">IERS https data download</a>
  103.      * @see #addEOPHistoryLoader(IERSConventions, EopHistoryLoader)
  104.      * @see #clearEOPHistoryLoaders()
  105.      * @see #addDefaultEOP2000HistoryLoaders(String, String, String, String, String, String, Supplier)
  106.      * @since 12.0
  107.      */
  108.     public void addDefaultEOP1980HistoryLoaders(final String rapidDataColumnsSupportedNames,
  109.                                                 final String xmlSupportedNames,
  110.                                                 final String eopC04SupportedNames,
  111.                                                 final String bulletinBSupportedNames,
  112.                                                 final String bulletinASupportedNames,
  113.                                                 final String csvSupportedNames,
  114.                                                 final Supplier<TimeScale> utcSupplier) {
  115.         final String rapidColNames =
  116.                 (rapidDataColumnsSupportedNames == null) ?
  117.                         FramesFactory.RAPID_DATA_PREDICTION_COLUMNS_1980_FILENAME :
  118.                         rapidDataColumnsSupportedNames;
  119.         addEOPHistoryLoader(IERSConventions.IERS_1996,
  120.                 new RapidDataAndPredictionColumnsLoader(false, rapidColNames,
  121.                         dataProvidersManager, utcSupplier));
  122.         final String xmlNames = (xmlSupportedNames == null) ?
  123.                                 FramesFactory.XML_1980_FILENAME :
  124.                                 xmlSupportedNames;
  125.         addEOPHistoryLoader(IERSConventions.IERS_1996,
  126.                             new EopXmlLoader(xmlNames, dataProvidersManager, utcSupplier));
  127.         final String eopcNames =
  128.                 (eopC04SupportedNames == null) ?
  129.                         FramesFactory.EOPC04_1980_FILENAME : eopC04SupportedNames;
  130.         addEOPHistoryLoader(IERSConventions.IERS_1996,
  131.                 new EopC04FilesLoader(eopcNames, dataProvidersManager, utcSupplier));
  132.         final String bulBNames =
  133.                 (bulletinBSupportedNames == null) ?
  134.                         FramesFactory.BULLETINB_1980_FILENAME : bulletinBSupportedNames;
  135.         addEOPHistoryLoader(IERSConventions.IERS_1996,
  136.                 new BulletinBFilesLoader(bulBNames, dataProvidersManager, utcSupplier));
  137.         final String bulANames =
  138.                 (bulletinASupportedNames == null) ?
  139.                         FramesFactory.BULLETINA_FILENAME : bulletinASupportedNames;
  140.         addEOPHistoryLoader(IERSConventions.IERS_1996,
  141.                 new BulletinAFilesLoader(bulANames, dataProvidersManager, utcSupplier));
  142.         final String csvNames = (csvSupportedNames == null) ?
  143.                                 FramesFactory.CSV_FILENAME : csvSupportedNames;
  144.         addEOPHistoryLoader(IERSConventions.IERS_1996,
  145.                             new EopCsvFilesLoader(csvNames, dataProvidersManager, utcSupplier));
  146.     }

  147.     /**
  148.      * Add the default loaders for EOP history (IAU 2000/2006 precession/nutation).
  149.      * <p>
  150.      * The default loaders look for IERS EOP C04 and bulletins B files. They correspond to
  151.      * both {@link IERSConventions#IERS_2003 IERS 2003} and {@link
  152.      * IERSConventions#IERS_2010 IERS 2010} conventions.
  153.      * </p>
  154.      *
  155.      * @param rapidDataColumnsSupportedNames regular expression for supported rapid data
  156.      *                                       columns EOP files names (may be null if the
  157.      *                                       default IERS file names are used)
  158.      * @param xmlSupportedNames              regular expression for supported XML EOP
  159.      *                                       files names (may be null if the
  160.      *                                       default IERS file names are used)
  161.      * @param eopC04SupportedNames           regular expression for supported EOP C04
  162.      *                                       files names (may be null if the default IERS
  163.      *                                       file names are used)
  164.      * @param bulletinBSupportedNames        regular expression for supported bulletin B
  165.      *                                       files names (may be null if the default IERS
  166.      *                                       file names are used)
  167.      * @param bulletinASupportedNames        regular expression for supported bulletin A
  168.      *                                       files names (may be null if the default IERS
  169.      *                                       file names are used)
  170.      * @param csvSupportedNames              regular expression for supported csv files names
  171.      *                                       (may be null if the default IERS file names are used)
  172.      * @param utcSupplier                    UTC time scale supplier. Value is not
  173.      *                                       accessed until attempting to load EOP.
  174.      * @see <a href="https://datacenter.iers.org/products/eop/">IERS https data download</a>
  175.      * @see #addEOPHistoryLoader(IERSConventions, EopHistoryLoader)
  176.      * @see #clearEOPHistoryLoaders()
  177.      * @see #addDefaultEOP1980HistoryLoaders(String, String, String, String, String, String, Supplier)
  178.      * @since 12.0
  179.      */
  180.     public void addDefaultEOP2000HistoryLoaders(final String rapidDataColumnsSupportedNames,
  181.                                                 final String xmlSupportedNames,
  182.                                                 final String eopC04SupportedNames,
  183.                                                 final String bulletinBSupportedNames,
  184.                                                 final String bulletinASupportedNames,
  185.                                                 final String csvSupportedNames,
  186.                                                 final Supplier<TimeScale> utcSupplier) {
  187.         final String rapidColNames =
  188.                 (rapidDataColumnsSupportedNames == null) ?
  189.                         FramesFactory.RAPID_DATA_PREDICTION_COLUMNS_2000_FILENAME :
  190.                         rapidDataColumnsSupportedNames;
  191.         addEOPHistoryLoader(IERSConventions.IERS_2003,
  192.                             new RapidDataAndPredictionColumnsLoader(true, rapidColNames, dataProvidersManager, utcSupplier));
  193.         addEOPHistoryLoader(IERSConventions.IERS_2010,
  194.                             new RapidDataAndPredictionColumnsLoader(true, rapidColNames, dataProvidersManager, utcSupplier));
  195.         final String xmlNames = (xmlSupportedNames == null) ?
  196.                                 FramesFactory.XML_2000_FILENAME :
  197.                                 xmlSupportedNames;
  198.         addEOPHistoryLoader(IERSConventions.IERS_2003,
  199.                             new EopXmlLoader(xmlNames, dataProvidersManager, utcSupplier));
  200.         addEOPHistoryLoader(IERSConventions.IERS_2010,
  201.                             new EopXmlLoader(xmlNames, dataProvidersManager, utcSupplier));
  202.         final String eopcNames = (eopC04SupportedNames == null) ?
  203.                                  FramesFactory.EOPC04_2000_FILENAME : eopC04SupportedNames;
  204.         addEOPHistoryLoader(IERSConventions.IERS_2003,
  205.                 new EopC04FilesLoader(eopcNames, dataProvidersManager, utcSupplier));
  206.         addEOPHistoryLoader(IERSConventions.IERS_2010,
  207.                 new EopC04FilesLoader(eopcNames, dataProvidersManager, utcSupplier));
  208.         final String bulBNames = (bulletinBSupportedNames == null) ?
  209.                                  FramesFactory.BULLETINB_2000_FILENAME : bulletinBSupportedNames;
  210.         addEOPHistoryLoader(IERSConventions.IERS_2003,
  211.                 new BulletinBFilesLoader(bulBNames, dataProvidersManager, utcSupplier));
  212.         addEOPHistoryLoader(IERSConventions.IERS_2010,
  213.                 new BulletinBFilesLoader(bulBNames, dataProvidersManager, utcSupplier));
  214.         final String bulANames = (bulletinASupportedNames == null) ?
  215.                                  FramesFactory.BULLETINA_FILENAME : bulletinASupportedNames;
  216.         addEOPHistoryLoader(IERSConventions.IERS_2003,
  217.                             new BulletinAFilesLoader(bulANames, dataProvidersManager, utcSupplier));
  218.         addEOPHistoryLoader(IERSConventions.IERS_2010,
  219.                             new BulletinAFilesLoader(bulANames, dataProvidersManager, utcSupplier));
  220.         final String csvNames = (csvSupportedNames == null) ?
  221.                                 FramesFactory.CSV_FILENAME : csvSupportedNames;
  222.         addEOPHistoryLoader(IERSConventions.IERS_2003,
  223.                             new EopCsvFilesLoader(csvNames, dataProvidersManager, utcSupplier));
  224.         addEOPHistoryLoader(IERSConventions.IERS_2010,
  225.                             new EopCsvFilesLoader(csvNames, dataProvidersManager, utcSupplier));
  226.     }

  227.     /**
  228.      * Add a loader for Earth Orientation Parameters history.
  229.      *
  230.      * @param conventions IERS conventions to which EOP history applies
  231.      * @param loader      custom loader to add for the EOP history
  232.      * @see #addDefaultEOP1980HistoryLoaders(String, String, String, String, String, String, Supplier)
  233.      * @see #clearEOPHistoryLoaders()
  234.      */
  235.     public void addEOPHistoryLoader(final IERSConventions conventions, final EopHistoryLoader loader) {
  236.         synchronized (eopHistoryLoaders) {
  237.             if (!eopHistoryLoaders.containsKey(conventions)) {
  238.                 eopHistoryLoaders.put(conventions, new ArrayList<>());
  239.             }
  240.             eopHistoryLoaders.get(conventions).add(loader);
  241.         }
  242.     }

  243.     /**
  244.      * Clear loaders for Earth Orientation Parameters history.
  245.      *
  246.      * @see #addEOPHistoryLoader(IERSConventions, EopHistoryLoader)
  247.      * @see #addDefaultEOP1980HistoryLoaders(String, String, String, String, String, String, Supplier)
  248.      */
  249.     public void clearEOPHistoryLoaders() {
  250.         synchronized (eopHistoryLoaders) {
  251.             eopHistoryLoaders.clear();
  252.         }
  253.     }

  254.     /**
  255.      * Set the threshold to check EOP continuity.
  256.      * <p>
  257.      * The default threshold (used if this method is never called) is 5 Julian days. If
  258.      * after loading EOP entries some holes between entries exceed this threshold, an
  259.      * exception will be triggered.
  260.      * </p>
  261.      * <p>
  262.      * One case when calling this method is really useful is for applications that use a
  263.      * single Bulletin A, as these bulletins have a roughly one month wide hole for the
  264.      * first bulletin of each month, which contains older final data in addition to the
  265.      * rapid data and the predicted data.
  266.      * </p>
  267.      *
  268.      * @param threshold threshold to use for checking EOP continuity (in seconds)
  269.      */
  270.     public void setEOPContinuityThreshold(final double threshold) {
  271.         eopContinuityThreshold = threshold;
  272.     }

  273.     /**
  274.      * Set the degree for interpolation degree.
  275.      * <p>
  276.      * The default threshold (used if this method is never called) is {@link EOPHistory#DEFAULT_INTERPOLATION_DEGREE}.
  277.      * </p>
  278.      *
  279.      * @param interpolationDegree interpolation degree, must be of the form 4k-1
  280.      * @since 12.0
  281.      */
  282.     public void setInterpolationDegree(final int interpolationDegree) {
  283.         this.interpolationDegree = interpolationDegree;
  284.     }

  285.     /**
  286.      * Get Earth Orientation Parameters history.
  287.      * <p>
  288.      * If no {@link EopHistoryLoader} has been added by calling {@link
  289.      * #addEOPHistoryLoader(IERSConventions, EopHistoryLoader) addEOPHistoryLoader} or if
  290.      * {@link #clearEOPHistoryLoaders() clearEOPHistoryLoaders} has been called
  291.      * afterwards, the {@link #addDefaultEOP1980HistoryLoaders(String, String, String,
  292.      * String, String, String, Supplier)} and {@link #addDefaultEOP2000HistoryLoaders(String,
  293.      * String, String, String, String, String, Supplier)} methods will be called automatically
  294.      * with supported file names parameters all set to null, in order to get the default
  295.      * loaders configuration.
  296.      * </p>
  297.      *
  298.      * @param conventions conventions for which EOP history is requested
  299.      * @param simpleEOP   if true, tidal effects are ignored when interpolating EOP
  300.      * @param timeScales  to use when loading EOP and computing corrections.
  301.      * @return Earth Orientation Parameters history
  302.      */
  303.     public EOPHistory getEOPHistory(final IERSConventions conventions,
  304.                                     final boolean simpleEOP,
  305.                                     final TimeScales timeScales) {

  306.         synchronized (eopHistoryLoaders) {

  307.             if (eopHistoryLoaders.isEmpty()) {
  308.                 // set up using default loaders
  309.                 final Supplier<TimeScale> utcSupplier = timeScales::getUTC;
  310.                 addDefaultEOP2000HistoryLoaders(null, null, null, null, null, null, utcSupplier);
  311.                 addDefaultEOP1980HistoryLoaders(null, null, null, null, null, null, utcSupplier);
  312.             }

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

  316.             // try to load canonical data if available
  317.             if (eopHistoryLoaders.containsKey(conventions)) {
  318.                 for (final EopHistoryLoader loader : eopHistoryLoaders.get(conventions)) {
  319.                     try {
  320.                         loader.fillHistory(conventions.getNutationCorrectionConverter(timeScales),
  321.                                            data);
  322.                     } catch (OrekitException oe) {
  323.                         pendingException = oe;
  324.                     }
  325.                 }
  326.             }

  327.             if (data.isEmpty() && pendingException != null) {
  328.                 throw pendingException;
  329.             }

  330.             final EOPHistory history = new EOPHistory(conventions, interpolationDegree, data, simpleEOP, timeScales);
  331.             history.checkEOPContinuity(eopContinuityThreshold);
  332.             return history;

  333.         }

  334.     }

  335. }