1   /* Copyright 2002-2020 CS GROUP
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  
18  package org.orekit.files.ccsds;
19  
20  import java.util.ArrayList;
21  import java.util.Collections;
22  import java.util.List;
23  
24  import org.orekit.bodies.CelestialBodies;
25  import org.orekit.bodies.CelestialBody;
26  import org.orekit.bodies.CelestialBodyFactory;
27  import org.orekit.errors.OrekitException;
28  import org.orekit.errors.OrekitMessages;
29  import org.orekit.frames.Frame;
30  import org.orekit.time.AbsoluteDate;
31  import org.orekit.time.TimeScale;
32  
33  /** This class gathers the meta-data present in the Orbital Data Message (ODM).
34   * @author sports
35   * @since 6.1
36   */
37  public class ODMMetaData {
38  
39      /** ODM file to which these meta-data belong. */
40      private final ODMFile odmFile;
41  
42      /** Time System: used for metadata, orbit state and covariance data. */
43      private CcsdsTimeScale timeSystem;
44  
45      /** Spacecraft name for which the orbit state is provided. */
46      private String objectName;
47  
48      /** Object identifier of the object for which the orbit state is provided. */
49      private String objectID;
50  
51      /** Launch Year. */
52      private int launchYear;
53  
54      /** Launch number. */
55      private int launchNumber;
56  
57      /** Piece of launch (from "A" to "ZZZ"). */
58      private String launchPiece;
59  
60      /** Origin of reference frame. */
61      private String centerName;
62  
63      /** Celestial body corresponding to the center name. */
64      private CelestialBody centerBody;
65  
66      /** Tests whether the body corresponding to the center name can be
67       * created through {@link CelestialBodies} in order to obtain the
68       * corresponding gravitational coefficient. */
69      private boolean hasCreatableBody;
70  
71      /** Reference frame in which data are given: used for state vector
72       * and Keplerian elements data (and for the covariance reference frame if none is given). */
73      private Frame refFrame;
74  
75      /** The reference frame specifier, as it appeared in the file. */
76      private String refFrameString;
77  
78      /** Epoch of reference frame, if not intrinsic to the definition of the
79       * reference frame. */
80      private String frameEpochString;
81  
82      /** Epoch of reference frame, if not intrinsic to the definition of the
83       * reference frame. */
84      private AbsoluteDate frameEpoch;
85  
86      /** Metadata comments. The list contains a string for each line of comment. */
87      private List<String> comment;
88  
89      /** Create a new meta-data.
90       * @param odmFile ODM file to which these meta-data belong
91       */
92      public ODMMetaData(final ODMFile odmFile) {
93          this.odmFile = odmFile;
94          comment = new ArrayList<String>();
95      }
96  
97      /** Get the ODM file to which these meta-data belong.
98       * @return ODM file to which these meta-data belong
99       */
100     public ODMFile getODMFile() {
101         return odmFile;
102     }
103 
104     /** Get the Time System that: for OPM, is used for metadata, state vector,
105      * maneuver and covariance data, for OMM, is used for metadata, orbit state
106      * and covariance data, for OEM, is used for metadata, ephemeris and
107      * covariance data.
108      * @return the time system
109      */
110     public CcsdsTimeScale getTimeSystem() {
111         return timeSystem;
112     }
113 
114     /** Set the Time System that: for OPM, is used for metadata, state vector,
115      * maneuver and covariance data, for OMM, is used for metadata, orbit state
116      * and covariance data, for OEM, is used for metadata, ephemeris and
117      * covariance data.
118      * @param timeSystem the time system to be set
119      */
120     public void setTimeSystem(final CcsdsTimeScale timeSystem) {
121         this.timeSystem = timeSystem;
122     }
123 
124     /**
125      * Get the time scale.
126      *
127      * @return the time scale.
128      * @see #getTimeSystem()
129      * @throws OrekitException if there is not corresponding time scale.
130      * @since 10.1
131      */
132     public TimeScale getTimeScale() {
133         return getTimeSystem().getTimeScale(
134                 odmFile.getConventions(),
135                 odmFile.getDataContext().getTimeScales());
136     }
137 
138     /** Get the spacecraft name for which the orbit state is provided.
139      * @return the spacecraft name
140      */
141     public String getObjectName() {
142         return objectName;
143     }
144 
145     /** Set the spacecraft name for which the orbit state is provided.
146      * @param objectName the spacecraft name to be set
147      */
148     public void setObjectName(final String objectName) {
149         this.objectName = objectName;
150     }
151 
152     /** Get the spacecraft ID for which the orbit state is provided.
153      * @return the spacecraft ID
154      */
155     public String getObjectID() {
156         return objectID;
157     }
158 
159     /** Set the spacecraft ID for which the orbit state is provided.
160      * @param objectID the spacecraft ID to be set
161      */
162     public void setObjectID(final String objectID) {
163         this.objectID = objectID;
164     }
165 
166     /** Set the launch year.
167      * @param launchYear launch year
168      */
169     public void setLaunchYear(final int launchYear) {
170         this.launchYear = launchYear;
171     }
172 
173     /** Get the launch year.
174      * @return launch year
175      */
176     public int getLaunchYear() {
177         return launchYear;
178     }
179 
180     /** Set the launch number.
181      * @param launchNumber launch number
182      */
183     public void setLaunchNumber(final int launchNumber) {
184         this.launchNumber = launchNumber;
185     }
186 
187     /** Get the launch number.
188      * @return launch number
189      */
190     public int getLaunchNumber() {
191         return launchNumber;
192     }
193 
194     /** Set the piece of launch.
195      * @param launchPiece piece of launch
196      */
197     public void setLaunchPiece(final String launchPiece) {
198         this.launchPiece = launchPiece;
199     }
200 
201     /** Get the piece of launch.
202      * @return piece of launch
203      */
204     public String getLaunchPiece() {
205         return launchPiece;
206     }
207 
208     /** Get the origin of reference frame.
209      * @return the origin of reference frame.
210      */
211     public String getCenterName() {
212         return centerName;
213     }
214 
215     /** Set the origin of reference frame.
216      * @param centerName the origin of reference frame to be set
217      */
218     public void setCenterName(final String centerName) {
219         this.centerName = centerName;
220     }
221 
222     /** Get the {@link CelestialBody} corresponding to the center name.
223      * @return the center body
224      */
225     public CelestialBody getCenterBody() {
226         return centerBody;
227     }
228 
229     /** Set the {@link CelestialBody} corresponding to the center name.
230      * @param centerBody the {@link CelestialBody} to be set
231      */
232     public void setCenterBody(final CelestialBody centerBody) {
233         this.centerBody = centerBody;
234     }
235 
236     /** Get boolean testing whether the body corresponding to the centerName
237      * attribute can be created through the {@link CelestialBodies}.
238      * @return true if {@link CelestialBody} can be created from centerName
239      *         false otherwise
240      */
241     public boolean getHasCreatableBody() {
242         return hasCreatableBody;
243     }
244 
245     /** Set boolean testing whether the body corresponding to the centerName
246      * attribute can be created through the {@link CelestialBodies}.
247      * @param hasCreatableBody the boolean to be set.
248      */
249     public void setHasCreatableBody(final boolean hasCreatableBody) {
250         this.hasCreatableBody = hasCreatableBody;
251     }
252 
253     /**
254      * Get the reference frame in which data are given: used for state vector and
255      * Keplerian elements data (and for the covariance reference frame if none is given).
256      *
257      * @return the reference frame
258      */
259     public Frame getFrame() {
260         final Frame frame = this.getRefFrame();
261         final CelestialBody body = this.getCenterBody();
262         if (body == null) {
263             throw new OrekitException(OrekitMessages.NO_DATA_LOADED_FOR_CELESTIAL_BODY,
264                     this.getCenterName());
265         }
266         // Just return frame if we don't need to shift the center based on CENTER_NAME
267         // MCI and ICRF are the only non-earth centered frames specified in Annex A.
268         final String frameString = this.getFrameString();
269         final boolean isMci = "MCI".equals(frameString);
270         final boolean isIcrf = "ICRF".equals(frameString);
271         final boolean isSolarSystemBarycenter =
272                 CelestialBodyFactory.SOLAR_SYSTEM_BARYCENTER.equals(body.getName());
273         if ((!(isMci || isIcrf) && CelestialBodyFactory.EARTH.equals(body.getName())) ||
274                 (isMci && CelestialBodyFactory.MARS.equals(body.getName())) ||
275                 (isIcrf && isSolarSystemBarycenter)) {
276             return frame;
277         }
278         // else, translate frame to specified center.
279         return new CcsdsModifiedFrame(frame, frameString, body, this.getCenterName());
280     }
281 
282     /**
283      * Get the the value of {@code REF_FRAME} as an Orekit {@link Frame}. The {@code
284      * CENTER_NAME} key word has not been applied yet, so the returned frame may not
285      * correspond to the reference frame of the data in the file.
286      *
287      * @return The reference frame specified by the {@code REF_FRAME} keyword.
288      * @see #getFrame()
289      */
290     public Frame getRefFrame() {
291         return refFrame;
292     }
293 
294     /** Set the reference frame in which data are given: used for state vector
295      * and Keplerian elements data (and for the covariance reference frame if none is given).
296      * @param refFrame the reference frame to be set
297      */
298     public void setRefFrame(final Frame refFrame) {
299         this.refFrame = refFrame;
300     }
301 
302     /**
303      * Get the reference frame specifier as it appeared in the file.
304      *
305      * @return the frame name as it appeared in the file.
306      * @see #getFrame()
307      */
308     public String getFrameString() {
309         return this.refFrameString;
310     }
311 
312     /**
313      * Set the reference frame name.
314      *
315      * @param frame specifier as it appeared in the file.
316      */
317     public void setFrameString(final String frame) {
318         this.refFrameString = frame;
319     }
320 
321     /** Get epoch of reference frame, if not intrinsic to the definition of the
322      * reference frame.
323      * @return epoch of reference frame
324      */
325     public String getFrameEpochString() {
326         return frameEpochString;
327     }
328 
329     /** Set epoch of reference frame, if not intrinsic to the definition of the
330      * reference frame.
331      * @param frameEpochString the epoch of reference frame to be set
332      */
333     public void setFrameEpochString(final String frameEpochString) {
334         this.frameEpochString = frameEpochString;
335     }
336 
337     /** Get epoch of reference frame, if not intrinsic to the definition of the
338      * reference frame.
339      * @return epoch of reference frame
340      */
341     public AbsoluteDate getFrameEpoch() {
342         return frameEpoch;
343     }
344 
345     /** Set epoch of reference frame, if not intrinsic to the definition of the
346      * reference frame.
347      * @param frameEpoch the epoch of reference frame to be set
348      */
349     public void setFrameEpoch(final AbsoluteDate frameEpoch) {
350         this.frameEpoch = frameEpoch;
351     }
352 
353     /** Get the meta-data comment.
354      * @return meta-data comment
355      */
356     public List<String> getComment() {
357         return Collections.unmodifiableList(comment);
358     }
359 
360     /** Set the meta-data comment.
361      * @param comment comment to set
362      */
363     public void setComment(final List<String> comment) {
364         this.comment = new ArrayList<String>(comment);
365     }
366 
367 }
368 
369 
370