1   package org.orekit.files.ccsds;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertNotNull;
5   import static org.junit.Assert.assertTrue;
6   import static org.junit.Assert.fail;
7   
8   import java.io.BufferedReader;
9   import java.io.BufferedWriter;
10  import java.io.File;
11  import java.io.FileInputStream;
12  import java.io.IOException;
13  import java.io.InputStream;
14  import java.io.InputStreamReader;
15  import java.nio.charset.StandardCharsets;
16  import java.util.ArrayList;
17  import java.util.HashMap;
18  import java.util.List;
19  import java.util.Map;
20  
21  import org.hipparchus.geometry.euclidean.threed.Vector3D;
22  import org.junit.Before;
23  import org.junit.Rule;
24  import org.junit.Test;
25  import org.junit.rules.TemporaryFolder;
26  import org.orekit.Utils;
27  import org.orekit.bodies.CelestialBodyFactory;
28  import org.orekit.errors.OrekitException;
29  import org.orekit.errors.OrekitIllegalArgumentException;
30  import org.orekit.errors.OrekitMessages;
31  import org.orekit.files.ccsds.OEMFile.EphemeridesBlock;
32  import org.orekit.files.ccsds.OEMWriter.InterpolationMethod;
33  import org.orekit.files.general.EphemerisFile;
34  import org.orekit.time.AbsoluteDate;
35  import org.orekit.utils.IERSConventions;
36  import org.orekit.utils.TimeStampedPVCoordinates;
37  
38  public class OEMWriterTest {
39      private static final double POSITION_PRECISION = 1e-9;
40      private static final double VELOCITY_PRECISION = 1e-9;
41  
42      @Rule
43      public TemporaryFolder tempFolder = new TemporaryFolder();
44  
45      @Before
46      public void setUp() throws Exception {
47          Utils.setDataRoot("regular-data");
48      }
49  
50      @Test
51      public void testOEMWriter() {
52          assertNotNull(new OEMWriter());
53      }
54  
55      @Test
56      public void testOEMWriterInterpolationMethodStringStringString() {
57          assertNotNull(new OEMWriter(OEMWriter.DEFAULT_INTERPOLATION_METHOD, null, null, null));
58          assertNotNull(new OEMWriter(InterpolationMethod.HERMITE, "FakeOriginator", null, null));
59          assertNotNull(new OEMWriter(InterpolationMethod.HERMITE, null, "FakeObjectId", null));
60          assertNotNull(new OEMWriter(InterpolationMethod.HERMITE, null, null, "Fake Object Name"));
61          assertNotNull(new OEMWriter(InterpolationMethod.HERMITE, "FakeOriginator", "FakeObjectId", null));
62          assertNotNull(new OEMWriter(InterpolationMethod.HERMITE, "FakeOriginator", null, "Fake Object Name"));
63          assertNotNull(new OEMWriter(InterpolationMethod.HERMITE, null, "FakeObjectId", "Fake Object Name"));
64          assertNotNull(new OEMWriter(InterpolationMethod.HERMITE, "FakeOriginator", "FakeObjectId", "Fake Object Name"));
65      }
66  
67      @Test
68      public void testWriteOEM1() throws OrekitException, IOException {
69          final String ex = "/ccsds/OEMExample.txt";
70          final InputStream inEntry = getClass().getResourceAsStream(ex);
71          final OEMParser parser = new OEMParser().withMu(CelestialBodyFactory.getEarth().getGM())
72                  .withConventions(IERSConventions.IERS_2010);
73          final OEMFile oemFile = parser.parse(inEntry, "OEMExample.txt");
74          final EphemerisFile ephemerisFile = (EphemerisFile) oemFile;
75  
76          String originator = oemFile.getOriginator();
77          String objectName = oemFile.getEphemeridesBlocks().get(0).getMetaData().getObjectName();
78          String objectID = oemFile.getEphemeridesBlocks().get(0).getMetaData().getObjectID();
79          String interpolationMethodString = oemFile.getEphemeridesBlocks().get(0).getInterpolationMethod();
80          InterpolationMethod interpolationMethod = Enum.valueOf(InterpolationMethod.class, interpolationMethodString);
81          String tempOEMFilePath = tempFolder.newFile("TestWriteOEM1.oem").toString();
82          OEMWriter writer = new OEMWriter(interpolationMethod, originator, objectID, objectName);
83          writer.write(tempOEMFilePath, ephemerisFile);
84  
85          final OEMFile generatedOemFile = parser.parse(tempOEMFilePath);
86          compareOemFiles(oemFile, generatedOemFile);
87      }
88  
89      @Test
90      public void testUnfoundSpaceId() throws OrekitException, IOException {
91          final String ex = "/ccsds/OEMExample.txt";
92          final InputStream inEntry = getClass().getResourceAsStream(ex);
93          final OEMParser parser = new OEMParser().withMu(CelestialBodyFactory.getEarth().getGM())
94                  .withConventions(IERSConventions.IERS_2010);
95          final OEMFile oemFile = parser.parse(inEntry, "OEMExample.txt");
96          final EphemerisFile ephemerisFile = (EphemerisFile) oemFile;
97  
98          String badObjectId = "12345";
99          String interpolationMethodString = oemFile.getEphemeridesBlocks().get(0).getInterpolationMethod();
100         InterpolationMethod interpolationMethod = Enum.valueOf(InterpolationMethod.class, interpolationMethodString);
101         String tempOEMFilePath = tempFolder.newFile("TestOEMUnfoundSpaceId.oem").toString();
102         OEMWriter writer = new OEMWriter(interpolationMethod, null, badObjectId, null);
103         try {
104             writer.write(tempOEMFilePath, ephemerisFile);
105             fail("an exception should have been thrown");
106         } catch (OrekitIllegalArgumentException oiae) {
107             assertEquals(OrekitMessages.VALUE_NOT_FOUND, oiae.getSpecifier());
108             assertEquals(badObjectId, oiae.getParts()[0]);
109         }
110 
111     }
112 
113     @Test
114     public void testNullFile() throws OrekitException, IOException {
115         final String ex = "/ccsds/OEMExample.txt";
116         final InputStream inEntry = getClass().getResourceAsStream(ex);
117         final OEMParser parser = new OEMParser().withMu(CelestialBodyFactory.getEarth().getGM())
118                 .withConventions(IERSConventions.IERS_2010);
119         final OEMFile oemFile = parser.parse(inEntry, "OEMExample.txt");
120         final EphemerisFile ephemerisFile = (EphemerisFile) oemFile;
121         String originator = oemFile.getOriginator();
122         String objectName = oemFile.getEphemeridesBlocks().get(0).getMetaData().getObjectName();
123         String objectID = oemFile.getEphemeridesBlocks().get(0).getMetaData().getObjectID();
124         String interpolationMethodString = oemFile.getEphemeridesBlocks().get(0).getInterpolationMethod();
125         InterpolationMethod interpolationMethod = Enum.valueOf(InterpolationMethod.class, interpolationMethodString);
126         OEMWriter writer = new OEMWriter(interpolationMethod, originator, objectID, objectName);
127         try {
128             writer.write((BufferedWriter) null, ephemerisFile);
129             fail("an exception should have been thrown");
130         } catch (OrekitIllegalArgumentException oiae) {
131             assertEquals(OrekitMessages.NULL_ARGUMENT, oiae.getSpecifier());
132             assertEquals("writer", oiae.getParts()[0]);
133         }
134     }
135 
136     @Test
137     public void testNullEphemeris() throws OrekitException, IOException {
138         File tempOEMFile = tempFolder.newFile("TestNullEphemeris.oem");
139         OEMWriter writer = new OEMWriter(InterpolationMethod.HERMITE,
140                                          "NASA/JPL", "1996-062A", "MARS GLOBAL SURVEYOR");
141         writer.write(tempOEMFile.toString(), null);
142         assertTrue(tempOEMFile.exists());
143         try (FileInputStream   fis = new FileInputStream(tempOEMFile);
144              InputStreamReader isr = new InputStreamReader(fis, StandardCharsets.UTF_8);
145              BufferedReader    br  = new BufferedReader(isr)) {
146             int count = 0;
147             for (String line = br.readLine(); line != null; line = br.readLine()) {
148                 ++count;
149             }
150             assertEquals(0, count);
151         }
152     }
153 
154     @Test
155     public void testUnisatelliteFileWithDefault() throws OrekitException, IOException {
156         final String ex = "/ccsds/OEMExample.txt";
157         final InputStream inEntry = getClass().getResourceAsStream(ex);
158         final OEMParser parser = new OEMParser().withMu(CelestialBodyFactory.getEarth().getGM())
159                 .withConventions(IERSConventions.IERS_2010);
160         final OEMFile oemFile = parser.parse(inEntry, "OEMExample.txt");
161         final EphemerisFile ephemerisFile = (EphemerisFile) oemFile;
162 
163         String tempOEMFilePath = tempFolder.newFile("TestOEMUnisatelliteWithDefault.oem").toString();
164         OEMWriter writer = new OEMWriter();
165         writer.write(tempOEMFilePath, ephemerisFile);
166 
167         final OEMFile generatedOemFile = parser.parse(tempOEMFilePath);
168         assertEquals(oemFile.getEphemeridesBlocks().get(0).getMetaData().getObjectID(),
169                 generatedOemFile.getEphemeridesBlocks().get(0).getMetaData().getObjectID());
170     }
171 
172     @Test
173     public void testMultisatelliteFile() throws OrekitException, IOException {
174         final String id1 = "ID1";
175         final String id2 = "ID2";
176         StandInEphemerisFile file = new StandInEphemerisFile();
177         file.getSatellites().put(id1, new StandInSatelliteEphemeris(id1));
178         file.getSatellites().put(id2, new StandInSatelliteEphemeris(id2));
179 
180         EphemerisFile ephemerisFile = (EphemerisFile) file;
181         String tempOEMFilePath = tempFolder.newFile("TestOEMMultisatellite-1.oem").toString();
182 
183         OEMWriter writer1 = new OEMWriter();
184 
185         try {
186             writer1.write(tempOEMFilePath, ephemerisFile);
187             fail("Should have thrown OrekitIllegalArgumentException due to multiple satellites");
188         } catch (OrekitIllegalArgumentException e) {
189             assertEquals(OrekitMessages.EPHEMERIS_FILE_NO_MULTI_SUPPORT, e.getSpecifier());
190         }
191 
192         tempOEMFilePath = tempFolder.newFile("TestOEMMultisatellite-2.oem").toString();
193         OEMWriter writer2 = new OEMWriter(OEMWriter.DEFAULT_INTERPOLATION_METHOD, null, id1, null);
194         writer2.write(tempOEMFilePath, ephemerisFile);
195     }
196 
197     private static void compareOemEphemerisBlocks(EphemeridesBlock block1, EphemeridesBlock block2) {
198         compareOemEphemerisBlocksMetadata(block1.getMetaData(), block2.getMetaData());
199         assertEquals(block1.getStart(), block2.getStart());
200         assertEquals(block1.getStop(), block2.getStop());
201         assertEquals(block1.getInterpolationDegree(), block2.getInterpolationDegree());
202         assertEquals(block1.getInterpolationMethod(), block2.getInterpolationMethod());
203         assertEquals(block1.getEphemeridesDataLines().size(), block2.getEphemeridesDataLines().size());
204         for (int i = 0; i < block1.getEphemeridesDataLines().size(); i++) {
205             TimeStampedPVCoordinates c1 = block1.getEphemeridesDataLines().get(i);
206             TimeStampedPVCoordinates c2 = block2.getEphemeridesDataLines().get(i);
207             assertEquals(c1.getDate(), c2.getDate());
208             assertEquals(c1.getPosition() + " -> " + c2.getPosition(), 0.0,
209                     Vector3D.distance(c1.getPosition(), c2.getPosition()), POSITION_PRECISION);
210             assertEquals(c1.getVelocity() + " -> " + c2.getVelocity(), 0.0,
211                     Vector3D.distance(c1.getVelocity(), c2.getVelocity()), VELOCITY_PRECISION);
212         }
213 
214     }
215 
216     private static void compareOemEphemerisBlocksMetadata(ODMMetaData meta1, ODMMetaData meta2) {
217         assertEquals(meta1.getObjectID(), meta2.getObjectID());
218         assertEquals(meta1.getObjectName(), meta2.getObjectName());
219         assertEquals(meta1.getCenterName(), meta2.getCenterName());
220         assertEquals(meta1.getFrameString(), meta2.getFrameString());
221         assertEquals(meta1.getTimeSystem(), meta2.getTimeSystem());
222     }
223 
224     static void compareOemFiles(OEMFile file1, OEMFile file2) {
225         assertEquals(file1.getOriginator(), file2.getOriginator());
226         assertEquals(file1.getEphemeridesBlocks().size(), file2.getEphemeridesBlocks().size());
227         for (int i = 0; i < file1.getEphemeridesBlocks().size(); i++) {
228             compareOemEphemerisBlocks(file1.getEphemeridesBlocks().get(i), file2.getEphemeridesBlocks().get(i));
229         }
230     }
231 
232     private class StandInSatelliteEphemeris implements EphemerisFile.SatelliteEphemeris {
233         final String id;
234 
235         public StandInSatelliteEphemeris(String id) {
236             this.id = id;
237         }
238 
239         @Override
240         public String getId() {
241             return id;
242         }
243 
244         @Override
245         public double getMu() {
246             // TODO Auto-generated method stub
247             return 0;
248         }
249 
250         @SuppressWarnings({ "rawtypes", "unchecked" })
251         @Override
252         public List<? extends EphemerisFile.EphemerisSegment> getSegments() {
253             return new ArrayList();
254         }
255 
256         @Override
257         public AbsoluteDate getStart() {
258             // TODO Auto-generated method stub
259             return null;
260         }
261 
262         @Override
263         public AbsoluteDate getStop() {
264             // TODO Auto-generated method stub
265             return null;
266         }
267 
268     }
269 
270     private class StandInEphemerisFile implements EphemerisFile {
271         private final Map<String, StandInSatelliteEphemeris> satEphem;
272 
273         public StandInEphemerisFile() {
274             this.satEphem = new HashMap<String, StandInSatelliteEphemeris>();
275         }
276 
277         @Override
278         public Map<String, StandInSatelliteEphemeris> getSatellites() {
279             return satEphem;
280         }
281 
282     }
283 
284 }