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.frames;
18
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.function.Supplier;
24
25 import org.orekit.data.DataProvidersManager;
26 import org.orekit.errors.OrekitException;
27 import org.orekit.time.TimeScale;
28 import org.orekit.time.TimeScales;
29 import org.orekit.utils.Constants;
30 import org.orekit.utils.IERSConventions;
31
32 /**
33 * Loads Earth Orientation Parameters (EOP) from a configured set of {@link
34 * EopHistoryLoader}s on demand. Methods are synchronized so it is safe for access from
35 * multiple threads.
36 *
37 * @author Guylaine Prat
38 * @author Luc Maisonobe
39 * @author Pascal Parraud
40 * @author Evan Ward
41 * @see LazyLoadedFrames
42 * @see FramesFactory
43 * @since 10.1
44 */
45 public class LazyLoadedEop {
46
47 /** Provides access to the EOP data files. */
48 private final DataProvidersManager dataProvidersManager;
49 /** Loaders for Earth Orientation parameters. */
50 private final Map<IERSConventions, List<EopHistoryLoader>> eopHistoryLoaders;
51 /** Threshold for EOP continuity. */
52 private double eopContinuityThreshold;
53 /** Degree for EOP interpolation.
54 * @since 12.0
55 */
56 private int interpolationDegree;
57
58 /**
59 * Create a new instance for loading EOP data from multiple {@link
60 * EopHistoryLoader}s.
61 *
62 * @param dataProvidersManager provides access to the needed EOP data files.
63 */
64 public LazyLoadedEop(final DataProvidersManager dataProvidersManager) {
65 this.dataProvidersManager = dataProvidersManager;
66 this.eopHistoryLoaders = new HashMap<>();
67 this.eopContinuityThreshold = 5 * Constants.JULIAN_DAY;
68 this.interpolationDegree = EOPHistory.DEFAULT_INTERPOLATION_DEGREE;
69 }
70
71 /**
72 * Get the data providers manager for this instance.
73 *
74 * @return the provider of EOP data files.
75 */
76 public DataProvidersManager getDataProvidersManager() {
77 return dataProvidersManager;
78 }
79
80 /**
81 * Add the default loaders EOP history (IAU 1980 precession/nutation).
82 * <p>
83 * The default loaders look for IERS EOP C04 and bulletins B files. They correspond to
84 * {@link IERSConventions#IERS_1996 IERS 1996} conventions.
85 * </p>
86 *
87 * @param rapidDataColumnsSupportedNames regular expression for supported rapid data
88 * columns EOP files names (may be null if the
89 * default IERS file names are used)
90 * @param xmlSupportedNames regular expression for supported XML EOP
91 * files names (may be null if the
92 * default IERS file names are used)
93 * @param eopC04SupportedNames regular expression for supported EOP C04
94 * files names (may be null if the default IERS
95 * file names are used)
96 * @param bulletinBSupportedNames regular expression for supported bulletin B
97 * files names (may be null if the default IERS
98 * file names are used)
99 * @param bulletinASupportedNames regular expression for supported bulletin A
100 * files names (may be null if the default IERS
101 * file names are used)
102 * @param csvSupportedNames regular expression for supported csv files names
103 * (may be null if the default IERS file names are used)
104 * @param utcSupplier UTC time scale supplier. Value is not
105 * accessed until attempting to load EOP.
106 * @see <a href="https://datacenter.iers.org/products/eop/">IERS https data download</a>
107 * @see #addEOPHistoryLoader(IERSConventions, EopHistoryLoader)
108 * @see #clearEOPHistoryLoaders()
109 * @see #addDefaultEOP2000HistoryLoaders(String, String, String, String, String, String, Supplier)
110 * @since 12.0
111 */
112 public void addDefaultEOP1980HistoryLoaders(final String rapidDataColumnsSupportedNames,
113 final String xmlSupportedNames,
114 final String eopC04SupportedNames,
115 final String bulletinBSupportedNames,
116 final String bulletinASupportedNames,
117 final String csvSupportedNames,
118 final Supplier<TimeScale> utcSupplier) {
119 final String rapidColNames =
120 (rapidDataColumnsSupportedNames == null) ?
121 FramesFactory.RAPID_DATA_PREDICTION_COLUMNS_1980_FILENAME :
122 rapidDataColumnsSupportedNames;
123 addEOPHistoryLoader(IERSConventions.IERS_1996,
124 new RapidDataAndPredictionColumnsLoader(false, rapidColNames,
125 dataProvidersManager, utcSupplier));
126 final String xmlNames = (xmlSupportedNames == null) ?
127 FramesFactory.XML_1980_FILENAME :
128 xmlSupportedNames;
129 addEOPHistoryLoader(IERSConventions.IERS_1996,
130 new EopXmlLoader(xmlNames, dataProvidersManager, utcSupplier));
131 final String eopcNames =
132 (eopC04SupportedNames == null) ?
133 FramesFactory.EOPC04_1980_FILENAME : eopC04SupportedNames;
134 addEOPHistoryLoader(IERSConventions.IERS_1996,
135 new EopC04FilesLoader(eopcNames, dataProvidersManager, utcSupplier));
136 final String bulBNames =
137 (bulletinBSupportedNames == null) ?
138 FramesFactory.BULLETINB_1980_FILENAME : bulletinBSupportedNames;
139 addEOPHistoryLoader(IERSConventions.IERS_1996,
140 new BulletinBFilesLoader(bulBNames, dataProvidersManager, utcSupplier));
141 final String bulANames =
142 (bulletinASupportedNames == null) ?
143 FramesFactory.BULLETINA_FILENAME : bulletinASupportedNames;
144 addEOPHistoryLoader(IERSConventions.IERS_1996,
145 new BulletinAFilesLoader(bulANames, dataProvidersManager, utcSupplier));
146 final String csvNames = (csvSupportedNames == null) ?
147 FramesFactory.CSV_FILENAME : csvSupportedNames;
148 addEOPHistoryLoader(IERSConventions.IERS_1996,
149 new EopCsvFilesLoader(csvNames, dataProvidersManager, utcSupplier));
150 }
151
152 /**
153 * Add the default loaders for EOP history (IAU 2000/2006 precession/nutation).
154 * <p>
155 * The default loaders look for IERS EOP C04 and bulletins B files. They correspond to
156 * both {@link IERSConventions#IERS_2003 IERS 2003} and {@link
157 * IERSConventions#IERS_2010 IERS 2010} conventions.
158 * </p>
159 *
160 * @param rapidDataColumnsSupportedNames regular expression for supported rapid data
161 * columns EOP files names (may be null if the
162 * default IERS file names are used)
163 * @param xmlSupportedNames regular expression for supported XML EOP
164 * files names (may be null if the
165 * default IERS file names are used)
166 * @param eopC04SupportedNames regular expression for supported EOP C04
167 * files names (may be null if the default IERS
168 * file names are used)
169 * @param bulletinBSupportedNames regular expression for supported bulletin B
170 * files names (may be null if the default IERS
171 * file names are used)
172 * @param bulletinASupportedNames regular expression for supported bulletin A
173 * files names (may be null if the default IERS
174 * file names are used)
175 * @param csvSupportedNames regular expression for supported csv files names
176 * (may be null if the default IERS file names are used)
177 * @param utcSupplier UTC time scale supplier. Value is not
178 * accessed until attempting to load EOP.
179 * @see <a href="https://datacenter.iers.org/products/eop/">IERS https data download</a>
180 * @see #addEOPHistoryLoader(IERSConventions, EopHistoryLoader)
181 * @see #clearEOPHistoryLoaders()
182 * @see #addDefaultEOP1980HistoryLoaders(String, String, String, String, String, String, Supplier)
183 * @since 12.0
184 */
185 public void addDefaultEOP2000HistoryLoaders(final String rapidDataColumnsSupportedNames,
186 final String xmlSupportedNames,
187 final String eopC04SupportedNames,
188 final String bulletinBSupportedNames,
189 final String bulletinASupportedNames,
190 final String csvSupportedNames,
191 final Supplier<TimeScale> utcSupplier) {
192 final String rapidColNames =
193 (rapidDataColumnsSupportedNames == null) ?
194 FramesFactory.RAPID_DATA_PREDICTION_COLUMNS_2000_FILENAME :
195 rapidDataColumnsSupportedNames;
196 addEOPHistoryLoader(IERSConventions.IERS_2003,
197 new RapidDataAndPredictionColumnsLoader(true, rapidColNames, dataProvidersManager, utcSupplier));
198 addEOPHistoryLoader(IERSConventions.IERS_2010,
199 new RapidDataAndPredictionColumnsLoader(true, rapidColNames, dataProvidersManager, utcSupplier));
200 final String xmlNames = (xmlSupportedNames == null) ?
201 FramesFactory.XML_2000_FILENAME :
202 xmlSupportedNames;
203 addEOPHistoryLoader(IERSConventions.IERS_2003,
204 new EopXmlLoader(xmlNames, dataProvidersManager, utcSupplier));
205 addEOPHistoryLoader(IERSConventions.IERS_2010,
206 new EopXmlLoader(xmlNames, dataProvidersManager, utcSupplier));
207 final String eopcNames = (eopC04SupportedNames == null) ?
208 FramesFactory.EOPC04_2000_FILENAME : eopC04SupportedNames;
209 addEOPHistoryLoader(IERSConventions.IERS_2003,
210 new EopC04FilesLoader(eopcNames, dataProvidersManager, utcSupplier));
211 addEOPHistoryLoader(IERSConventions.IERS_2010,
212 new EopC04FilesLoader(eopcNames, dataProvidersManager, utcSupplier));
213 final String bulBNames = (bulletinBSupportedNames == null) ?
214 FramesFactory.BULLETINB_2000_FILENAME : bulletinBSupportedNames;
215 addEOPHistoryLoader(IERSConventions.IERS_2003,
216 new BulletinBFilesLoader(bulBNames, dataProvidersManager, utcSupplier));
217 addEOPHistoryLoader(IERSConventions.IERS_2010,
218 new BulletinBFilesLoader(bulBNames, dataProvidersManager, utcSupplier));
219 final String bulANames = (bulletinASupportedNames == null) ?
220 FramesFactory.BULLETINA_FILENAME : bulletinASupportedNames;
221 addEOPHistoryLoader(IERSConventions.IERS_2003,
222 new BulletinAFilesLoader(bulANames, dataProvidersManager, utcSupplier));
223 addEOPHistoryLoader(IERSConventions.IERS_2010,
224 new BulletinAFilesLoader(bulANames, dataProvidersManager, utcSupplier));
225 final String csvNames = (csvSupportedNames == null) ?
226 FramesFactory.CSV_FILENAME : csvSupportedNames;
227 addEOPHistoryLoader(IERSConventions.IERS_2003,
228 new EopCsvFilesLoader(csvNames, dataProvidersManager, utcSupplier));
229 addEOPHistoryLoader(IERSConventions.IERS_2010,
230 new EopCsvFilesLoader(csvNames, dataProvidersManager, utcSupplier));
231 }
232
233 /**
234 * Add a loader for Earth Orientation Parameters history.
235 *
236 * @param conventions IERS conventions to which EOP history applies
237 * @param loader custom loader to add for the EOP history
238 * @see #addDefaultEOP1980HistoryLoaders(String, String, String, String, String, String, Supplier)
239 * @see #clearEOPHistoryLoaders()
240 */
241 public void addEOPHistoryLoader(final IERSConventions conventions, final EopHistoryLoader loader) {
242 synchronized (eopHistoryLoaders) {
243 if (!eopHistoryLoaders.containsKey(conventions)) {
244 eopHistoryLoaders.put(conventions, new ArrayList<>());
245 }
246 eopHistoryLoaders.get(conventions).add(loader);
247 }
248 }
249
250 /**
251 * Clear loaders for Earth Orientation Parameters history.
252 *
253 * @see #addEOPHistoryLoader(IERSConventions, EopHistoryLoader)
254 * @see #addDefaultEOP1980HistoryLoaders(String, String, String, String, String, String, Supplier)
255 */
256 public void clearEOPHistoryLoaders() {
257 synchronized (eopHistoryLoaders) {
258 eopHistoryLoaders.clear();
259 }
260 }
261
262 /**
263 * Set the threshold to check EOP continuity.
264 * <p>
265 * The default threshold (used if this method is never called) is 5 Julian days. If
266 * after loading EOP entries some holes between entries exceed this threshold, an
267 * exception will be triggered.
268 * </p>
269 * <p>
270 * One case when calling this method is really useful is for applications that use a
271 * single Bulletin A, as these bulletins have a roughly one month wide hole for the
272 * first bulletin of each month, which contains older final data in addition to the
273 * rapid data and the predicted data.
274 * </p>
275 *
276 * @param threshold threshold to use for checking EOP continuity (in seconds)
277 */
278 public void setEOPContinuityThreshold(final double threshold) {
279 eopContinuityThreshold = threshold;
280 }
281
282 /**
283 * Set the degree for interpolation degree.
284 * <p>
285 * The default threshold (used if this method is never called) is {@link EOPHistory#DEFAULT_INTERPOLATION_DEGREE}.
286 * </p>
287 *
288 * @param interpolationDegree interpolation degree, must be of the form 4k-1
289 * @since 12.0
290 */
291 public void setInterpolationDegree(final int interpolationDegree) {
292 this.interpolationDegree = interpolationDegree;
293 }
294
295 /**
296 * Get Earth Orientation Parameters history.
297 * <p>
298 * If no {@link EopHistoryLoader} has been added by calling {@link
299 * #addEOPHistoryLoader(IERSConventions, EopHistoryLoader) addEOPHistoryLoader} or if
300 * {@link #clearEOPHistoryLoaders() clearEOPHistoryLoaders} has been called
301 * afterwards, the {@link #addDefaultEOP1980HistoryLoaders(String, String, String,
302 * String, String, String, Supplier)} and {@link #addDefaultEOP2000HistoryLoaders(String,
303 * String, String, String, String, String, Supplier)} methods will be called automatically
304 * with supported file names parameters all set to null, in order to get the default
305 * loaders configuration.
306 * </p>
307 *
308 * @param conventions conventions for which EOP history is requested
309 * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
310 * @param timeScales to use when loading EOP and computing corrections.
311 * @return Earth Orientation Parameters history
312 */
313 public EOPHistory getEOPHistory(final IERSConventions conventions,
314 final boolean simpleEOP,
315 final TimeScales timeScales) {
316
317 synchronized (eopHistoryLoaders) {
318
319 if (eopHistoryLoaders.isEmpty()) {
320 // set up using default loaders
321 final Supplier<TimeScale> utcSupplier = timeScales::getUTC;
322 addDefaultEOP2000HistoryLoaders(null, null, null, null, null, null, utcSupplier);
323 addDefaultEOP1980HistoryLoaders(null, null, null, null, null, null, utcSupplier);
324 }
325
326 OrekitException pendingException = null;
327 final List<EOPEntry> data = new ArrayList<>();
328
329 // try to load canonical data if available
330 if (eopHistoryLoaders.containsKey(conventions)) {
331 for (final EopHistoryLoader loader : eopHistoryLoaders.get(conventions)) {
332 try {
333 loader.fillHistory(conventions.getNutationCorrectionConverter(timeScales), data);
334 } catch (OrekitException oe) {
335 pendingException = oe;
336 }
337 }
338 }
339
340 if (data.isEmpty() && pendingException != null) {
341 throw pendingException;
342 }
343
344 final EOPHistory history = new EOPHistory(conventions, interpolationDegree, data, simpleEOP, timeScales);
345 history.checkEOPContinuity(eopContinuityThreshold);
346 return history;
347
348 }
349
350 }
351
352 }