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
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22
23 import org.orekit.data.DataProvidersManager;
24 import org.orekit.errors.OrekitException;
25 import org.orekit.errors.OrekitMessages;
26 import org.orekit.frames.EOPHistory;
27 import org.orekit.frames.LazyLoadedEop;
28 import org.orekit.utils.IERSConventions;
29
30 /**
31 * An implementation of {@link TimeScales} that loads auxiliary data, leap seconds and
32 * UT1-UTC, when it is first accessed. The list of loaders may be modified before the
33 * first data access.
34 *
35 * @author Luc Maisonobe
36 * @author Evan Ward
37 * @see TimeScalesFactory
38 * @since 10.1
39 */
40 public class LazyLoadedTimeScales extends AbstractTimeScales {
41
42 /** Source of EOP data. */
43 private final LazyLoadedEop lazyLoadedEop;
44
45 /** UTCTAI offsets loaders. */
46 private final List<UTCTAIOffsetsLoader> loaders = new ArrayList<>();
47 /** Universal Time Coordinate scale. */
48 private UTCScale utc = null;
49
50 /** International Atomic Time scale. */
51 private TAIScale tai = null;
52
53 /** Terrestrial Time scale. */
54 private TTScale tt = null;
55
56 /** Galileo System Time scale. */
57 private GalileoScale gst = null;
58
59 /** GLObal NAvigation Satellite System scale. */
60 private GLONASSScale glonass = null;
61
62 /** Quasi-Zenith Satellite System scale. */
63 private QZSSScale qzss = null;
64
65 /** Global Positioning System scale. */
66 private GPSScale gps = null;
67
68 /** Geocentric Coordinate Time scale. */
69 private TCGScale tcg = null;
70
71 /** Barycentric Dynamic Time scale. */
72 private TDBScale tdb = null;
73
74 /** Barycentric Coordinate Time scale. */
75 private TCBScale tcb = null;
76
77 /** IRNSS System Time scale. */
78 private IRNSSScale irnss = null;
79
80 /** BDS System Time scale. */
81 private BDTScale bds = null;
82
83 /**
84 * Create a new set of time scales with the given sources of auxiliary data. This
85 * constructor uses the same {@link DataProvidersManager} for the default EOP loaders
86 * and the default leap second loaders.
87 *
88 * @param lazyLoadedEop loads Earth Orientation Parameters for {@link
89 * #getUT1(IERSConventions, boolean)}.
90 */
91 public LazyLoadedTimeScales(final LazyLoadedEop lazyLoadedEop) {
92 this.lazyLoadedEop = lazyLoadedEop;
93 }
94
95 /**
96 * Add a loader for UTC-TAI offsets history files.
97 *
98 * @param loader custom loader to add
99 * @see TAIUTCDatFilesLoader
100 * @see UTCTAIHistoryFilesLoader
101 * @see UTCTAIBulletinAFilesLoader
102 * @see #getUTC()
103 * @see #clearUTCTAIOffsetsLoaders()
104 * @since 7.1
105 */
106 public void addUTCTAIOffsetsLoader(final UTCTAIOffsetsLoader loader) {
107 synchronized (this) {
108 loaders.add(loader);
109 }
110 }
111
112 /**
113 * Add the default loaders for UTC-TAI offsets history files (both IERS and USNO).
114 * <p>
115 * The default loaders are {@link TAIUTCDatFilesLoader} that looks for a file named
116 * {@code tai-utc.dat} that must be in USNO format and {@link
117 * UTCTAIHistoryFilesLoader} that looks fir a file named {@code UTC-TAI.history} that
118 * must be in the IERS format. The {@link UTCTAIBulletinAFilesLoader} is
119 * <em>not</em> added by default as it is not recommended. USNO warned us that
120 * the TAI-UTC data present in bulletin A was for convenience only and was not
121 * reliable, there have been errors in several bulletins regarding these data.
122 * </p>
123 *
124 * @see <a href="http://maia.usno.navy.mil/ser7/tai-utc.dat">USNO tai-utc.dat
125 * file</a>
126 * @see <a href="http://hpiers.obspm.fr/eoppc/bul/bulc/UTC-TAI.history">IERS
127 * UTC-TAI.history file</a>
128 * @see TAIUTCDatFilesLoader
129 * @see UTCTAIHistoryFilesLoader
130 * @see #getUTC()
131 * @see #clearUTCTAIOffsetsLoaders()
132 * @since 7.1
133 */
134 public void addDefaultUTCTAIOffsetsLoaders() {
135 synchronized (this) {
136 final DataProvidersManager dataProvidersManager =
137 lazyLoadedEop.getDataProvidersManager();
138 addUTCTAIOffsetsLoader(new TAIUTCDatFilesLoader(TAIUTCDatFilesLoader.DEFAULT_SUPPORTED_NAMES, dataProvidersManager));
139 addUTCTAIOffsetsLoader(new UTCTAIHistoryFilesLoader(dataProvidersManager));
140 }
141 }
142
143 /**
144 * Clear loaders for UTC-TAI offsets history files.
145 *
146 * @see #getUTC()
147 * @see #addUTCTAIOffsetsLoader(UTCTAIOffsetsLoader)
148 * @see #addDefaultUTCTAIOffsetsLoaders()
149 * @since 7.1
150 */
151 public void clearUTCTAIOffsetsLoaders() {
152 synchronized (this) {
153 loaders.clear();
154 }
155 }
156
157 @Override
158 public TAIScale getTAI() {
159 synchronized (this) {
160
161 if (tai == null) {
162 tai = new TAIScale();
163 }
164
165 return tai;
166
167 }
168 }
169
170 @Override
171 public UTCScale getUTC() {
172 synchronized (this) {
173 if (utc == null) {
174 List<OffsetModel> entries = Collections.emptyList();
175 if (loaders.isEmpty()) {
176 addDefaultUTCTAIOffsetsLoaders();
177 }
178 for (UTCTAIOffsetsLoader loader : loaders) {
179 entries = loader.loadOffsets();
180 if (!entries.isEmpty()) {
181 break;
182 }
183 }
184 if (entries.isEmpty()) {
185 throw new OrekitException(OrekitMessages.NO_IERS_UTC_TAI_HISTORY_DATA_LOADED);
186 }
187 utc = new UTCScale(getTAI(), entries);
188 }
189
190 return utc;
191 }
192 }
193
194 @Override
195 public UT1Scale getUT1(final IERSConventions conventions, final boolean simpleEOP) {
196 // synchronized to maintain the same semantics as Orekit 10.0
197 synchronized (this) {
198 return super.getUT1(conventions, simpleEOP);
199 }
200 }
201
202 @Override
203 protected EOPHistory getEopHistory(final IERSConventions conventions,
204 final boolean simpleEOP) {
205 return lazyLoadedEop.getEOPHistory(conventions, simpleEOP, this);
206 }
207
208 // need to make this public for compatibility. Provides access to UT1 constructor.
209 /** {@inheritDoc} */
210 @Override
211 public UT1Scale getUT1(final EOPHistory history) {
212 return super.getUT1(history);
213 }
214
215 @Override
216 public TTScale getTT() {
217 synchronized (this) {
218
219 if (tt == null) {
220 tt = new TTScale();
221 }
222
223 return tt;
224
225 }
226 }
227
228 @Override
229 public GalileoScale getGST() {
230 synchronized (this) {
231
232 if (gst == null) {
233 gst = new GalileoScale();
234 }
235
236 return gst;
237
238 }
239 }
240
241 @Override
242 public GLONASSScale getGLONASS() {
243 synchronized (this) {
244
245 if (glonass == null) {
246 glonass = new GLONASSScale(getUTC());
247 }
248
249 return glonass;
250
251 }
252 }
253
254 @Override
255 public QZSSScale getQZSS() {
256 synchronized (this) {
257
258 if (qzss == null) {
259 qzss = new QZSSScale();
260 }
261
262 return qzss;
263
264 }
265 }
266
267 @Override
268 public GPSScale getGPS() {
269 synchronized (this) {
270
271 if (gps == null) {
272 gps = new GPSScale();
273 }
274
275 return gps;
276
277 }
278 }
279
280 @Override
281 public TCGScale getTCG() {
282 synchronized (this) {
283
284 if (tcg == null) {
285 tcg = new TCGScale(getTT(), getTAI());
286 }
287
288 return tcg;
289
290 }
291 }
292
293 @Override
294 public TDBScale getTDB() {
295 synchronized (this) {
296
297 if (tdb == null) {
298 tdb = new TDBScale(getTT(), getJ2000Epoch());
299 }
300
301 return tdb;
302
303 }
304 }
305
306 @Override
307 public TCBScale getTCB() {
308 synchronized (this) {
309
310 if (tcb == null) {
311 tcb = new TCBScale(getTDB(), getTAI());
312 }
313
314 return tcb;
315
316 }
317 }
318
319 @Override
320 public GMSTScale getGMST(final IERSConventions conventions, final boolean simpleEOP) {
321 // synchronized to maintain the same semantics as Orekit 10.0
322 synchronized (this) {
323 return super.getGMST(conventions, simpleEOP);
324 }
325 }
326
327 @Override
328 public IRNSSScale getIRNSS() {
329 synchronized (this) {
330
331 if (irnss == null) {
332 irnss = new IRNSSScale();
333 }
334
335 return irnss;
336
337 }
338 }
339
340 @Override
341 public BDTScale getBDT() {
342 synchronized (this) {
343
344 if (bds == null) {
345 bds = new BDTScale();
346 }
347
348 return bds;
349
350 }
351 }
352
353 }