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.opm;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.CharArrayWriter;
21  import java.io.IOException;
22  import java.net.URISyntaxException;
23  import java.nio.charset.StandardCharsets;
24  import java.util.ArrayList;
25  import java.util.HashMap;
26  
27  import org.hamcrest.MatcherAssert;
28  import org.hipparchus.geometry.euclidean.threed.Vector3D;
29  import org.hipparchus.linear.Array2DRowRealMatrix;
30  import org.hipparchus.util.FastMath;
31  import org.junit.Assert;
32  import org.junit.Before;
33  import org.junit.Test;
34  import org.orekit.OrekitMatchers;
35  import org.orekit.Utils;
36  import org.orekit.bodies.CelestialBody;
37  import org.orekit.bodies.CelestialBodyFactory;
38  import org.orekit.data.DataSource;
39  import org.orekit.errors.OrekitException;
40  import org.orekit.errors.OrekitIllegalArgumentException;
41  import org.orekit.errors.OrekitMessages;
42  import org.orekit.files.ccsds.definitions.CelestialBodyFrame;
43  import org.orekit.files.ccsds.ndm.ParsedUnitsBehavior;
44  import org.orekit.files.ccsds.ndm.ParserBuilder;
45  import org.orekit.files.ccsds.ndm.WriterBuilder;
46  import org.orekit.files.ccsds.ndm.odm.CartesianCovariance;
47  import org.orekit.files.ccsds.ndm.odm.KeplerianElements;
48  import org.orekit.files.ccsds.ndm.odm.SpacecraftParameters;
49  import org.orekit.files.ccsds.utils.generation.Generator;
50  import org.orekit.files.ccsds.utils.generation.KvnGenerator;
51  import org.orekit.frames.Frame;
52  import org.orekit.frames.FramesFactory;
53  import org.orekit.frames.LOFType;
54  import org.orekit.orbits.PositionAngle;
55  import org.orekit.time.AbsoluteDate;
56  import org.orekit.time.TimeScalesFactory;
57  import org.orekit.utils.Constants;
58  import org.orekit.utils.IERSConventions;
59  import org.orekit.utils.PVCoordinates;
60  
61  public class OpmParserTest {
62  
63      @Before
64      public void setUp() {
65          Utils.setDataRoot("regular-data");
66      }
67  
68      @Test
69      public void testParseOPM1KVN() {
70          // simple test for OPM file, contains p/v entries and other mandatory
71          // data.
72          final String ex = "/ccsds/odm/opm/OPMExample1.txt";
73          final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
74  
75          final OpmParser parser = new ParserBuilder().withMu(398600e9).withDefaultMass(1000.0).buildOpmParser();
76  
77          final Opm file = parser.parseMessage(source);
78          Assert.assertEquals(IERSConventions.IERS_2010, file.getConventions());
79  
80          // Check Header Block;
81          Assert.assertEquals(3.0, file.getHeader().getFormatVersion(), 1.0e-10);
82          Assert.assertEquals(new AbsoluteDate(1998, 11, 06, 9, 23, 57,
83                                               TimeScalesFactory.getUTC()),
84                              file.getHeader().getCreationDate());
85          Assert.assertEquals("JAXA", file.getHeader().getOriginator());
86  
87          // Check Metadata Block;
88  
89          Assert.assertEquals("GODZILLA 5", file.getMetadata().getObjectName());
90          Assert.assertEquals("1998-999A", file.getMetadata().getObjectID());
91          Assert.assertEquals(1998, file.getMetadata().getLaunchYear());
92          Assert.assertEquals(999, file.getMetadata().getLaunchNumber());
93          Assert.assertEquals("A", file.getMetadata().getLaunchPiece());
94          Assert.assertEquals("EARTH", file.getMetadata().getCenter().getName());
95          Assert.assertNotNull(file.getMetadata().getCenter().getBody());
96          Assert.assertEquals(CelestialBodyFactory.getEarth(), file.getMetadata().getCenter().getBody());
97          Assert.assertEquals(CelestialBodyFrame.ITRF2000, CelestialBodyFrame.map(file.getMetadata().getFrame()));
98          Assert.assertEquals("UTC", file.getMetadata().getTimeSystem().name());
99          Assert.assertNull(file.getData().getCovarianceBlock());
100 
101         // Check State Vector data Block;
102         Assert.assertEquals(new AbsoluteDate(1998, 12, 18, 14, 28, 15.1172,
103                                              TimeScalesFactory.getUTC()),
104                             file.getDate());
105         checkPVEntry(new PVCoordinates(new Vector3D(6503514.000, 1239647.000, -717490.000),
106                                        new Vector3D(-873.160, 8740.420, -4191.076)),
107                      file.getPVCoordinates());
108 
109         try {
110             file.generateCartesianOrbit();
111             Assert.fail("an exception should have been thrown");
112         } catch(OrekitIllegalArgumentException oiae) {
113             Assert.assertEquals(OrekitMessages.NON_PSEUDO_INERTIAL_FRAME, oiae.getSpecifier());
114             Assert.assertEquals("ITRF-2000/CIO/2010-based ITRF simple EOP", oiae.getParts()[0]);
115         }
116         try {
117             file.generateKeplerianOrbit();
118             Assert.fail("an exception should have been thrown");
119         } catch(OrekitIllegalArgumentException oiae) {
120             Assert.assertEquals(OrekitMessages.NON_PSEUDO_INERTIAL_FRAME, oiae.getSpecifier());
121             Assert.assertEquals("ITRF-2000/CIO/2010-based ITRF simple EOP", oiae.getParts()[0]);
122         }
123         try {
124             file.generateSpacecraftState();
125             Assert.fail("an exception should have been thrown");
126         } catch(OrekitIllegalArgumentException oiae) {
127             Assert.assertEquals(OrekitMessages.NON_PSEUDO_INERTIAL_FRAME, oiae.getSpecifier());
128             Assert.assertEquals("ITRF-2000/CIO/2010-based ITRF simple EOP", oiae.getParts()[0]);
129         }
130 
131     }
132 
133     @Test
134     public void testParseOPM2() {
135         // simple test for OPM file, contains all mandatory information plus
136         // Keplerian elements, Spacecraft parameters and 2 maneuvers.
137         final String ex = "/ccsds/odm/opm/OPMExample2.txt";
138         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
139 
140         final OpmParser parser = new ParserBuilder().withMu(Constants.EIGEN5C_EARTH_MU).withDefaultMass(1000.0).buildOpmParser();
141         final Opm file = parser.parseMessage(source);
142         Assert.assertEquals(IERSConventions.IERS_2010, file.getConventions());
143 
144         // Check Header Block;
145         Assert.assertEquals(3.0, file.getHeader().getFormatVersion(), 1.0e-10);
146         ArrayList<String> headerComment = new ArrayList<String>();
147         headerComment.add("Generated by GSOC, R. Kiehling");
148         headerComment.add("Current intermediate orbit IO2 and maneuver planning data");
149         Assert.assertEquals(headerComment, file.getHeader().getComments());
150         Assert.assertEquals(new AbsoluteDate(2000, 06, 03, 05, 33, 00,
151                                              TimeScalesFactory.getUTC()),
152                             file.getHeader().getCreationDate());
153         Assert.assertEquals(file.getHeader().getOriginator(), "GSOC");
154 
155         // Check Metadata Block;
156 
157         Assert.assertEquals("EUTELSAT W4", file.getMetadata().getObjectName());
158         Assert.assertEquals("2000-028A", file.getMetadata().getObjectID());
159         Assert.assertEquals("EARTH", file.getMetadata().getCenter().getName());
160         Assert.assertNotNull(file.getMetadata().getCenter().getBody());
161         Assert.assertEquals(CelestialBodyFactory.getEarth(), file.getMetadata().getCenter().getBody());
162         Assert.assertEquals(FramesFactory.getTOD(IERSConventions.IERS_2010, true),
163                             file.getMetadata().getFrame());
164         Assert.assertEquals("UTC", file.getMetadata().getTimeSystem().name());
165         Assert.assertEquals(0, file.getMetadata().getComments().size());
166 
167         // Check Data State Vector block
168         ArrayList<String> epochComment = new ArrayList<String>();
169         epochComment.add("State Vector");
170         Assert.assertEquals(epochComment, file.getData().getStateVectorBlock().getComments());
171         Assert.assertEquals(new AbsoluteDate(2006, 06, 03, 00, 00, 00,
172                                              TimeScalesFactory.getUTC()),
173                             file.getDate());
174         checkPVEntry(new PVCoordinates(new Vector3D(6655994.2, -40218575.1, -82917.7),
175                                        new Vector3D(3115.48208, 470.42605, -1.01495)),
176                      file.getPVCoordinates());
177 
178         // Check Data Keplerian Elements block
179         KeplerianElements keplerianElements = file.getData().getKeplerianElementsBlock();
180         Assert.assertNotNull(keplerianElements);
181         ArrayList<String> keplerianElementsComment = new ArrayList<String>();
182         keplerianElementsComment.add("Keplerian elements");
183         Assert.assertEquals(keplerianElementsComment, keplerianElements.getComments());
184         Assert.assertEquals(41399512.3, keplerianElements.getA(), 1e-6);
185         Assert.assertEquals(0.020842611, keplerianElements.getE(), 1e-10);
186         Assert.assertEquals(FastMath.toRadians(0.117746), keplerianElements.getI(), 1e-10);
187         Assert.assertEquals(FastMath.toRadians(17.604721), keplerianElements.getRaan(), 1e-10);
188         Assert.assertEquals(FastMath.toRadians(218.242943), keplerianElements.getPa(), 1e-10);
189         Assert.assertEquals(PositionAngle.TRUE, keplerianElements.getAnomalyType());
190         Assert.assertEquals(FastMath.toRadians(41.922339), keplerianElements.getAnomaly(), 1e-10);
191         Assert.assertEquals(398600.4415 * 1e9, keplerianElements.getMu(), 1e-10);
192 
193         // Check Data Spacecraft block
194         SpacecraftParameters spacecraftParameters = file.getData().getSpacecraftParametersBlock();
195         Assert.assertNotNull(spacecraftParameters);
196         ArrayList<String> spacecraftComment = new ArrayList<String>();
197         spacecraftComment.add("Spacecraft parameters");
198         Assert.assertEquals(spacecraftComment, spacecraftParameters.getComments());
199         Assert.assertEquals(1913.000, spacecraftParameters.getMass(), 1e-10);
200         Assert.assertEquals(10.000, spacecraftParameters.getSolarRadArea(), 1e-10);
201         Assert.assertEquals(1.300, spacecraftParameters.getSolarRadCoeff(), 1e-10);
202         Assert.assertEquals(10.000, spacecraftParameters.getDragArea(), 1e-10);
203         Assert.assertEquals(2.300, spacecraftParameters.getDragCoeff(), 1e-10);
204 
205         // Check covariance block
206         Assert.assertNull(file.getData().getCovarianceBlock());
207 
208         // Check Data Maneuvers block
209         Assert.assertTrue(file.getData().hasManeuvers());
210         Assert.assertEquals(2, file.getNbManeuvers());
211         ArrayList<String> stateManeuverComment0 = new ArrayList<String>();
212         stateManeuverComment0.add("2 planned maneuvers");
213         stateManeuverComment0.add("First maneuver: AMF-3");
214         stateManeuverComment0.add("Non-impulsive, thrust direction fixed in inertial frame");
215         Assert.assertEquals(stateManeuverComment0, file.getManeuver(0).getComments());
216         Assert.assertEquals(new AbsoluteDate(2000, 06, 03, 9, 00, 34.1,
217                                              TimeScalesFactory.getUTC()),
218                             file.getManeuvers().get(0).getEpochIgnition());
219         Assert.assertEquals(132.6, file.getManeuver(0).getDuration(), 1e-10);
220         Assert.assertEquals(-18.418, file.getManeuver(0).getDeltaMass(), 1e-10);
221         Assert.assertNull(file.getManeuver(0).getReferenceFrame().asOrbitRelativeFrame());
222         Assert.assertEquals(FramesFactory.getEME2000(), file.getManeuver(0).getReferenceFrame().asFrame());
223         Assert.assertEquals(0.0,
224                             new Vector3D(-23.25700, 16.83160, -8.93444).distance(file.getManeuver(0).getDV()),
225                             1.0e-10);
226 
227         ArrayList<String> stateManeuverComment1 = new ArrayList<String>();
228         stateManeuverComment1.add("Second maneuver: first station acquisition maneuver");
229         stateManeuverComment1.add("impulsive, thrust direction fixed in RTN frame");
230         Assert.assertEquals(stateManeuverComment1, file.getManeuver(1).getComments());
231         Assert.assertEquals(new AbsoluteDate(2000, 06, 05, 18, 59, 21,
232                                              TimeScalesFactory.getUTC()),
233                             file.getManeuvers().get(1).getEpochIgnition());
234         Assert.assertEquals(0.0, file.getManeuver(1).getDuration(), 1e-10);
235         Assert.assertEquals(-1.469, file.getManeuver(1).getDeltaMass(), 1e-10);
236         Assert.assertEquals(LOFType.QSW, file.getManeuver(1).getReferenceFrame().asOrbitRelativeFrame().getLofType());
237         Assert.assertNull(file.getManeuver(1).getReferenceFrame().asFrame());
238         Assert.assertNull(file.getManeuver(1).getReferenceFrame().asCelestialBodyFrame());
239         Assert.assertEquals(0.0,
240                             new Vector3D(1.015, -1.873, 0.0).distance(file.getManeuver(1).getDV()),
241                             1.0e-10);
242 
243         Assert.assertNull(file.getData().getUserDefinedBlock());
244         Assert.assertNotNull(file.generateCartesianOrbit());
245         Assert.assertNotNull(file.generateKeplerianOrbit());
246         Assert.assertNotNull(file.generateSpacecraftState());
247 
248     }
249 
250     @Test
251     public void testParseOPM5() {
252         // simple test for OPM file, contains all mandatory information plus
253         // Keplerian elements, Spacecraft parameters and 3 maneuvers.
254         final String ex = "/ccsds/odm/opm/OPMExample5.txt";
255         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
256 
257         final OpmParser parser = new ParserBuilder().withMu(Constants.EIGEN5C_EARTH_MU).withDefaultMass(1000.0).buildOpmParser();
258         final Opm file = parser.parseMessage(source);
259 
260         // Check Header Block;
261         Assert.assertEquals(2.0, file.getHeader().getFormatVersion(), 1.0e-10);
262         ArrayList<String> headerComment = new ArrayList<String>();
263         headerComment.add("Generated by GSOC, R. Kiehling");
264         headerComment.add("Current intermediate orbit IO2 and maneuver planning data");
265         Assert.assertEquals(headerComment, file.getHeader().getComments());
266         Assert.assertEquals(new AbsoluteDate(2000, 06, 03, 05, 33, 00,
267                                              TimeScalesFactory.getUTC()),
268                             file.getHeader().getCreationDate());
269         Assert.assertEquals(file.getHeader().getOriginator(), "GSOC");
270 
271         // Check Metadata Block;
272         Assert.assertEquals("EUTELSAT W4", file.getMetadata().getObjectName());
273         Assert.assertEquals("2000-028A", file.getMetadata().getObjectID());
274         Assert.assertEquals("EARTH", file.getMetadata().getCenter().getName());
275         Assert.assertNotNull(file.getMetadata().getCenter().getBody());
276         Assert.assertEquals(CelestialBodyFactory.getEarth(), file.getMetadata().getCenter().getBody());
277         Assert.assertEquals(FramesFactory.getGCRF(), file.getMetadata().getFrame());
278         Assert.assertEquals("GPS", file.getMetadata().getTimeSystem().name());
279         Assert.assertEquals(0, file.getMetadata().getComments().size());
280 
281         // Check Data State Vector block
282         ArrayList<String> stateVectorComment = new ArrayList<String>();
283         stateVectorComment.add("State Vector");
284         Assert.assertEquals(stateVectorComment, file.getData().getStateVectorBlock().getComments());
285         Assert.assertEquals(new AbsoluteDate(2006, 06, 03, 00, 00, 00,
286                                              TimeScalesFactory.getGPS()),
287                             file.getData().getStateVectorBlock().getEpoch());
288         checkPVEntry(new PVCoordinates(new Vector3D(6655994.2, -40218575.1, -82917.7),
289                                        new Vector3D(3115.48208, 470.42605, -1.01495)),
290                      file.getPVCoordinates());
291 
292         // Check Data Keplerian Elements block
293         KeplerianElements keplerianElements = file.getData().getKeplerianElementsBlock();
294         Assert.assertNotNull(keplerianElements);
295         ArrayList<String> keplerianElementsComment = new ArrayList<String>();
296         keplerianElementsComment.add("Keplerian elements");
297         Assert.assertEquals(keplerianElementsComment, keplerianElements.getComments());
298         Assert.assertEquals(41399512.3, keplerianElements.getA(), 1e-6);
299         Assert.assertEquals(0.020842611, keplerianElements.getE(), 1e-10);
300         Assert.assertEquals(FastMath.toRadians(0.117746), keplerianElements.getI(), 1e-10);
301         Assert.assertEquals(FastMath.toRadians(17.604721), keplerianElements.getRaan(), 1e-10);
302         Assert.assertEquals(FastMath.toRadians(218.242943), keplerianElements.getPa(), 1e-10);
303         Assert.assertEquals(PositionAngle.TRUE, keplerianElements.getAnomalyType());
304         Assert.assertEquals(FastMath.toRadians(41.922339), keplerianElements.getAnomaly(), 1e-10);
305         Assert.assertEquals(398600.4415 * 1e9, keplerianElements.getMu(), 1e-10);
306 
307         // Check Data Spacecraft block
308         SpacecraftParameters spacecraftParameters = file.getData().getSpacecraftParametersBlock();
309         ArrayList<String> spacecraftComment = new ArrayList<String>();
310         spacecraftComment.add("Spacecraft parameters");
311         Assert.assertEquals(spacecraftComment, spacecraftParameters.getComments());
312         Assert.assertEquals(1913.000, spacecraftParameters.getMass(), 1e-10);
313         Assert.assertEquals(10.000, spacecraftParameters.getSolarRadArea(), 1e-10);
314         Assert.assertEquals(1.300, spacecraftParameters.getSolarRadCoeff(), 1e-10);
315         Assert.assertEquals(10.000, spacecraftParameters.getDragArea(), 1e-10);
316         Assert.assertEquals(2.300, spacecraftParameters.getDragCoeff(), 1e-10);
317 
318         // Check covariance block
319         Assert.assertNull(file.getData().getCovarianceBlock());
320 
321         // Check Data Maneuvers block
322         Assert.assertTrue(file.getData().hasManeuvers());
323         Assert.assertEquals(3, file.getNbManeuvers());
324         ArrayList<String> stateManeuverComment0 = new ArrayList<String>();
325         stateManeuverComment0.add("2 planned maneuvers");
326         stateManeuverComment0.add("First maneuver: AMF-3");
327         stateManeuverComment0.add("Non-impulsive, thrust direction fixed in inertial frame");
328         Assert.assertEquals(stateManeuverComment0, file.getManeuver(0).getComments());
329         Assert.assertEquals(new AbsoluteDate(2000, 06, 03, 9, 00, 34.1,
330                                              TimeScalesFactory.getGPS()),
331                             file.getManeuvers().get(0).getEpochIgnition());
332         Assert.assertEquals(132.6, file.getManeuver(0).getDuration(), 1e-10);
333         Assert.assertEquals(-18.418, file.getManeuver(0).getDeltaMass(), 1e-10);
334         Assert.assertNull(file.getManeuver(0).getReferenceFrame().asOrbitRelativeFrame());
335         Assert.assertEquals(FramesFactory.getEME2000(), file.getManeuver(0).getReferenceFrame().asFrame());
336         Assert.assertEquals(0.0,
337                             new Vector3D(-23.25700, 16.83160, -8.93444).distance(file.getManeuver(0).getDV()),
338                             1.0e-10);
339 
340         ArrayList<String> stateManeuverComment1 = new ArrayList<String>();
341         stateManeuverComment1.add("Second maneuver: first station acquisition maneuver");
342         stateManeuverComment1.add("impulsive, thrust direction fixed in RTN frame");
343         Assert.assertEquals(stateManeuverComment1, file.getManeuver(1).getComments());
344         Assert.assertEquals(new AbsoluteDate(2000, 06, 05, 18, 59, 21,
345                                              TimeScalesFactory.getGPS()),
346                             file.getManeuvers().get(1).getEpochIgnition());
347         Assert.assertEquals(0.0, file.getManeuver(1).getDuration(), 1e-10);
348         Assert.assertEquals(-1.469, file.getManeuver(1).getDeltaMass(), 1e-10);
349         Assert.assertEquals(LOFType.QSW, file.getManeuver(1).getReferenceFrame().asOrbitRelativeFrame().getLofType());
350         Assert.assertNull(file.getManeuver(1).getReferenceFrame().asFrame());
351         Assert.assertNull(file.getManeuver(1).getReferenceFrame().asCelestialBodyFrame());
352         Assert.assertEquals(0.0,
353                             new Vector3D(1.015, -1.873, 0.0).distance(file.getManeuver(1).getDV()),
354                             1.0e-10);
355 
356         Assert.assertTrue(file.getManeuver(2).getComments().isEmpty());
357         Assert.assertEquals(new AbsoluteDate(2000, 06, 05, 18, 59, 51,
358                                              TimeScalesFactory.getGPS()),
359                             file.getManeuvers().get(2).getEpochIgnition());
360         Assert.assertEquals(0.0, file.getManeuver(2).getDuration(), 1e-10);
361         Assert.assertEquals(-1.469, file.getManeuver(2).getDeltaMass(), 1e-10);
362         Assert.assertEquals(LOFType.QSW, file.getManeuver(2).getReferenceFrame().asOrbitRelativeFrame().getLofType());
363         Assert.assertNull(file.getManeuver(2).getReferenceFrame().asFrame());
364         Assert.assertNull(file.getManeuver(2).getReferenceFrame().asCelestialBodyFrame());
365         Assert.assertEquals(0.0,
366                             new Vector3D(1.015, -1.873, 0.0).distance(file.getManeuver(2).getDV()),
367                             1.0e-10);
368 
369         file.generateCartesianOrbit();
370         file.generateKeplerianOrbit();
371         file.generateSpacecraftState();
372 
373     }
374 
375     @Test
376     public void testParseOPM3KVN() throws URISyntaxException {
377         // simple test for OPM file, contains all mandatory information plus
378         // Spacecraft parameters and the position/velocity Covariance Matrix.
379         final String name = "/ccsds/odm/opm/OPMExample3.txt";
380         final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
381         OpmParser parser = new ParserBuilder().withDefaultMass(1000.0).buildOpmParser();
382         final Opm file = parser.parseMessage(source);
383         Assert.assertEquals("OPM 201113719185", file.getHeader().getMessageId());
384         Assert.assertEquals(CelestialBodyFrame.TOD, file.getMetadata().getReferenceFrame().asCelestialBodyFrame());
385         Assert.assertEquals(new AbsoluteDate(1998, 12, 18, 14, 28, 15.1172,
386                                              TimeScalesFactory.getUTC()),
387                             file.getMetadata().getFrameEpoch());
388         Assert.assertEquals(1, file.getMetadata().getComments().size());
389         Assert.assertEquals("GEOCENTRIC, CARTESIAN, EARTH FIXED", file.getMetadata().getComments().get(0));
390         Assert.assertEquals(15951238.3495, file.generateKeplerianOrbit().getA(), 0.001);
391         Assert.assertEquals(0.5914452565, file.generateKeplerianOrbit().getE(), 1.0e-10);
392         // Check Data Covariance matrix Block
393         CartesianCovariance covariance = file.getData().getCovarianceBlock();
394         Assert.assertNotNull(covariance);
395         Assert.assertSame(file.getMetadata().getReferenceFrame(), covariance.getReferenceFrame());
396 
397         Array2DRowRealMatrix covMatrix = new Array2DRowRealMatrix(6, 6);
398         double[] column1 = {
399             333.1349476038534, 461.8927349220216,
400             -307.0007847730449, -0.3349365033922630,
401             -0.2211832501084875, -0.3041346050686871
402         };
403         double[] column2 = {
404             461.8927349220216, 678.2421679971363,
405             -422.1234189514228, -0.4686084221046758,
406             -0.2864186892102733, -0.4989496988610662
407         };
408         double[] column3 = {
409             -307.0007847730449, -422.1234189514228,
410             323.1931992380369, 0.2484949578400095,
411             0.1798098699846038, 0.3540310904497689
412         };
413         double[] column4 = {
414             -0.3349365033922630, -0.4686084221046758,
415             0.2484949578400095, 0.0004296022805587290,
416             0.0002608899201686016, 0.0001869263192954590
417         };
418         double[] column5 = {
419             -0.2211832501084875, -0.2864186892102733,
420             0.1798098699846038, 0.0002608899201686016,
421             0.0001767514756338532, 0.0001008862586240695
422         };
423         double[] column6 = {
424             -0.3041346050686871, -0.4989496988610662,
425             0.3540310904497689, 0.0001869263192954590,
426             0.0001008862586240695, 0.0006224444338635500
427         };
428         covMatrix.setColumn(0, column1);
429         covMatrix.setColumn(1, column2);
430         covMatrix.setColumn(2, column3);
431         covMatrix.setColumn(3, column4);
432         covMatrix.setColumn(4, column5);
433         covMatrix.setColumn(5, column6);
434         for (int i = 0; i < 6; i++) {
435             for (int j = 0; j < 6; j++) {
436                 Assert.assertEquals(covMatrix.getEntry(i, j),
437                                     covariance.getCovarianceMatrix().getEntry(i, j),
438                                     1e-15);
439             }
440         }
441 
442     }
443 
444     @Test
445     public void testParseOPM3XML() throws URISyntaxException {
446         // simple test for OPM file, contains all mandatory information plus
447         // Spacecraft parameters and the position/velocity Covariance Matrix.
448         // the content of the file is slightly different from the KVN file in the covariance section
449         final String name = "/ccsds/odm/opm/OPMExample3.xml";
450         final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
451         OpmParser parser = new ParserBuilder().withDefaultMass(1000.0).buildOpmParser();
452         validateOPM3XML(parser.parseMessage(source));
453     }
454 
455     @Test
456     public void testWriteOPM3() throws URISyntaxException, IOException {
457         // simple test for OPM file, contains all mandatory information plus
458         // Spacecraft parameters and the position/velocity Covariance Matrix.
459         // the content of the file is slightly different from the KVN file in the covariance section
460         final String name = "/ccsds/odm/opm/OPMExample3.xml";
461         final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
462         OpmParser parser = new ParserBuilder().withDefaultMass(1000.0).buildOpmParser();
463         final Opm original = parser.parseMessage(source);
464 
465         // write the parsed file back to a characters array
466         final CharArrayWriter caw = new CharArrayWriter();
467         final Generator generator = new KvnGenerator(caw, OpmWriter.KVN_PADDING_WIDTH, "dummy", 60);
468         new WriterBuilder().buildOpmWriter().writeMessage(generator, original);
469 
470         // reparse the written file
471         final byte[]     bytes   = caw.toString().getBytes(StandardCharsets.UTF_8);
472         final DataSource source2 = new DataSource(name, () -> new ByteArrayInputStream(bytes));
473         final Opm    rebuilt = new ParserBuilder().buildOpmParser().parseMessage(source2);
474         validateOPM3XML(rebuilt);
475 
476     }
477 
478     private void validateOPM3XML(final Opm file) {
479         Assert.assertEquals("OPM 201113719185", file.getHeader().getMessageId());
480         Assert.assertEquals(CelestialBodyFrame.TOD, file.getMetadata().getReferenceFrame().asCelestialBodyFrame());
481         Assert.assertEquals(new AbsoluteDate(1998, 12, 18, 14, 28, 15.1172,
482                                              TimeScalesFactory.getUTC()),
483                             file.getMetadata().getFrameEpoch());
484         Assert.assertEquals(1, file.getMetadata().getComments().size());
485         Assert.assertEquals("GEOCENTRIC, CARTESIAN, EARTH FIXED", file.getMetadata().getComments().get(0));
486         Assert.assertEquals(15951238.3495, file.generateKeplerianOrbit().getA(), 0.001);
487         Assert.assertEquals(0.5914452565, file.generateKeplerianOrbit().getE(), 1.0e-10);
488         // Check Data Covariance matrix Block
489         CartesianCovariance covariance = file.getData().getCovarianceBlock();
490         Assert.assertNotNull(covariance);
491         Assert.assertEquals(CelestialBodyFrame.ITRF1997, covariance.getReferenceFrame().asCelestialBodyFrame());
492 
493         Array2DRowRealMatrix covMatrix = new Array2DRowRealMatrix(6, 6);
494         double[] column1 = {
495             316000.0, 722000.0, 202000.0, 912000.0, 562000.0, 245000.0
496         };
497         double[] column2 = {
498             722000.0, 518000.0, 715000.0, 306000.0, 899000.0, 965000.0
499         };
500         double[] column3 = {
501             202000.0, 715000.0, 002000.0, 276000.0, 022000.0, 950000.0
502         };
503         double[] column4 = {
504             912000.0, 306000.0, 276000.0, 797000.0, 079000.0, 435000.0
505         };
506         double[] column5 = {
507             562000.0, 899000.0, 022000.0, 079000.0, 415000.0, 621000.0
508         };
509         double[] column6 = {
510             245000.0, 965000.0, 950000.0, 435000.0, 621000.0, 991000.0
511         };
512         covMatrix.setColumn(0, column1);
513         covMatrix.setColumn(1, column2);
514         covMatrix.setColumn(2, column3);
515         covMatrix.setColumn(3, column4);
516         covMatrix.setColumn(4, column5);
517         covMatrix.setColumn(5, column6);
518         for (int i = 0; i < 6; i++) {
519             for (int j = 0; j < 6; j++) {
520                 Assert.assertEquals(covMatrix.getEntry(i, j),
521                                     covariance.getCovarianceMatrix().getEntry(i, j),
522                                     1e-15);
523             }
524         }
525 
526     }
527 
528     @Test
529     public void testParseOPM3NoDesignator() throws URISyntaxException {
530         final String ex = "/ccsds/odm/opm/OPM-no-designator.txt";
531         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
532         OpmParser parser = new ParserBuilder().withMu(Constants.EIGEN5C_EARTH_MU).withDefaultMass(1000.0).buildOpmParser();
533         final Opm file = parser.parseMessage(source);
534         Assert.assertEquals(new AbsoluteDate(1998, 12, 18, 14, 28, 15.1172,
535                                                  TimeScalesFactory.getGMST(IERSConventions.IERS_2010, false)),
536                             file.getMetadata().getFrameEpoch());
537         try {
538             file.getMetadata().getLaunchYear();
539             Assert.fail("an exception should have been thrown");
540         } catch (OrekitException oe) {
541             Assert.assertEquals(OrekitMessages.NOT_VALID_INTERNATIONAL_DESIGNATOR, oe.getSpecifier());
542             Assert.assertEquals("REDACTED FOR TEST PURPOSES", (String) oe.getParts()[0]);
543         }
544         try {
545             file.getMetadata().getLaunchNumber();
546             Assert.fail("an exception should have been thrown");
547         } catch (OrekitException oe) {
548             Assert.assertEquals(OrekitMessages.NOT_VALID_INTERNATIONAL_DESIGNATOR, oe.getSpecifier());
549             Assert.assertEquals("REDACTED FOR TEST PURPOSES", (String) oe.getParts()[0]);
550         }
551         try {
552             file.getMetadata().getLaunchPiece();
553             Assert.fail("an exception should have been thrown");
554         } catch (OrekitException oe) {
555             Assert.assertEquals(OrekitMessages.NOT_VALID_INTERNATIONAL_DESIGNATOR, oe.getSpecifier());
556             Assert.assertEquals("REDACTED FOR TEST PURPOSES", (String) oe.getParts()[0]);
557         }
558     }
559 
560     @Test
561     public void testParseOPM4() {
562         //
563         final String ex = "/ccsds/odm/opm/OPMExample4.txt";
564         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
565         final Opm file = new ParserBuilder().
566                              withMu(Constants.EIGEN5C_EARTH_MU).
567                              withSimpleEOP(false).
568                              withDefaultMass(1000.0).
569                              buildOpmParser().
570                              parseMessage(source);
571         Assert.assertEquals("TOD/2010 accurate EOP", file.getMetadata().getFrame().toString());
572         Assert.assertEquals("2000-028A", file.getMetadata().getObjectID());
573         Assert.assertEquals(new AbsoluteDate(2006, 6, 3, TimeScalesFactory.getUTC()), file.getDate());
574         Assert.assertEquals(  6655994.2, file.getPVCoordinates().getPosition().getX(), 1.0e-10);
575         Assert.assertEquals(-40218575.1, file.getPVCoordinates().getPosition().getY(), 1.0e-10);
576         Assert.assertEquals(   -82917.7, file.getPVCoordinates().getPosition().getZ(), 1.0e-10);
577         Assert.assertEquals( 3115.48208, file.getPVCoordinates().getVelocity().getX(), 1.0e-10);
578         Assert.assertEquals( 0470.42605, file.getPVCoordinates().getVelocity().getY(), 1.0e-10);
579         Assert.assertEquals(-0001.01495, file.getPVCoordinates().getVelocity().getZ(), 1.0e-10);
580     }
581 
582     @Test
583     public void testParseOPM6() throws URISyntaxException {
584         // simple test for OPM file, contains all mandatory information plus
585         // Spacecraft parameters and the position/velocity Covariance Matrix.
586         final String name = "/ccsds/odm/opm/OPMExample6.txt";
587         final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
588         OpmParser parser = new ParserBuilder().buildOpmParser();
589         validate6(parser.parseMessage(source));
590     }
591 
592     @Test
593     public void testParseOPM7() {
594         final String ex = "/ccsds/odm/opm/OPMExample7.txt";
595         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
596         final Opm file = new ParserBuilder().buildOpmParser().parseMessage(source);
597         Frame frame = file.getMetadata().getFrame();
598         Assert.assertSame(CelestialBodyFactory.getMars().getInertiallyOrientedFrame(), frame);
599     }
600 
601     @Test
602     public void testParseOPM8() {
603         final String ex = "/ccsds/odm/opm/OPMExample8.txt";
604         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
605         final Opm file = new ParserBuilder().buildOpmParser().parseMessage(source);
606         Frame frame = file.getMetadata().getFrame();
607         Assert.assertSame(CelestialBodyFactory.getSolarSystemBarycenter().getInertiallyOrientedFrame(), frame);
608     }
609 
610     @Test
611     public void testParseNonStandardUnits() throws URISyntaxException {
612         // this file is similar to OPMExample6.txt but uses non-standard units
613         // it is therefore NOT a regular CCSDS OPM, but is correctly parsed by Orekit
614         final String name = "/ccsds/odm/opm/OPM-non-standard-units.txt";
615         final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
616         OpmParser parser = new ParserBuilder().
617                            withParsedUnitsBehavior(ParsedUnitsBehavior.CONVERT_COMPATIBLE).
618                            buildOpmParser();
619         validate6(parser.parseMessage(source));
620     }
621 
622     @Test
623     public void testRefuseNonStandardUnits() throws URISyntaxException {
624         // this file is similar to OPMExample6.txt but uses non-standard units
625         // it is therefore NOT a regular CCSDS OPM, but is correctly parsed by Orekit
626         final String name = "/ccsds/odm/opm/OPM-non-standard-units.txt";
627         final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
628         try {
629             new ParserBuilder().
630             withParsedUnitsBehavior(ParsedUnitsBehavior.STRICT_COMPLIANCE).
631             buildOpmParser().
632             parseMessage(source);
633             Assert.fail("an exception should have been thrown");
634         } catch (OrekitException oe) {
635             Assert.assertEquals(OrekitMessages.INCOMPATIBLE_UNITS, oe.getSpecifier());
636             Assert.assertEquals("m",  oe.getParts()[0]);
637             Assert.assertEquals("km", oe.getParts()[1]);
638         }
639     }
640 
641     private void validate6(final Opm file) {
642         Assert.assertEquals(new AbsoluteDate(1998, 12, 18, 14, 28, 15.1172,
643                                              TimeScalesFactory.getGMST(IERSConventions.IERS_2010, false)),
644                             file.getMetadata().getFrameEpoch());
645         Assert.assertEquals(1, file.getMetadata().getComments().size());
646         Assert.assertEquals("GEOCENTRIC, CARTESIAN, EARTH FIXED", file.getMetadata().getComments().get(0));
647         Assert.assertEquals("OREKIT-4D00FC96-AC64-11E9-BF71-001FD054093C", file.getHeader().getMessageId());
648 
649         Assert.assertEquals(15951238.3495, file.generateKeplerianOrbit().getA(), 0.001);
650         Assert.assertEquals(0.5914452565, file.generateKeplerianOrbit().getE(), 1.0e-10);
651         // Check Data Covariance matrix Block
652         CartesianCovariance covariance = file.getData().getCovarianceBlock();
653         Assert.assertNotNull(covariance);
654         ArrayList<String> dataCovMatrixComment = new ArrayList<String>();
655         dataCovMatrixComment.add("covariance comment 1");
656         dataCovMatrixComment.add("covariance comment 2");
657         Assert.assertEquals(dataCovMatrixComment, covariance.getComments());
658         Assert.assertEquals(FramesFactory.getTEME(), covariance.getReferenceFrame().asFrame());
659 
660         Array2DRowRealMatrix covMatrix = new Array2DRowRealMatrix(6, 6);
661         double[] column1 = {
662             333.1349476038534, 461.8927349220216,
663             -307.0007847730449, -0.3349365033922630,
664             -0.2211832501084875, -0.3041346050686871
665         };
666         double[] column2 = {
667             461.8927349220216, 678.2421679971363,
668             -422.1234189514228, -0.4686084221046758,
669             -0.2864186892102733, -0.4989496988610662
670         };
671         double[] column3 = {
672             -307.0007847730449, -422.1234189514228,
673             323.1931992380369, 0.2484949578400095,
674             0.1798098699846038, 0.3540310904497689
675         };
676         double[] column4 = {
677             -0.3349365033922630, -0.4686084221046758,
678             0.2484949578400095, 0.0004296022805587290,
679             0.0002608899201686016, 0.0001869263192954590
680         };
681         double[] column5 = {
682             -0.2211832501084875, -0.2864186892102733,
683             0.1798098699846038, 0.0002608899201686016,
684             0.0001767514756338532, 0.0001008862586240695
685         };
686         double[] column6 = {
687             -0.3041346050686871, -0.4989496988610662,
688             0.3540310904497689, 0.0001869263192954590,
689             0.0001008862586240695, 0.0006224444338635500
690         };
691         covMatrix.setColumn(0, column1);
692         covMatrix.setColumn(1, column2);
693         covMatrix.setColumn(2, column3);
694         covMatrix.setColumn(3, column4);
695         covMatrix.setColumn(4, column5);
696         covMatrix.setColumn(5, column6);
697         for (int i = 0; i < 6; i++) {
698             for (int j = 0; j < 6; j++) {
699                 Assert.assertEquals(covMatrix.getEntry(i, j),
700                                     file.getData().getCovarianceBlock().getCovarianceMatrix().getEntry(i, j), 1e-15);
701             }
702         }
703 
704         // Check User defined Parameters Block
705         HashMap<String, String> userDefinedParameters = new HashMap<String, String>();
706         userDefinedParameters.put("EARTH_MODEL", "WGS-84");
707         Assert.assertEquals(userDefinedParameters, file.getData().getUserDefinedBlock().getParameters());
708 
709     }
710 
711     @Test
712     public void testCentersAndTimeScales() {
713 
714         final OpmParser parser = new ParserBuilder().withMu(Constants.EIGEN5C_EARTH_MU).withDefaultMass(1000.0).buildOpmParser();
715 
716         final String name1 = "/ccsds/odm/opm/OPM-dummy-solar-system-barycenter.txt";
717         final DataSource source1 = new DataSource(name1, () -> getClass().getResourceAsStream(name1));
718         Opm file1 = parser.parseMessage(source1);
719         Assert.assertEquals("TDB", file1.getMetadata().getTimeSystem().name());
720         Assert.assertEquals("solar system barycenter", file1.getMetadata().getCenter().getBody().getName());
721 
722         final String name2 = "/ccsds/odm/opm/OPM-dummy-ssb.txt";
723         final DataSource source2 = new DataSource(name2, () -> getClass().getResourceAsStream(name2));
724         Opm file2 = parser.parseMessage(source2);
725         Assert.assertEquals("TCB", file2.getMetadata().getTimeSystem().name());
726         Assert.assertEquals("solar system barycenter", file2.getMetadata().getCenter().getBody().getName());
727 
728         final String name3 = "/ccsds/odm/opm/OPM-dummy-earth-barycenter.txt";
729         final DataSource source3 = new DataSource(name3, () -> getClass().getResourceAsStream(name3));
730         Opm file3 = parser.parseMessage(source3);
731         Assert.assertEquals("TDB", file3.getMetadata().getTimeSystem().name());
732         Assert.assertEquals("Earth-Moon barycenter", file3.getMetadata().getCenter().getBody().getName());
733 
734         final String name4 = "/ccsds/odm/opm/OPM-dummy-earth-dash-moon-barycenter.txt";
735         final DataSource source4 = new DataSource(name4, () -> getClass().getResourceAsStream(name4));
736         Opm file4 = parser.parseMessage(source4);
737         Assert.assertEquals("TDB", file4.getMetadata().getTimeSystem().name());
738         Assert.assertEquals("Earth-Moon barycenter", file4.getMetadata().getCenter().getBody().getName());
739 
740         final String name5 = "/ccsds/odm/opm/OPM-dummy-earth-moon-barycenter.txt";
741         final DataSource source5 = new DataSource(name5, () -> getClass().getResourceAsStream(name5));
742         Opm file5 = parser.parseMessage(source5);
743         Assert.assertEquals("UT1", file5.getMetadata().getTimeSystem().name());
744         Assert.assertEquals("Earth-Moon barycenter", file5.getMetadata().getCenter().getBody().getName());
745 
746         final String name6 = "/ccsds/odm/opm/OPM-dummy-emb.txt";
747         final DataSource source6 = new DataSource(name6, () -> getClass().getResourceAsStream(name6));
748         Opm file6 = parser.parseMessage(source6);
749         Assert.assertEquals("TT", file6.getMetadata().getTimeSystem().name());
750         Assert.assertEquals("Earth-Moon barycenter", file6.getMetadata().getCenter().getBody().getName());
751 
752     }
753 
754     @Test
755     public void testOrbitFileInterface() {
756         final String ex = "/ccsds/odm/opm/OPMExample4.txt";
757         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
758 
759         final OpmParser parser = new ParserBuilder().withMu(Constants.EIGEN5C_EARTH_MU).withDefaultMass(1000.0).buildOpmParser();
760 
761         final Opm file = parser.parseMessage(source);
762 
763         final String satId = "2000-028A";
764         Assert.assertEquals(satId, file.getMetadata().getObjectID());
765 
766         checkPVEntry(file.getPVCoordinates(), file.getPVCoordinates());
767 
768     }
769 
770     private void checkPVEntry(final PVCoordinates expected,
771                               final PVCoordinates actual) {
772         final Vector3D expectedPos = expected.getPosition();
773         final Vector3D expectedVel = expected.getVelocity();
774 
775         final Vector3D actualPos = actual.getPosition();
776         final Vector3D actualVel = actual.getVelocity();
777 
778         final double eps = 1e-12;
779 
780         Assert.assertEquals(expectedPos.getX(), actualPos.getX(), eps);
781         Assert.assertEquals(expectedPos.getY(), actualPos.getY(), eps);
782         Assert.assertEquals(expectedPos.getZ(), actualPos.getZ(), eps);
783 
784         Assert.assertEquals(expectedVel.getX(), actualVel.getX(), eps);
785         Assert.assertEquals(expectedVel.getY(), actualVel.getY(), eps);
786         Assert.assertEquals(expectedVel.getZ(), actualVel.getZ(), eps);
787     }
788 
789     @Test
790     public void testWrongODMType() {
791         final String name = "/ccsds/odm/omm/OMMExample1.txt";
792         final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
793         try {
794             new ParserBuilder().
795             withMu(Constants.EIGEN5C_EARTH_MU).
796             withDefaultMass(1000.0).
797             buildOpmParser().
798             parseMessage(source);
799             Assert.fail("an exception should have been thrown");
800         } catch (OrekitException oe) {
801             Assert.assertEquals(OrekitMessages.UNSUPPORTED_FILE_FORMAT, oe.getSpecifier());
802             Assert.assertEquals(name, oe.getParts()[0]);
803         }
804     }
805 
806     @Test
807     public void testNumberFormatErrorType() {
808         final String name = "/ccsds/odm/opm/OPM-number-format-error.txt";
809         final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
810         try {
811             new ParserBuilder().
812             withMu(Constants.EIGEN5C_EARTH_MU).
813             withMissionReferenceDate(new AbsoluteDate()).
814             withDefaultMass(1000.0).
815             buildOpmParser().
816             parseMessage(source);
817             Assert.fail("an exception should have been thrown");
818         } catch (OrekitException oe) {
819             Assert.assertEquals(OrekitMessages.UNABLE_TO_PARSE_ELEMENT_IN_FILE, oe.getSpecifier());
820             Assert.assertEquals("SEMI_MAJOR_AXIS", oe.getParts()[0]);
821             Assert.assertEquals(17, oe.getParts()[1]);
822             Assert.assertEquals(name, oe.getParts()[2]);
823         }
824     }
825 
826     @Test
827     public void testUnknownCenter() throws URISyntaxException {
828         final String name = "/ccsds/odm/opm/OPM-unknown-center.txt";
829         final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
830         final Opm opm = new ParserBuilder().
831                             withMu(Constants.EIGEN5C_EARTH_MU).
832                             withDefaultMass(1000.0).
833                             buildOpmParser().
834                             parseMessage(source);
835         Assert.assertEquals("UNKNOWN-CENTER", opm.getMetadata().getCenter().getName());
836         Assert.assertNull(opm.getMetadata().getCenter().getBody());
837         try {
838             opm.getMetadata().getFrame();
839             Assert.fail("an exception should have been thrown");
840         } catch (OrekitException oe) {
841             Assert.assertEquals(OrekitMessages.NO_DATA_LOADED_FOR_CELESTIAL_BODY, oe.getSpecifier());
842             Assert.assertEquals("UNKNOWN-CENTER", oe.getParts()[0]);
843         }
844     }
845 
846     @Test
847     public void testUnknownFrame() throws URISyntaxException {
848         final String name = "/ccsds/odm/opm/OPM-unknown-frame.txt";
849         final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
850         final Opm opm = new ParserBuilder().
851                             withMu(Constants.EIGEN5C_EARTH_MU).
852                             withDefaultMass(1000.0).
853                             buildOpmParser().
854                             parseMessage(source);
855         Assert.assertEquals("ZZRF", opm.getMetadata().getReferenceFrame().getName());
856         try {
857             opm.getMetadata().getFrame();
858             Assert.fail("an exception should have been thrown");
859         } catch (OrekitException oe) {
860             Assert.assertEquals(OrekitMessages.CCSDS_INVALID_FRAME, oe.getSpecifier());
861             Assert.assertEquals("ZZRF", oe.getParts()[0]);
862         }
863     }
864 
865     @Test
866     public void testNonExistentFile() throws URISyntaxException {
867         final String realName = getClass().getResource("/ccsds/odm/opm/OPMExample1.txt").toURI().getPath();
868         final String wrongName = realName + "xxxxx";
869         final DataSource source = new DataSource(wrongName, () -> getClass().getResourceAsStream(wrongName));
870         try {
871             new ParserBuilder().withMu(Constants.EIGEN5C_EARTH_MU).withDefaultMass(1000.0).buildOpmParser().
872             parseMessage(source);
873             Assert.fail("an exception should have been thrown");
874         } catch (OrekitException oe) {
875             Assert.assertEquals(OrekitMessages.UNABLE_TO_FIND_FILE, oe.getSpecifier());
876             Assert.assertEquals(wrongName, oe.getParts()[0]);
877         }
878     }
879 
880     @Test
881     public void testWrongKeyword() throws URISyntaxException {
882         // simple test for OMM file, contains p/v entries and other mandatory data.
883         final String name = "/ccsds/odm/opm/OPM-wrong-keyword.txt";
884         final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
885         try {
886             new ParserBuilder().
887             withMu(Constants.EIGEN5C_EARTH_MU).
888             withDefaultMass(1000.0).
889             buildOpmParser().
890             parseMessage(source);
891             Assert.fail("an exception should have been thrown");
892         } catch (OrekitException oe) {
893             Assert.assertEquals(OrekitMessages.CCSDS_UNEXPECTED_KEYWORD, oe.getSpecifier());
894             Assert.assertEquals(11, ((Integer) oe.getParts()[0]).intValue());
895             Assert.assertTrue(((String) oe.getParts()[2]).startsWith("WRONG_KEYWORD"));
896         }
897     }
898 
899     @Test
900     public void testIncompatibleUnits1() throws URISyntaxException {
901         final String name = "/ccsds/odm/opm/OPM-incompatible-units.txt";
902         final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
903         try {
904             new ParserBuilder().
905             withParsedUnitsBehavior(ParsedUnitsBehavior.CONVERT_COMPATIBLE).
906             buildOpmParser().
907             parseMessage(source);
908             Assert.fail("an exception should have been thrown");
909         } catch (OrekitException oe) {
910             Assert.assertEquals(OrekitMessages.INCOMPATIBLE_UNITS, oe.getSpecifier());
911             Assert.assertEquals("s",  oe.getParts()[0]);
912             Assert.assertEquals("m²", oe.getParts()[1]);
913         }
914     }
915 
916     @Test
917     public void testIncompatibleUnits2() throws URISyntaxException {
918         final String name = "/ccsds/odm/opm/OPM-incompatible-units.txt";
919         final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
920         try {
921             new ParserBuilder().
922             withParsedUnitsBehavior(ParsedUnitsBehavior.STRICT_COMPLIANCE).
923             buildOpmParser().
924             parseMessage(source);
925             Assert.fail("an exception should have been thrown");
926         } catch (OrekitException oe) {
927             Assert.assertEquals(OrekitMessages.INCOMPATIBLE_UNITS, oe.getSpecifier());
928             Assert.assertEquals("s",  oe.getParts()[0]);
929             Assert.assertEquals("m²", oe.getParts()[1]);
930         }
931     }
932 
933     @Test
934     public void testIgnoredIncompatibleUnits() throws URISyntaxException {
935         final String name = "/ccsds/odm/opm/OPM-incompatible-units.txt";
936         final DataSource source = new DataSource(name, () -> getClass().getResourceAsStream(name));
937         final Opm file = new ParserBuilder().
938                              withParsedUnitsBehavior(ParsedUnitsBehavior.IGNORE_PARSED).
939                              buildOpmParser().
940                              parseMessage(source);
941         Assert.assertEquals(18.77, file.getData().getSpacecraftParametersBlock().getSolarRadArea(), 1.0e-10);
942     }
943 
944     @Test
945     public void testIssue619() {
946         // test for issue 619 - moon centered transformation
947     	// Verify that moon is at the center of the new frame
948         CelestialBody moon = CelestialBodyFactory.getMoon();
949 		AbsoluteDate date = new AbsoluteDate(2000, 1, 1, 12, 0, 00, TimeScalesFactory.getUTC());
950 		final String ex = "/ccsds/odm/opm/OPM-dummy-moon-EME2000.txt";
951         final DataSource source = new DataSource(ex, () -> getClass().getResourceAsStream(ex));
952 		final OpmParser parser = new ParserBuilder().
953 		                         withMu(CelestialBodyFactory.getEarth().getGM()).
954 		                         withDefaultMass(1000.0).
955 		                         buildOpmParser();
956 		final Opm file = parser.parseMessage(source);
957         final Frame actualFrame = file.getMetadata().getFrame();
958         MatcherAssert.assertThat(moon.getPVCoordinates(date, actualFrame),
959                                  OrekitMatchers.pvCloseTo(PVCoordinates.ZERO, 1e-3));     
960     }
961 
962 }