TimeScalesFactory.java

  1. /* Copyright 2002-2019 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (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.time;

  18. import java.io.Serializable;
  19. import java.util.ArrayList;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;

  23. import org.orekit.errors.OrekitException;
  24. import org.orekit.errors.OrekitMessages;
  25. import org.orekit.frames.EOPHistory;
  26. import org.orekit.frames.FramesFactory;
  27. import org.orekit.utils.IERSConventions;


  28. /** Factory for predefined time scales.
  29.  * <p>
  30.  * This is a utility class, so its constructor is private.
  31.  * </p>
  32.  * @author Luc Maisonobe
  33.  */
  34. public class TimeScalesFactory implements Serializable {

  35.     /** Serializable UID. */
  36.     private static final long serialVersionUID = 20130807L;

  37.     /** International Atomic Time scale. */
  38.     private static TAIScale tai = null;

  39.     /** Universal Time Coordinate depscale. */
  40.     private static UTCScale utc = null;

  41.     /** Universal Time 1 scale (tidal effects ignored). */
  42.     private static Map<IERSConventions, UT1Scale> ut1MapSimpleEOP = new HashMap<IERSConventions, UT1Scale>();

  43.     /** Universal Time 1 scale (tidal effects considered). */
  44.     private static Map<IERSConventions, UT1Scale> ut1MapCompleteEOP = new HashMap<IERSConventions, UT1Scale>();

  45.     /** Terrestrial Time scale. */
  46.     private static TTScale tt = null;

  47.     /** Galileo System Time scale. */
  48.     private static GalileoScale gst = null;

  49.     /** GLObal NAvigation Satellite System scale. */
  50.     private static GLONASSScale glonass = null;

  51.     /** Quasi-Zenith Satellite System scale. */
  52.     private static QZSSScale qzss = null;

  53.     /** Global Positioning System scale. */
  54.     private static GPSScale gps = null;

  55.     /** Geocentric Coordinate Time scale. */
  56.     private static TCGScale tcg = null;

  57.     /** Barycentric Dynamic Time scale. */
  58.     private static TDBScale tdb = null;

  59.     /** Barycentric Coordinate Time scale. */
  60.     private static TCBScale tcb = null;

  61.     /** Greenwich Mean Sidereal Time scale. */
  62.     private static GMSTScale gmst = null;

  63.     /** UTCTAI offsets loaders. */
  64.     private static List<UTCTAIOffsetsLoader> loaders = new ArrayList<UTCTAIOffsetsLoader>();

  65.     /** IRNSS System Time scale. */
  66.     private static IRNSSScale irnss = null;

  67.     /** BDS System Time scale. */
  68.     private static BDTScale bds = null;


  69.     /** Private constructor.
  70.      * <p>This class is a utility class, it should neither have a public
  71.      * nor a default constructor. This private constructor prevents
  72.      * the compiler from generating one automatically.</p>
  73.      */
  74.     private TimeScalesFactory() {
  75.     }

  76.     /** Add a loader for UTC-TAI offsets history files.
  77.      * @param loader custom loader to add
  78.      * @see TAIUTCDatFilesLoader
  79.      * @see UTCTAIHistoryFilesLoader
  80.      * @see UTCTAIBulletinAFilesLoader
  81.      * @see #getUTC()
  82.      * @see #clearUTCTAIOffsetsLoaders()
  83.      * @since 7.1
  84.      */
  85.     public static void addUTCTAIOffsetsLoader(final UTCTAIOffsetsLoader loader) {
  86.         loaders.add(loader);
  87.     }

  88.     /** Add the default loaders for UTC-TAI offsets history files (both IERS and USNO).
  89.      * <p>
  90.      * The default loaders are {@link TAIUTCDatFilesLoader} that looks for
  91.      * a file named {@code tai-utc.dat} that must be in USNO format and
  92.      * {@link UTCTAIHistoryFilesLoader} that looks fir a file named
  93.      * {@code UTC-TAI.history} that must be in the IERS format. The
  94.      * {@link UTCTAIBulletinAFilesLoader} is <em>not</em> added by default
  95.      * as it is not recommended. USNO warned us that the TAI-UTC data present
  96.      * in bulletin A was for convenience only and was not reliable, there
  97.      * have been errors in several bulletins regarding these data.
  98.      * </p>
  99.      * @see <a href="http://maia.usno.navy.mil/ser7/tai-utc.dat">USNO tai-utc.dat file</a>
  100.      * @see <a href="http://hpiers.obspm.fr/eoppc/bul/bulc/UTC-TAI.history">IERS UTC-TAI.history file</a>
  101.      * @see TAIUTCDatFilesLoader
  102.      * @see UTCTAIHistoryFilesLoader
  103.      * @see #getUTC()
  104.      * @see #clearUTCTAIOffsetsLoaders()
  105.      * @since 7.1
  106.      */
  107.     public static void addDefaultUTCTAIOffsetsLoaders() {
  108.         addUTCTAIOffsetsLoader(new TAIUTCDatFilesLoader(TAIUTCDatFilesLoader.DEFAULT_SUPPORTED_NAMES));
  109.         addUTCTAIOffsetsLoader(new UTCTAIHistoryFilesLoader());
  110.     }

  111.     /** Clear loaders for UTC-TAI offsets history files.
  112.      * @see #getUTC()
  113.      * @see #addUTCTAIOffsetsLoader(UTCTAIOffsetsLoader)
  114.      * @see #addDefaultUTCTAIOffsetsLoaders()
  115.      * @since 7.1
  116.      */
  117.     public static void clearUTCTAIOffsetsLoaders() {
  118.         loaders.clear();
  119.     }

  120.     /** Get the International Atomic Time scale.
  121.      * @return International Atomic Time scale
  122.      */
  123.     public static TAIScale getTAI() {
  124.         synchronized (TimeScalesFactory.class) {

  125.             if (tai == null) {
  126.                 tai = new TAIScale();
  127.             }

  128.             return tai;

  129.         }
  130.     }

  131.     /** Get the Universal Time Coordinate scale.
  132.      * <p>
  133.      * If no {@link UTCTAIOffsetsLoader} has been added by calling {@link
  134.      * #addUTCTAIOffsetsLoader(UTCTAIOffsetsLoader) addUTCTAIOffsetsLoader} or if {@link
  135.      * #clearUTCTAIOffsetsLoaders() clearUTCTAIOffsetsLoaders} has been called afterwards,
  136.      * the {@link #addDefaultUTCTAIOffsetsLoaders() addDefaultUTCTAILoaders} method
  137.      * will be called automatically.
  138.      * </p>
  139.      * @return Universal Time Coordinate scale
  140.      * @see #addDefaultUTCTAIOffsetsLoaders()
  141.      */
  142.     public static UTCScale getUTC() {
  143.         synchronized (TimeScalesFactory.class) {

  144.             if (utc == null) {
  145.                 List<OffsetModel> entries = null;
  146.                 if (loaders.isEmpty()) {
  147.                     addDefaultUTCTAIOffsetsLoaders();
  148.                 }
  149.                 for (UTCTAIOffsetsLoader loader : loaders) {
  150.                     entries = loader.loadOffsets();
  151.                     if (!entries.isEmpty()) {
  152.                         break;
  153.                     }
  154.                 }
  155.                 if (entries.isEmpty()) {
  156.                     throw new OrekitException(OrekitMessages.NO_IERS_UTC_TAI_HISTORY_DATA_LOADED);
  157.                 }
  158.                 utc = new UTCScale(entries);
  159.             }

  160.             return utc;
  161.         }
  162.     }

  163.     /** Get the Universal Time 1 scale.
  164.      * <p>
  165.      * UT1 scale depends on both UTC scale and Earth Orientation Parameters,
  166.      * so this method loads these data sets. See the {@link #getUTC()
  167.      * TimeScalesFactory.getUTC()} and {@link
  168.      * FramesFactory#getEOPHistory(IERSConventions, boolean)} methods
  169.      * for an explanation of how the corresponding data loaders can be configured.
  170.      * </p>
  171.      * @param conventions IERS conventions for which EOP parameters will provide dUT1
  172.      * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
  173.      * @return Universal Time 1 scale
  174.      * @see #getUTC()
  175.      * @see FramesFactory#getEOPHistory(IERSConventions, boolean)
  176.      */
  177.     public static UT1Scale getUT1(final IERSConventions conventions, final boolean simpleEOP) {
  178.         synchronized (TimeScalesFactory.class) {

  179.             final Map<IERSConventions, UT1Scale> map =
  180.                     simpleEOP ? ut1MapSimpleEOP : ut1MapCompleteEOP;
  181.             UT1Scale ut1 = map.get(conventions);
  182.             if (ut1 == null) {
  183.                 ut1 = getUT1(FramesFactory.getEOPHistory(conventions, simpleEOP));
  184.                 map.put(conventions, ut1);
  185.             }
  186.             return ut1;
  187.         }
  188.     }

  189.     /** Get the Universal Time 1 scale.
  190.      * <p>
  191.      * As this method allow associating any history with the time scale,
  192.      * it may involve large data sets. So this method does <em>not</em>
  193.      * cache the resulting {@link UT1Scale UT1Scale} instance, a new
  194.      * instance will be returned each time. In order to avoid wasting
  195.      * memory, calling {@link #getUT1(IERSConventions, boolean)}
  196.      * with the single enumerate corresponding to the conventions may be
  197.      * a better solution. This method is made available only for expert use.
  198.      * </p>
  199.      * @param history EOP parameters providing dUT1
  200.      * (may be null if no correction is desired)
  201.      * @return Universal Time 1 scale
  202.      * @see #getUT1(IERSConventions, boolean)
  203.      */
  204.     public static UT1Scale getUT1(final EOPHistory history) {
  205.         return new UT1Scale(history, getUTC());
  206.     }

  207.     /** Get the Terrestrial Time scale.
  208.      * @return Terrestrial Time scale
  209.      */
  210.     public static TTScale getTT() {
  211.         synchronized (TimeScalesFactory.class) {

  212.             if (tt == null) {
  213.                 tt = new TTScale();
  214.             }

  215.             return tt;

  216.         }
  217.     }

  218.     /** Get the Galileo System Time scale.
  219.      * @return Galileo System Time scale
  220.      */
  221.     public static GalileoScale getGST() {
  222.         synchronized (TimeScalesFactory.class) {

  223.             if (gst == null) {
  224.                 gst = new GalileoScale();
  225.             }

  226.             return gst;

  227.         }
  228.     }

  229.     /** Get the GLObal NAvigation Satellite System time scale.
  230.      * @return  GLObal NAvigation Satellite System time scale
  231.      */
  232.     public static GLONASSScale getGLONASS() {
  233.         synchronized (TimeScalesFactory.class) {

  234.             if (glonass == null) {
  235.                 glonass = new GLONASSScale(getUTC());
  236.             }

  237.             return glonass;

  238.         }
  239.     }

  240.     /** Get the Quasi-Zenith Satellite System time scale.
  241.      * @return  Quasi-Zenith Satellite System time scale
  242.      */
  243.     public static QZSSScale getQZSS() {
  244.         synchronized (TimeScalesFactory.class) {

  245.             if (qzss == null) {
  246.                 qzss = new QZSSScale();
  247.             }

  248.             return qzss;

  249.         }
  250.     }

  251.     /** Get the Global Positioning System scale.
  252.      * @return Global Positioning System scale
  253.      */
  254.     public static GPSScale getGPS() {
  255.         synchronized (TimeScalesFactory.class) {

  256.             if (gps == null) {
  257.                 gps = new GPSScale();
  258.             }

  259.             return gps;

  260.         }
  261.     }

  262.     /** Get the Geocentric Coordinate Time scale.
  263.      * @return Geocentric Coordinate Time scale
  264.      */
  265.     public static TCGScale getTCG() {
  266.         synchronized (TimeScalesFactory.class) {

  267.             if (tcg == null) {
  268.                 tcg = new TCGScale();
  269.             }

  270.             return tcg;

  271.         }
  272.     }

  273.     /** Get the Barycentric Dynamic Time scale.
  274.      * @return Barycentric Dynamic Time scale
  275.      */
  276.     public static TDBScale getTDB() {
  277.         synchronized (TimeScalesFactory.class) {

  278.             if (tdb == null) {
  279.                 tdb = new TDBScale();
  280.             }

  281.             return tdb;

  282.         }
  283.     }

  284.     /** Get the Barycentric Coordinate Time scale.
  285.      * @return Barycentric Coordinate Time scale
  286.      */
  287.     public static TCBScale getTCB() {
  288.         synchronized (TimeScalesFactory.class) {

  289.             if (tcb == null) {
  290.                 tcb = new TCBScale(getTDB());
  291.             }

  292.             return tcb;

  293.         }
  294.     }

  295.     /** Get the Greenwich Mean Sidereal Time scale.
  296.      * @param conventions IERS conventions for which EOP parameters will provide dUT1
  297.      * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
  298.      * @return Greenwich Mean Sidereal Time scale
  299.      * @since 7.0
  300.      */
  301.     public static GMSTScale getGMST(final IERSConventions conventions, final boolean simpleEOP) {
  302.         synchronized (TimeScalesFactory.class) {

  303.             if (gmst == null) {
  304.                 gmst = new GMSTScale(getUT1(conventions, simpleEOP));
  305.             }

  306.             return gmst;

  307.         }
  308.     }
  309.     /** Get the Indian Regional Navigation Satellite System time scale.
  310.      * @return  Indian Regional Navigation Satellite System time scale
  311.      */
  312.     public static IRNSSScale getIRNSS() {
  313.         synchronized (TimeScalesFactory.class) {

  314.             if (irnss == null) {
  315.                 irnss = new IRNSSScale();
  316.             }

  317.             return irnss;

  318.         }
  319.     }

  320.     /** Get the BeiDou Navigation Satellite System time scale.
  321.      * @return  BeiDou Navigation Satellite System time scale
  322.      */
  323.     public static BDTScale getBDT() {
  324.         synchronized (TimeScalesFactory.class) {

  325.             if (bds == null) {
  326.                 bds = new BDTScale();
  327.             }

  328.             return bds;

  329.         }
  330.     }

  331. }