TimeScalesFactory.java

  1. /* Copyright 2002-2013 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 java.util.SortedMap;
  24. import java.util.TreeMap;

  25. import org.orekit.data.DataProvidersManager;
  26. import org.orekit.errors.OrekitException;
  27. import org.orekit.errors.OrekitMessages;
  28. import org.orekit.frames.EOPHistory;
  29. import org.orekit.frames.FramesFactory;
  30. import org.orekit.utils.IERSConventions;

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

  38.     /** Serializable UID. */
  39.     private static final long serialVersionUID = 20130807L;

  40.     /** International Atomic Time scale. */
  41.     private static TAIScale tai = null;

  42.     /** Universal Time Coordinate scale. */
  43.     private static UTCScale utc = null;

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

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

  48.     /** Terrestrial Time scale. */
  49.     private static TTScale tt = null;

  50.     /** Galileo System Time scale. */
  51.     private static GalileoScale gst = null;

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

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

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

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

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

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

  64.     /** Private constructor.
  65.      * <p>This class is a utility class, it should neither have a public
  66.      * nor a default constructor. This private constructor prevents
  67.      * the compiler from generating one automatically.</p>
  68.      */
  69.     private TimeScalesFactory() {
  70.     }

  71.     /** Add a loader for UTC-TAI offsets history files.
  72.      * @param loader custom loader to add
  73.      * @see #getUTC()
  74.      * @see #clearUTCTAILoaders()
  75.      */
  76.     public static void addUTCTAILoader(final UTCTAILoader loader) {
  77.         loaders.add(loader);
  78.     }

  79.     /** Add the default loader for UTC-TAI offsets history files.
  80.      * <p>
  81.      * The default loader looks for a file named {@code UTC-TAI.history}
  82.      * that must be in the IERS format.
  83.      * </p>
  84.      * @see <a href="http://hpiers.obspm.fr/eoppc/bul/bulc/UTC-TAI.history">IERS UTC-TAI.history file</a>
  85.      * @see #getUTC()
  86.      * @see #clearUTCTAILoaders()
  87.      */
  88.     public static void addDefaultUTCTAILoader() {
  89.         addUTCTAILoader(new UTCTAIHistoryFilesLoader());
  90.     }

  91.     /** Clear loaders for UTC-TAI offsets history files.
  92.      * @see #getUTC()
  93.      * @see #addUTCTAILoader(UTCTAILoader)
  94.      * @see #addDefaultUTCTAILoader()
  95.      */
  96.     public static void clearUTCTAILoaders() {
  97.         loaders.clear();
  98.     }

  99.     /** Get the International Atomic Time scale.
  100.      * @return International Atomic Time scale
  101.      */
  102.     public static TAIScale getTAI() {
  103.         synchronized (TimeScalesFactory.class) {

  104.             if (tai == null) {
  105.                 tai = new TAIScale();
  106.             }

  107.             return tai;

  108.         }
  109.     }

  110.     /** Get the Universal Time Coordinate scale.
  111.      * <p>
  112.      * If no {@link UTCTAILoader} has been added by calling {@link
  113.      * #addUTCTAILoader(UTCTAILoader) addUTCTAILoader} or if {@link
  114.      * #clearUTCTAILoaders() clearUTCTAILoaders} has been called afterwards,
  115.      * the {@link #addDefaultUTCTAILoader() addDefaultUTCTAILoader} method
  116.      * will be called automatically.
  117.      * </p>
  118.      * @return Universal Time Coordinate scale
  119.      * @exception OrekitException if some data can't be read or some
  120.      * file content is corrupted
  121.      * @see #addUTCTAILoader(UTCTAILoader)
  122.      * @see #clearUTCTAILoaders()
  123.      * @see #addDefaultUTCTAILoader()
  124.      */
  125.     public static UTCScale getUTC() throws OrekitException {
  126.         synchronized (TimeScalesFactory.class) {

  127.             if (utc == null) {
  128.                 SortedMap<DateComponents, Integer> entries =
  129.                     new TreeMap<DateComponents, Integer>();
  130.                 boolean loaded = false;
  131.                 if (loaders.isEmpty()) {
  132.                     addDefaultUTCTAILoader();
  133.                 }
  134.                 for (UTCTAILoader loader : loaders) {
  135.                     DataProvidersManager.getInstance().feed(loader.getSupportedNames(), loader);
  136.                     if (!loader.stillAcceptsData()) {
  137.                         entries = loader.loadTimeSteps();
  138.                         loaded = true;
  139.                     }
  140.                 }
  141.                 if (!loaded) {
  142.                     throw new OrekitException(OrekitMessages.NO_IERS_UTC_TAI_HISTORY_DATA_LOADED);
  143.                 }
  144.                 utc = new UTCScale(entries);
  145.             }

  146.             return utc;
  147.         }
  148.     }

  149.     /** Get the Universal Time 1 scale.
  150.      * @return Universal Time 1 scale
  151.      * @exception OrekitException if some data can't be read or some
  152.      * file content is corrupted
  153.      * @see #getUTC()
  154.      * @see FramesFactory#getEOPHistory(IERSConventions, boolean)
  155.      * @deprecated as of 6.1 replaced with {@link #getUT1(IERSConventions, boolean)}
  156.      */
  157.     @Deprecated
  158.     public static UT1Scale getUT1() throws OrekitException {
  159.         return getUT1(IERSConventions.IERS_2010, true);
  160.     }

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

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

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

  210.     /** Get the Terrestrial Time scale.
  211.      * @return Terrestrial Time scale
  212.      */
  213.     public static TTScale getTT() {
  214.         synchronized (TimeScalesFactory.class) {

  215.             if (tt == null) {
  216.                 tt = new TTScale();
  217.             }

  218.             return tt;

  219.         }
  220.     }

  221.     /** Get the Galileo System Time scale.
  222.      * @return Galileo System Time scale
  223.      */
  224.     public static GalileoScale getGST() {
  225.         synchronized (TimeScalesFactory.class) {

  226.             if (gst == null) {
  227.                 gst = new GalileoScale();
  228.             }

  229.             return gst;

  230.         }
  231.     }

  232.     /** Get the Global Positioning System scale.
  233.      * @return Global Positioning System scale
  234.      */
  235.     public static GPSScale getGPS() {
  236.         synchronized (TimeScalesFactory.class) {

  237.             if (gps == null) {
  238.                 gps = new GPSScale();
  239.             }

  240.             return gps;

  241.         }
  242.     }

  243.     /** Get the Geocentric Coordinate Time scale.
  244.      * @return Geocentric Coordinate Time scale
  245.      */
  246.     public static TCGScale getTCG() {
  247.         synchronized (TimeScalesFactory.class) {

  248.             if (tcg == null) {
  249.                 tcg = new TCGScale();
  250.             }

  251.             return tcg;

  252.         }
  253.     }

  254.     /** Get the Barycentric Dynamic Time scale.
  255.      * @return Barycentric Dynamic Time scale
  256.      */
  257.     public static TDBScale getTDB() {
  258.         synchronized (TimeScalesFactory.class) {

  259.             if (tdb == null) {
  260.                 tdb = new TDBScale();
  261.             }

  262.             return tdb;

  263.         }
  264.     }

  265.     /** Get the Barycentric Coordinate Time scale.
  266.      * @return Barycentric Coordinate Time scale
  267.      */
  268.     public static TCBScale getTCB() {
  269.         synchronized (TimeScalesFactory.class) {

  270.             if (tcb == null) {
  271.                 tcb = new TCBScale(getTDB());
  272.             }

  273.             return tcb;

  274.         }
  275.     }

  276.     /** Get the Greenwich Mean Sidereal Time scale.
  277.      * @return Greenwich Mean Sidereal Time scale
  278.      * @exception OrekitException if some data can't be read or some
  279.      * file content is corrupted
  280.      */
  281.     public static GMSTScale getGMST() throws OrekitException {
  282.         synchronized (TimeScalesFactory.class) {

  283.             if (gmst == null) {
  284.                 gmst = new GMSTScale(getUT1());
  285.             }

  286.             return gmst;

  287.         }
  288.     }

  289. }