1 /* Copyright 2002-2021 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 package org.orekit.files.ilrs;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.concurrent.ConcurrentHashMap;
24
25 import org.hipparchus.geometry.euclidean.threed.Vector3D;
26 import org.orekit.files.general.EphemerisFile;
27 import org.orekit.frames.Frame;
28 import org.orekit.propagation.BoundedPropagator;
29 import org.orekit.time.AbsoluteDate;
30 import org.orekit.time.TimeScale;
31 import org.orekit.utils.CartesianDerivativesFilter;
32 import org.orekit.utils.TimeStampedPVCoordinates;
33
34 /**
35 * This class stores all the information of the Consolidated laser ranging Prediction File (CPF) parsed
36 * by CPFParser. It contains the header and a list of ephemeris entry.
37 * @author Bryan Cazabonne
38 * @since 10.3
39 */
40 public class CPF implements EphemerisFile<CPF.CPFCoordinate, CPF.CPFEphemeris> {
41
42 /** Default satellite ID, used if header is null when initializing the ephemeris. */
43 public static final String DEFAULT_ID = "9999999";
44
45 /** Gravitational coefficient. */
46 private double mu;
47
48 /** The interpolation sample. */
49 private int interpolationSample;
50
51 /** Time scale of dates in the ephemeris file. */
52 private TimeScale timeScale;
53
54 /** Indicates if data contains velocity or not. */
55 private CartesianDerivativesFilter filter;
56
57 /** CPF file header. */
58 private CPFHeader header;
59
60 /** Map containing satellite information. */
61 private Map<String, CPFEphemeris> ephemeris;
62
63 /** List of comments contained in the file. */
64 private List<String> comments;
65
66 /**
67 * Constructor.
68 */
69 public CPF() {
70 this.mu = Double.NaN;
71 this.ephemeris = new ConcurrentHashMap<>();
72 this.header = new CPFHeader();
73 this.comments = new ArrayList<>();
74 }
75
76 /** {@inheritDoc}
77 * First key corresponds to String value of {@link CPFHeader#getIlrsSatelliteId()}
78 */
79 @Override
80 public Map<String, CPFEphemeris> getSatellites() {
81 // Return the map
82 return Collections.unmodifiableMap(ephemeris);
83 }
84
85 /**
86 * Get the CPF file header.
87 * @return the CPF file header
88 */
89 public CPFHeader getHeader() {
90 return header;
91 }
92
93 /**
94 * Get the time scale used in CPF file.
95 * @return the time scale used to parse epochs in CPF file.
96 */
97 public TimeScale getTimeScale() {
98 return timeScale;
99 }
100
101 /**
102 * Get the comments contained in the file.
103 * @return the comments contained in the file
104 */
105 public List<String> getComments() {
106 return comments;
107 }
108
109 /**
110 * Adds a new P/V coordinate to the satellite.
111 * <p>
112 * If the header has not been read, the {@link #DEFAULT_ID} is used.
113 * </p>
114 * @param coord the P/V coordinate of the satellite
115 * @deprecated as of 11.0.1, replaced by {@link CPF#addSatelliteCoordinate(String, CPFCoordinate)}
116 */
117 @Deprecated
118 public void addSatelliteCoordinate(final CPFCoordinate coord) {
119 addSatelliteCoordinate(DEFAULT_ID, coord);
120 }
121
122 /**
123 * Adds a set of P/V coordinates to the satellite.
124 * @param id satellite ILRS identifier
125 * @param coord set of coordinates
126 * @since 11.0.1
127 */
128 public void addSatelliteCoordinates(final String id, final List<CPFCoordinate> coord) {
129 createIfNeeded(id);
130 ephemeris.get(id).coordinates.addAll(coord);
131 }
132
133 /**
134 * Add a new P/V coordinates to the satellite.
135 * @param id satellite ILRS identifier
136 * @param coord the P/V coordinate of the satellite
137 * @since 11.0.1
138 */
139 public void addSatelliteCoordinate(final String id, final CPFCoordinate coord) {
140 createIfNeeded(id);
141 ephemeris.get(id).coordinates.add(coord);
142 }
143
144 /**
145 * Set the interpolation sample.
146 * @param interpolationSample interpolation sample
147 */
148 public void setInterpolationSample(final int interpolationSample) {
149 this.interpolationSample = interpolationSample;
150 }
151
152 /**
153 * Set the gravitational coefficient.
154 * @param mu the coefficient to be set
155 */
156 public void setMu(final double mu) {
157 this.mu = mu;
158 }
159
160 /**
161 * Set the time scale.
162 * @param timeScale use to parse dates in this file.
163 */
164 public void setTimeScale(final TimeScale timeScale) {
165 this.timeScale = timeScale;
166 }
167
168 /**
169 * Set the derivatives filter.
170 * @param filter that indicates which derivatives of position are available.
171 */
172 public void setFilter(final CartesianDerivativesFilter filter) {
173 this.filter = filter;
174 }
175
176 /**
177 * Create the satellite ephemeris corresponding to the given ID (if needed).
178 * @param id satellite ILRS identifier
179 */
180 private void createIfNeeded(final String id) {
181 if (ephemeris.get(id) == null) {
182 ephemeris.put(id, new CPFEphemeris(id));
183 }
184 }
185
186 /** An ephemeris entry for a single satellite contains in a CPF file. */
187 public class CPFEphemeris
188 implements EphemerisFile.SatelliteEphemeris<CPFCoordinate, CPFEphemeris>,
189 EphemerisFile.EphemerisSegment<CPFCoordinate> {
190
191 /** Satellite ID. */
192 private final String id;
193
194 /** Ephemeris Data. */
195 private final List<CPFCoordinate> coordinates;
196
197 /**
198 * Constructor.
199 * @deprecated as of 11.0.1, replaced by
200 */
201 @Deprecated
202 public CPFEphemeris() {
203 this(null);
204 }
205
206 /**
207 * Constructor.
208 * @param id satellite ID
209 */
210 public CPFEphemeris(final String id) {
211 this.id = id;
212 this.coordinates = new ArrayList<>();
213 }
214
215
216 /** {@inheritDoc} */
217 @Override
218 public Frame getFrame() {
219 return header.getRefFrame();
220 }
221
222 /** {@inheritDoc} */
223 @Override
224 public int getInterpolationSamples() {
225 return interpolationSample;
226 }
227
228 /** {@inheritDoc} */
229 @Override
230 public CartesianDerivativesFilter getAvailableDerivatives() {
231 return filter;
232 }
233
234 /** {@inheritDoc} */
235 @Override
236 public List<CPFCoordinate> getCoordinates() {
237 return Collections.unmodifiableList(this.coordinates);
238 }
239
240 /** {@inheritDoc} */
241 @Override
242 public String getId() {
243 return id == null ? DEFAULT_ID : id;
244 }
245
246 /** {@inheritDoc} */
247 @Override
248 public double getMu() {
249 return mu;
250 }
251
252 /** Returns a list containing only {@code this}. */
253 @Override
254 public List<CPFEphemeris> getSegments() {
255 return Collections.singletonList(this);
256 }
257
258 /** {@inheritDoc} */
259 @Override
260 public AbsoluteDate getStart() {
261 return coordinates.get(0).getDate();
262 }
263
264 /** {@inheritDoc} */
265 @Override
266 public AbsoluteDate getStop() {
267 return coordinates.get(coordinates.size() - 1).getDate();
268 }
269
270 /** {@inheritDoc} */
271 @Override
272 public BoundedPropagator getPropagator() {
273 return EphemerisSegment.super.getPropagator();
274 }
275
276 /** Get the list of Ephemerides data lines.
277 * @return a reference to the internal list of Ephemerides data lines
278 */
279 public List<CPFCoordinate> getEphemeridesDataLines() {
280 return this.coordinates;
281 }
282
283 }
284
285 /** A single record of position and possibility velocity in an SP3 file. */
286 public static class CPFCoordinate extends TimeStampedPVCoordinates {
287
288 /** Serializable UID. */
289 private static final long serialVersionUID = 20201016L;
290
291 /** Leap second flag. */
292 private final int leap;
293
294 /**
295 * Constructor with null velocity vector.
296 * @param date date of coordinates validity
297 * @param position position vector
298 * @param leap leap second flag (= 0 or the value of the new leap second)
299 */
300 public CPFCoordinate(final AbsoluteDate date,
301 final Vector3D position,
302 final int leap) {
303 this(date, position, Vector3D.ZERO, leap);
304 }
305
306 /**
307 * Constructor.
308 * @param date date of coordinates validity
309 * @param position position vector
310 * @param velocity velocity vector
311 * @param leap leap second flag (= 0 or the value of the new leap second)
312 */
313 public CPFCoordinate(final AbsoluteDate date,
314 final Vector3D position,
315 final Vector3D velocity,
316 final int leap) {
317 super(date, position, velocity);
318 this.leap = leap;
319 }
320
321 /**
322 * Get the leap second flag (= 0 or the value of the new leap second).
323 * @return the leap second flag
324 */
325 public int getLeap() {
326 return leap;
327 }
328
329 }
330
331 }