1 /* Copyright 2002-2025 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.ndm.odm;
19
20 import org.orekit.bodies.CelestialBodyFactory;
21 import org.orekit.errors.OrekitException;
22 import org.orekit.errors.OrekitMessages;
23 import org.orekit.files.ccsds.definitions.BodyFacade;
24 import org.orekit.files.ccsds.definitions.CelestialBodyFrame;
25 import org.orekit.files.ccsds.definitions.FrameFacade;
26 import org.orekit.files.ccsds.definitions.ModifiedFrame;
27 import org.orekit.files.ccsds.utils.ContextBinding;
28 import org.orekit.frames.Frame;
29 import org.orekit.time.AbsoluteDate;
30
31 /** Common metadata for Orbit Parameter/Ephemeris/Mean Messages.
32 * @author Luc Maisonobe
33 * @since 11.0
34 */
35 public class OdmCommonMetadata extends OdmMetadata {
36
37 /** Object identifier of the object for which the orbit state is provided. */
38 private String objectID;
39
40 /** Origin of reference frame. */
41 private BodyFacade center;
42
43 /** Reference frame in which data are given: used for state vector
44 * and Keplerian elements data (and for the covariance reference frame if none is given). */
45 private FrameFacade referenceFrame;
46
47 /** Epoch of reference frame, if not intrinsic to the definition of the
48 * reference frame. */
49 private String frameEpochString;
50
51 /** Epoch of reference frame, if not intrinsic to the definition of the
52 * reference frame. */
53 private AbsoluteDate frameEpoch;
54
55 /** Simple constructor.
56 */
57 public OdmCommonMetadata() {
58 super(null);
59 }
60
61 /** {@inheritDoc} */
62 @Override
63 public void validate(final double version) {
64 super.validate(version);
65 checkNotNull(getObjectName(), OdmMetadataKey.OBJECT_NAME.name());
66 checkNotNull(objectID, CommonMetadataKey.OBJECT_ID.name());
67 checkNotNull(center, CommonMetadataKey.CENTER_NAME.name());
68 checkNotNull(referenceFrame, CommonMetadataKey.REF_FRAME.name());
69 }
70
71 /** Finalize the metadata.
72 * <p>
73 * ODM standard enforces {@code TIME_SYSTEM} to appear *after*
74 * {@code REF_FRAME_EPOCH}, despite it is needed to interpret it.
75 * We have to wait until parsing end to finalize this date.
76 * </p>
77 * @param context context binding
78 */
79 public void finalizeMetadata(final ContextBinding context) {
80 if (frameEpochString != null) {
81 frameEpoch = context.getTimeSystem().getConverter(context).parse(frameEpochString);
82 }
83 }
84
85 /** Get the spacecraft ID for which the orbit state is provided.
86 * @return the spacecraft ID
87 */
88 public String getObjectID() {
89 return objectID;
90 }
91
92 /** Set the spacecraft ID for which the orbit state is provided.
93 * @param objectID the spacecraft ID to be set
94 */
95 public void setObjectID(final String objectID) {
96 refuseFurtherComments();
97 this.objectID = objectID;
98 }
99
100 /** Get the launch year.
101 * @return launch year
102 */
103 public int getLaunchYear() {
104 return getLaunchYear(objectID);
105 }
106
107 /** Get the launch number.
108 * @return launch number
109 */
110 public int getLaunchNumber() {
111 return getLaunchNumber(objectID);
112 }
113
114 /** Get the piece of launch.
115 * @return piece of launch
116 */
117 public String getLaunchPiece() {
118 return getLaunchPiece(objectID);
119 }
120
121 /** Get the origin of reference frame.
122 * @return the origin of reference frame.
123 */
124 public BodyFacade getCenter() {
125 return center;
126 }
127
128 /** Set the origin of reference frame.
129 * @param center origin of reference frame to be set
130 */
131 public void setCenter(final BodyFacade center) {
132 refuseFurtherComments();
133 this.center = center;
134 }
135
136 /**
137 * Get the reference frame in which data are given: used for state vector and
138 * Keplerian elements data (and for the covariance reference frame if none is given).
139 *
140 * @return the reference frame
141 */
142 public Frame getFrame() {
143 if (center.getBody() == null) {
144 throw new OrekitException(OrekitMessages.NO_DATA_LOADED_FOR_CELESTIAL_BODY, center.getName());
145 }
146 if (referenceFrame.asFrame() == null) {
147 throw new OrekitException(OrekitMessages.CCSDS_INVALID_FRAME, referenceFrame.getName());
148 }
149 // Just return frame if we don't need to shift the center based on CENTER_NAME
150 // MCI and ICRF are the only non-Earth centered frames specified in Annex A.
151 final boolean isMci = referenceFrame.asCelestialBodyFrame() == CelestialBodyFrame.MCI;
152 final boolean isIcrf = referenceFrame.asCelestialBodyFrame() == CelestialBodyFrame.ICRF;
153 final boolean isSolarSystemBarycenter =
154 CelestialBodyFactory.SOLAR_SYSTEM_BARYCENTER.equals(center.getBody().getName());
155 if (!(isMci || isIcrf) && CelestialBodyFactory.EARTH.equals(center.getBody().getName()) ||
156 isMci && CelestialBodyFactory.MARS.equals(center.getBody().getName()) ||
157 isIcrf && isSolarSystemBarycenter) {
158 return referenceFrame.asFrame();
159 }
160 // else, translate frame to specified center.
161 return new ModifiedFrame(referenceFrame.asFrame(), referenceFrame.asCelestialBodyFrame(),
162 center.getBody(), center.getName());
163 }
164
165 /**
166 * Get the value of {@code REF_FRAME} as an Orekit {@link Frame}. The {@code
167 * CENTER_NAME} key word has not been applied yet, so the returned frame may not
168 * correspond to the reference frame of the data in the file.
169 *
170 * @return The reference frame specified by the {@code REF_FRAME} keyword.
171 * @see #getFrame()
172 */
173 public FrameFacade getReferenceFrame() {
174 return referenceFrame;
175 }
176
177 /** Set the reference frame in which data are given: used for state vector
178 * and Keplerian elements data (and for the covariance reference frame if none is given).
179 * @param referenceFrame the reference frame to be set
180 */
181 public void setReferenceFrame(final FrameFacade referenceFrame) {
182 refuseFurtherComments();
183 this.referenceFrame = referenceFrame;
184 }
185
186 /** Set epoch of reference frame, if not intrinsic to the definition of the
187 * reference frame.
188 * @param frameEpochString the epoch of reference frame to be set
189 */
190 public void setFrameEpochString(final String frameEpochString) {
191 refuseFurtherComments();
192 this.frameEpochString = frameEpochString;
193 }
194
195 /** Get epoch of reference frame, if not intrinsic to the definition of the
196 * reference frame.
197 * @return epoch of reference frame
198 */
199 public AbsoluteDate getFrameEpoch() {
200 return frameEpoch;
201 }
202
203 /** Set epoch of reference frame, if not intrinsic to the definition of the
204 * reference frame.
205 * @param frameEpoch the epoch of reference frame to be set
206 */
207 public void setFrameEpoch(final AbsoluteDate frameEpoch) {
208 refuseFurtherComments();
209 this.frameEpoch = frameEpoch;
210 }
211
212 }