AbstractTimeScales.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.time;

  18. import java.util.concurrent.ConcurrentHashMap;
  19. import java.util.concurrent.ConcurrentMap;

  20. import org.hipparchus.util.MathArrays;
  21. import org.hipparchus.util.Pair;
  22. import org.orekit.frames.EOPHistory;
  23. import org.orekit.utils.Constants;
  24. import org.orekit.utils.IERSConventions;

  25. /**
  26.  * Abstract base class for {@link TimeScales} that implements some common functionality.
  27.  *
  28.  * @author Evan Ward
  29.  * @author Luc Maisonobe
  30.  * @since 10.1
  31.  */
  32. public abstract class AbstractTimeScales implements TimeScales {

  33.     /** GMST time scales. */
  34.     private final ConcurrentMap<Pair<IERSConventions, Boolean>, GMSTScale> gmstMap;
  35.     /** UT1 time scales. */
  36.     private final ConcurrentMap<Pair<IERSConventions, Boolean>, UT1Scale> ut1Map;

  37.     /** Simple constructor. */
  38.     public AbstractTimeScales() {
  39.         final int n = IERSConventions.values().length;
  40.         gmstMap = new ConcurrentHashMap<>(n * 2);
  41.         ut1Map = new ConcurrentHashMap<>(n * 2);
  42.     }

  43.     /**
  44.      * Get the Universal Time 1 scale.
  45.      * <p>
  46.      * As this method allow associating any history with the time scale, it may involve
  47.      * large data sets. So this method does <em>not</em> cache the resulting {@link
  48.      * UT1Scale UT1Scale} instance, a new instance will be returned each time. In order to
  49.      * avoid wasting memory, calling {@link #getUT1(IERSConventions, boolean)} with the
  50.      * single enumerate corresponding to the conventions may be a better solution. This
  51.      * method is made available only for expert use.
  52.      * </p>
  53.      *
  54.      * @param history EOP parameters providing dUT1 (may be null if no correction is
  55.      *                desired)
  56.      * @return Universal Time 1 scale
  57.      * @see #getUT1(IERSConventions, boolean)
  58.      */
  59.     protected UT1Scale getUT1(final EOPHistory history) {
  60.         return new UT1Scale(history, getUTC());
  61.     }

  62.     /**
  63.      * Get the EOP history for the given conventions.
  64.      *
  65.      * @param conventions to use in computing the EOP history.
  66.      * @param simpleEOP   whether to ignore some small tidal effects.
  67.      * @return EOP history.
  68.      */
  69.     protected abstract EOPHistory getEopHistory(IERSConventions conventions,
  70.                                                 boolean simpleEOP);

  71.     @Override
  72.     public UT1Scale getUT1(final IERSConventions conventions, final boolean simpleEOP) {
  73.         final Pair<IERSConventions, Boolean> key = new Pair<>(conventions, simpleEOP);
  74.         synchronized (this) {
  75.             return ut1Map.computeIfAbsent(key, k -> getUT1(getEopHistory(conventions, simpleEOP)));
  76.         }
  77.     }

  78.     @Override
  79.     public GMSTScale getGMST(final IERSConventions conventions, final boolean simpleEOP) {
  80.         final Pair<IERSConventions, Boolean> key = new Pair<>(conventions, simpleEOP);
  81.         synchronized (this) {
  82.             return gmstMap.computeIfAbsent(key, k -> new GMSTScale(getUT1(conventions, simpleEOP)));
  83.         }
  84.     }

  85.     @Override
  86.     public AbsoluteDate getJulianEpoch() {
  87.         return new AbsoluteDate(DateComponents.JULIAN_EPOCH, TimeComponents.H12, this.getTT());
  88.     }

  89.     @Override
  90.     public AbsoluteDate getModifiedJulianEpoch() {
  91.         return new AbsoluteDate(DateComponents.MODIFIED_JULIAN_EPOCH, TimeComponents.H00, this.getTT());
  92.     }

  93.     @Override
  94.     public AbsoluteDate getFiftiesEpoch() {
  95.         return new AbsoluteDate(DateComponents.FIFTIES_EPOCH, TimeComponents.H00, this.getTT());
  96.     }

  97.     @Override
  98.     public AbsoluteDate getCcsdsEpoch() {
  99.         return new AbsoluteDate(DateComponents.CCSDS_EPOCH, TimeComponents.H00, this.getTAI());
  100.     }

  101.     @Override
  102.     public AbsoluteDate getGalileoEpoch() {
  103.         return new AbsoluteDate(DateComponents.GALILEO_EPOCH, TimeComponents.H00, this.getGST());
  104.     }

  105.     @Override
  106.     public AbsoluteDate getGpsEpoch() {
  107.         return new AbsoluteDate(DateComponents.GPS_EPOCH, TimeComponents.H00, this.getGPS());
  108.     }

  109.     @Override
  110.     public AbsoluteDate getQzssEpoch() {
  111.         return new AbsoluteDate(DateComponents.QZSS_EPOCH, TimeComponents.H00, this.getQZSS());
  112.     }

  113.     @Override
  114.     public AbsoluteDate getNavicEpoch() {
  115.         return new AbsoluteDate(DateComponents.NAVIC_EPOCH, TimeComponents.H00, this.getNavIC());
  116.     }

  117.     @Override
  118.     public AbsoluteDate getBeidouEpoch() {
  119.         return new AbsoluteDate(DateComponents.BEIDOU_EPOCH, TimeComponents.H00, this.getBDT());
  120.     }

  121.     @Override
  122.     public AbsoluteDate getGlonassEpoch() {
  123.         return new AbsoluteDate(DateComponents.GLONASS_EPOCH,
  124.                                 new TimeComponents(new TimeOffset(29L, 0L)), this.getTAI()).shiftedBy(new TimeOffset(-10800L, 0L));
  125.     }

  126.     @Override
  127.     public AbsoluteDate getJ2000Epoch() {
  128.         return new AbsoluteDate(DateComponents.J2000_EPOCH, TimeComponents.H12, this.getTT());
  129.     }

  130.     @Override
  131.     public AbsoluteDate getJavaEpoch() {
  132.         return new AbsoluteDate(DateComponents.JAVA_EPOCH, this.getTAI()).shiftedBy(new TimeOffset(8L, 82000000000000L));
  133.     }

  134.     @Override
  135.     public AbsoluteDate getPastInfinity() {
  136.         return getJavaEpoch().shiftedBy(Double.NEGATIVE_INFINITY);
  137.     }

  138.     @Override
  139.     public AbsoluteDate getFutureInfinity() {
  140.         return getJavaEpoch().shiftedBy(Double.POSITIVE_INFINITY);
  141.     }

  142.     @Override
  143.     public AbsoluteDate createJulianEpoch(final double julianEpoch) {
  144.         return new AbsoluteDate(getJ2000Epoch(),
  145.                 Constants.JULIAN_YEAR * (julianEpoch - 2000.0));
  146.     }

  147.     @Override
  148.     public AbsoluteDate createBesselianEpoch(final double besselianEpoch) {
  149.         return new AbsoluteDate(getJ2000Epoch(),
  150.                 MathArrays.linearCombination(
  151.                         Constants.BESSELIAN_YEAR, besselianEpoch - 1900,
  152.                         Constants.JULIAN_DAY, -36525,
  153.                         Constants.JULIAN_DAY, 0.31352));
  154.     }

  155. }