1   /* Copyright 2002-2020 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;
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.hipparchus.geometry.euclidean.threed.Rotation;
30  import org.hipparchus.geometry.euclidean.threed.Vector3D;
31  import org.hipparchus.linear.Array2DRowRealMatrix;
32  import org.hipparchus.util.Pair;
33  import org.junit.Assert;
34  import org.junit.Before;
35  import org.junit.Test;
36  import org.orekit.OrekitMatchers;
37  import org.orekit.Utils;
38  import org.orekit.bodies.CelestialBody;
39  import org.orekit.bodies.CelestialBodyFactory;
40  import org.orekit.errors.OrekitException;
41  import org.orekit.errors.OrekitMessages;
42  import org.orekit.files.ccsds.OEMFile.EphemeridesBlock;
43  import org.orekit.files.ccsds.OEMFile.OemSatelliteEphemeris;
44  import org.orekit.frames.FactoryManagedFrame;
45  import org.orekit.frames.Frame;
46  import org.orekit.frames.FramesFactory;
47  import org.orekit.frames.ITRFVersion;
48  import org.orekit.frames.LOFType;
49  import org.orekit.frames.Transform;
50  import org.orekit.orbits.CartesianOrbit;
51  import org.orekit.propagation.BoundedPropagator;
52  import org.orekit.time.AbsoluteDate;
53  import org.orekit.time.TimeScalesFactory;
54  import org.orekit.utils.CartesianDerivativesFilter;
55  import org.orekit.utils.IERSConventions;
56  import org.orekit.utils.PVCoordinates;
57  import org.orekit.utils.TimeStampedPVCoordinates;
58  
59  
60  public class OEMParserTest {
61  
62      @Before
63      public void setUp()
64          throws Exception {
65          Utils.setDataRoot("regular-data");
66      }
67  
68      @Test
69      public void testParseOEM1() throws IOException {
70          //
71          final String ex = "/ccsds/OEMExample.txt";
72          final InputStream inEntry = getClass().getResourceAsStream(ex);
73          final OEMParser parser = new OEMParser().withMu(CelestialBodyFactory.getEarth().getGM());
74          final OEMFile file = parser.parse(inEntry, "OEMExample.txt");
75          Assert.assertEquals(CcsdsTimeScale.UTC, file.getEphemeridesBlocks().get(0).getMetaData().getTimeSystem());
76          Assert.assertEquals("MARS GLOBAL SURVEYOR", file.getEphemeridesBlocks().get(0).getMetaData().getObjectName());
77          Assert.assertEquals("1996-062A", file.getEphemeridesBlocks().get(0).getMetaData().getObjectID());
78          Assert.assertEquals("MARS BARYCENTER", file.getEphemeridesBlocks().get(0).getMetaData().getCenterName());
79          Assert.assertEquals(1996, file.getEphemeridesBlocks().get(0).getMetaData().getLaunchYear());
80          Assert.assertEquals(62, file.getEphemeridesBlocks().get(0).getMetaData().getLaunchNumber());
81          Assert.assertEquals("A", file.getEphemeridesBlocks().get(0).getMetaData().getLaunchPiece());
82          Assert.assertFalse(file.getEphemeridesBlocks().get(0).getMetaData().getHasCreatableBody());
83          Assert.assertNull(file.getEphemeridesBlocks().get(0).getMetaData().getCenterBody());
84          Assert.assertEquals(new AbsoluteDate(1996, 12, 18, 12, 00, 0.331, TimeScalesFactory.getUTC()),
85                              file.getEphemeridesBlocks().get(0).getStartTime());
86          Assert.assertEquals(new AbsoluteDate(1996, 12, 28, 21, 28, 0.331, TimeScalesFactory.getUTC()),
87                              file.getEphemeridesBlocks().get(0).getStopTime());
88          Assert.assertEquals(new AbsoluteDate(1996, 12, 18, 12, 10, 0.331, TimeScalesFactory.getUTC()),
89                              file.getEphemeridesBlocks().get(0).getUseableStartTime());
90          Assert.assertEquals(new AbsoluteDate(1996, 12, 28, 21, 23, 0.331, TimeScalesFactory.getUTC()),
91                              file.getEphemeridesBlocks().get(0).getUseableStopTime());
92          Assert.assertEquals("HERMITE", file.getEphemeridesBlocks().get(0).getInterpolationMethod());
93          Assert.assertEquals(7, file.getEphemeridesBlocks().get(0).getInterpolationDegree());
94          ArrayList<String> ephemeridesDataLinesComment = new ArrayList<String>();
95          ephemeridesDataLinesComment.add("This file was produced by M.R. Somebody, MSOO NAV/JPL, 1996NOV 04. It is");
96          ephemeridesDataLinesComment.add("to be used for DSN scheduling purposes only.");
97          Assert.assertEquals(ephemeridesDataLinesComment, file.getEphemeridesBlocks().get(0).getEphemeridesDataLinesComment());
98          CartesianOrbit orbit = new CartesianOrbit(new PVCoordinates
99                                                    (new Vector3D(2789.619 * 1000, -280.045 * 1000, -1746.755 * 1000),
100                                                    new Vector3D(4.73372 * 1000, -2.49586 * 1000, -1.04195 * 1000)),
101                                                    FramesFactory.getEME2000(),
102                                                    new AbsoluteDate("1996-12-18T12:00:00.331", TimeScalesFactory.getUTC()),
103                                                    CelestialBodyFactory.getEarth().getGM());
104         Assert.assertArrayEquals(orbit.getPVCoordinates().getPosition().toArray(), file.getEphemeridesBlocks().get(0).getEphemeridesDataLines().get(0).getPosition().toArray(), 1e-10);
105         Assert.assertArrayEquals(orbit.getPVCoordinates().getVelocity().toArray(), file.getEphemeridesBlocks().get(0).getEphemeridesDataLines().get(0).getVelocity().toArray(), 1e-10);
106         Assert.assertArrayEquals((new Vector3D(1, 1, 1)).toArray(), file.getEphemeridesBlocks().get(1).getEphemeridesDataLines().get(0).getAcceleration().toArray(), 1e-10);
107         Assert.assertEquals(Vector3D.ZERO, file.getEphemeridesBlocks().get(1).getEphemeridesDataLines().get(1).getAcceleration());
108         final Array2DRowRealMatrix covMatrix = new Array2DRowRealMatrix(6, 6);
109         final double[] column1 = {
110             3.331349476038534e-04, 4.618927349220216e-04,
111             -3.070007847730449e-04, -3.349365033922630e-07,
112             -2.211832501084875e-07, -3.041346050686871e-07
113         };
114         final double[] column2 = {
115             4.618927349220216e-04, 6.782421679971363e-04,
116             -4.221234189514228e-04, -4.686084221046758e-07,
117             -2.864186892102733e-07, -4.989496988610662e-07
118         };
119         final double[] column3 = {
120             -3.070007847730449e-04, -4.221234189514228e-04,
121             3.231931992380369e-04, 2.484949578400095e-07,
122             1.798098699846038e-07, 3.540310904497689e-07
123         };
124         final double[] column4 = {
125             -3.349365033922630e-07, -4.686084221046758e-07,
126             2.484949578400095e-07, 4.296022805587290e-10,
127             2.608899201686016e-10, 1.869263192954590e-10
128         };
129         final double[] column5 = {
130             -2.211832501084875e-07, -2.864186892102733e-07,
131             1.798098699846038e-07, 2.608899201686016e-10,
132             1.767514756338532e-10, 1.008862586240695e-10
133         };
134         final double[] column6 = {
135             -3.041346050686871e-07, -4.989496988610662e-07,
136             3.540310904497689e-07, 1.869263192954590e-10,
137             1.008862586240695e-10, 6.224444338635500e-10
138         };
139         covMatrix.setColumn(0, column1);
140         covMatrix.setColumn(1, column2);
141         covMatrix.setColumn(2, column3);
142         covMatrix.setColumn(3, column4);
143         covMatrix.setColumn(4, column5);
144         covMatrix.setColumn(5, column6);
145         for (int i = 0; i < 6; i++) {
146             for (int j = 0; j < 6; j++) {
147                 Assert.assertEquals(covMatrix.getEntry(i, j),
148                                     file.getEphemeridesBlocks().get(2).getCovarianceMatrices().get(0).getMatrix().getEntry(i, j),
149                                     1e-10);
150             }
151         }
152         Assert.assertEquals(new AbsoluteDate("1996-12-28T21:29:07.267", TimeScalesFactory.getUTC()),
153                             file.getEphemeridesBlocks().get(2).getCovarianceMatrices().get(0).getEpoch());
154         Assert.assertEquals(LOFType.QSW,
155                             file.getEphemeridesBlocks().get(2).getCovarianceMatrices().get(0).getLofType());
156         Assert.assertNull(file.getEphemeridesBlocks().get(2).getCovarianceMatrices().get(0).getFrame());
157         Assert.assertEquals(FramesFactory.getEME2000(),
158                             file.getEphemeridesBlocks().get(2).getCovarianceMatrices().get(1).getFrame());
159         Assert.assertNull(file.getEphemeridesBlocks().get(2).getCovarianceMatrices().get(1).getLofType());
160     }
161 
162     @Test
163     public void testParseOEM1OrbitFile() throws IOException {
164 
165         final String ex = "/ccsds/OEMExample3.txt";
166         final InputStream inEntry = getClass().getResourceAsStream(ex);
167         final OEMParser parser = new OEMParser()
168                 .withMu(CelestialBodyFactory.getEarth().getGM())
169                 .withConventions(IERSConventions.IERS_2010);
170         final OEMFile file = parser.parse(inEntry);
171         Assert.assertEquals(CcsdsTimeScale.UTC, file.getEphemeridesBlocks().get(0).getMetaData().getTimeSystem());
172         Assert.assertEquals("MARS GLOBAL SURVEYOR", file.getEphemeridesBlocks().get(0).getMetaData().getObjectName());
173         Assert.assertEquals("1996-062A", file.getEphemeridesBlocks().get(0).getMetaData().getObjectID());
174 
175         Assert.assertEquals(1, file.getSatellites().size());
176         Assert.assertEquals(true, file.getSatellites().containsKey("1996-062A"));
177         Assert.assertEquals(false, file.getSatellites().containsKey("MARS GLOBAL SURVEYOR"));
178         Assert.assertEquals(1, file.getSatellites().size());
179         Assert.assertEquals("1996-062A", file.getSatellites().values().iterator().next().getId());
180         Assert.assertEquals(
181                 new AbsoluteDate("1996-12-18T12:00:00.331", TimeScalesFactory.getUTC()),
182                 file.getEphemeridesBlocks().get(0).getStartTime());
183 
184         final OemSatelliteEphemeris satellite = file.getSatellites().get("1996-062A");
185         Assert.assertEquals(satellite.getId(), "1996-062A");
186         Assert.assertEquals(satellite.getMu(), file.getMuUsed(), 0);
187         final EphemeridesBlock actualBlock = satellite.getSegments().get(0);
188         Assert.assertEquals(actualBlock.getMu(), file.getMuUsed(), 0);
189         Assert.assertEquals(actualBlock.getFrameString(), "EME2000");
190         Assert.assertEquals(actualBlock.getFrameCenterString(), "MARS BARYCENTER");
191         Assert.assertEquals(actualBlock.getMetaData().getHasCreatableBody(), false);
192         // Frame not creatable since it's center can't be created.
193         try {
194             actualBlock.getFrame();
195             Assert.fail("Expected Exception");
196         } catch (OrekitException e){
197             Assert.assertEquals(e.getSpecifier(),
198                     OrekitMessages.NO_DATA_LOADED_FOR_CELESTIAL_BODY);
199         }
200         Assert.assertEquals(actualBlock.getTimeScaleString(), "UTC");
201         Assert.assertEquals(actualBlock.getTimeScale(), TimeScalesFactory.getUTC());
202         Assert.assertEquals(actualBlock.getInterpolationSamples(), 3);
203         Assert.assertEquals(actualBlock.getAvailableDerivatives(),
204                 CartesianDerivativesFilter.USE_PV);
205         // propagator can't be created since frame can't be created
206         try {
207             satellite.getPropagator();
208             Assert.fail("Expected Exception");
209         } catch (OrekitException e){
210             Assert.assertEquals(e.getSpecifier(),
211                     OrekitMessages.NO_DATA_LOADED_FOR_CELESTIAL_BODY);
212         }
213     }
214 
215     @Test
216     public void testParseOemMissingOptionalData() throws IOException {
217 
218         final String ex = "/ccsds/OEMExample6.txt";
219         final InputStream inEntry = getClass().getResourceAsStream(ex);
220         final OEMParser parser = new OEMParser()
221                 .withMu(CelestialBodyFactory.getEarth().getGM())
222                 .withConventions(IERSConventions.IERS_2010);
223         final OEMFile file = parser.parse(inEntry);
224         Assert.assertEquals(CcsdsTimeScale.UTC, file.getEphemeridesBlocks().get(0).getMetaData().getTimeSystem());
225         Assert.assertEquals("MARS GLOBAL SURVEYOR", file.getEphemeridesBlocks().get(0).getMetaData().getObjectName());
226         Assert.assertEquals("1996-062A", file.getEphemeridesBlocks().get(0).getMetaData().getObjectID());
227 
228         Assert.assertEquals(1, file.getSatellites().size());
229         Assert.assertEquals(true, file.getSatellites().containsKey("1996-062A"));
230         Assert.assertEquals(false, file.getSatellites().containsKey("MARS GLOBAL SURVEYOR"));
231         Assert.assertEquals(1, file.getSatellites().size());
232         Assert.assertEquals("1996-062A", file.getSatellites().values().iterator().next().getId());
233         Assert.assertEquals(
234                 new AbsoluteDate("2002-12-18T12:00:00.331", TimeScalesFactory.getUTC()),
235                 file.getEphemeridesBlocks().get(0).getStartTime());
236 
237         OemSatelliteEphemeris satellite = file.getSatellites().get("1996-062A");
238         Assert.assertEquals(satellite.getId(), "1996-062A");
239         Assert.assertEquals(satellite.getMu(), file.getMuUsed(), 0);
240         EphemeridesBlock actualBlock = satellite.getSegments().get(0);
241         Assert.assertEquals(actualBlock.getMu(), file.getMuUsed(), 0);
242         FactoryManagedFrame eme2000 = FramesFactory.getEME2000();
243         Frame actualFrame = actualBlock.getFrame();
244         AbsoluteDate actualStart = satellite.getStart();
245         Transform actualTransform = eme2000.getTransformTo(actualFrame, actualStart);
246         CelestialBody mars = CelestialBodyFactory.getMars();
247         TimeStampedPVCoordinates marsPV = mars.getPVCoordinates(actualStart, eme2000);
248         TimeStampedPVCoordinates marsPV_in_marscentered_frame = mars.getPVCoordinates(actualStart, actualFrame);
249         Assert.assertThat(
250         		marsPV_in_marscentered_frame,
251                 OrekitMatchers.pvCloseTo(PVCoordinates.ZERO, 1e-3));
252         Assert.assertEquals(actualTransform.getTranslation(), marsPV.getPosition().negate());
253         Assert.assertEquals(actualTransform.getVelocity(), marsPV.getVelocity().negate());
254         Assert.assertEquals(actualTransform.getAcceleration(), marsPV.getAcceleration().negate());
255         Assert.assertEquals(
256                 Rotation.distance(actualTransform.getRotation(), Rotation.IDENTITY),
257                 0.0, 0.0);
258         Assert.assertEquals(actualTransform.getRotationRate(), Vector3D.ZERO);
259         Assert.assertEquals(actualTransform.getRotationAcceleration(), Vector3D.ZERO);
260         Assert.assertEquals(actualFrame.getName(), "Mars/EME2000");
261         Assert.assertEquals(actualBlock.getFrameString(), "EME2000");
262         Assert.assertEquals(actualBlock.getTimeScaleString(), "UTC");
263         Assert.assertEquals(actualBlock.getTimeScale(), TimeScalesFactory.getUTC());
264         Assert.assertEquals(actualBlock.getAvailableDerivatives(),
265                 CartesianDerivativesFilter.USE_PV);
266         Assert.assertEquals(satellite.getSegments().get(0).getStartTime(), actualStart);
267         Assert.assertEquals(satellite.getSegments().get(2).getStopTime(), satellite.getStop());
268 
269         final BoundedPropagator propagator = satellite.getPropagator();
270         Assert.assertEquals(propagator.getMinDate(), satellite.getStart());
271         Assert.assertEquals(propagator.getMinDate(), satellite.getSegments().get(0).getStart());
272         Assert.assertEquals(propagator.getMaxDate(), satellite.getStop());
273         Assert.assertEquals(propagator.getMaxDate(), satellite.getSegments().get(2).getStop());
274 
275         final List<TimeStampedPVCoordinates> dataLines = new ArrayList<>();
276         for (EphemeridesBlock block : file.getEphemeridesBlocks()) {
277             for (TimeStampedPVCoordinates dataLine : block.getEphemeridesDataLines()) {
278                 if (dataLine.getDate().compareTo(satellite.getStart()) >= 0) {
279                     dataLines.add(dataLine);
280                 }
281             }
282         }
283 
284         final int ulps = 12;
285         for (TimeStampedPVCoordinates coord : dataLines) {
286             Assert.assertThat(
287                     propagator.getPVCoordinates(coord.getDate(), actualFrame),
288                     OrekitMatchers.pvCloseTo(coord, ulps));
289             Assert.assertThat(
290                     propagator.propagate(coord.getDate()).getPVCoordinates(),
291                     OrekitMatchers.pvCloseTo(coord, ulps));
292         }
293 
294     }
295 
296 
297 
298     @Test
299     public void testParseOEM2()
300             throws URISyntaxException {
301 
302         final String name = getClass().getResource("/ccsds/OEMExample2.txt").toURI().getPath();
303         OEMParser parser = new OEMParser().
304                 withConventions(IERSConventions.IERS_2010).
305                 withSimpleEOP(true).
306                 withMu(CelestialBodyFactory.getMars().getGM()).
307                 withInternationalDesignator(1996, 2, "A").
308                 withMissionReferenceDate(new AbsoluteDate("1996-12-17T00:00:00.000",
309                                                           TimeScalesFactory.getUTC()));
310 
311         final OEMFile file = parser.parse(name);
312         final List<String> headerComment = new ArrayList<String>();
313         headerComment.add("comment");
314         Assert.assertEquals(headerComment, file.getHeaderComment());
315         final List<String> metadataComment = new ArrayList<String>();
316         metadataComment.add("comment 1");
317         metadataComment.add("comment 2");
318         Assert.assertEquals(metadataComment, file.getEphemeridesBlocks().get(0).getMetaData().getComment());
319         Assert.assertEquals("TOD", file.getEphemeridesBlocks().get(0).getFrameString());
320         Assert.assertEquals("EME2000", file.getEphemeridesBlocks().get(1).getFrameString());
321         List<EphemeridesBlock> blocks = file.getEphemeridesBlocks();
322         Assert.assertEquals(2, blocks.size());
323         Assert.assertTrue(blocks.get(0).getHasRefFrameEpoch());
324         Assert.assertEquals(129600.331,
325                             blocks.get(0).getStartTime().durationFrom(file.getMissionReferenceDate()),
326                             1.0e-15);
327         Assert.assertEquals(941347.267,
328                             blocks.get(1).getStartTime().durationFrom(file.getMissionReferenceDate()),
329                             1.0e-15);
330 
331     }
332 
333     @Test
334     public void testWrongODMType() {
335         try {
336             new OEMParser().parse(getClass().getResourceAsStream("/ccsds/OPMExample.txt"), "OPMExample.txt");
337         } catch (OrekitException oe) {
338             Assert.assertEquals(OrekitMessages.CCSDS_UNEXPECTED_KEYWORD, oe.getSpecifier());
339             Assert.assertEquals(1, oe.getParts()[0]);
340             Assert.assertEquals("OPMExample.txt", oe.getParts()[1]);
341             Assert.assertEquals("CCSDS_OPM_VERS = 2.0", oe.getParts()[2]);
342         }
343     }
344 
345     @Test
346     public void testEphemerisNumberFormatErrorType() {
347         try {
348             new OEMParser().withMu(CelestialBodyFactory.getMars().getGM()).
349             parse(getClass().getResourceAsStream("/ccsds/OEM-ephemeris-number-format-error.txt"),
350                                                  "OEM-ephemeris-number-format-error.txt");
351         } catch (OrekitException oe) {
352             Assert.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, oe.getSpecifier());
353             Assert.assertEquals(44, oe.getParts()[0]);
354             Assert.assertEquals("OEM-ephemeris-number-format-error.txt", oe.getParts()[1]);
355             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]);
356         }
357     }
358 
359     @Test
360     public void testCovarianceNumberFormatErrorType() {
361         try {
362             new OEMParser().withMu(CelestialBodyFactory.getMars().getGM()).
363             parse(getClass().getResourceAsStream("/ccsds/OEM-covariance-number-format-error.txt"),
364                                                  "OEM-covariance-number-format-error.txt");
365         } catch (OrekitException oe) {
366             Assert.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, oe.getSpecifier());
367             Assert.assertEquals(52, oe.getParts()[0]);
368             Assert.assertEquals("OEM-covariance-number-format-error.txt", oe.getParts()[1]);
369             Assert.assertEquals("4.6189273e-04 this-is-not-a-number", oe.getParts()[2]);
370         }
371     }
372 
373     @Test
374     public void testNonExistentFile() throws URISyntaxException {
375         final String realName = getClass().getResource("/ccsds/OEMExample.txt").toURI().getPath();
376         final String wrongName = realName + "xxxxx";
377         try {
378             new OEMParser().parse(wrongName);
379             Assert.fail("an exception should have been thrown");
380         } catch (OrekitException oe) {
381             Assert.assertEquals(OrekitMessages.UNABLE_TO_FIND_FILE, oe.getSpecifier());
382             Assert.assertEquals(wrongName, oe.getParts()[0]);
383         }
384     }
385 
386     @Test
387     public void testInconsistentTimeSystems() {
388         try {
389             new OEMParser().withMu(CelestialBodyFactory.getMars().getGM()).parse(getClass().getResourceAsStream("/ccsds/OEM-inconsistent-time-systems.txt"));
390         } catch (OrekitException oe) {
391             Assert.assertEquals(OrekitMessages.CCSDS_OEM_INCONSISTENT_TIME_SYSTEMS, oe.getSpecifier());
392             Assert.assertEquals(CcsdsTimeScale.UTC, oe.getParts()[0]);
393             Assert.assertEquals(CcsdsTimeScale.TCG, oe.getParts()[1]);
394         }
395     }
396 
397     @Test
398     public void testLowerCaseValue() {
399         //setup
400         String file = "/ccsds/oemLowerCaseValue.oem";
401         InputStream in = getClass().getResourceAsStream(file);
402 
403         //action
404         OEMFile actual = new OEMParser().parse(in, file);
405 
406         //verify
407         Assert.assertEquals(
408                 CelestialBodyFactory.getEarth(),
409                 actual.getEphemeridesBlocks().get(0).getMetaData().getCenterBody());
410     }
411 
412     @Test
413     public void testWrongKeyword()
414         throws URISyntaxException {
415         // simple test for OMM file, contains p/v entries and other mandatory
416         // data.
417         final String name = getClass().getResource("/ccsds/OEM-wrong-keyword.txt").toURI().getPath();
418         try {
419             new OEMParser().parse(name);
420             Assert.fail("an exception should have been thrown");
421         } catch (OrekitException oe) {
422             Assert.assertEquals(OrekitMessages.CCSDS_UNEXPECTED_KEYWORD, oe.getSpecifier());
423             Assert.assertEquals(19, ((Integer) oe.getParts()[0]).intValue());
424             Assert.assertTrue(((String) oe.getParts()[2]).startsWith("WRONG_KEYWORD"));
425         }
426     }
427 
428     @Test
429     public void testKeywordWithinEphemeris()
430         throws URISyntaxException {
431         // simple test for OMM file, contains p/v entries and other mandatory
432         // data.
433         final String name = getClass().getResource("/ccsds/OEM-keyword-within-ephemeris.txt").toURI().getPath();
434         try {
435             new OEMParser().withMu(CelestialBodyFactory.getMars().getGM()).parse(name);
436             Assert.fail("an exception should have been thrown");
437         } catch (OrekitException oe) {
438             Assert.assertEquals(OrekitMessages.CCSDS_UNEXPECTED_KEYWORD, oe.getSpecifier());
439             Assert.assertEquals(24, ((Integer) oe.getParts()[0]).intValue());
440             Assert.assertTrue(((String) oe.getParts()[2]).startsWith("USER_DEFINED_TEST_KEY"));
441         }
442     }
443 
444     @Test
445     public void testKeywordWithinCovariance()
446         throws URISyntaxException {
447         // simple test for OMM file, contains p/v entries and other mandatory
448         // data.
449         final String name = getClass().getResource("/ccsds/OEM-keyword-within-covariance.txt").toURI().getPath();
450         try {
451             new OEMParser().withMu(CelestialBodyFactory.getMars().getGM()).parse(name);
452             Assert.fail("an exception should have been thrown");
453         } catch (OrekitException oe) {
454             Assert.assertEquals(OrekitMessages.CCSDS_UNEXPECTED_KEYWORD, oe.getSpecifier());
455             Assert.assertEquals(91, ((Integer) oe.getParts()[0]).intValue());
456             Assert.assertTrue(((String) oe.getParts()[2]).startsWith("USER_DEFINED_TEST_KEY"));
457         }
458     }
459 
460     /**
461      * Check the parser can parse several ITRF frames. Test case for #361.
462      */
463     @Test
464     public void testITRFFrames() {
465         // setup
466         Charset utf8 = StandardCharsets.UTF_8;
467         IERSConventions conventions = IERSConventions.IERS_2010;
468         boolean simpleEop = true;
469         OEMParser parser = new OEMParser()
470                 .withSimpleEOP(simpleEop)
471                 .withConventions(conventions);
472         // frames to check
473         List<Pair<String, Frame>> frames = new ArrayList<>();
474         frames.add(new Pair<>("ITRF-93",  FramesFactory.getITRF(ITRFVersion.ITRF_93,   conventions, simpleEop)));
475         frames.add(new Pair<>("ITRF-97",  FramesFactory.getITRF(ITRFVersion.ITRF_97,   conventions, simpleEop)));
476         frames.add(new Pair<>("ITRF2000", FramesFactory.getITRF(ITRFVersion.ITRF_2000, conventions, simpleEop)));
477         frames.add(new Pair<>("ITRF2005", FramesFactory.getITRF(ITRFVersion.ITRF_2005, conventions, simpleEop)));
478         frames.add(new Pair<>("ITRF2008", FramesFactory.getITRF(ITRFVersion.ITRF_2008, conventions, simpleEop)));
479         frames.add(new Pair<>("ITRF2014", FramesFactory.getITRF(ITRFVersion.ITRF_2014, conventions, simpleEop)));
480 
481         for (Pair<String, Frame> frame : frames) {
482             final String frameName = frame.getFirst();
483 
484             InputStream pre = OEMParserTest.class
485                     .getResourceAsStream("/ccsds/OEMExample7.txt.pre");
486             InputStream middle = new ByteArrayInputStream(
487                     ("REF_FRAME = " + frameName).getBytes(utf8));
488             InputStream post = OEMParserTest.class
489                     .getResourceAsStream("/ccsds/OEMExample7.txt.post");
490             InputStream input =
491                     new SequenceInputStream(pre, new SequenceInputStream(middle, post));
492 
493             // action
494             OEMFile actual = parser.parse(input);
495 
496             // verify
497             EphemeridesBlock actualBlock = actual.getEphemeridesBlocks().get(0);
498             Assert.assertEquals(actualBlock.getFrameString(), frameName);
499             // check expected frame
500             Frame actualFrame = actualBlock.getFrame();
501             Frame expectedFrame = frame.getSecond();
502             Assert.assertEquals(expectedFrame, actualFrame);
503             Assert.assertEquals(expectedFrame.getTransformProvider(),
504                                 actualFrame.getTransformProvider());
505         }
506     }
507 
508 }