1 /* Copyright 2002-2026 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.oem;
19
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.orekit.data.DataContext;
26 import org.orekit.errors.OrekitException;
27 import org.orekit.errors.OrekitMessages;
28 import org.orekit.files.ccsds.definitions.TimeSystem;
29 import org.orekit.files.ccsds.ndm.NdmConstituent;
30 import org.orekit.files.ccsds.ndm.odm.OdmHeader;
31 import org.orekit.files.general.EphemerisFile;
32 import org.orekit.utils.IERSConventions;
33 import org.orekit.utils.TimeStampedPVCoordinates;
34
35 /** This class stores all the information of the OEM File parsed by OEMParser.
36 * <p>
37 * It contains the header and a list of Ephemerides Blocks each containing
38 * metadata, a list of ephemerides data lines and optional covariance matrices
39 * (and their metadata).
40 * </p>
41 * @author sports
42 * @author Evan Ward
43 * @since 6.1
44 */
45 public class Oem extends NdmConstituent<OdmHeader, OemSegment>
46 implements EphemerisFile<TimeStampedPVCoordinates, OemSegment> {
47
48 /** Root element for XML files. */
49 public static final String ROOT = "oem";
50
51 /** Key for format version. */
52 public static final String FORMAT_VERSION_KEY = "CCSDS_OEM_VERS";
53
54 /** Default name for unknown object. */
55 public static final String UNKNOWN_OBJECT = "UNKNOWN";
56
57 /** Gravitational coefficient to use for building Cartesian/Keplerian orbits. */
58 private final double mu;
59
60 /** Simple constructor.
61 * @param header file header
62 * @param segments file segments
63 * @param conventions IERS conventions
64 * @param dataContext used for creating frames, time scales, etc.
65 * @param mu gravitational coefficient
66 */
67 public Oem(final OdmHeader header, final List<OemSegment> segments,
68 final IERSConventions conventions, final DataContext dataContext,
69 final double mu) {
70 super(header, segments, conventions, dataContext);
71 this.mu = mu;
72 }
73
74 /** {@inheritDoc}
75 * <p>
76 * The metadata entries checked for use as the key are the following ones,
77 * the first non-null being used. The map from OEM files always contains only
78 * one object.
79 * <ul>
80 * <li>{@link org.orekit.files.ccsds.ndm.odm.OdmCommonMetadata#getObjectID()} OBJECT_ID}
81 * if non-null and not equal to {@link #UNKNOWN_OBJECT}</li>
82 * <li>{@link org.orekit.files.ccsds.ndm.odm.OdmMetadata#getObjectName() OBJECT_NAME}</li>
83 * <li>the default name {@link #UNKNOWN_OBJECT} for unknown objects</li>
84 * </ul>
85 */
86 @Override
87 public Map<String, OemSatelliteEphemeris> getSatellites() {
88 final Map<String, List<OemSegment>> byName = new HashMap<>();
89 for (final OemSegment segment : getSegments()) {
90 final String name;
91 if (segment.getMetadata().getObjectID() != null &&
92 !UNKNOWN_OBJECT.equals(segment.getMetadata().getObjectID())) {
93 name = segment.getMetadata().getObjectID();
94 } else if (segment.getMetadata().getObjectName() != null) {
95 name = segment.getMetadata().getObjectName();
96 } else {
97 name = UNKNOWN_OBJECT;
98 }
99 byName.putIfAbsent(name, new ArrayList<>());
100 byName.get(name).add(segment);
101 }
102 final Map<String, OemSatelliteEphemeris> ret = new HashMap<>();
103 for (final Map.Entry<String, List<OemSegment>> entry : byName.entrySet()) {
104 ret.put(entry.getKey(), new OemSatelliteEphemeris(entry.getKey(), mu, entry.getValue()));
105 }
106 return ret;
107 }
108
109 /** Check that, according to the CCSDS standard, every OEMBlock has the same time system.
110 */
111 public void checkTimeSystems() {
112 TimeSystem referenceTimeSystem = null;
113 for (final OemSegment segment : getSegments()) {
114 final TimeSystem timeSystem = segment.getMetadata().getTimeSystem();
115 if (referenceTimeSystem == null) {
116 referenceTimeSystem = timeSystem;
117 } else if (!referenceTimeSystem.equals(timeSystem)) {
118 throw new OrekitException(OrekitMessages.CCSDS_INCONSISTENT_TIME_SYSTEMS,
119 referenceTimeSystem.name(), timeSystem.name());
120 }
121 }
122 }
123
124 }