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.Collection;
20  import java.util.function.BiFunction;
21  import java.util.function.Supplier;
22  
23  import org.orekit.bodies.CelestialBodies;
24  import org.orekit.time.TimeScales;
25  import org.orekit.time.UT1Scale;
26  import org.orekit.utils.IERSConventions;
27  
28  /**
29   * A collection of commonly used {@link Frame}s. This interface defines methods for
30   * obtaining instances of many commonly used reference frames.
31   *
32   * @author Guylaine Prat
33   * @author Luc Maisonobe
34   * @author Pascal Parraud
35   * @author Evan Ward
36   * @see FramesFactory
37   * @since 10.0
38   */
39  public interface Frames {
40  
41      /** Get Earth Orientation Parameters history.
42       * @param conventions conventions for which EOP history is requested
43       * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
44       * @return Earth Orientation Parameters history
45       */
46      EOPHistory getEOPHistory(IERSConventions conventions, boolean simpleEOP);
47  
48      /** Get one of the predefined frames.
49       * @param factoryKey key of the frame within the factory
50       * @return the predefined frame
51       */
52      Frame getFrame(Predefined factoryKey);
53  
54      /** Get the unique GCRF frame.
55       * <p>The GCRF frame is the root frame in the frame tree.</p>
56       * @return the unique instance of the GCRF frame
57       */
58      Frame getGCRF();
59  
60      /** Get the unique ICRF frame.
61       * <p>The ICRF frame is centered at solar system barycenter and aligned
62       * with GCRF.</p>
63       * @return the unique instance of the ICRF frame
64       */
65      Frame getICRF();
66  
67      /** Get the ecliptic frame.
68       * The IAU defines the ecliptic as "the plane perpendicular to the mean heliocentric
69       * orbital angular momentum vector of the Earth-Moon barycentre in the BCRS (IAU 2006
70       * Resolution B1)." The +z axis is aligned with the angular momentum vector, and the +x
71       * axis is aligned with +x axis of {@link #getMOD(IERSConventions) MOD}.
72       *
73       * <p> This implementation agrees with the JPL 406 ephemerides to within 0.5 arc seconds.
74       * @param conventions IERS conventions to apply
75       * @return the selected reference frame singleton.
76       */
77      Frame getEcliptic(IERSConventions conventions);
78  
79      /** Get the unique EME2000 frame.
80       * <p>The EME2000 frame is also called the J2000 frame.
81       * The former denomination is preferred in Orekit.</p>
82       * @return the unique instance of the EME2000 frame
83       */
84      FactoryManagedFrame getEME2000();
85  
86      /** Get an unspecified International Terrestrial Reference Frame.
87       * <p>
88       * The frame returned uses the {@link EOPEntry Earth Orientation Parameters}
89       * blindly. So if for example one loads only EOP 14 C04 files to retrieve
90       * the parameters, the frame will be an {@link ITRFVersion#ITRF_2014}. However,
91       * if parameters are loaded from different files types, or even for file
92       * types that changed their reference (like Bulletin A switching from
93       * {@link ITRFVersion#ITRF_2008} to {@link ITRFVersion#ITRF_2014} starting
94       * with Vol. XXXI No. 013 published on 2018-03-29), then the ITRF returned
95       * by this method will jump from one version to another version.
96       * </p>
97       * <p>
98       * IF a specific version of ITRF is needed, then {@link #getITRF(ITRFVersion,
99       * IERSConventions, boolean)} should be used instead.
100      * </p>
101      * @param conventions IERS conventions to apply
102      * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
103      * @return the selected reference frame singleton.
104      * @see #getITRF(ITRFVersion, IERSConventions, boolean)
105      * @since 6.1
106      */
107     FactoryManagedFrame getITRF(IERSConventions conventions,
108                                 boolean simpleEOP);
109 
110     /** Get the TIRF reference frame, ignoring tidal effects.
111      * @param conventions IERS conventions to apply
112      * @return the selected reference frame singleton.
113      * library cannot be read.
114      */
115     FactoryManagedFrame getTIRF(IERSConventions conventions);
116 
117     /** Get an specific International Terrestrial Reference Frame.
118      * <p>
119      * Note that if a specific version of ITRF is required, then {@code simpleEOP}
120      * should most probably be set to {@code false}, as ignoring tidal effects
121      * has an effect of the same order of magnitude as the differences between
122      * the various {@link ITRFVersion ITRF versions}.
123      * </p>
124      * @param version ITRF version
125      * @param conventions IERS conventions to apply
126      * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
127      * @return the selected reference frame singleton.
128      * @since 9.2
129      */
130     VersionedITRF getITRF(ITRFVersion version,
131                           IERSConventions conventions,
132                           boolean simpleEOP);
133 
134     /** Build an uncached International Terrestrial Reference Frame with specific {@link EOPHistory EOP history}.
135      * <p>
136      * This frame and its parent frames (TIRF and CIRF) will <em>not</em> be cached, they are
137      * rebuilt from scratch each time this method is called. This factory method is intended
138      * to be used when EOP history is changed at run time. For regular ITRF use, the
139      * {@link #getITRF(IERSConventions, boolean)} and {link {@link #getITRF(ITRFVersion, IERSConventions, boolean)}
140      * are more suitable.
141      * </p>
142      * @param ut1 UT1 time scale (contains the {@link EOPHistory EOP history})
143      * @return an ITRF frame with specified time scale and embedded EOP history
144      * @since 12.0
145      */
146     Frame buildUncachedITRF(UT1Scale ut1);
147 
148     /** Get the TIRF reference frame.
149      * @param conventions IERS conventions to apply
150      * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
151      * @return the selected reference frame singleton.
152      * @since 6.1
153      */
154     FactoryManagedFrame getTIRF(IERSConventions conventions,
155                                 boolean simpleEOP);
156 
157     /** Get the CIRF2000 reference frame.
158      * @param conventions IERS conventions to apply
159      * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
160      * @return the selected reference frame singleton.
161      */
162     FactoryManagedFrame getCIRF(IERSConventions conventions,
163                                 boolean simpleEOP);
164 
165     /** Get the VEIS 1950 reference frame.
166      * <p>Its parent frame is the GTOD frame with IERS 1996 conventions without EOP corrections.</p>
167      * @return the selected reference frame singleton.
168      */
169     FactoryManagedFrame getVeis1950();
170 
171     /** Get the equinox-based ITRF reference frame.
172      * @param conventions IERS conventions to apply
173      * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
174      * @return the selected reference frame singleton.
175      * @since 6.1
176      */
177     FactoryManagedFrame getITRFEquinox(IERSConventions conventions,
178                                        boolean simpleEOP);
179 
180     /** Get the GTOD reference frame.
181      * <p>
182      * The applyEOPCorr parameter is available mainly for testing purposes or for
183      * consistency with legacy software that don't handle EOP correction parameters.
184      * Beware that setting this parameter to {@code false} leads to crude accuracy
185      * (order of magnitudes for errors might be above 250m in LEO and 1400m in GEO).
186      * For this reason, setting this parameter to false is restricted to {@link
187      * IERSConventions#IERS_1996 IERS 1996} conventions, and hence the {@link
188      * IERSConventions IERS conventions} cannot be freely chosen here.
189      * </p>
190      * @param applyEOPCorr if true, EOP corrections are applied (here, dut1 and lod)
191      * @return the selected reference frame singleton.
192      */
193     FactoryManagedFrame getGTOD(boolean applyEOPCorr);
194 
195     /** Get the GTOD reference frame.
196      * @param conventions IERS conventions to apply
197      * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
198      * @return the selected reference frame singleton.
199      */
200     FactoryManagedFrame getGTOD(IERSConventions conventions,
201                                 boolean simpleEOP);
202 
203     /** Get the TOD reference frame.
204      * <p>
205      * The applyEOPCorr parameter is available mainly for testing purposes or for
206      * consistency with legacy software that don't handle EOP correction parameters.
207      * Beware that setting this parameter to {@code false} leads to crude accuracy
208      * (order of magnitudes for errors might be above 1m in LEO and 10m in GEO).
209      * For this reason, setting this parameter to false is restricted to {@link
210      * IERSConventions#IERS_1996 IERS 1996} conventions, and hence the {@link
211      * IERSConventions IERS conventions} cannot be freely chosen here.
212      * </p>
213      * @param applyEOPCorr if true, EOP corrections are applied (here, nutation)
214      * @return the selected reference frame singleton.
215      */
216     FactoryManagedFrame getTOD(boolean applyEOPCorr);
217 
218     /** Get the TOD reference frame.
219      * @param conventions IERS conventions to apply
220      * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
221      * @return the selected reference frame singleton.
222      */
223     FactoryManagedFrame getTOD(IERSConventions conventions,
224                                boolean simpleEOP);
225 
226     /** Get the MOD reference frame.
227      * <p>
228      * The applyEOPCorr parameter is available mainly for testing purposes or for
229      * consistency with legacy software that don't handle EOP correction parameters.
230      * Beware that setting this parameter to {@code false} leads to crude accuracy
231      * (order of magnitudes for errors might be above 1m in LEO and 10m in GEO).
232      * For this reason, setting this parameter to false is restricted to {@link
233      * IERSConventions#IERS_1996 IERS 1996} conventions, and hence the {@link
234      * IERSConventions IERS conventions} cannot be freely chosen here.
235      * </p>
236      * @param applyEOPCorr if true, EOP corrections are applied (EME2000/GCRF bias compensation)
237      * @return the selected reference frame singleton.
238      */
239     FactoryManagedFrame getMOD(boolean applyEOPCorr);
240 
241     /** Get the MOD reference frame.
242      * @param conventions IERS conventions to apply
243      * @return the selected reference frame singleton.
244      */
245     FactoryManagedFrame getMOD(IERSConventions conventions);
246 
247     /** Get the TEME reference frame.
248      * <p>
249      * The TEME frame is used for the SGP4 model in TLE propagation. This frame has <em>no</em>
250      * official definition and there are some ambiguities about whether it should be used
251      * as "of date" or "of epoch". This frame should therefore be used <em>only</em> for
252      * TLE propagation and not for anything else, as recommended by the CCSDS Orbit Data Message
253      * blue book.
254      * </p>
255      * @return the selected reference frame singleton.
256      */
257     FactoryManagedFrame getTEME();
258 
259     /** Get the PZ-90.11 (Parametry Zemly  – 1990.11) reference frame.
260      * <p>
261      * The PZ-90.11 reference system was updated on all operational
262      * GLONASS satellites starting from 3:00 pm on December 31, 2013.
263      * </p>
264      * <p>
265      * The transition between parent frame (ITRF-2008) and PZ-90.11 frame is performed using
266      * a seven parameters Helmert transformation.
267      * <pre>
268      *    From       To      ΔX(m)   ΔY(m)   ΔZ(m)   RX(mas)   RY(mas)  RZ(mas)   Epoch
269      * ITRF-2008  PZ-90.11  +0.003  +0.001  -0.000   +0.019    -0.042   +0.002     2010
270      * </pre>
271      * @see "Springer Handbook of Global Navigation Satellite Systems, Peter Teunissen & Oliver Montenbruck"
272      *
273      * @param convention IERS conventions to apply
274      * @param simpleEOP if true, tidal effects are ignored when interpolating EOP
275      * @return the selected reference frame singleton.
276      */
277     FactoryManagedFrame getPZ9011(IERSConventions convention,
278                                   boolean simpleEOP);
279 
280     /* Helpers for creating instances */
281 
282     /**
283      * Create a set of frames from the given data.
284      *
285      * @param timeScales      used to build the frames as well as the EOP data set.
286      * @param celestialBodies used to get {@link #getICRF()} which is the inertial frame
287      *                        of the solar system barycenter.
288      * @return a set of reference frame constructed from the given data.
289      * @see #of(TimeScales, Supplier)
290      */
291     static Frames of(final TimeScales timeScales,
292                      final CelestialBodies celestialBodies) {
293         return of(timeScales, () -> celestialBodies.getSolarSystemBarycenter()
294                 .getInertiallyOrientedFrame());
295     }
296 
297     /**
298      * Create a set of frames from the given data.
299      *
300      * @param timeScales   used to build the frames as well as the EOP data set.
301      * @param icrfSupplier used to get {@link #getICRF()}. For example, {@code
302      *                     celestialBodies.getSolarSystemBarycenter().getInertiallyOrientedFrame()}
303      * @return a set of reference frame constructed from the given data.
304      * @see CelestialBodies
305      * @see TimeScales#of(Collection, BiFunction)
306      */
307     static Frames of(final TimeScales timeScales,
308                      final Supplier<Frame> icrfSupplier) {
309         return new AbstractFrames(timeScales, icrfSupplier) {
310             @Override
311             public EOPHistory getEOPHistory(final IERSConventions conventions,
312                                             final boolean simpleEOP) {
313                 return getTimeScales().getUT1(conventions, simpleEOP).getEOPHistory();
314             }
315         };
316     }
317 
318 }