1   /* Copyright 2002-2022 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.ccsds.ndm.odm.oem;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.io.SequenceInputStream;
23  import java.net.URISyntaxException;
24  import java.nio.charset.Charset;
25  import java.nio.charset.StandardCharsets;
26  import java.util.ArrayList;
27  import java.util.List;
28  
29  import org.hamcrest.MatcherAssert;
30  import org.hipparchus.geometry.euclidean.threed.Rotation;
31  import org.hipparchus.geometry.euclidean.threed.Vector3D;
32  import org.hipparchus.linear.Array2DRowRealMatrix;
33  import org.hipparchus.util.Pair;
34  import org.junit.Assert;
35  import org.junit.Before;
36  import org.junit.Test;
37  import org.orekit.OrekitMatchers;
38  import org.orekit.Utils;
39  import org.orekit.bodies.CelestialBody;
40  import org.orekit.bodies.CelestialBodyFactory;
41  import org.orekit.data.DataContext;
42  import org.orekit.data.DataSource;
43  import org.orekit.errors.OrekitException;
44  import org.orekit.errors.OrekitMessages;
45  import org.orekit.files.ccsds.definitions.CelestialBodyFrame;
46  import org.orekit.files.ccsds.definitions.OrbitRelativeFrame;
47  import org.orekit.files.ccsds.ndm.ParserBuilder;
48  import org.orekit.files.ccsds.ndm.odm.CartesianCovariance;
49  import org.orekit.frames.FactoryManagedFrame;
50  import org.orekit.frames.Frame;
51  import org.orekit.frames.FramesFactory;
52  import org.orekit.frames.ITRFVersion;
53  import org.orekit.frames.LOFType;
54  import org.orekit.frames.Transform;
55  import org.orekit.orbits.CartesianOrbit;
56  import org.orekit.propagation.BoundedPropagator;
57  import org.orekit.time.AbsoluteDate;
58  import org.orekit.time.TimeScalesFactory;
59  import org.orekit.utils.CartesianDerivativesFilter;
60  import org.orekit.utils.IERSConventions;
61  import org.orekit.utils.PVCoordinates;
62  import org.orekit.utils.TimeStampedPVCoordinates;
63  
64  
65  public class OemParserTest {
66  
67      @Before
68      public void setUp()
69          throws Exception {
70          Utils.setDataRoot("regular-data");
71      }
72  
73      @Test
74      public void testIssue788() {
75  
76          // Read the file
77          final String ex = "/ccsds/odm/oem/test.oem";
78          final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
79          final OemParser parser  = new ParserBuilder().buildOemParser();
80          final Oem file = parser.parseMessage(source);
81  
82          // Verify
83          Assert.assertEquals(file.getDataContext().getCelestialBodies().getEarth().getGM(), file.getSegments().get(0).getMu(), Double.MIN_VALUE);
84          Assert.assertEquals(3.986004328969392E14, file.getSegments().get(0).getMu(), Double.MIN_VALUE);
85  
86      }
87  
88      @Test
89      public void testParseOEM1() throws IOException {
90          //
91          final String ex = "/ccsds/odm/oem/OEMExample1.txt";
92          final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
93          final OemParser parser  = new ParserBuilder().withMu(CelestialBodyFactory.getMars().getGM()).buildOemParser();
94          final Oem file = parser.parseMessage(source);
95          Assert.assertEquals(3, file.getSegments().size());
96          Assert.assertEquals("UTC", file.getSegments().get(0).getMetadata().getTimeSystem().name());
97          Assert.assertEquals("MARS GLOBAL SURVEYOR", file.getSegments().get(0).getMetadata().getObjectName());
98          Assert.assertEquals("1996-062A", file.getSegments().get(0).getMetadata().getObjectID());
99          Assert.assertEquals("MARS BARYCENTER", file.getSegments().get(0).getMetadata().getCenter().getName());
100         Assert.assertEquals(1996, file.getSegments().get(0).getMetadata().getLaunchYear());
101         Assert.assertEquals(62, file.getSegments().get(0).getMetadata().getLaunchNumber());
102         Assert.assertEquals("A", file.getSegments().get(0).getMetadata().getLaunchPiece());
103         Assert.assertNull(file.getSegments().get(0).getMetadata().getCenter().getBody());
104         Assert.assertNull(file.getSegments().get(0).getMetadata().getCenter().getBody());
105         Assert.assertEquals(new AbsoluteDate(1996, 12, 18, 12, 00, 0.331, TimeScalesFactory.getUTC()),
106                             file.getSegments().get(0).getMetadata().getStartTime());
107         Assert.assertEquals(new AbsoluteDate(1996, 12, 28, 21, 28, 0.331, TimeScalesFactory.getUTC()),
108                             file.getSegments().get(0).getMetadata().getStopTime());
109         Assert.assertEquals(new AbsoluteDate(1996, 12, 18, 12, 10, 0.331, TimeScalesFactory.getUTC()),
110                             file.getSegments().get(0).getMetadata().getUseableStartTime());
111         Assert.assertEquals(new AbsoluteDate(1996, 12, 28, 21, 23, 0.331, TimeScalesFactory.getUTC()),
112                             file.getSegments().get(0).getMetadata().getUseableStopTime());
113         Assert.assertEquals(InterpolationMethod.HERMITE, file.getSegments().get(0).getMetadata().getInterpolationMethod());
114         Assert.assertEquals(7, file.getSegments().get(0).getMetadata().getInterpolationDegree());
115         ArrayList<String> ephemeridesDataLinesComment = new ArrayList<String>();
116         ephemeridesDataLinesComment.add("This file was produced by M.R. Somebody, MSOO NAV/JPL, 1996NOV 04. It is");
117         ephemeridesDataLinesComment.add("to be used for DSN scheduling purposes only.");
118         Assert.assertEquals(ephemeridesDataLinesComment, file.getSegments().get(0).getData().getComments());
119         CartesianOrbit orbit = new CartesianOrbit(new PVCoordinates
120                                                   (new Vector3D(2789.619 * 1000, -280.045 * 1000, -1746.755 * 1000),
121                                                    new Vector3D(4.73372 * 1000, -2.49586 * 1000, -1.04195 * 1000)),
122                                                    FramesFactory.getEME2000(),
123                                                    new AbsoluteDate("1996-12-18T12:00:00.331", TimeScalesFactory.getUTC()),
124                                                    CelestialBodyFactory.getEarth().getGM());
125         Assert.assertArrayEquals(orbit.getPVCoordinates().getPosition().toArray(), file.getSegments().get(0).getData().getEphemeridesDataLines().get(0).getPosition().toArray(), 1e-10);
126         Assert.assertArrayEquals(orbit.getPVCoordinates().getVelocity().toArray(), file.getSegments().get(0).getData().getEphemeridesDataLines().get(0).getVelocity().toArray(), 1e-10);
127         Assert.assertEquals(Vector3D.ZERO, file.getSegments().get(1).getData().getEphemeridesDataLines().get(1).getAcceleration());
128         final Array2DRowRealMatrix covMatrix = new Array2DRowRealMatrix(6, 6);
129         final double[] column1 = {
130              3.3313494e-04,  4.6189273e-04, -3.0700078e-04, -3.3493650e-07, -2.2118325e-07, -3.0413460e-07
131         };
132         final double[] column2 = {
133              4.6189273e-04,  6.7824216e-04, -4.2212341e-04, -4.6860842e-07, -2.8641868e-07, -4.9894969e-07
134         };
135         final double[] column3 = {
136             -3.0700078e-04, -4.2212341e-04, 3.2319319e-04,  2.4849495e-07, 1.7980986e-07,  3.5403109e-07
137         };
138         final double[] column4 = {
139             -3.3493650e-07, -4.6860842e-07, 2.4849495e-07,  4.29602280e-10, 2.6088992e-10,  1.86926319e-10
140         };
141         final double[] column5 = {
142             -2.2118325e-07, -2.8641868e-07, 1.7980986e-07,  2.6088992e-10, 1.7675147e-10,  1.0088625e-10
143         };
144         final double[] column6 = {
145             -3.0413460e-07, -4.9894969e-07, 3.5403109e-07,  1.8692631e-10, 1.0088625e-10,  6.2244443e-10
146         };
147         covMatrix.setColumn(0, column1);
148         covMatrix.setColumn(1, column2);
149         covMatrix.setColumn(2, column3);
150         covMatrix.setColumn(3, column4);
151         covMatrix.setColumn(4, column5);
152         covMatrix.setColumn(5, column6);
153         for (int i = 0; i < 6; i++) {
154             for (int j = 0; j < 6; j++) {
155                 Assert.assertEquals(covMatrix.getEntry(i, j) * 1.0e6,
156                                     file.getSegments().get(2).getData().getCovarianceMatrices().get(0).getCovarianceMatrix().getEntry(i, j),
157                                     1e-10);
158             }
159         }
160         Assert.assertEquals(new AbsoluteDate("1996-12-28T21:29:07.267", TimeScalesFactory.getUTC()),
161                             file.getSegments().get(2).getCovarianceMatrices().get(0).getEpoch());
162         Assert.assertEquals(LOFType.QSW,
163                             file.getSegments().get(2).getCovarianceMatrices().get(0).getReferenceFrame().asOrbitRelativeFrame().getLofType());
164         Assert.assertNull(file.getSegments().get(2).getCovarianceMatrices().get(0).getReferenceFrame().asFrame());
165         Assert.assertNull(file.getSegments().get(2).getCovarianceMatrices().get(0).getReferenceFrame().asCelestialBodyFrame());
166         Assert.assertNull(file.getSegments().get(2).getCovarianceMatrices().get(0).getReferenceFrame().asSpacecraftBodyFrame());
167         Assert.assertNull(file.getSegments().get(2).getCovarianceMatrices().get(1).getReferenceFrame().asOrbitRelativeFrame());
168         Assert.assertEquals(FramesFactory.getEME2000(),
169                             file.getSegments().get(2).getCovarianceMatrices().get(1).getReferenceFrame().asFrame());
170     }
171 
172     @Test
173     public void testParseOEM2() throws URISyntaxException {
174 
175         final String ex = "/ccsds/odm/oem/OEMExample2.txt";
176         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
177         final AbsoluteDate missionReferenceDate = new AbsoluteDate("1996-12-17T00:00:00.000", TimeScalesFactory.getUTC());
178         OemParser parser = new ParserBuilder().
179                            withConventions(IERSConventions.IERS_2010).
180                            withSimpleEOP(true).
181                            withDataContext(DataContext.getDefault()).
182                            withMissionReferenceDate(missionReferenceDate).
183                            withMu(CelestialBodyFactory.getMars().getGM()).
184                            withDefaultInterpolationDegree(1).
185                            buildOemParser();
186 
187         final Oem file = parser.parseMessage(source);
188         final List<String> headerComment = new ArrayList<String>();
189         headerComment.add("comment");
190         Assert.assertEquals(headerComment, file.getHeader().getComments());
191         final List<String> metadataComment = new ArrayList<String>();
192         metadataComment.add("comment 1");
193         metadataComment.add("comment 2");
194         Assert.assertEquals(metadataComment, file.getSegments().get(0).getMetadata().getComments());
195         Assert.assertEquals("TOD/2010 simple EOP",
196                             file.getSegments().get(0).getMetadata().getReferenceFrame().asFrame().getName());
197         Assert.assertEquals("TOD",
198                             file.getSegments().get(0).getMetadata().getReferenceFrame().getName());
199         Assert.assertEquals("EME2000", file.getSegments().get(1).getMetadata().getReferenceFrame().getName());
200         List<OemSegment> blocks = file.getSegments();
201         Assert.assertEquals(2, blocks.size());
202         Assert.assertEquals(129600.331,
203                             blocks.get(0).getMetadata().getFrameEpoch().durationFrom(missionReferenceDate),
204                             1.0e-15);
205         Assert.assertEquals(129600.331,
206                             blocks.get(0).getMetadata().getStartTime().durationFrom(missionReferenceDate),
207                             1.0e-15);
208         Assert.assertEquals(941347.267,
209                             blocks.get(1).getMetadata().getStartTime().durationFrom(missionReferenceDate),
210                             1.0e-15);
211 
212     }
213 
214     @Test
215     public void testParseOEM3KVN() throws IOException {
216 
217         final String ex = "/ccsds/odm/oem/OEMExample3.txt";
218         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
219         final OemParser parser  = new ParserBuilder().withMu(CelestialBodyFactory.getMars().getGM()).buildOemParser();
220         final Oem file = parser.parse(source); // using the generic API here
221         Assert.assertEquals("Copy of OEMExample.txt with changes so that interpolation will work.",
222                             file.getHeader().getComments().get(0));
223         Assert.assertEquals(new AbsoluteDate("1996-11-04T17:22:31", TimeScalesFactory.getUTC()),
224                             file.getHeader().getCreationDate());
225         Assert.assertEquals("NASA/JPL", file.getHeader().getOriginator());
226         Assert.assertEquals("OEM 201113719185", file.getHeader().getMessageId());
227         Assert.assertEquals("UTC", file.getSegments().get(0).getMetadata().getTimeSystem().name());
228         Assert.assertEquals("MARS GLOBAL SURVEYOR", file.getSegments().get(0).getMetadata().getObjectName());
229         Assert.assertEquals("1996-062A", file.getSegments().get(0).getMetadata().getObjectID());
230 
231         Assert.assertEquals(1, file.getSatellites().size());
232         Assert.assertEquals(true, file.getSatellites().containsKey("1996-062A"));
233         Assert.assertEquals(false, file.getSatellites().containsKey("MARS GLOBAL SURVEYOR"));
234         Assert.assertEquals(1, file.getSatellites().size());
235         Assert.assertEquals("1996-062A", file.getSatellites().values().iterator().next().getId());
236         Assert.assertEquals(
237                 new AbsoluteDate("1996-12-18T12:00:00.331", TimeScalesFactory.getUTC()),
238                 file.getSegments().get(0).getMetadata().getStartTime());
239 
240         final OemSatelliteEphemeris satellite = file.getSatellites().get("1996-062A");
241         Assert.assertEquals("1996-062A", satellite.getId());
242         final OemSegment segment = (OemSegment) satellite.getSegments().get(0);
243         Assert.assertEquals(CelestialBodyFactory.getMars().getGM(), segment.getMu(), 1.0);
244         Assert.assertEquals("EME2000", segment.getMetadata().getReferenceFrame().getName());
245         Assert.assertEquals(segment.getMetadata().getCenter().getName(), "MARS BARYCENTER");
246         Assert.assertNull(segment.getMetadata().getCenter().getBody());
247         // Frame not creatable since it's center can't be created.
248         try {
249             segment.getFrame();
250             Assert.fail("Expected Exception");
251         } catch (OrekitException e){
252             Assert.assertEquals(e.getSpecifier(), OrekitMessages.NO_DATA_LOADED_FOR_CELESTIAL_BODY);
253         }
254         Assert.assertEquals("UTC", segment.getMetadata().getTimeSystem().name());
255         Assert.assertEquals(InterpolationMethod.HERMITE, segment.getMetadata().getInterpolationMethod());
256         Assert.assertEquals(2, segment.getMetadata().getInterpolationDegree());
257         Assert.assertEquals(3, segment.getInterpolationSamples());
258         Assert.assertEquals(segment.getAvailableDerivatives(), CartesianDerivativesFilter.USE_PV);
259         // propagator can't be created since frame can't be created
260         try {
261             satellite.getPropagator();
262             Assert.fail("Expected Exception");
263         } catch (OrekitException e){
264             Assert.assertEquals(e.getSpecifier(),
265                     OrekitMessages.NO_DATA_LOADED_FOR_CELESTIAL_BODY);
266         }
267 
268         List<OemSegment> segments = file.getSegments();
269         Assert.assertEquals(3, segments.size());
270         Assert.assertEquals(3, segments.get(2).getData().getCoordinates().size());
271         final TimeStampedPVCoordinates pv20 = segments.get(2).getData().getCoordinates().get(0);
272         Assert.assertEquals(
273                             new AbsoluteDate("1996-12-28T21:29:07.267", TimeScalesFactory.getUTC()),
274                             pv20.getDate());
275         Assert.assertEquals(-2432166.0,   pv20.getPosition().getX(), 1.0e-10);
276         Assert.assertEquals(  -63042.0,   pv20.getPosition().getY(), 1.0e-10);
277         Assert.assertEquals( 1742754.0,   pv20.getPosition().getZ(), 1.0e-10);
278         Assert.assertEquals(    7337.02,  pv20.getVelocity().getX(), 1.0e-10);
279         Assert.assertEquals(   -3495.867, pv20.getVelocity().getY(), 1.0e-10);
280         Assert.assertEquals(   -1041.945, pv20.getVelocity().getZ(), 1.0e-10);
281         final TimeStampedPVCoordinates pv21 = segments.get(2).getData().getCoordinates().get(1);
282         Assert.assertEquals(new AbsoluteDate("1996-12-28T21:59:02.267", TimeScalesFactory.getUTC()),
283                             pv21.getDate());
284         Assert.assertEquals(-2445234.0,   pv21.getPosition().getX(), 1.0e-10);
285         Assert.assertEquals( -878141.0,   pv21.getPosition().getY(), 1.0e-10);
286         Assert.assertEquals( 1873073.0,   pv21.getPosition().getZ(), 1.0e-10);
287         Assert.assertEquals(    1860.43,  pv21.getVelocity().getX(), 1.0e-10);
288         Assert.assertEquals(   -3421.256, pv21.getVelocity().getY(), 1.0e-10);
289         Assert.assertEquals(    -996.366, pv21.getVelocity().getZ(), 1.0e-10);
290         final TimeStampedPVCoordinates pv22 = segments.get(2).getData().getCoordinates().get(2);
291         Assert.assertEquals(new AbsoluteDate("1996-12-28T22:00:02.267", TimeScalesFactory.getUTC()),
292                             pv22.getDate());
293         Assert.assertEquals(-2458079.0,   pv22.getPosition().getX(), 1.0e-10);
294         Assert.assertEquals( -683858.0,   pv22.getPosition().getY(), 1.0e-10);
295         Assert.assertEquals( 2007684.0,   pv22.getPosition().getZ(), 1.0e-10);
296         Assert.assertEquals(    6367.86,  pv22.getVelocity().getX(), 1.0e-10);
297         Assert.assertEquals(   -3339.563, pv22.getVelocity().getY(), 1.0e-10);
298         Assert.assertEquals(    -946.654, pv22.getVelocity().getZ(), 1.0e-10);
299 
300         Assert.assertEquals(2, segments.get(2).getCovarianceMatrices().size());
301         final CartesianCovariance c20 = segments.get(2).getCovarianceMatrices().get(0);
302         Assert.assertEquals(new AbsoluteDate("1996-12-28T21:29:07.267", TimeScalesFactory.getUTC()),
303                             c20.getEpoch());
304         Assert.assertEquals(OrbitRelativeFrame.RTN, c20.getReferenceFrame().asOrbitRelativeFrame());
305         Assert.assertEquals( 333.13494,       c20.getCovarianceMatrix().getEntry(0, 0), 1.0e-5);
306         Assert.assertEquals( 461.89273,       c20.getCovarianceMatrix().getEntry(1, 0), 1.0e-5);
307         Assert.assertEquals( 678.24216,       c20.getCovarianceMatrix().getEntry(1, 1), 1.0e-5);
308         Assert.assertEquals(-307.00078,       c20.getCovarianceMatrix().getEntry(2, 0), 1.0e-5);
309         Assert.assertEquals(-422.12341,       c20.getCovarianceMatrix().getEntry(2, 1), 1.0e-5);
310         Assert.assertEquals( 323.19319,       c20.getCovarianceMatrix().getEntry(2, 2), 1.0e-5);
311         Assert.assertEquals(  -0.33493650,    c20.getCovarianceMatrix().getEntry(3, 0), 1.0e-8);
312         Assert.assertEquals(  -0.46860842,    c20.getCovarianceMatrix().getEntry(3, 1), 1.0e-8);
313         Assert.assertEquals(   0.24849495,    c20.getCovarianceMatrix().getEntry(3, 2), 1.0e-8);
314         Assert.assertEquals(   0.00042960228, c20.getCovarianceMatrix().getEntry(3, 3), 1.0e-11);
315         Assert.assertEquals(  -0.22118325,    c20.getCovarianceMatrix().getEntry(4, 0), 1.0e-8);
316         Assert.assertEquals(  -0.28641868,    c20.getCovarianceMatrix().getEntry(4, 1), 1.0e-8);
317         Assert.assertEquals(   0.17980986,    c20.getCovarianceMatrix().getEntry(4, 2), 1.0e-8);
318         Assert.assertEquals(   0.00026088992, c20.getCovarianceMatrix().getEntry(4, 3), 1.0e-11);
319         Assert.assertEquals(   0.00017675147, c20.getCovarianceMatrix().getEntry(4, 4), 1.0e-11);
320         Assert.assertEquals(  -0.30413460,    c20.getCovarianceMatrix().getEntry(5, 0), 1.0e-8);
321         Assert.assertEquals(  -0.49894969,    c20.getCovarianceMatrix().getEntry(5, 1), 1.0e-8);
322         Assert.assertEquals(   0.35403109,    c20.getCovarianceMatrix().getEntry(5, 2), 1.0e-8);
323         Assert.assertEquals(   0.00018692631, c20.getCovarianceMatrix().getEntry(5, 3), 1.0e-11);
324         Assert.assertEquals(   0.00010088625, c20.getCovarianceMatrix().getEntry(5, 4), 1.0e-11);
325         Assert.assertEquals(   0.00062244443, c20.getCovarianceMatrix().getEntry(5, 5), 1.0e-11);
326         for (int i = 0; i < c20.getCovarianceMatrix().getRowDimension(); ++i) {
327             for (int j = i + 1; j < c20.getCovarianceMatrix().getColumnDimension(); ++j) {
328                 Assert.assertEquals(c20.getCovarianceMatrix().getEntry(j, i),
329                                     c20.getCovarianceMatrix().getEntry(i, j),
330                                     1.0e-10);
331             }
332         }
333 
334         final CartesianCovariance c21 = segments.get(2).getCovarianceMatrices().get(1);
335         Assert.assertEquals(new AbsoluteDate("1996-12-29T21:00:00", TimeScalesFactory.getUTC()),
336                             c21.getEpoch());
337         Assert.assertEquals(CelestialBodyFrame.EME2000, c21.getReferenceFrame().asCelestialBodyFrame());
338         Assert.assertEquals( 344.24505,       c21.getCovarianceMatrix().getEntry(0, 0), 1.0e-5);
339         Assert.assertEquals( 450.78162,       c21.getCovarianceMatrix().getEntry(1, 0), 1.0e-5);
340         Assert.assertEquals( 689.35327,       c21.getCovarianceMatrix().getEntry(1, 1), 1.0e-5);
341         for (int i = 0; i < c21.getCovarianceMatrix().getRowDimension(); ++i) {
342             for (int j = i + 1; j < c21.getCovarianceMatrix().getColumnDimension(); ++j) {
343                 Assert.assertEquals(c21.getCovarianceMatrix().getEntry(j, i),
344                                     c21.getCovarianceMatrix().getEntry(i, j),
345                                     1.0e-10);
346             }
347         }
348 
349     }
350 
351     @Test
352     public void testParseOEM3XML() throws IOException {
353 
354         final String ex = "/ccsds/odm/oem/OEMExample3.xml";
355         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
356         final OemParser parser  = new ParserBuilder().withMu(CelestialBodyFactory.getMars().getGM()).buildOemParser();
357         final Oem file = parser.parseMessage(source);
358         Assert.assertEquals("OEM 201113719185", file.getHeader().getMessageId());
359         Assert.assertEquals("UTC", file.getSegments().get(0).getMetadata().getTimeSystem().name());
360         Assert.assertEquals("MARS GLOBAL SURVEYOR", file.getSegments().get(0).getMetadata().getObjectName());
361         Assert.assertEquals("2000-028A", file.getSegments().get(0).getMetadata().getObjectID());
362 
363         Assert.assertEquals(1, file.getSatellites().size());
364         Assert.assertEquals(true, file.getSatellites().containsKey("2000-028A"));
365         Assert.assertEquals(false, file.getSatellites().containsKey("MARS GLOBAL SURVEYOR"));
366         Assert.assertEquals(1, file.getSatellites().size());
367         Assert.assertEquals("2000-028A", file.getSatellites().values().iterator().next().getId());
368         Assert.assertEquals(
369                 new AbsoluteDate("1996-12-18T12:00:00.331", TimeScalesFactory.getUTC()),
370                 file.getSegments().get(0).getMetadata().getStartTime());
371 
372         final OemSatelliteEphemeris satellite = file.getSatellites().get("2000-028A");
373         Assert.assertEquals("2000-028A", satellite.getId());
374         final OemSegment segment = (OemSegment) satellite.getSegments().get(0);
375         Assert.assertEquals(CelestialBodyFactory.getMars().getGM(), segment.getMu(), 1.0);
376         Assert.assertEquals("J2000", segment.getMetadata().getReferenceFrame().getName());
377         Assert.assertEquals(segment.getMetadata().getCenter().getName(), "MARS BARYCENTER");
378         Assert.assertNull(segment.getMetadata().getCenter().getBody());
379         // Frame not creatable since it's center can't be created.
380         try {
381             segment.getFrame();
382             Assert.fail("Expected Exception");
383         } catch (OrekitException e){
384             Assert.assertEquals(e.getSpecifier(), OrekitMessages.NO_DATA_LOADED_FOR_CELESTIAL_BODY);
385         }
386         Assert.assertEquals("UTC", segment.getMetadata().getTimeSystem().name());
387         Assert.assertEquals(InterpolationMethod.HERMITE, segment.getMetadata().getInterpolationMethod());
388         Assert.assertEquals(7, segment.getMetadata().getInterpolationDegree());
389         Assert.assertEquals(segment.getAvailableDerivatives(), CartesianDerivativesFilter.USE_PVA);
390 
391         List<OemSegment> segments = file.getSegments();
392         Assert.assertEquals(1, segments.size());
393         Assert.assertEquals("Produced by M.R. Sombedody, MSOO NAV/JPL, 1996 OCT 11. It is", segments.get(0).getData().getComments().get(0));
394         Assert.assertEquals("to be used for DSN scheduling purposes only.", segments.get(0).getData().getComments().get(1));
395         Assert.assertEquals(4, segments.get(0).getData().getCoordinates().size());
396         final TimeStampedPVCoordinates pv00 = segments.get(0).getData().getCoordinates().get(0);
397         Assert.assertEquals(new AbsoluteDate("1996-12-18T12:00:00.331", TimeScalesFactory.getUTC()),
398                             pv00.getDate());
399         Assert.assertEquals( 2789600.0, pv00.getPosition().getX(),     1.0e-10);
400         Assert.assertEquals( -280000.0, pv00.getPosition().getY(),     1.0e-10);
401         Assert.assertEquals(-1746800.0, pv00.getPosition().getZ(),     1.0e-10);
402         Assert.assertEquals(    4730.0, pv00.getVelocity().getX(),     1.0e-10);
403         Assert.assertEquals(   -2500.0, pv00.getVelocity().getY(),     1.0e-10);
404         Assert.assertEquals(   -1040.0, pv00.getVelocity().getZ(),     1.0e-10);
405         Assert.assertEquals(       8.0, pv00.getAcceleration().getX(), 1.0e-10);
406         Assert.assertEquals(       1.0, pv00.getAcceleration().getY(), 1.0e-10);
407         Assert.assertEquals(    -159.0, pv00.getAcceleration().getZ(), 1.0e-10);
408         final TimeStampedPVCoordinates pv01 = segments.get(0).getData().getCoordinates().get(1);
409         Assert.assertEquals(new AbsoluteDate("1996-12-18T12:01:00.331", TimeScalesFactory.getUTC()),
410                             pv01.getDate());
411         Assert.assertEquals( 2783400.0, pv01.getPosition().getX(),     1.0e-10);
412         Assert.assertEquals( -308100.0, pv01.getPosition().getY(),     1.0e-10);
413         Assert.assertEquals(-1877100.0, pv01.getPosition().getZ(),     1.0e-10);
414         Assert.assertEquals(    5190.0, pv01.getVelocity().getX(),     1.0e-10);
415         Assert.assertEquals(   -2420.0, pv01.getVelocity().getY(),     1.0e-10);
416         Assert.assertEquals(   -2000.0, pv01.getVelocity().getZ(),     1.0e-10);
417         Assert.assertEquals(       8.0, pv01.getAcceleration().getX(), 1.0e-10);
418         Assert.assertEquals(       1.0, pv01.getAcceleration().getY(), 1.0e-10);
419         Assert.assertEquals(       1.0, pv01.getAcceleration().getZ(), 1.0e-10);
420         final TimeStampedPVCoordinates pv02 = segments.get(0).getData().getCoordinates().get(2);
421         Assert.assertEquals(new AbsoluteDate("1996-12-18T12:02:00.331", TimeScalesFactory.getUTC()),
422                             pv02.getDate());
423         Assert.assertEquals( 2776000.0, pv02.getPosition().getX(),     1.0e-10);
424         Assert.assertEquals( -336900.0, pv02.getPosition().getY(),     1.0e-10);
425         Assert.assertEquals(-2008700.0, pv02.getPosition().getZ(),     1.0e-10);
426         Assert.assertEquals(    5640.0, pv02.getVelocity().getX(),     1.0e-10);
427         Assert.assertEquals(   -2340.0, pv02.getVelocity().getY(),     1.0e-10);
428         Assert.assertEquals(   -1950.0, pv02.getVelocity().getZ(),     1.0e-10);
429         Assert.assertEquals(       8.0, pv02.getAcceleration().getX(), 1.0e-10);
430         Assert.assertEquals(       1.0, pv02.getAcceleration().getY(), 1.0e-10);
431         Assert.assertEquals(     159.0, pv02.getAcceleration().getZ(), 1.0e-10);
432         final TimeStampedPVCoordinates pv03 = segments.get(0).getData().getCoordinates().get(3);
433         Assert.assertEquals(new AbsoluteDate("1996-12-28T21:28:00.331", TimeScalesFactory.getUTC()),
434                             pv03.getDate());
435         Assert.assertEquals(-3881000.0, pv03.getPosition().getX(),     1.0e-10);
436         Assert.assertEquals(  564000.0, pv03.getPosition().getY(),     1.0e-10);
437         Assert.assertEquals( -682800.0, pv03.getPosition().getZ(),     1.0e-10);
438         Assert.assertEquals(   -3290.0, pv03.getVelocity().getX(),     1.0e-10);
439         Assert.assertEquals(   -3670.0, pv03.getVelocity().getY(),     1.0e-10);
440         Assert.assertEquals(    1640.0, pv03.getVelocity().getZ(),     1.0e-10);
441         Assert.assertEquals(      -3.0, pv03.getAcceleration().getX(), 1.0e-10);
442         Assert.assertEquals(       0.0, pv03.getAcceleration().getY(), 1.0e-10);
443         Assert.assertEquals(       0.0, pv03.getAcceleration().getZ(), 1.0e-10);
444 
445         Assert.assertEquals(1, segments.get(0).getCovarianceMatrices().size());
446         final CartesianCovariance c20 = segments.get(0).getCovarianceMatrices().get(0);
447         Assert.assertEquals(new AbsoluteDate("1996-12-28T22:28:00.331", TimeScalesFactory.getUTC()),
448                             c20.getEpoch());
449         Assert.assertEquals(CelestialBodyFrame.ITRF1997, c20.getReferenceFrame().asCelestialBodyFrame());
450         Assert.assertEquals( 316000.0, c20.getCovarianceMatrix().getEntry(0, 0), 1.0e-10);
451         Assert.assertEquals( 722000.0, c20.getCovarianceMatrix().getEntry(1, 0), 1.0e-10);
452         Assert.assertEquals( 518000.0, c20.getCovarianceMatrix().getEntry(1, 1), 1.0e-10);
453         Assert.assertEquals( 202000.0, c20.getCovarianceMatrix().getEntry(2, 0), 1.0e-10);
454         Assert.assertEquals( 715000.0, c20.getCovarianceMatrix().getEntry(2, 1), 1.0e-10);
455         Assert.assertEquals(   2000.0, c20.getCovarianceMatrix().getEntry(2, 2), 1.0e-10);
456         Assert.assertEquals( 912000.0, c20.getCovarianceMatrix().getEntry(3, 0), 1.0e-10);
457         Assert.assertEquals( 306000.0, c20.getCovarianceMatrix().getEntry(3, 1), 1.0e-10);
458         Assert.assertEquals( 276000.0, c20.getCovarianceMatrix().getEntry(3, 2), 1.0e-10);
459         Assert.assertEquals( 797000.0, c20.getCovarianceMatrix().getEntry(3, 3), 1.0e-10);
460         Assert.assertEquals( 562000.0, c20.getCovarianceMatrix().getEntry(4, 0), 1.0e-10);
461         Assert.assertEquals( 899000.0, c20.getCovarianceMatrix().getEntry(4, 1), 1.0e-10);
462         Assert.assertEquals(  22000.0, c20.getCovarianceMatrix().getEntry(4, 2), 1.0e-10);
463         Assert.assertEquals(  79000.0, c20.getCovarianceMatrix().getEntry(4, 3), 1.0e-10);
464         Assert.assertEquals( 415000.0, c20.getCovarianceMatrix().getEntry(4, 4), 1.0e-10);
465         Assert.assertEquals( 245000.0, c20.getCovarianceMatrix().getEntry(5, 0), 1.0e-10);
466         Assert.assertEquals( 965000.0, c20.getCovarianceMatrix().getEntry(5, 1), 1.0e-10);
467         Assert.assertEquals( 950000.0, c20.getCovarianceMatrix().getEntry(5, 2), 1.0e-10);
468         Assert.assertEquals( 435000.0, c20.getCovarianceMatrix().getEntry(5, 3), 1.0e-10);
469         Assert.assertEquals( 621000.0, c20.getCovarianceMatrix().getEntry(5, 4), 1.0e-10);
470         Assert.assertEquals( 991000.0, c20.getCovarianceMatrix().getEntry(5, 5), 1.0e-10);
471         for (int i = 0; i < c20.getCovarianceMatrix().getRowDimension(); ++i) {
472             for (int j = i + 1; j < c20.getCovarianceMatrix().getColumnDimension(); ++j) {
473                 Assert.assertEquals(c20.getCovarianceMatrix().getEntry(j, i),
474                                     c20.getCovarianceMatrix().getEntry(i, j),
475                                     1.0e-10);
476             }
477         }
478 
479     }
480 
481     @Test
482     public void testParseOemMissingOptionalData() throws IOException {
483 
484         final String ex = "/ccsds/odm/oem/OEMExample6.txt";
485         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
486         final OemParser parser  = new ParserBuilder().withMu(CelestialBodyFactory.getMars().getGM()).buildOemParser();
487         final Oem file = parser.parseMessage(source);
488         Assert.assertEquals("UTC", file.getSegments().get(0).getMetadata().getTimeSystem().name());
489         Assert.assertEquals("MARS GLOBAL SURVEYOR", file.getSegments().get(0).getMetadata().getObjectName());
490         Assert.assertEquals("1996-062A", file.getSegments().get(0).getMetadata().getObjectID());
491 
492         Assert.assertEquals(1, file.getSatellites().size());
493         Assert.assertEquals(true, file.getSatellites().containsKey("1996-062A"));
494         Assert.assertEquals(false, file.getSatellites().containsKey("MARS GLOBAL SURVEYOR"));
495         Assert.assertEquals(1, file.getSatellites().size());
496         Assert.assertEquals("1996-062A", file.getSatellites().values().iterator().next().getId());
497         Assert.assertEquals(
498                 new AbsoluteDate("2002-12-18T12:00:00.331", TimeScalesFactory.getUTC()),
499                 file.getSegments().get(0).getMetadata().getStartTime());
500 
501         OemSatelliteEphemeris satellite = file.getSatellites().get("1996-062A");
502         Assert.assertEquals("1996-062A", satellite.getId());
503         OemSegment segment = satellite.getSegments().get(0);
504         Assert.assertEquals(CelestialBodyFactory.getMars().getGM(), segment.getMu(), 1.0);
505         FactoryManagedFrame eme2000 = FramesFactory.getEME2000();
506         Frame actualFrame = segment.getFrame();
507         AbsoluteDate actualStart = satellite.getStart();
508         Transform actualTransform = eme2000.getTransformTo(actualFrame, actualStart);
509         CelestialBody mars = CelestialBodyFactory.getMars();
510         TimeStampedPVCoordinates marsPV = mars.getPVCoordinates(actualStart, eme2000);
511         TimeStampedPVCoordinates marsPV_in_marscentered_frame = mars.getPVCoordinates(actualStart, actualFrame);
512         MatcherAssert.assertThat(marsPV_in_marscentered_frame,
513                                  OrekitMatchers.pvCloseTo(PVCoordinates.ZERO, 1e-3));
514         Assert.assertEquals(actualTransform.getTranslation(), marsPV.getPosition().negate());
515         Assert.assertEquals(actualTransform.getVelocity(), marsPV.getVelocity().negate());
516         Assert.assertEquals(actualTransform.getAcceleration(), marsPV.getAcceleration().negate());
517         Assert.assertEquals(
518                 Rotation.distance(actualTransform.getRotation(), Rotation.IDENTITY),
519                 0.0, 0.0);
520         Assert.assertEquals(actualTransform.getRotationRate(), Vector3D.ZERO);
521         Assert.assertEquals(actualTransform.getRotationAcceleration(), Vector3D.ZERO);
522         Assert.assertEquals("Mars/EME2000", actualFrame.getName());
523         Assert.assertEquals(CelestialBodyFrame.EME2000, segment.getMetadata().getReferenceFrame().asCelestialBodyFrame());
524         Assert.assertEquals("UTC", segment.getMetadata().getTimeSystem().name());
525         Assert.assertEquals(segment.getAvailableDerivatives(),
526                 CartesianDerivativesFilter.USE_PV);
527         Assert.assertEquals(satellite.getSegments().get(0).getMetadata().getStartTime(), actualStart);
528         Assert.assertEquals(satellite.getSegments().get(2).getMetadata().getStopTime(), satellite.getStop());
529 
530         final BoundedPropagator propagator = satellite.getPropagator();
531         Assert.assertEquals(propagator.getMinDate(), satellite.getStart());
532         Assert.assertEquals(propagator.getMinDate(), satellite.getSegments().get(0).getStart());
533         Assert.assertEquals(propagator.getMaxDate(), satellite.getStop());
534         Assert.assertEquals(propagator.getMaxDate(), satellite.getSegments().get(2).getStop());
535 
536         final List<TimeStampedPVCoordinates> dataLines = new ArrayList<>();
537         for (OemSegment block : file.getSegments()) {
538             for (TimeStampedPVCoordinates dataLine : block.getData().getEphemeridesDataLines()) {
539                 if (dataLine.getDate().compareTo(satellite.getStart()) >= 0) {
540                     dataLines.add(dataLine);
541                 }
542             }
543         }
544 
545         final int ulps = 12;
546         for (TimeStampedPVCoordinates coord : dataLines) {
547             MatcherAssert.assertThat(propagator.getPVCoordinates(coord.getDate(), actualFrame),
548                                      OrekitMatchers.pvCloseTo(coord, ulps));
549             MatcherAssert.assertThat(propagator.propagate(coord.getDate()).getPVCoordinates(),
550                                      OrekitMatchers.pvCloseTo(coord, ulps));
551         }
552 
553     }
554 
555     @Test
556     public void testWrongODMType() {
557         try {
558             final String ex = "/ccsds/odm/oem/OEMExample1.txt";
559             final DataSource source =  new DataSource(ex, () -> getClass().getResourceAsStream(ex));
560             new ParserBuilder().
561             withMu(CelestialBodyFactory.getMars().getGM()).
562             buildOemParser().
563             parseMessage(source);
564         } catch (OrekitException oe) {
565             Assert.assertEquals(OrekitMessages.UNSUPPORTED_FILE_FORMAT, oe.getSpecifier());
566             Assert.assertEquals("OPMExample1.txt", oe.getParts()[0]);
567         }
568     }
569 
570     @Test
571     public void testEphemerisNumberFormatErrorType() {
572         final String ex = "/ccsds/odm/oem/OEM-ephemeris-number-format-error.txt";
573         try {
574             final DataSource source =  new DataSource(ex, () -> getClass().getResourceAsStream(ex));
575             new ParserBuilder().
576             withMu(CelestialBodyFactory.getMars().getGM()).
577             buildOemParser().
578             parseMessage(source);
579         } catch (OrekitException oe) {
580             Assert.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, oe.getSpecifier());
581             Assert.assertEquals(44, oe.getParts()[0]);
582             Assert.assertEquals(ex, oe.getParts()[1]);
583             Assert.assertEquals("1996-12-28T21:59:02.267 -2445.234 -878.141 this-is-not-a-number 1.86043 -3.421256 -0.996366", oe.getParts()[2]);
584         }
585     }
586 
587     @Test
588     public void testCovarianceNumberFormatErrorType() {
589         final String ex = "/ccsds/odm/oem/OEM-covariance-number-format-error.txt";
590         try {
591             final DataSource source =  new DataSource(ex, () -> getClass().getResourceAsStream(ex));
592             new ParserBuilder().
593             withMu(CelestialBodyFactory.getMars().getGM()).
594             buildOemParser().
595             parseMessage(source);
596         } catch (OrekitException oe) {
597             Assert.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, oe.getSpecifier());
598             Assert.assertEquals(52, oe.getParts()[0]);
599             Assert.assertEquals(ex, oe.getParts()[1]);
600             Assert.assertEquals("4.6189273e-04 this-is-not-a-number", oe.getParts()[2]);
601         }
602     }
603 
604     @Test
605     public void testNonExistentFile() throws URISyntaxException {
606         final String realName = getClass().getResource("/ccsds/odm/oem/OEMExample1.txt").toURI().getPath();
607         final String wrongName = realName + "xxxxx";
608         final DataSource source =  new DataSource(wrongName, () -> getClass().getResourceAsStream(wrongName));
609         try {
610             new ParserBuilder().
611             withMu(CelestialBodyFactory.getMars().getGM()).
612             buildOemParser().
613             parseMessage(source);
614             Assert.fail("an exception should have been thrown");
615         } catch (OrekitException oe) {
616             Assert.assertEquals(OrekitMessages.UNABLE_TO_FIND_FILE, oe.getSpecifier());
617             Assert.assertEquals(wrongName, oe.getParts()[0]);
618         }
619     }
620 
621     @Test
622     public void testInconsistentTimeSystems() {
623         try {
624             final String ex = "/ccsds/odm/oem/OEM-inconsistent-time-systems.txt";
625             final DataSource source =  new DataSource(ex, () -> getClass().getResourceAsStream(ex));
626             new ParserBuilder().
627             withMu(CelestialBodyFactory.getMars().getGM()).
628             buildOemParser().
629             parseMessage(source);
630         } catch (OrekitException oe) {
631             Assert.assertEquals(OrekitMessages.CCSDS_INCONSISTENT_TIME_SYSTEMS, oe.getSpecifier());
632             Assert.assertEquals("UTC", oe.getParts()[0]);
633             Assert.assertEquals("TCG", oe.getParts()[1]);
634         }
635     }
636 
637     @Test
638     public void testLowerCaseValue() {
639         //setup
640         String file = "/ccsds/odm/oem/oemLowerCaseValue.oem";
641         final DataSource source =  new DataSource(file, () -> getClass().getResourceAsStream(file));
642 
643         //action
644         final Oem actual = new ParserBuilder().
645                                withMu(CelestialBodyFactory.getMars().getGM()).
646                                buildOemParser().
647                                parseMessage(source);
648 
649         //verify
650         Assert.assertEquals(
651                 CelestialBodyFactory.getEarth(),
652                 actual.getSegments().get(0).getMetadata().getCenter().getBody());
653     }
654 
655     @Test
656     public void testWrongKeyword()
657         throws URISyntaxException {
658         // simple test for OMM file, contains p/v entries and other mandatory
659         // data.
660         final String name = "/ccsds/odm/oem/OEM-wrong-keyword.txt";
661         final DataSource source =  new DataSource(name, () -> getClass().getResourceAsStream(name));
662         try {
663             new ParserBuilder().
664             withMu(CelestialBodyFactory.getMars().getGM()).
665             buildOemParser().
666             parseMessage(source);
667             Assert.fail("an exception should have been thrown");
668         } catch (OrekitException oe) {
669             Assert.assertEquals(OrekitMessages.CCSDS_UNEXPECTED_KEYWORD, oe.getSpecifier());
670             Assert.assertEquals(19, ((Integer) oe.getParts()[0]).intValue());
671             Assert.assertTrue(((String) oe.getParts()[2]).startsWith("WRONG_KEYWORD"));
672         }
673     }
674 
675     @Test
676     public void testKeywordWithinEphemeris()
677         throws URISyntaxException {
678         // simple test for OMM file, contains p/v entries and other mandatory
679         // data.
680         final String name = "/ccsds/odm/oem/OEM-keyword-within-ephemeris.txt";
681         final DataSource source =  new DataSource(name, () -> getClass().getResourceAsStream(name));
682         try {
683             new ParserBuilder().
684             withMu(CelestialBodyFactory.getMars().getGM()).
685             buildOemParser().
686             parseMessage(source);
687             Assert.fail("an exception should have been thrown");
688         } catch (OrekitException oe) {
689             Assert.assertEquals(OrekitMessages.CCSDS_UNEXPECTED_KEYWORD, oe.getSpecifier());
690             Assert.assertEquals(24, ((Integer) oe.getParts()[0]).intValue());
691             Assert.assertTrue(((String) oe.getParts()[2]).startsWith("USER_DEFINED_TEST_KEY"));
692         }
693     }
694 
695     @Test
696     public void testKeywordWithinCovariance()
697         throws URISyntaxException {
698         // simple test for OMM file, contains p/v entries and other mandatory
699         // data.
700         final String name = "/ccsds/odm/oem/OEM-keyword-within-covariance.txt";
701         final DataSource source =  new DataSource(name, () -> getClass().getResourceAsStream(name));
702         try {
703             new ParserBuilder().
704             withMu(CelestialBodyFactory.getMars().getGM()).
705             buildOemParser().
706             parseMessage(source);
707             Assert.fail("an exception should have been thrown");
708         } catch (OrekitException oe) {
709             Assert.assertEquals(OrekitMessages.CCSDS_UNEXPECTED_KEYWORD, oe.getSpecifier());
710             Assert.assertEquals(91, ((Integer) oe.getParts()[0]).intValue());
711             Assert.assertTrue(((String) oe.getParts()[2]).startsWith("USER_DEFINED_TEST_KEY"));
712         }
713     }
714 
715     @Test
716     public void testTooLargeCovarianceDimension()
717         throws URISyntaxException {
718         final String name = "/ccsds/odm/oem/OEM-too-large-covariance-dimension.txt";
719         final DataSource source =  new DataSource(name, () -> getClass().getResourceAsStream(name));
720         try {
721             new ParserBuilder().
722             withMu(CelestialBodyFactory.getMars().getGM()).
723             buildOemParser().
724             parseMessage(source);
725             Assert.fail("an exception should have been thrown");
726         } catch (OrekitException oe) {
727             Assert.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, oe.getSpecifier());
728             Assert.assertEquals(91, ((Integer) oe.getParts()[0]).intValue());
729             Assert.assertTrue(((String) oe.getParts()[2]).startsWith("1.0e-12"));
730         }
731     }
732 
733     @Test
734     public void testTooSmallCovarianceDimension()
735         throws URISyntaxException {
736         final String name = "/ccsds/odm/oem/OEM-too-small-covariance-dimension.txt";
737         final DataSource source =  new DataSource(name, () -> getClass().getResourceAsStream(name));
738         try {
739             new ParserBuilder().
740             withMu(CelestialBodyFactory.getMars().getGM()).
741             buildOemParser().
742             parseMessage(source);
743             Assert.fail("an exception should have been thrown");
744         } catch (OrekitException oe) {
745             Assert.assertEquals(OrekitMessages.UNABLE_TO_PARSE_ELEMENT_IN_FILE, oe.getSpecifier());
746             Assert.assertEquals("EPOCH", oe.getParts()[0]);
747             Assert.assertEquals(89, ((Integer) oe.getParts()[1]).intValue());
748             Assert.assertTrue(((String) oe.getParts()[2]).endsWith("OEM-too-small-covariance-dimension.txt"));
749         }
750     }
751 
752     @Test
753     public void testTooManyCovarianceColumns()
754         throws URISyntaxException {
755         final String name = "/ccsds/odm/oem/OEM-too-many-covariance-columns.txt";
756         final DataSource source =  new DataSource(name, () -> getClass().getResourceAsStream(name));
757         try {
758             new ParserBuilder().
759             withMu(CelestialBodyFactory.getMars().getGM()).
760             buildOemParser().
761             parseMessage(source);
762             Assert.fail("an exception should have been thrown");
763         } catch (OrekitException oe) {
764             Assert.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, oe.getSpecifier());
765             Assert.assertEquals(51, ((Integer) oe.getParts()[0]).intValue());
766             Assert.assertTrue(((String) oe.getParts()[2]).startsWith("3.3313494e-04"));
767         }
768     }
769 
770     @Test
771     public void testTooFewCovarianceColumns()
772         throws URISyntaxException {
773         final String name = "/ccsds/odm/oem/OEM-too-few-covariance-columns.txt";
774         final DataSource source =  new DataSource(name, () -> getClass().getResourceAsStream(name));
775         try {
776             new ParserBuilder().
777             withMu(CelestialBodyFactory.getMars().getGM()).
778             buildOemParser().
779             parseMessage(source);
780             Assert.fail("an exception should have been thrown");
781         } catch (OrekitException oe) {
782             Assert.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, oe.getSpecifier());
783             Assert.assertEquals(55, ((Integer) oe.getParts()[0]).intValue());
784             Assert.assertTrue(((String) oe.getParts()[2]).startsWith("-2.2118325e-07"));
785         }
786     }
787 
788     /**
789      * Check if the parser enters the correct interpolation degree
790      * (the parsed one or the default if there is none)
791      */
792     @Test
793     public void testDefaultInterpolationDegree()
794         throws URISyntaxException {
795 
796         final String name = "/ccsds/odm/oem/OEMExample8.txt";
797 
798         final ParserBuilder builder = new ParserBuilder().withMu(CelestialBodyFactory.getMars().getGM());
799 
800         final DataSource source1 =  new DataSource(name, () -> getClass().getResourceAsStream(name));
801         final Oem file1 = builder.buildOemParser().parseMessage(source1);
802         Assert.assertEquals(1, file1.getSegments().get(0).getMetadata().getInterpolationDegree());
803         Assert.assertEquals(7, file1.getSegments().get(1).getMetadata().getInterpolationDegree());
804 
805         final DataSource source2 =  new DataSource(name, () -> getClass().getResourceAsStream(name));
806         final Oem file2 = builder.withDefaultInterpolationDegree(5).buildOemParser().parseMessage(source2);
807         Assert.assertEquals(5, file2.getSegments().get(0).getMetadata().getInterpolationDegree());
808         Assert.assertEquals(7, file2.getSegments().get(1).getMetadata().getInterpolationDegree());
809     }
810 
811     /**
812      * Check the parser can parse several ITRF frames. Test case for #361.
813      */
814     @Test
815     public void testITRFFrames() {
816         // setup
817         Charset utf8 = StandardCharsets.UTF_8;
818         IERSConventions conventions = IERSConventions.IERS_2010;
819         boolean simpleEop = true;
820         OemParser parser  = new ParserBuilder().
821                             withMu(CelestialBodyFactory.getMars().getGM()).
822                             buildOemParser();
823 
824         // frames to check
825         List<Pair<String, Frame>> frames = new ArrayList<>();
826         frames.add(new Pair<>("ITRF-93",  FramesFactory.getITRF(ITRFVersion.ITRF_1993, conventions, simpleEop)));
827         frames.add(new Pair<>("ITRF-97",  FramesFactory.getITRF(ITRFVersion.ITRF_1997, conventions, simpleEop)));
828         frames.add(new Pair<>("ITRF2000", FramesFactory.getITRF(ITRFVersion.ITRF_2000, conventions, simpleEop)));
829         frames.add(new Pair<>("ITRF2005", FramesFactory.getITRF(ITRFVersion.ITRF_2005, conventions, simpleEop)));
830         frames.add(new Pair<>("ITRF2008", FramesFactory.getITRF(ITRFVersion.ITRF_2008, conventions, simpleEop)));
831         frames.add(new Pair<>("ITRF2014", FramesFactory.getITRF(ITRFVersion.ITRF_2014, conventions, simpleEop)));
832 
833         for (Pair<String, Frame> frame : frames) {
834             final String frameName = frame.getFirst();
835 
836             InputStream pre    = OemParserTest.class.getResourceAsStream("/ccsds/odm/oem/OEMExample7.txt.pre");
837             InputStream middle = new ByteArrayInputStream(("REF_FRAME = " + frameName).getBytes(utf8));
838             InputStream post   = OemParserTest.class.getResourceAsStream("/ccsds/odm/oem/OEMExample7.txt.post");
839             DataSource   source = new DataSource("<patched>", () -> new SequenceInputStream(pre, new SequenceInputStream(middle, post)));
840 
841             // action
842             Oem actual = parser.parseMessage(source);
843 
844             // verify
845             OemSegment segment = actual.getSegments().get(0);
846             Assert.assertEquals(frameName,
847                                 segment.getMetadata().getReferenceFrame().getName());
848             // check expected frame
849             Frame actualFrame = segment.getFrame();
850             Frame expectedFrame = frame.getSecond();
851             Assert.assertEquals(expectedFrame, actualFrame);
852             Assert.assertEquals(expectedFrame.getTransformProvider(),
853                                 actualFrame.getTransformProvider());
854         }
855     }
856 
857     @Test
858     public void testEmptyComments() {
859         final String name = "/ccsds/odm/oem/ISS.resampled.truncated.txt";
860         final ParserBuilder builder = new ParserBuilder();
861         final DataSource source =  new DataSource(name, () -> getClass().getResourceAsStream(name));
862         final Oem iss = builder.buildOemParser().parseMessage(source);
863         Assert.assertEquals("1998-067-A", iss.getSegments().get(0).getMetadata().getObjectID());
864         Assert.assertEquals(23, iss.getSegments().get(0).getData().getComments().size());
865         Assert.assertEquals("", iss.getSegments().get(0).getData().getComments().get(13));
866         Assert.assertEquals("", iss.getSegments().get(0).getData().getComments().get(20));
867         Assert.assertEquals(25, iss.getSegments().get(0).getData().getCoordinates().size());
868     }
869 
870 }