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.files.ccsds;
18  
19  import org.orekit.annotation.DefaultDataContext;
20  import org.orekit.data.DataContext;
21  import org.orekit.errors.OrekitException;
22  import org.orekit.errors.OrekitMessages;
23  import org.orekit.time.AbsoluteDate;
24  import org.orekit.time.DateTimeComponents;
25  import org.orekit.time.TimeScale;
26  import org.orekit.time.TimeScales;
27  import org.orekit.utils.Constants;
28  import org.orekit.utils.IERSConventions;
29  
30  /**
31   * The set of time scales defined in Annex A of the ODM CCSDS standard 502.0-B-2.
32   *
33   * @author Evan Ward
34   */
35  public enum CcsdsTimeScale {
36  
37      /** Greenwich Mean Sidereal Time. */
38      GMST {
39          @Override
40          public TimeScale getTimeScale(final IERSConventions conventions, final TimeScales timeScales) {
41              return timeScales.getGMST(conventions, false);
42          }
43      },
44      /** Global Positioning System. */
45      GPS {
46          @Override
47          public TimeScale getTimeScale(final IERSConventions conventions, final TimeScales timeScales) {
48              return timeScales.getGPS();
49          }
50      },
51      /** Mission Elapsed Time. */
52      MET {
53          @Override
54          public AbsoluteDate parseDate(final String date,
55                                        final IERSConventions conventions,
56                                        final AbsoluteDate missionReferenceDate,
57                                        final TimeScales timeScales) {
58              final DateTimeComponents clock = DateTimeComponents.parseDateTime(date);
59              final double offset = clock.getDate().getYear() * Constants.JULIAN_YEAR +
60                      clock.getDate().getDayOfYear() * Constants.JULIAN_DAY +
61                      clock.getTime().getSecondsInUTCDay();
62              return missionReferenceDate.shiftedBy(offset);
63          }
64  
65          @Override
66          public TimeScale getTimeScale(final IERSConventions conventions, final TimeScales timeScales) {
67              throw new OrekitException(
68                      OrekitMessages.CCSDS_NO_CORRESPONDING_TIME_SCALE,
69                      "MET");
70          }
71      },
72      /** Mission Relative Time. */
73      MRT {
74          @Override
75          public AbsoluteDate parseDate(final String date,
76                                        final IERSConventions conventions,
77                                        final AbsoluteDate missionReferenceDate,
78                                        final TimeScales timeScales) {
79              final DateTimeComponents clock = DateTimeComponents.parseDateTime(date);
80              final double offset = clock.getDate().getYear() * Constants.JULIAN_YEAR +
81                      clock.getDate().getDayOfYear() * Constants.JULIAN_DAY +
82                      clock.getTime().getSecondsInUTCDay();
83              return missionReferenceDate.shiftedBy(offset);
84          }
85  
86          @Override
87          public TimeScale getTimeScale(final IERSConventions conventions, final TimeScales timeScales) {
88              throw new OrekitException(
89                      OrekitMessages.CCSDS_NO_CORRESPONDING_TIME_SCALE,
90                      "MRT");
91          }
92      },
93      /** Spacecraft Clock. Not currently Implemented. */
94      SCLK {
95          @Override
96          public AbsoluteDate parseDate(final String date,
97                                        final IERSConventions conventions,
98                                        final AbsoluteDate missionReferenceDate,
99                                        final TimeScales timeScales) {
100             throw new OrekitException(
101                     OrekitMessages.CCSDS_TIME_SYSTEM_NOT_IMPLEMENTED,
102                     this.name());
103         }
104 
105         @Override
106         public TimeScale getTimeScale(final IERSConventions conventions, final TimeScales timeScales) {
107             throw new OrekitException(
108                     OrekitMessages.CCSDS_NO_CORRESPONDING_TIME_SCALE,
109                     this.name());
110         }
111     },
112     /** International Atomic Time. */
113     TAI {
114         @Override
115         public TimeScale getTimeScale(final IERSConventions conventions, final TimeScales timeScales) {
116             return timeScales.getTAI();
117         }
118     },
119     /** Barycentric Coordinate Time. */
120     TCB {
121         @Override
122         public TimeScale getTimeScale(final IERSConventions conventions, final TimeScales timeScales) {
123             return timeScales.getTCB();
124         }
125     },
126     /** Barycentric Dynamical Time. */
127     TDB {
128         @Override
129         public TimeScale getTimeScale(final IERSConventions conventions, final TimeScales timeScales) {
130             return timeScales.getTDB();
131         }
132     },
133     /** Geocentric Coordinate Time. */
134     TCG {
135         @Override
136         public TimeScale getTimeScale(final IERSConventions conventions, final TimeScales timeScales) {
137             return timeScales.getTCG();
138         }
139     },
140     /** Terrestrial Time. */
141     TT {
142         @Override
143         public TimeScale getTimeScale(final IERSConventions conventions, final TimeScales timeScales) {
144             return timeScales.getTT();
145         }
146     },
147     /** Universal Time. */
148     UT1 {
149         @Override
150         public TimeScale getTimeScale(final IERSConventions conventions, final TimeScales timeScales) {
151             return timeScales.getUT1(conventions, false);
152         }
153     },
154     /** Universal Coordinated Time. */
155     UTC {
156         @Override
157         public TimeScale getTimeScale(final IERSConventions conventions, final TimeScales timeScales) {
158             return timeScales.getUTC();
159         }
160     };
161 
162     /**
163      * Parse a date in this time scale.
164      *
165      * <p>This method uses the {@link DataContext#getDefault() default data context}.
166      *
167      * @param date                 a CCSDS date string.
168      * @param conventions          IERS conventions for {@link #UT1} and {@link #GMST}.
169      * @param missionReferenceDate epoch for {@link #MET} and {@link #MRT}.
170      * @return parsed {@code date}.
171      * @see #parseDate(String, IERSConventions, AbsoluteDate, TimeScales)
172      */
173     @DefaultDataContext
174     public AbsoluteDate parseDate(final String date,
175                                   final IERSConventions conventions,
176                                   final AbsoluteDate missionReferenceDate) {
177         return parseDate(date, conventions, missionReferenceDate,
178                 DataContext.getDefault().getTimeScales());
179     }
180 
181     /**
182      * Parse a date in this time scale.
183      *
184      * @param date                 a CCSDS date string.
185      * @param conventions          IERS conventions for {@link #UT1} and {@link #GMST}.
186      * @param missionReferenceDate epoch for {@link #MET} and {@link #MRT}.
187      * @param timeScales the set of time scales to use.
188      * @return parsed {@code date}.
189      * @since 10.1
190      */
191     public AbsoluteDate parseDate(final String date,
192                                   final IERSConventions conventions,
193                                   final AbsoluteDate missionReferenceDate,
194                                   final TimeScales timeScales) {
195         return new AbsoluteDate(date, this.getTimeScale(conventions, timeScales));
196     }
197 
198     /**
199      * Get the corresponding {@link TimeScale}.
200      *
201      * <p>This method uses the {@link DataContext#getDefault() default data context}.
202      *
203      * @param conventions IERS Conventions for the {@link #GMST} and {@link #UT1} scales.
204      * @return the time scale.
205      */
206     @DefaultDataContext
207     public TimeScale getTimeScale(final IERSConventions conventions) {
208         return getTimeScale(conventions, DataContext.getDefault().getTimeScales());
209     }
210 
211     /**
212      * Get the corresponding {@link TimeScale}.
213      *
214      * @param conventions IERS Conventions for the {@link #GMST} and {@link #UT1} scales.
215      * @param timeScales the set of time scales to use.
216      * @return the time scale.
217      */
218     public abstract TimeScale getTimeScale(IERSConventions conventions,
219                                            TimeScales timeScales);
220 
221     /**
222      * Check if {@code timeScale} is one of the values supported by this enum.
223      *
224      * @param timeScale specifier.
225      * @return {@code true} if {@link #valueOf(String)} will not throw an exception with
226      * the same string.
227      */
228     public static boolean contains(final String timeScale) {
229         for (final CcsdsTimeScale scale : values()) {
230             if (scale.name().equals(timeScale)) {
231                 return true;
232             }
233         }
234         return false;
235     }
236 
237 }