1   /* Copyright 2002-2012 Space Applications Services
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.sp3;
18  
19  import java.io.IOException;
20  import java.net.URISyntaxException;
21  import java.util.Arrays;
22  import java.util.List;
23  
24  import org.hipparchus.geometry.euclidean.threed.Vector3D;
25  import org.junit.jupiter.api.Assertions;
26  import org.junit.jupiter.api.BeforeEach;
27  import org.junit.jupiter.api.Test;
28  import org.orekit.Utils;
29  import org.orekit.attitudes.FrameAlignedProvider;
30  import org.orekit.data.DataSource;
31  import org.orekit.data.UnixCompressFilter;
32  import org.orekit.errors.OrekitException;
33  import org.orekit.errors.OrekitIllegalArgumentException;
34  import org.orekit.errors.OrekitMessages;
35  import org.orekit.frames.FactoryManagedFrame;
36  import org.orekit.frames.Frame;
37  import org.orekit.frames.FramesFactory;
38  import org.orekit.frames.Predefined;
39  import org.orekit.gnss.TimeSystem;
40  import org.orekit.propagation.BoundedPropagator;
41  import org.orekit.time.AbsoluteDate;
42  import org.orekit.time.TimeScale;
43  import org.orekit.time.TimeScalesFactory;
44  import org.orekit.utils.CartesianDerivativesFilter;
45  import org.orekit.utils.Constants;
46  import org.orekit.utils.IERSConventions;
47  import org.orekit.utils.PVCoordinates;
48  
49  public class SP3ParserTest {
50  
51      @Test
52      public void testParseSP3a1() throws IOException, URISyntaxException {
53          // simple test for version sp3-a, only contains position entries
54          final String    ex     = "/sp3/example-a-1.sp3";
55          final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
56          final SP3   file   = new SP3Parser().parse(source);
57  
58          Assertions.assertEquals('a', file.getHeader().getVersion());
59          Assertions.assertEquals(SP3OrbitType.FIT, file.getHeader().getOrbitType());
60          Assertions.assertEquals(TimeSystem.GPS, file.getHeader().getTimeSystem());
61          Assertions.assertSame(Predefined.ITRF_CIO_CONV_2010_ACCURATE_EOP,
62                            ((FactoryManagedFrame) file.getSatellites().get("1").getFrame()).getFactoryKey());
63  
64          Assertions.assertEquals(25, file.getSatelliteCount());
65  
66          final List<SP3Coordinate> coords = file.getSatellites().get("1").getSegments().get(0).getCoordinates();
67          Assertions.assertEquals(2, coords.size());
68  
69          final SP3Coordinate coord = coords.get(0);
70  
71          // 1994 12 17 0 0 0.00000000
72          Assertions.assertEquals(new AbsoluteDate(1994, 12, 17, 0, 0, 0,
73                  TimeScalesFactory.getGPS()), coord.getDate());
74  
75          // P 1 16258.524750 -3529.015750 -20611.427050 -62.540600
76          checkPVEntry(new PVCoordinates(new Vector3D(16258524.75, -3529015.75, -20611427.049),
77                                         Vector3D.ZERO),
78                       coord);
79          Assertions.assertEquals(-0.0000625406, coord.getClockCorrection(), 1.0e-15);
80          Assertions.assertEquals("NGS", file.getHeader().getAgency());
81          Assertions.assertEquals("ITR92", file.getHeader().getCoordinateSystem());
82          Assertions.assertEquals(1, file.getHeader().getDataUsed().size());
83          Assertions.assertEquals(DataUsed.TWO_RECEIVER_TWO_SATELLITE_CARRIER_PHASE, file.getHeader().getDataUsed().get(0));
84          Assertions.assertEquals(0.0, file.getHeader().getDayFraction(), 1.0e-15);
85          Assertions.assertEquals("1994-12-16T23:59:50.000", file.getHeader().getEpoch().toString(TimeScalesFactory.getUTC()));
86          Assertions.assertEquals(49703, file.getHeader().getModifiedJulianDay());
87          Assertions.assertEquals(3, file.getHeader().getNumberOfEpochs());
88          Assertions.assertEquals(900.0, file.getHeader().getEpochInterval(), 1.0e-15);
89          Assertions.assertEquals(779, file.getHeader().getGpsWeek());
90          Assertions.assertEquals(518400.0, file.getHeader().getSecondsOfWeek(), 1.0e-10);
91          Assertions.assertEquals(25, file.getSatellites().size());
92          Assertions.assertEquals(SP3FileType.UNDEFINED, file.getHeader().getType());
93          Assertions.assertNull(file.getSatellites().get(null));
94      }
95  
96      @Test
97      public void testParseSP3a2() throws IOException {
98          // simple test for version sp3-a, contains p/v entries
99          final String    ex     = "/sp3/example-a-2.sp3";
100         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
101         final SP3   file   = new SP3Parser().parse(source);
102 
103         Assertions.assertEquals('a', file.getHeader().getVersion());
104         Assertions.assertEquals(SP3OrbitType.FIT, file.getHeader().getOrbitType());
105         Assertions.assertEquals(TimeSystem.GPS, file.getHeader().getTimeSystem());
106         Assertions.assertEquals(CartesianDerivativesFilter.USE_PV, file.getHeader().getFilter());
107 
108         Assertions.assertEquals(25, file.getSatelliteCount());
109 
110         final List<SP3Coordinate> coords = file.getSatellites().get("1").getSegments().get(0).getCoordinates();
111         Assertions.assertEquals(2, coords.size());
112 
113         final SP3Coordinate coord = coords.get(0);
114 
115         // 1994 12 17 0 0 0.00000000
116         Assertions.assertEquals(new AbsoluteDate(1994, 12, 17, 0, 0, 0,
117                 TimeScalesFactory.getGPS()), coord.getDate());
118 
119         // P 1 16258.524750 -3529.015750 -20611.427050 -62.540600
120         // V 1  -6560.373522  25605.954994  -9460.427179     -0.024236
121         checkPVEntry(new PVCoordinates(new Vector3D(16258524.75, -3529015.75, -20611427.049),
122                                        new Vector3D(-656.0373, 2560.5954, -946.0427)),
123                      coord);
124         Assertions.assertEquals(-0.0000625406, coord.getClockCorrection(), 1.0e-15);
125         Assertions.assertEquals(-0.0000000000024236, coord.getClockRateChange(), 1.0e-15);
126     }
127 
128     @Test
129     public void testParseSP3c1() throws IOException {
130         // simple test for version sp3-c, contains p entries
131         final String    ex     = "/sp3/example-c-1.sp3";
132         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
133         final SP3   file   = new SP3Parser().parse(source);
134 
135         Assertions.assertEquals('c', file.getHeader().getVersion());
136         Assertions.assertEquals(SP3OrbitType.HLM, file.getHeader().getOrbitType());
137         Assertions.assertEquals(TimeSystem.GPS, file.getHeader().getTimeSystem());
138         Assertions.assertEquals(CartesianDerivativesFilter.USE_P, file.getHeader().getFilter());
139 
140         Assertions.assertEquals(26, file.getSatelliteCount());
141 
142         final List<SP3Coordinate> coords = file.getSatellites().get("G01").getSegments().get(0).getCoordinates();
143         Assertions.assertEquals(1, coords.size());
144 
145         final SP3Coordinate coord = coords.get(0);
146 
147         // 2001  8  8  0  0  0.00000000
148         Assertions.assertEquals(new AbsoluteDate(2001, 8, 8, 0, 0, 0,
149                 TimeScalesFactory.getGPS()), coord.getDate());
150 
151         // PG01 -11044.805800 -10475.672350  21929.418200    189.163300 18 18 18 219
152         checkPVEntry(new PVCoordinates(new Vector3D(-11044805.8, -10475672.35, 21929418.2),
153                                        Vector3D.ZERO),
154                      coord);
155         Assertions.assertEquals(0.0001891633, coord.getClockCorrection(), 1.0e-15);
156     }
157 
158     @Test
159     public void testParseSP3c2() throws IOException {
160         // simple test for version sp3-c, contains p/v entries and correlations
161         final String    ex     = "/sp3/example-c-2.sp3";
162         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
163         final SP3   file   = new SP3Parser().parse(source);
164 
165         Assertions.assertEquals('c', file.getHeader().getVersion());
166         Assertions.assertEquals(SP3OrbitType.HLM, file.getHeader().getOrbitType());
167         Assertions.assertEquals(TimeSystem.GPS, file.getHeader().getTimeSystem());
168 
169         Assertions.assertEquals(26, file.getSatelliteCount());
170 
171         Assertions.assertEquals(2, file.getSatellites().get("G01").getSegments().size());
172         final List<SP3Coordinate> coords = file.getSatellites().get("G01").getSegments().get(0).getCoordinates();
173         Assertions.assertEquals(1, coords.size());
174 
175         final SP3Coordinate coord = coords.get(0);
176 
177         // 2001  8  8  0  0  0.00000000
178         Assertions.assertEquals(new AbsoluteDate(2001, 8, 8, 0, 0, 0,
179                 TimeScalesFactory.getGPS()), coord.getDate());
180 
181         // PG01 -11044.805800 -10475.672350  21929.418200    189.163300 18 18 18 219
182         // VG01  20298.880364 -18462.044804   1381.387685     -4.534317 14 14 14 191
183         checkPVEntry(new PVCoordinates(new Vector3D(-11044805.8, -10475672.35, 21929418.2),
184                                        new Vector3D(2029.8880364, -1846.2044804, 138.1387685)),
185                      coord);
186         Assertions.assertEquals(0.0001891633,  coord.getClockCorrection(), 1.0e-15);
187         Assertions.assertEquals(-0.0000000004534317, coord.getClockRateChange(), 1.0e-15);
188     }
189 
190     @Test
191     public void testParseSP3d1() throws IOException {
192         // simple test for version sp3-d, contains p entries
193         final String    ex     = "/sp3/example-d-1.sp3";
194         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
195         final SP3   file   = new SP3Parser().parse(source);
196 
197         Assertions.assertEquals('d', file.getHeader().getVersion());
198         Assertions.assertEquals(SP3OrbitType.BCT, file.getHeader().getOrbitType());
199         Assertions.assertEquals(TimeSystem.GPS, file.getHeader().getTimeSystem());
200 
201         Assertions.assertEquals(5, file.getHeader().getComments().size());
202         Assertions.assertEquals("Note: This is a simulated file, meant to illustrate what an SP3-d header",     file.getHeader().getComments().get(0));
203         Assertions.assertEquals("might look like with more than 85 satellites. Source for GPS and SBAS satel-", file.getHeader().getComments().get(1));
204         Assertions.assertEquals("lite positions: BRDM0930.13N. G=GPS,R=GLONASS,E=Galileo,C=BeiDou,J=QZSS,",     file.getHeader().getComments().get(2));
205         Assertions.assertEquals("I=IRNSS,S=SBAS. For definitions of SBAS satellites, refer to the website:",    file.getHeader().getComments().get(3));
206         Assertions.assertEquals("http://igs.org/mgex/status-SBAS",                                              file.getHeader().getComments().get(4));
207 
208         Assertions.assertEquals(140, file.getSatelliteCount());
209 
210         Assertions.assertEquals(2, file.getSatellites().get("S37").getSegments().size());
211         Assertions.assertEquals(1, file.getSatellites().get("S37").getSegments().get(0).getCoordinates().size());
212         Assertions.assertEquals(1, file.getSatellites().get("S37").getSegments().get(1).getCoordinates().size());
213 
214         final SP3Coordinate coord = file.getSatellites().get("S37").getSegments().get(0).getCoordinates().get(0);
215 
216         // 2013  4  3  0  0  0.00000000
217         Assertions.assertEquals(new AbsoluteDate(2013, 4, 3, 0, 0, 0,
218                 TimeScalesFactory.getGPS()), coord.getDate());
219 
220         // PS37 -34534.904566  24164.610955     29.812840      0.299420
221         checkPVEntry(new PVCoordinates(new Vector3D(-34534904.566, 24164610.955, 29812.840),
222                                        Vector3D.ZERO),
223                      coord);
224         Assertions.assertEquals(0.00000029942, coord.getClockCorrection(), 1.0e-15);
225     }
226 
227     @Test
228     public void testParseSP3d2() throws IOException {
229         // simple test for version sp3-c, contains p/v entries and correlations
230         final String    ex     = "/sp3/example-d-2.sp3";
231         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
232         final SP3   file   = new SP3Parser().parse(source);
233 
234         Assertions.assertEquals('d', file.getHeader().getVersion());
235         Assertions.assertEquals(SP3OrbitType.HLM, file.getHeader().getOrbitType());
236         Assertions.assertEquals(TimeSystem.GPS, file.getHeader().getTimeSystem());
237 
238         Assertions.assertEquals(26, file.getSatelliteCount());
239 
240         Assertions.assertEquals(2, file.getSatellites().get("G01").getSegments().size());
241         final List<SP3Coordinate> coords = file.getSatellites().get("G01").getSegments().get(0).getCoordinates();
242         Assertions.assertEquals(1, coords.size());
243 
244         final SP3Coordinate coord = coords.get(0);
245 
246         // 2001  8  8  0  0  0.00000000
247         Assertions.assertEquals(new AbsoluteDate(2001, 8, 8, 0, 0, 0,
248                 TimeScalesFactory.getGPS()), coord.getDate());
249 
250         // PG01 -11044.805800 -10475.672350  21929.418200    189.163300 18 18 18 219
251         // VG01  20298.880364 -18462.044804   1381.387685     -4.534317 14 14 14 191
252         checkPVEntry(new PVCoordinates(new Vector3D(-11044805.8, -10475672.35, 21929418.2),
253                                        new Vector3D(2029.8880364, -1846.2044804, 138.1387685)),
254                      coord);
255         Assertions.assertEquals(0.0001891633,        coord.getClockCorrection(),         1.0e-10);
256         Assertions.assertEquals(55.512e-3,           coord.getPositionAccuracy().getX(), 1.0e-6);
257         Assertions.assertEquals(55.512e-3,           coord.getPositionAccuracy().getY(), 1.0e-6);
258         Assertions.assertEquals(55.512e-3,           coord.getPositionAccuracy().getZ(), 1.0e-6);
259         Assertions.assertEquals(223.1138e-12,        coord.getClockAccuracy(),           1.0e-16);
260         Assertions.assertEquals(-0.0000000004534317, coord.getClockRateChange(),         1.0e-16);
261         Assertions.assertEquals(22.737e-7,           coord.getVelocityAccuracy().getX(), 1.0e-10);
262         Assertions.assertEquals(22.737e-7,           coord.getVelocityAccuracy().getY(), 1.0e-10);
263         Assertions.assertEquals(22.737e-7,           coord.getVelocityAccuracy().getZ(), 1.0e-10);
264         Assertions.assertEquals(111.75277e-16,       coord.getClockRateAccuracy(),       1.0e-21);
265         Assertions.assertFalse(coord.hasClockEvent());
266         Assertions.assertFalse(coord.hasClockPrediction());
267         Assertions.assertFalse(coord.hasOrbitManeuverEvent());
268         Assertions.assertFalse(coord.hasOrbitPrediction());
269 
270         final List<SP3Coordinate> coords2 = file.getSatellites().get("G01").getSegments().get(1).getCoordinates();
271         Assertions.assertFalse(coords2.get(0).hasClockEvent());
272         Assertions.assertTrue(coords2.get(0).hasClockPrediction());
273         Assertions.assertFalse(coords2.get(0).hasOrbitManeuverEvent());
274         Assertions.assertTrue(coords2.get(0).hasOrbitPrediction());
275 
276     }
277 
278     @Test
279     public void testSP3GFZ() throws IOException {
280         // simple test for version sp3-c, contains more than 85 satellites
281         final String    ex     = "/sp3/gbm19500_truncated.sp3";
282         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
283         final SP3   file   = new SP3Parser().parse(source);
284 
285         Assertions.assertEquals(SP3OrbitType.FIT, file.getHeader().getOrbitType());
286         Assertions.assertEquals(TimeSystem.GPS, file.getHeader().getTimeSystem());
287 
288         Assertions.assertEquals(87, file.getSatelliteCount());
289 
290         final List<SP3Coordinate> coords = file.getSatellites().get("R23").getSegments().get(0).getCoordinates();
291         Assertions.assertEquals(2, coords.size());
292 
293         final SP3Coordinate coord = coords.get(0);
294 
295         Assertions.assertEquals(new AbsoluteDate(2017, 5, 21, 0, 0, 0,
296                 TimeScalesFactory.getGPS()), coord.getDate());
297 
298         // PG01 -11044.805800 -10475.672350  21929.418200    189.163300 18 18 18 219
299         // PR23  24552.470459   -242.899447   6925.437998     86.875825
300         checkPVEntry(new PVCoordinates(new Vector3D(24552470.459, -242899.447, 6925437.998),
301                                        Vector3D.ZERO),
302                      coord);
303         Assertions.assertEquals(0.000086875825, coord.getClockCorrection(), 1.0e-15);
304     }
305 
306     @Test
307     public void testSP3Propagator() throws Exception {
308         // setup
309         final String     ex         = "/sp3/gbm18432.sp3.Z";
310         final DataSource compressed = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
311         final DataSource source     = new UnixCompressFilter().filter(compressed);
312         final Frame      frame      = FramesFactory.getITRF(IERSConventions.IERS_2003, true);
313         final SP3Parser  parser     = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 2, s -> frame);
314 
315         // action
316         final SP3 file = parser.parse(source);
317 
318         // verify
319         TimeScale gps = TimeScalesFactory.getGPS();
320         Assertions.assertNull(file.getSatellites().get("XYZ"));
321         SP3Ephemeris ephemeris = file.getSatellites().get("C03");
322         BoundedPropagator propagator = ephemeris.getPropagator();
323         Assertions.assertEquals(propagator.getMinDate(), new AbsoluteDate(2015, 5, 5, gps));
324         Assertions.assertEquals(propagator.getMaxDate(), new AbsoluteDate(2015, 5, 5, 23, 55, 0, gps));
325         SP3Coordinate expected = ephemeris.getSegments().get(0).getCoordinates().get(0);
326         Assertions.assertEquals(0.0,
327                                 Vector3D.distance(propagator.getPVCoordinates(propagator.getMinDate(), frame).getPosition(),
328                                                   expected.getPosition()),
329                                 3.0e-8);
330         expected = ephemeris.getSegments().get(0).getCoordinates().get(1);
331         Assertions.assertEquals(0.0,
332                                 Vector3D.distance(propagator.getPVCoordinates(expected.getDate(), frame).getPosition(),
333                                                   expected.getPosition()),
334                                 3.0e-8);
335         expected = ephemeris.getSegments().get(0).getCoordinates().get(ephemeris.getSegments().get(0).getCoordinates().size() - 1);
336         Assertions.assertEquals(0.0,
337                                 Vector3D.distance(propagator.getPVCoordinates(propagator.getMaxDate(), frame).getPosition(),
338                                                   expected.getPosition()),
339                                 3.0e-8);
340 
341         ephemeris = file.getSatellites().get("E19");
342         propagator = ephemeris.getPropagator(new FrameAlignedProvider(ephemeris.getFrame()));
343         Assertions.assertEquals(propagator.getMinDate(), new AbsoluteDate(2015, 5, 5, gps));
344         Assertions.assertEquals(propagator.getMaxDate(), new AbsoluteDate(2015, 5, 5, 23, 55, 0, gps));
345         expected = ephemeris.getSegments().get(0).getCoordinates().get(0);
346         Assertions.assertEquals(0.0,
347                                 Vector3D.distance(propagator.propagate(propagator.getMinDate()).getPVCoordinates(frame).getPosition(),
348                                                   expected.getPosition()),
349                                 3.0e-8);
350         expected = ephemeris.getSegments().get(0).getCoordinates().get(1);
351         Assertions.assertEquals(0.0,
352                                 Vector3D.distance(propagator.propagate(expected.getDate()).getPVCoordinates(frame).getPosition(),
353                                                   expected.getPosition()),
354                                 3.0e-8);
355         expected = ephemeris.getSegments().get(0).getCoordinates().get(ephemeris.getSegments().get(0).getCoordinates().size() - 1);
356         Assertions.assertEquals(0.0,
357                                 Vector3D.distance(propagator.propagate(propagator.getMaxDate()).getPVCoordinates(frame).getPosition(),
358                                                   expected.getPosition()),
359                                 3.0e-8);
360     }
361 
362     @Test
363     public void testSP3Compressed() throws IOException {
364         final String ex = "/sp3/gbm18432.sp3.Z";
365 
366         final SP3Parser parser = new SP3Parser();
367         final DataSource compressed = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
368         final SP3 file = parser.parse(new UnixCompressFilter().filter(compressed));
369 
370         Assertions.assertEquals(SP3OrbitType.FIT, file.getHeader().getOrbitType());
371         Assertions.assertEquals("FIT",file.getHeader().getOrbitTypeKey());
372         Assertions.assertEquals(TimeSystem.GPS, file.getHeader().getTimeSystem());
373 
374         Assertions.assertEquals(71, file.getSatelliteCount());
375 
376         final List<SP3Coordinate> coords = file.getSatellites().get("R13").getSegments().get(0).getCoordinates();
377         Assertions.assertEquals(288, coords.size());
378 
379         final SP3Coordinate coord = coords.get(228);
380 
381 
382         Assertions.assertEquals(new AbsoluteDate(2015, 5, 5, 19, 0, 0,
383                 TimeScalesFactory.getGPS()), coord.getDate());
384 
385         // PR13  25330.290321   -411.728000   2953.331527   -482.447619
386         checkPVEntry(new PVCoordinates(new Vector3D(25330290.321, -411728.000, 2953331.527),
387                                        Vector3D.ZERO),
388                      coord);
389         Assertions.assertEquals(-0.000482447619,  coord.getClockCorrection(), 1.0e-15);
390     }
391 
392     private void checkPVEntry(final PVCoordinates expected, final PVCoordinates actual) {
393         final Vector3D expectedPos = expected.getPosition();
394         final Vector3D expectedVel = expected.getVelocity();
395 
396         final Vector3D actualPos = actual.getPosition();
397         final Vector3D actualVel = actual.getVelocity();
398 
399         // sp3 files can have mm accuracy
400         final double eps = 1e-3;
401 
402         Assertions.assertEquals(expectedPos.getX(), actualPos.getX(), eps);
403         Assertions.assertEquals(expectedPos.getY(), actualPos.getY(), eps);
404         Assertions.assertEquals(expectedPos.getZ(), actualPos.getZ(), eps);
405 
406         Assertions.assertEquals(expectedVel.getX(), actualVel.getX(), eps);
407         Assertions.assertEquals(expectedVel.getY(), actualVel.getY(), eps);
408         Assertions.assertEquals(expectedVel.getZ(), actualVel.getZ(), eps);
409 
410         Assertions.assertEquals(Vector3D.ZERO, actual.getAcceleration());
411     }
412 
413     @Test
414     public void testTruncatedLine() throws IOException {
415         try {
416             final String    ex     = "/sp3/truncated-line.sp3";
417             final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
418             final Frame     frame = FramesFactory.getITRF(IERSConventions.IERS_2003, true);
419             final SP3Parser parser = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 3, s -> frame);
420             parser.parse(source);
421             Assertions.fail("an exception should have been thrown");
422         } catch (OrekitException oe) {
423             Assertions.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE,
424                                 oe.getSpecifier());
425             Assertions.assertEquals(27, ((Integer) oe.getParts()[0]).intValue());
426         }
427 
428     }
429 
430     @Test
431     public void testMissingEOF() throws IOException {
432         final String    ex     = "/sp3/missing-eof.sp3";
433         try {
434             final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
435             final Frame     frame  = FramesFactory.getITRF(IERSConventions.IERS_2003, true);
436             final SP3Parser parser = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 3, s -> frame);
437             parser.parse(source);
438             Assertions.fail("an exception should have been thrown");
439         } catch (OrekitException oe) {
440             Assertions.assertEquals(OrekitMessages.SP3_NUMBER_OF_EPOCH_MISMATCH, oe.getSpecifier());
441             Assertions.assertEquals(  1, ((Integer) oe.getParts()[0]).intValue());
442             Assertions.assertEquals( ex, oe.getParts()[1]);
443             Assertions.assertEquals(192, ((Integer) oe.getParts()[2]).intValue());
444         }
445 
446     }
447 
448     @Test
449     public void testMissingStandardDeviation() throws IOException {
450         final String    ex     = "/sp3/missing-standard-deviation.sp3";
451         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
452         final Frame     frame  = FramesFactory.getITRF(IERSConventions.IERS_2003, true);
453         final SP3Parser parser = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 3, s -> frame);
454         final SP3 sp3 = parser.parse(source);
455         Assertions.assertEquals(32, sp3.getSatelliteCount());
456         List<SP3Coordinate> coordinates06 = sp3.getEphemeris("G06").getSegments().get(0).getCoordinates();
457         Assertions.assertEquals(21, coordinates06.size());
458         for (int i = 0; i < 21; ++i) {
459             final Vector3D positionAccuracy = coordinates06.get(i).getPositionAccuracy();
460             if (i == 7 || i == 8) {
461                 // some standard deviations are missing
462                 Assertions.assertNull(positionAccuracy);
463             } else {
464                 // other are present
465                 Assertions.assertTrue(positionAccuracy.getNorm() < 0.0122);
466                 Assertions.assertTrue(positionAccuracy.getNorm() > 0.0045);
467             }
468         }
469     }
470 
471     @Test
472     public void testWrongLineIdentifier() throws IOException {
473         try {
474             final String    ex     = "/sp3/wrong-line-identifier.sp3";
475             final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
476             final Frame     frame  = FramesFactory.getITRF(IERSConventions.IERS_2003, true);
477             final SP3Parser parser = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 3, s -> frame);
478             parser.parse(source);
479             Assertions.fail("an exception should have been thrown");
480         } catch (OrekitException oe) {
481             Assertions.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE,
482                                 oe.getSpecifier());
483             Assertions.assertEquals(13, ((Integer) oe.getParts()[0]).intValue());
484         }
485 
486     }
487 
488     @Test
489     public void testBHN() throws IOException {
490         final Frame       frame        = FramesFactory.getITRF(IERSConventions.IERS_2003, true);
491         final SP3Parser   parser       = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 3, s -> frame);
492         final String      ex           = "/sp3/esaBHN.sp3.Z";
493         final DataSource   compressed   = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
494         final DataSource   uncompressed = new UnixCompressFilter().filter(compressed);
495         final SP3     file         = parser.parse(uncompressed);
496         Assertions.assertEquals(SP3OrbitType.FIT, file.getHeader().getOrbitType());
497         Assertions.assertEquals("BHN", file.getHeader().getOrbitTypeKey());
498     }
499 
500     @Test
501     public void testPRO() throws IOException {
502         final Frame       frame        = FramesFactory.getITRF(IERSConventions.IERS_2003, true);
503         final SP3Parser   parser       = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 3, s -> frame);
504         final String      ex           = "/sp3/esaPRO.sp3.Z";
505         final DataSource   compressed   = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
506         final DataSource   uncompressed = new UnixCompressFilter().filter(compressed);
507         final SP3     file         = parser.parse(uncompressed);
508         Assertions.assertEquals(SP3OrbitType.EXT, file.getHeader().getOrbitType());
509         Assertions.assertEquals("PRO", file.getHeader().getOrbitTypeKey());
510     }
511 
512     @Test
513     public void testUnknownType() throws IOException {
514         final Frame       frame        = FramesFactory.getITRF(IERSConventions.IERS_2003, true);
515         final SP3Parser   parser       = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 3, s -> frame);
516         final String      ex           = "/sp3/unknownType.sp3.Z";
517         final DataSource   compressed   = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
518         final DataSource   uncompressed = new UnixCompressFilter().filter(compressed);
519         final SP3     file         = parser.parse(uncompressed);
520         Assertions.assertEquals(SP3OrbitType.OTHER, file.getHeader().getOrbitType());
521         Assertions.assertEquals("UKN", file.getHeader().getOrbitTypeKey());
522     }
523 
524     @Test
525     public void testUnsupportedVersion() throws IOException {
526         try {
527             final String    ex     = "/sp3/unsupported-version.sp3";
528             final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
529             final Frame     frame  = FramesFactory.getITRF(IERSConventions.IERS_2003, true);
530             final SP3Parser parser = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 3, s -> frame);
531             parser.parse(source);
532             Assertions.fail("an exception should have been thrown");
533         } catch (OrekitException oe) {
534             Assertions.assertEquals(OrekitMessages.SP3_UNSUPPORTED_VERSION,
535                                 oe.getSpecifier());
536             Assertions.assertEquals('z', ((Character) oe.getParts()[0]).charValue());
537         }
538 
539     }
540 
541     @Test
542     public void testWrongNumberOfEpochs() throws IOException {
543         try {
544             final String    ex     = "/sp3/wrong-number-of-epochs.sp3";
545             final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
546             final Frame     frame  = FramesFactory.getITRF(IERSConventions.IERS_2003, true);
547             final SP3Parser parser = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 3, s -> frame);
548             parser.parse(source);
549             Assertions.fail("an exception should have been thrown");
550         } catch (OrekitException oe) {
551             Assertions.assertEquals(OrekitMessages.SP3_NUMBER_OF_EPOCH_MISMATCH,
552                                 oe.getSpecifier());
553             Assertions.assertEquals(  2, ((Integer) oe.getParts()[0]).intValue());
554             Assertions.assertEquals(192, ((Integer) oe.getParts()[2]).intValue());
555         }
556 
557     }
558 
559     @Test
560     public void testInconsistentSamplingDates() throws IOException {
561         try {
562             final String    ex     = "/sp3/inconsistent-sampling-dates.sp3";
563             final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
564             final Frame     frame  = FramesFactory.getITRF(IERSConventions.IERS_2003, true);
565             final SP3Parser parser = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 3, s -> frame);
566             parser.parse(source);
567             Assertions.fail("an exception should have been thrown");
568         } catch (OrekitException oe) {
569             Assertions.assertEquals(OrekitMessages.INCONSISTENT_SAMPLING_DATE, oe.getSpecifier());
570             Assertions.assertEquals(new AbsoluteDate(1994, 12, 17, 23, 45, 0.0, TimeScalesFactory.getGPS()), oe.getParts()[0]);
571             Assertions.assertEquals(new AbsoluteDate(1994, 12, 17, 23, 46, 0.0, TimeScalesFactory.getGPS()), oe.getParts()[1]);
572         }
573 
574     }
575 
576     @Test
577     public void testIssue803() {
578 
579         // Test issue 803 (see https://gitlab.orekit.org/orekit/orekit/-/issues/803)
580         final String    ex     = "/sp3/truncated-nsgf.orb.lageos2.160305.v35.sp3";
581         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
582         final SP3   file   = new SP3Parser().parse(source);
583 
584         // Coordinates
585         final List<SP3Coordinate> coords = file.getSatellites().get("L52").getSegments().get(0).getCoordinates();
586         Assertions.assertEquals(1, coords.size());
587         final SP3Coordinate coord = coords.get(0);
588 
589         // Verify
590         Assertions.assertEquals(SP3FileType.LEO, file.getHeader().getType());
591 
592         // PL52   2228.470946   7268.265924   9581.471543
593         // VL52 -44856.945000  24321.151000  -7116.222800
594         checkPVEntry(new PVCoordinates(new Vector3D(2228470.946, 7268265.924, 9581471.543),
595                                        new Vector3D(-4485.6945000, 2432.1151000, -711.6222800)),
596                      coord);
597         Assertions.assertEquals(0.999999999999,   coord.getClockCorrection(), 1.0e-12);
598         Assertions.assertEquals(9.99999999999e-5, coord.getClockRateChange(), 1.0e-16);
599 
600     }
601 
602     @Test
603     public void testIssue827() {
604 
605         // Test issue 827 (see https://gitlab.orekit.org/orekit/orekit/-/issues/827)
606         final String    ex     = "/sp3/truncated-nsgf.orb.lageos2.160305.v35.sp3";
607         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
608         final SP3   file   = new SP3Parser().parse(source);
609 
610         // Coordinates
611         final List<SP3Coordinate> coords = file.getSatellites().get("L52").getSegments().get(0).getCoordinates();
612         Assertions.assertEquals(1, coords.size());
613         final SP3Coordinate coord = coords.get(0);
614 
615         // Verify
616         Assertions.assertEquals(TimeSystem.UTC, file.getHeader().getTimeSystem());
617         Assertions.assertEquals(SP3FileType.LEO, file.getHeader().getType());
618 
619         // 2016  2 28 0 0 0.00000000
620         Assertions.assertEquals(new AbsoluteDate(2016, 2, 28, 0, 0, 0,
621                 TimeScalesFactory.getUTC()), coord.getDate());
622 
623 
624         // PL52   2228.470946   7268.265924   9581.471543
625         // VL52 -44856.945000  24321.151000  -7116.222800
626         checkPVEntry(new PVCoordinates(new Vector3D(2228470.946, 7268265.924, 9581471.543),
627                                        new Vector3D(-4485.6945000, 2432.1151000, -711.6222800)),
628                      coord);
629         Assertions.assertEquals(0.999999999999,   coord.getClockCorrection(), 1.0e-12);
630         Assertions.assertEquals(9.99999999999e-5, coord.getClockRateChange(), 1.0e-16);
631 
632     }
633 
634     @Test
635     public void testIssue828() {
636 
637         // Test issue 828 (see https://gitlab.orekit.org/orekit/orekit/-/issues/828)
638         final String    ex     = "/sp3/example-d-3.sp3";
639         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
640         final SP3   file   = new SP3Parser().parse(source);
641 
642         // Verify
643         Assertions.assertEquals(TimeSystem.UTC, file.getHeader().getTimeSystem());
644         Assertions.assertEquals(SP3FileType.IRNSS, file.getHeader().getType());
645 
646     }
647 
648     @Test
649     public void testIssue828Bis() {
650 
651         // Test issue 828 (see https://gitlab.orekit.org/orekit/orekit/-/issues/828)
652         final String    ex     = "/sp3/example-d-4.sp3";
653         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
654         final SP3   file   = new SP3Parser().parse(source);
655 
656         // Verify
657         Assertions.assertEquals(TimeSystem.UTC, file.getHeader().getTimeSystem());
658         Assertions.assertEquals(SP3FileType.SBAS, file.getHeader().getType());
659 
660     }
661 
662     @Test
663     public void testIssue1314() {
664 
665         // Test issue 828 (see https://gitlab.orekit.org/orekit/orekit/-/issues/1314)
666         final String    ex     = "/sp3/example-d-5.sp3";
667         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
668         final SP3   file   = new SP3Parser().parse(source);
669 
670         // Verify
671         Assertions.assertEquals(TimeSystem.GALILEO, file.getHeader().getTimeSystem());
672         Assertions.assertEquals(SP3FileType.SBAS, file.getHeader().getType());
673 
674     }
675 
676     @Test
677     public void testIssue895HeaderComment() {
678 
679         // Test issue 895
680         final String    ex     = "/sp3/issue895-header-comment.sp3";
681         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
682         final SP3   file   = new SP3Parser().parse(source);
683 
684         // Verify
685         Assertions.assertEquals(TimeSystem.UTC, file.getHeader().getTimeSystem());
686         Assertions.assertEquals(SP3FileType.LEO, file.getHeader().getType());
687 
688     }
689 
690     @Test
691     public void testIssue895ClockRecord() {
692 
693         // Test issue 895
694         final String    ex     = "/sp3/issue895-clock-record.sp3";
695         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
696         final SP3   file   = new SP3Parser().parse(source);
697 
698         // Verify
699         Assertions.assertEquals(TimeSystem.UTC, file.getHeader().getTimeSystem());
700         Assertions.assertEquals(SP3FileType.LEO, file.getHeader().getType());
701         Assertions.assertEquals(1, file.getSatelliteCount());
702 
703         final List<SP3Coordinate> coords = file.getSatellites().get("L51").getSegments().get(0).getCoordinates();
704         Assertions.assertEquals(1, coords.size());
705 
706         final SP3Coordinate coord = coords.get(0);
707 
708         // 2021 12 26  0  0  0.00000000
709         Assertions.assertEquals(new AbsoluteDate(2021, 12, 26, 0, 0, 0,
710                 TimeScalesFactory.getUTC()), coord.getDate());
711 
712         // PL51   5029.867893   1304.362160 -11075.527276 999999.999999
713         // VL51 -17720.521773 -55720.482742 -14441.695083 999999.999999
714         checkPVEntry(new PVCoordinates(new Vector3D(5029867.893, 1304362.160, -11075527.276),
715                                        new Vector3D(-1772.0521773, -5572.0482742, -1444.1695083)),
716                      coord);
717 
718     }
719 
720     @Test
721     public void testIssue895RolloverMinutes() {
722 
723         // Test issue 895
724         final String    ex     = "/sp3/issue895-minutes-increment.sp3";
725         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
726         final SP3   file   = new SP3Parser().parse(source);
727 
728         // Verify
729         Assertions.assertEquals(TimeSystem.UTC, file.getHeader().getTimeSystem());
730         Assertions.assertEquals(SP3FileType.LEO, file.getHeader().getType());
731         Assertions.assertEquals(1, file.getSatelliteCount());
732 
733         final List<SP3Coordinate> coords = file.getSatellites().get("L51").getSegments().get(0).getCoordinates();
734         Assertions.assertEquals(91, coords.size());
735 
736         final SP3Coordinate coord30 = coords.get(30);
737 
738         // 2016  7  6 16 60  0.00000000
739         Assertions.assertEquals(new AbsoluteDate(2016, 7, 6, 17, 0, 0,
740                 TimeScalesFactory.getUTC()), coord30.getDate());
741 
742         // PL51  11948.228978   2986.113872   -538.901114 999999.999999
743         // VL51   4605.419303 -27972.588048 -53316.820671 999999.999999
744         checkPVEntry(new PVCoordinates(new Vector3D(11948228.978,   2986113.872,   -538901.114),
745                                        new Vector3D(460.5419303, -2797.2588048, -5331.6820671)),
746                      coord30);
747 
748         final SP3Coordinate coord31 = coords.get(31);
749 
750         // 2016  7  6 17  2  0.00000000
751         Assertions.assertEquals(new AbsoluteDate(2016, 7, 6, 17, 2, 0,
752                 TimeScalesFactory.getUTC()), coord31.getDate());
753 
754         // PL51  11982.652569   2645.786926  -1177.549463 999999.999999
755         // VL51   1128.248622 -28724.293303 -53097.358387 999999.999999
756         checkPVEntry(new PVCoordinates(new Vector3D(11982652.569,   2645786.926,  -1177549.463),
757                                        new Vector3D(112.8248622, -2872.4293303, -5309.7358387)),
758                      coord31);
759 
760         final SP3Coordinate coord60 = coords.get(60);
761 
762         // 2016  7  6 17 60  0.00000000
763         Assertions.assertEquals(new AbsoluteDate(2016, 7, 6, 18, 0, 0,
764                 TimeScalesFactory.getUTC()), coord60.getDate());
765 
766         // PL51  -1693.056569  -4123.276630 -11431.599723 999999.999999
767         // VL51 -59412.268951   4066.817074   7604.890337 999999.999999
768         checkPVEntry(new PVCoordinates(new Vector3D(-1693056.569,  -4123276.630, -11431599.723),
769                                        new Vector3D(-5941.2268951,   406.6817074,   760.4890337)),
770                      coord60);
771 
772     }
773 
774     @Test
775     public void testIssue895RolloverHours() {
776 
777         // Test issue 895
778         final String    ex     = "/sp3/issue895-hours-increment.sp3";
779         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
780         final SP3   file   = new SP3Parser().parse(source);
781 
782         // Verify
783         Assertions.assertEquals(TimeSystem.UTC, file.getHeader().getTimeSystem());
784         Assertions.assertEquals(SP3FileType.LEO, file.getHeader().getType());
785         Assertions.assertEquals(1, file.getSatelliteCount());
786 
787         final List<SP3Coordinate> coords = file.getSatellites().get("L51").getSegments().get(0).getCoordinates();
788         Assertions.assertEquals(61, coords.size());
789 
790         final SP3Coordinate coord30 = coords.get(30);
791 
792         // 2016  7  7 24  0  0.00000000
793         Assertions.assertEquals(new AbsoluteDate(2016, 7, 7, 0, 0, 0,
794                 TimeScalesFactory.getUTC()), coord30.getDate());
795 
796         //PL51   2989.229334  -8494.421415   8385.068555
797         //VL51 -19617.027447 -43444.824985 -36706.159070
798         checkPVEntry(new PVCoordinates(new Vector3D(2989229.334,  -8494421.415,   8385068.555),
799                                        new Vector3D(-1961.7027447, -4344.4824985, -3670.6159070)),
800                      coord30);
801 
802         final SP3Coordinate coord31 = coords.get(31);
803 
804         // 2016  7  7  0  2  0.00000000
805         Assertions.assertEquals(new AbsoluteDate(2016, 7, 7, 0, 2, 0,
806                 TimeScalesFactory.getUTC()), coord31.getDate());
807 
808         // PL51   2744.983592  -9000.639164   7931.904779
809         // VL51 -21072.925764 -40899.633288 -38801.567078
810         checkPVEntry(new PVCoordinates(new Vector3D(2744983.592,  -9000639.164,   7931904.779),
811                                        new Vector3D(-2107.2925764, -4089.9633288, -3880.1567078)),
812                      coord31);
813 
814     }
815 
816     @Test
817     public void testIssue895SecondDigits() {
818 
819         // Test issue 895
820         final String    ex     = "/sp3/issue895-second-digits.sp3";
821         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
822         final SP3   file   = new SP3Parser().parse(source);
823 
824         // Verify
825         Assertions.assertEquals(TimeSystem.UTC, file.getHeader().getTimeSystem());
826         Assertions.assertEquals(SP3FileType.LEO, file.getHeader().getType());
827         Assertions.assertEquals(1, file.getSatelliteCount());
828 
829         final List<SP3Coordinate> coords = file.getSatellites().get("L51").getSegments().get(0).getCoordinates();
830         Assertions.assertEquals(1, coords.size());
831 
832         final SP3Coordinate coord = coords.get(0);
833 
834         // 2016  7  3  0  0  0.1234
835         Assertions.assertEquals(new AbsoluteDate(2016, 7, 3, 0, 0, 0.1234,
836                 TimeScalesFactory.getUTC()), coord.getDate());
837 
838     }
839 
840     @Test
841     public void testIssue895NoEOF() {
842 
843         // Test issue 895
844         final String    ex     = "/sp3/issue895-no-eof.sp3";
845         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
846         final SP3   file   = new SP3Parser().parse(source);
847 
848         // Verify
849         Assertions.assertEquals(TimeSystem.UTC, file.getHeader().getTimeSystem());
850         Assertions.assertEquals(SP3FileType.LEO, file.getHeader().getType());
851         Assertions.assertEquals(1, file.getSatelliteCount());
852 
853         final List<SP3Coordinate> coords = file.getSatellites().get("L51").getSegments().get(0).getCoordinates();
854         Assertions.assertEquals(1, coords.size());
855 
856         final SP3Coordinate coord = coords.get(0);
857 
858         // 2021 12 26  0  0  0.00000000
859         Assertions.assertEquals(new AbsoluteDate(2021, 12, 26, 0, 0, 0,
860                 TimeScalesFactory.getUTC()), coord.getDate());
861 
862         // PL51   5029.867893   1304.362160 -11075.527276 999999.999999
863         // VL51 -17720.521773 -55720.482742 -14441.695083 999999.999999
864         checkPVEntry(new PVCoordinates(new Vector3D(5029867.893, 1304362.160, -11075527.276),
865                                        new Vector3D(-1772.0521773, -5572.0482742, -1444.1695083)),
866                      coord);
867 
868     }
869 
870     @Test
871     public void testExceededSatCount() {
872         final String    ex     = "/sp3/exceeded-sat-count.sp3";
873         try {
874             final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
875             new SP3Parser().parse(source);
876             Assertions.fail("an exception should have been thrown");
877         } catch (OrekitException oe) {
878             Assertions.assertEquals(OrekitMessages.SP3_TOO_MANY_SATELLITES_FOR_VERSION, oe.getSpecifier());
879             Assertions.assertEquals('c', ((Character) oe.getParts()[0]).charValue());
880             Assertions.assertEquals( 99, ((Integer) oe.getParts()[1]).intValue());
881             Assertions.assertEquals(140, ((Integer) oe.getParts()[2]).intValue());
882             Assertions.assertEquals(ex, oe.getParts()[3]);
883         }
884     }
885 
886     @Test
887     public void testIssue1014() {
888 
889         // Test issue 1014
890         final String    ex     = "/sp3/issue1014-days-increment.sp3";
891         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
892         final SP3   file   = new SP3Parser().parse(source);
893 
894         // Verify
895         Assertions.assertEquals(TimeSystem.UTC, file.getHeader().getTimeSystem());
896         Assertions.assertEquals(SP3FileType.LEO, file.getHeader().getType());
897         Assertions.assertEquals(1, file.getSatelliteCount());
898 
899         final List<SP3Coordinate> coords = file.getSatellites().get("L51").getSegments().get(0).getCoordinates();
900         Assertions.assertEquals(62, coords.size());
901 
902         final SP3Coordinate coord = coords.get(61);
903 
904         // following date is completely wrong (2022 january 0th instead of 2021 december 31st)
905         // 2022  1  0  1  2  0.00000000
906         Assertions.assertEquals(new AbsoluteDate(2021, 12, 31, 1, 2, 0,
907                               TimeScalesFactory.getUTC()), coord.getDate());
908 
909         // PL51  -5691.093473  -9029.216710  -5975.427658
910         // VL51 -39188.598237  -5856.539265  45893.223756
911         checkPVEntry(new PVCoordinates(new Vector3D(-5691093.473,  -9029216.710,  -5975427.658),
912                                        new Vector3D(-3918.8598237,  -585.6539265,  4589.3223756)),
913                      coord);
914 
915     }
916 
917     @Test
918     public void testWrongPosVelBaseA() {
919         doTestWrongHeaderEntry("/sp3/wrong-pos-vel-base-a.sp3", "pos/vel accuracy base");
920     }
921 
922     @Test
923     public void testWrongPosVelBaseD() {
924         doTestWrongHeaderEntry("/sp3/wrong-pos-vel-base-d.sp3", "pos/vel accuracy base");
925     }
926 
927     @Test
928     public void testWrongClockBaseA() {
929         doTestWrongHeaderEntry("/sp3/wrong-clock-base-a.sp3", "clock accuracy base");
930     }
931 
932     @Test
933     public void testWrongClockBaseD() {
934         doTestWrongHeaderEntry("/sp3/wrong-clock-base-d.sp3", "clock accuracy base");
935     }
936 
937     @Test
938     public void testWrongTooManyCommentsA() {
939         doTestWrongHeaderEntry("/sp3/too-many-comments-a.sp3", "comments");
940     }
941 
942     @Test
943     public void testWrongTooLongCommentA() {
944         doTestWrongHeaderEntry("/sp3/too-long-comment-a.sp3", "comments");
945     }
946 
947     @Test
948     public void testWrongTooLongCommentD() {
949         doTestWrongHeaderEntry("/sp3/too-long-comment-d.sp3", "comments");
950     }
951 
952     private void doTestWrongHeaderEntry(final String ex, final String entry) {
953         try {
954             final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
955             new SP3Parser().parse(source);
956             Assertions.fail("an exception should have been thrown");
957         } catch (OrekitException oe) {
958             Assertions.assertEquals(OrekitMessages.SP3_INVALID_HEADER_ENTRY, oe.getSpecifier());
959             Assertions.assertEquals(entry, oe.getParts()[0]);
960             Assertions.assertEquals(ex, oe.getParts()[2]);
961         }
962     }
963 
964     @Test
965     public void testSpliceWrongType() {
966         try {
967             splice("/sp3/gbm19500_truncated.sp3", "/sp3/gbm19500_wrong_type.sp3");
968             Assertions.fail("an exception should have been thrown");
969         } catch (OrekitException oe) {
970             Assertions.assertEquals(OrekitMessages.SP3_INCOMPATIBLE_FILE_METADATA, oe.getSpecifier());
971         }
972     }
973 
974     @Test
975     public void testSpliceWrongTimeSystem() {
976         try {
977             splice("/sp3/gbm19500_truncated.sp3", "/sp3/gbm19500_wrong_time_system.sp3");
978             Assertions.fail("an exception should have been thrown");
979         } catch (OrekitException oe) {
980             Assertions.assertEquals(OrekitMessages.SP3_INCOMPATIBLE_FILE_METADATA, oe.getSpecifier());
981         }
982     }
983 
984     @Test
985     public void testSpliceWrongSatelliteCount() {
986         final SP3 spliced = splice("/sp3/gbm19500_truncated.sp3", "/sp3/gbm19500_wrong_satellite_count.sp3");
987         Assertions.assertEquals(86, spliced.getSatelliteCount());
988     }
989 
990     @Test
991     public void testSpliceWrongOrbitType() {
992         try {
993             splice("/sp3/gbm19500_truncated.sp3", "/sp3/gbm19500_wrong_orbit_type.sp3");
994             Assertions.fail("an exception should have been thrown");
995         } catch (OrekitException oe) {
996             Assertions.assertEquals(OrekitMessages.SP3_INCOMPATIBLE_FILE_METADATA, oe.getSpecifier());
997         }
998     }
999 
1000     @Test
1001     public void testSpliceWrongCoordinateSystem() {
1002         try {
1003             splice("/sp3/gbm19500_truncated.sp3", "/sp3/gbm19500_wrong_coordinate_system.sp3");
1004             Assertions.fail("an exception should have been thrown");
1005         } catch (OrekitException oe) {
1006             Assertions.assertEquals(OrekitMessages.SP3_INCOMPATIBLE_FILE_METADATA, oe.getSpecifier());
1007         }
1008     }
1009 
1010     @Test
1011     public void testSpliceWrongDataUsed() {
1012         try {
1013             splice("/sp3/gbm19500_truncated.sp3", "/sp3/gbm19500_wrong_data_used.sp3");
1014             Assertions.fail("an exception should have been thrown");
1015         } catch (OrekitIllegalArgumentException oe) {
1016             Assertions.assertEquals(OrekitMessages.SP3_INVALID_HEADER_ENTRY, oe.getSpecifier());
1017             Assertions.assertEquals("data used", oe.getParts()[0]);
1018             Assertions.assertEquals("v", oe.getParts()[1]);
1019         }
1020     }
1021 
1022     @Test
1023     public void testSpliceWrongAgency() {
1024         try {
1025             splice("/sp3/gbm19500_truncated.sp3", "/sp3/gbm19500_wrong_agency.sp3");
1026             Assertions.fail("an exception should have been thrown");
1027         } catch (OrekitException oe) {
1028             Assertions.assertEquals(OrekitMessages.SP3_INCOMPATIBLE_FILE_METADATA, oe.getSpecifier());
1029         }
1030     }
1031 
1032     @Test
1033     public void testSpliceWrongSatelliteList() {
1034         final SP3 spliced = splice("/sp3/gbm19500_truncated.sp3", "/sp3/gbm19500_wrong_satellite_list.sp3");
1035         Assertions.assertEquals(86, spliced.getSatelliteCount());
1036     }
1037 
1038     @Test
1039     public void testSpliceWrongDerivatives() {
1040         try {
1041             splice("/sp3/gbm19500_truncated.sp3", "/sp3/gbm19500_wrong_derivatives.sp3");
1042             Assertions.fail("an exception should have been thrown");
1043         } catch (OrekitException oe) {
1044             Assertions.assertEquals(OrekitMessages.SP3_INCOMPATIBLE_SATELLITE_MEDATADA, oe.getSpecifier());
1045         }
1046     }
1047 
1048     @Test
1049     public void testSpliceWrongFrame() {
1050         try {
1051             final String     name1 = "/sp3/gbm19500_truncated.sp3";
1052             final DataSource source1 = new DataSource(name1, () -> getClass().getResourceAsStream(name1));
1053             final SP3        file1   = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 7,
1054                                                      s -> FramesFactory.getITRF(IERSConventions.IERS_2010, false)).
1055                                        parse(source1);
1056             final String     name2 = "/sp3/gbm19500_after_no_drop.sp3";
1057             final DataSource source2 = new DataSource(name2, () -> getClass().getResourceAsStream(name2));
1058             final SP3        file2   = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 7,
1059                                                      s -> FramesFactory.getITRF(IERSConventions.IERS_1996, false)).
1060                                        parse(source2);
1061             SP3.splice(Arrays.asList(file1, file2));
1062             Assertions.fail("an exception should have been thrown");
1063         } catch (OrekitException oe) {
1064             Assertions.assertEquals(OrekitMessages.SP3_INCOMPATIBLE_SATELLITE_MEDATADA, oe.getSpecifier());
1065         }
1066     }
1067 
1068     @Test
1069     public void testSpliceWrongInterpolationSamples() {
1070         try {
1071             final String     name1 = "/sp3/gbm19500_truncated.sp3";
1072             final DataSource source1 = new DataSource(name1, () -> getClass().getResourceAsStream(name1));
1073             final SP3        file1   = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 7,
1074                                                      s -> FramesFactory.getITRF(IERSConventions.IERS_2010, false)).
1075                                        parse(source1);
1076             final String     name2 = "/sp3/gbm19500_after_no_drop.sp3";
1077             final DataSource source2 = new DataSource(name2, () -> getClass().getResourceAsStream(name2));
1078             final SP3        file2   = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 4,
1079                                                      s -> FramesFactory.getITRF(IERSConventions.IERS_2010, false)).
1080                                        parse(source2);
1081             SP3.splice(Arrays.asList(file1, file2));
1082              Assertions.fail("an exception should have been thrown");
1083         } catch (OrekitException oe) {
1084             Assertions.assertEquals(OrekitMessages.SP3_INCOMPATIBLE_SATELLITE_MEDATADA, oe.getSpecifier());
1085         }
1086     }
1087 
1088     @Test
1089     public void testSpliceWrongMu() {
1090         try {
1091             final String     name1 = "/sp3/gbm19500_truncated.sp3";
1092             final DataSource source1 = new DataSource(name1, () -> getClass().getResourceAsStream(name1));
1093             final SP3        file1   = new SP3Parser(Constants.EIGEN5C_EARTH_MU, 7,
1094                                                      s -> FramesFactory.getITRF(IERSConventions.IERS_2010, false)).
1095                                        parse(source1);
1096             final String     name2 = "/sp3/gbm19500_after_no_drop.sp3";
1097             final DataSource source2 = new DataSource(name2, () -> getClass().getResourceAsStream(name2));
1098             final SP3        file2   = new SP3Parser(1.00001 * Constants.EIGEN5C_EARTH_MU, 7,
1099                                                      s -> FramesFactory.getITRF(IERSConventions.IERS_2010, false)).
1100                                        parse(source2);
1101             SP3.splice(Arrays.asList(file1, file2));
1102             Assertions.fail("an exception should have been thrown");
1103         } catch (OrekitException oe) {
1104             Assertions.assertEquals(OrekitMessages.SP3_INCOMPATIBLE_SATELLITE_MEDATADA, oe.getSpecifier());
1105         }
1106     }
1107 
1108     @Test
1109     public void testSpliceNewSegment() {
1110         SP3 sp3 = splice("/sp3/gbm19500_truncated.sp3", "/sp3/gbm19500_large_gap.sp3");
1111         Assertions.assertEquals(2, sp3.getEphemeris("C01").getSegments().size());
1112     }
1113 
1114     @Test
1115     public void testSpliceDrop() {
1116 
1117         final SP3 spliced = splice("/sp3/gbm19500_truncated.sp3", "/sp3/gbm19500_after_drop.sp3");
1118 
1119         Assertions.assertEquals(SP3OrbitType.FIT, spliced.getHeader().getOrbitType());
1120         Assertions.assertEquals(TimeSystem.GPS, spliced.getHeader().getTimeSystem());
1121 
1122         Assertions.assertEquals(87, spliced.getSatelliteCount());
1123 
1124         final List<SP3Coordinate> coords = spliced.getSatellites().get("R23").getSegments().get(0).getCoordinates();
1125         Assertions.assertEquals(3, coords.size());
1126 
1127         final SP3Coordinate coord = coords.get(0);
1128 
1129         Assertions.assertEquals(new AbsoluteDate(2017, 5, 21, 0, 0, 0, TimeScalesFactory.getGPS()),
1130                                 coord.getDate());
1131 
1132         // PG01 -11044.805800 -10475.672350  21929.418200    189.163300 18 18 18 219
1133         // PR23  24552.470459   -242.899447   6925.437998     86.875825
1134         checkPVEntry(new PVCoordinates(new Vector3D(24552470.459, -242899.447, 6925437.998), Vector3D.ZERO),
1135                      coord);
1136         Assertions.assertEquals(0.000086875825, coord.getClockCorrection(), 1.0e-15);
1137 
1138         Assertions.assertEquals(new AbsoluteDate(2017, 5, 21, 0, 10, 0, TimeScalesFactory.getGPS()),
1139                                 coords.get(coords.size() - 1).getDate());
1140 
1141         Assertions.assertEquals(1.25,  spliced.getHeader().getPosVelBase(), 1.0e-15);
1142         Assertions.assertEquals(1.025, spliced.getHeader().getClockBase(),  1.0e-15);
1143 
1144     }
1145 
1146     @Test
1147     public void testSpliceNoDrop() {
1148 
1149         final SP3 spliced = splice("/sp3/gbm19500_truncated.sp3", "/sp3/gbm19500_after_no_drop.sp3");
1150 
1151         Assertions.assertEquals(SP3OrbitType.FIT, spliced.getHeader().getOrbitType());
1152         Assertions.assertEquals(TimeSystem.GPS, spliced.getHeader().getTimeSystem());
1153 
1154         Assertions.assertEquals(87, spliced.getSatelliteCount());
1155 
1156         final List<SP3Coordinate> coords = spliced.getSatellites().get("R23").getSegments().get(0).getCoordinates();
1157         Assertions.assertEquals(4, coords.size());
1158 
1159         final SP3Coordinate coord = coords.get(0);
1160 
1161         Assertions.assertEquals(new AbsoluteDate(2017, 5, 21, 0, 0, 0, TimeScalesFactory.getGPS()),
1162                                 coord.getDate());
1163 
1164         // PG01 -11044.805800 -10475.672350  21929.418200    189.163300 18 18 18 219
1165         // PR23  24552.470459   -242.899447   6925.437998     86.875825
1166         checkPVEntry(new PVCoordinates(new Vector3D(24552470.459, -242899.447, 6925437.998), Vector3D.ZERO),
1167                      coord);
1168         Assertions.assertEquals(0.000086875825, coord.getClockCorrection(), 1.0e-15);
1169 
1170         Assertions.assertEquals(new AbsoluteDate(2017, 5, 21, 0, 15, 0, TimeScalesFactory.getGPS()),
1171                                 coords.get(coords.size() - 1).getDate());
1172 
1173         Assertions.assertEquals("R23", spliced.getEphemeris("R23").getId());
1174         try {
1175             spliced.getEphemeris(88);
1176             Assertions.fail("an exception should have been thrown");
1177         } catch (OrekitException oe) {
1178             Assertions.assertEquals(OrekitMessages.INVALID_SATELLITE_ID, oe.getSpecifier());
1179             Assertions.assertEquals(88, ((Integer) oe.getParts()[0]).intValue());
1180         }
1181         try {
1182             spliced.getEphemeris("Z00");
1183             Assertions.fail("an exception should have been thrown");
1184         } catch (OrekitException oe) {
1185             Assertions.assertEquals(OrekitMessages.INVALID_SATELLITE_ID, oe.getSpecifier());
1186             Assertions.assertEquals("Z00", oe.getParts()[0]);
1187         }
1188 
1189     }
1190 
1191     private SP3 splice(final String name1, final String name2) {
1192         final DataSource source1 = new DataSource(name1, () -> getClass().getResourceAsStream(name1));
1193         final SP3        file1   = new SP3Parser().parse(source1);
1194         final DataSource source2 = new DataSource(name2, () -> getClass().getResourceAsStream(name2));
1195         final SP3        file2   = new SP3Parser().parse(source2);
1196         return SP3.splice(Arrays.asList(file1, file2));
1197     }
1198 
1199     @BeforeEach
1200     public void setUp() {
1201         Utils.setDataRoot("regular-data");
1202     }
1203 }