TimeScalesFactory.java

  1. /* Copyright 2002-2018 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.      * @exception OrekitException if some data can't be read or some
  141.      * file content is corrupted
  142.      * @see #addDefaultUTCTAIOffsetsLoaders()
  143.      */
  144.     public static UTCScale getUTC() throws OrekitException {
  145.         synchronized (TimeScalesFactory.class) {

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

  162.             return utc;
  163.         }
  164.     }

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

  184.             final Map<IERSConventions, UT1Scale> map =
  185.                     simpleEOP ? ut1MapSimpleEOP : ut1MapCompleteEOP;
  186.             UT1Scale ut1 = map.get(conventions);
  187.             if (ut1 == null) {
  188.                 ut1 = getUT1(FramesFactory.getEOPHistory(conventions, simpleEOP));
  189.                 map.put(conventions, ut1);
  190.             }
  191.             return ut1;
  192.         }
  193.     }

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

  214.     /** Get the Terrestrial Time scale.
  215.      * @return Terrestrial Time scale
  216.      */
  217.     public static TTScale getTT() {
  218.         synchronized (TimeScalesFactory.class) {

  219.             if (tt == null) {
  220.                 tt = new TTScale();
  221.             }

  222.             return tt;

  223.         }
  224.     }

  225.     /** Get the Galileo System Time scale.
  226.      * @return Galileo System Time scale
  227.      */
  228.     public static GalileoScale getGST() {
  229.         synchronized (TimeScalesFactory.class) {

  230.             if (gst == null) {
  231.                 gst = new GalileoScale();
  232.             }

  233.             return gst;

  234.         }
  235.     }

  236.     /** Get the GLObal NAvigation Satellite System time scale.
  237.      * @return  GLObal NAvigation Satellite System time scale
  238.      * @exception OrekitException if UTC time scale cannot be retrieved
  239.      */
  240.     public static GLONASSScale getGLONASS() throws OrekitException {
  241.         synchronized (TimeScalesFactory.class) {

  242.             if (glonass == null) {
  243.                 glonass = new GLONASSScale(getUTC());
  244.             }

  245.             return glonass;

  246.         }
  247.     }

  248.     /** Get the Quasi-Zenith Satellite System time scale.
  249.      * @return  Quasi-Zenith Satellite System time scale
  250.      */
  251.     public static QZSSScale getQZSS() {
  252.         synchronized (TimeScalesFactory.class) {

  253.             if (qzss == null) {
  254.                 qzss = new QZSSScale();
  255.             }

  256.             return qzss;

  257.         }
  258.     }

  259.     /** Get the Global Positioning System scale.
  260.      * @return Global Positioning System scale
  261.      */
  262.     public static GPSScale getGPS() {
  263.         synchronized (TimeScalesFactory.class) {

  264.             if (gps == null) {
  265.                 gps = new GPSScale();
  266.             }

  267.             return gps;

  268.         }
  269.     }

  270.     /** Get the Geocentric Coordinate Time scale.
  271.      * @return Geocentric Coordinate Time scale
  272.      */
  273.     public static TCGScale getTCG() {
  274.         synchronized (TimeScalesFactory.class) {

  275.             if (tcg == null) {
  276.                 tcg = new TCGScale();
  277.             }

  278.             return tcg;

  279.         }
  280.     }

  281.     /** Get the Barycentric Dynamic Time scale.
  282.      * @return Barycentric Dynamic Time scale
  283.      */
  284.     public static TDBScale getTDB() {
  285.         synchronized (TimeScalesFactory.class) {

  286.             if (tdb == null) {
  287.                 tdb = new TDBScale();
  288.             }

  289.             return tdb;

  290.         }
  291.     }

  292.     /** Get the Barycentric Coordinate Time scale.
  293.      * @return Barycentric Coordinate Time scale
  294.      */
  295.     public static TCBScale getTCB() {
  296.         synchronized (TimeScalesFactory.class) {

  297.             if (tcb == null) {
  298.                 tcb = new TCBScale(getTDB());
  299.             }

  300.             return tcb;

  301.         }
  302.     }

  303.     /** Get the Greenwich Mean Sidereal Time scale.
  304.      * @param conventions IERS conventions for which EOP parameters will provide dUT1
  305.      * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
  306.      * @return Greenwich Mean Sidereal Time scale
  307.      * @exception OrekitException if some data can't be read or some
  308.      * file content is corrupted
  309.      * @since 7.0
  310.      */
  311.     public static GMSTScale getGMST(final IERSConventions conventions, final boolean simpleEOP) throws OrekitException {
  312.         synchronized (TimeScalesFactory.class) {

  313.             if (gmst == null) {
  314.                 gmst = new GMSTScale(getUT1(conventions, simpleEOP));
  315.             }

  316.             return gmst;

  317.         }
  318.     }
  319.     /** Get the Indian Regional Navigation Satellite System time scale.
  320.      * @return  Indian Regional Navigation Satellite System time scale
  321.      */
  322.     public static IRNSSScale getIRNSS() {
  323.         synchronized (TimeScalesFactory.class) {

  324.             if (irnss == null) {
  325.                 irnss = new IRNSSScale();
  326.             }

  327.             return irnss;

  328.         }
  329.     }

  330.     /** Get the BeiDou Navigation Satellite System time scale.
  331.      * @return  BeiDou Navigation Satellite System time scale
  332.      */
  333.     public static BDTScale getBDT() {
  334.         synchronized (TimeScalesFactory.class) {

  335.             if (bds == null) {
  336.                 bds = new BDTScale();
  337.             }

  338.             return bds;

  339.         }
  340.     }

  341. }