1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.files.ccsds.ndm;
18
19 import java.lang.reflect.InvocationTargetException;
20 import java.util.List;
21 import java.util.Locale;
22 import java.util.Map;
23 import java.util.stream.Stream;
24
25 import org.hipparchus.complex.Quaternion;
26 import org.hipparchus.geometry.euclidean.threed.Rotation;
27 import org.hipparchus.geometry.euclidean.threed.Vector3D;
28 import org.hipparchus.linear.RealMatrix;
29 import org.hipparchus.util.FastMath;
30 import org.hipparchus.util.Precision;
31 import org.junit.jupiter.api.Assertions;
32 import org.opentest4j.AssertionFailedError;
33 import org.orekit.data.DataContext;
34 import org.orekit.errors.OrekitException;
35 import org.orekit.errors.OrekitMessages;
36 import org.orekit.files.ccsds.definitions.BodyFacade;
37 import org.orekit.files.ccsds.definitions.CcsdsFrameMapper;
38 import org.orekit.files.ccsds.definitions.FrameFacade;
39 import org.orekit.files.ccsds.definitions.OdMethodFacade;
40 import org.orekit.files.ccsds.definitions.PocMethodFacade;
41 import org.orekit.files.ccsds.definitions.SpacecraftBodyFrame;
42 import org.orekit.files.ccsds.ndm.adm.AttitudeEndpoints;
43 import org.orekit.files.ccsds.ndm.adm.acm.AcmSatelliteEphemeris;
44 import org.orekit.files.ccsds.ndm.adm.acm.AttitudeCovariance;
45 import org.orekit.files.ccsds.ndm.adm.acm.AttitudeCovarianceHistory;
46 import org.orekit.files.ccsds.ndm.adm.acm.AttitudeState;
47 import org.orekit.files.ccsds.ndm.adm.acm.AttitudeStateHistory;
48 import org.orekit.files.ccsds.ndm.adm.aem.AemSatelliteEphemeris;
49 import org.orekit.files.ccsds.ndm.adm.apm.ApmQuaternion;
50 import org.orekit.files.ccsds.ndm.cdm.CdmRelativeMetadata;
51 import org.orekit.files.ccsds.ndm.odm.ocm.OcmSatelliteEphemeris;
52 import org.orekit.files.ccsds.ndm.odm.ocm.OrbitCovariance;
53 import org.orekit.files.ccsds.ndm.odm.ocm.OrbitCovarianceHistory;
54 import org.orekit.files.ccsds.ndm.odm.ocm.OrbitManeuver;
55 import org.orekit.files.ccsds.ndm.odm.ocm.OrbitManeuverHistory;
56 import org.orekit.files.ccsds.ndm.odm.ocm.TrajectoryState;
57 import org.orekit.files.ccsds.ndm.odm.ocm.TrajectoryStateHistory;
58 import org.orekit.files.ccsds.ndm.odm.oem.OemSatelliteEphemeris;
59 import org.orekit.files.ccsds.ndm.tdm.Observation;
60 import org.orekit.files.ccsds.section.CommentsContainer;
61 import org.orekit.files.ccsds.section.Section;
62 import org.orekit.files.ccsds.section.Segment;
63 import org.orekit.frames.Frame;
64 import org.orekit.time.AbsoluteDate;
65 import org.orekit.utils.AngularCoordinates;
66 import org.orekit.utils.PVCoordinates;
67 import org.orekit.utils.units.Unit;
68
69 public class NdmTestUtils {
70
71 private static final int ULPS = 207;
72
73 public static void checkEquals(final NdmConstituent<?, ?> original, final NdmConstituent<?, ?> rebuilt) {
74 checkContainer(original.getHeader(), rebuilt.getHeader());
75 Assertions.assertEquals(original.getSegments().size(), rebuilt.getSegments().size());
76 for (int i = 0; i < original.getSegments().size(); ++i) {
77 checkContainer(original.getSegments().get(i).getMetadata(), rebuilt.getSegments().get(i).getMetadata());
78 checkContainer(original.getSegments().get(i).getData(), rebuilt.getSegments().get(i).getData());
79 }
80 }
81
82 public static boolean recurseCheck(final Object original, final Object rebuilt) {
83
84 if (original == null) {
85 return rebuilt == null;
86 } else if (original instanceof String ||
87 original instanceof Boolean ||
88 original instanceof Character ||
89 original instanceof Integer ||
90 original instanceof Enum) {
91 return original.equals(rebuilt);
92 } else if (original instanceof Double) {
93 checkDouble((Double) original, (Double) rebuilt);
94 return true;
95 } else if (original instanceof int[]) {
96 checkIntArray((int[]) original, (int[]) rebuilt);
97 return true;
98 } else if (original instanceof double[]) {
99 checkDoubleArray((double[]) original, (double[]) rebuilt);
100 return true;
101 } else if (original instanceof List) {
102 checkList((List<?>) original, (List<?>) rebuilt);
103 return true;
104 } else if (original instanceof Map) {
105 checkMap((Map<?, ?>) original, (Map<?, ?>) rebuilt);
106 return true;
107 } else if (original instanceof NdmConstituent ||
108 original instanceof Segment ||
109 original instanceof Section ||
110 original instanceof CommentsContainer ||
111 original instanceof ApmQuaternion ||
112 original instanceof AttitudeEndpoints ||
113 original instanceof OcmSatelliteEphemeris ||
114 original instanceof OemSatelliteEphemeris ||
115 original instanceof AemSatelliteEphemeris ||
116 original instanceof OrbitCovarianceHistory ||
117 original instanceof OrbitManeuverHistory ||
118 original instanceof TrajectoryState ||
119 original instanceof OrbitCovariance ||
120 original instanceof OrbitManeuver ||
121 original instanceof Observation ||
122 original instanceof SpacecraftBodyFrame ||
123 original instanceof PVCoordinates ||
124 original instanceof AngularCoordinates ||
125 original instanceof CdmRelativeMetadata ||
126 original instanceof AttitudeStateHistory ||
127 original instanceof AttitudeState ||
128 original instanceof AttitudeCovarianceHistory ||
129 original instanceof AttitudeCovariance ||
130 original instanceof AcmSatelliteEphemeris) {
131 checkContainer(original, rebuilt);
132 return true;
133 } else if (original instanceof FrameFacade) {
134 checkFrameFacade((FrameFacade) original, (FrameFacade) rebuilt);
135 return true;
136 } else if (original instanceof BodyFacade) {
137 checkBodyFacade((BodyFacade) original, (BodyFacade) rebuilt);
138 return true;
139 } else if (original instanceof OdMethodFacade) {
140 checkOdMethodFacade((OdMethodFacade) original, (OdMethodFacade) rebuilt);
141 return true;
142 } else if (original instanceof PocMethodFacade) {
143 checkPocMethodFacade((PocMethodFacade) original, (PocMethodFacade) rebuilt);
144 return true;
145 } else if (original instanceof TrajectoryStateHistory) {
146 checkOrbitStateHistory((TrajectoryStateHistory) original, (TrajectoryStateHistory) rebuilt);
147 return true;
148 } else if (original instanceof DataContext) {
149 return true;
150 } else if (original instanceof Frame) {
151 checkFrame((Frame) original, (Frame) rebuilt);
152 return true;
153 } else if (original instanceof AbsoluteDate) {
154 checkDate((AbsoluteDate) original, (AbsoluteDate) rebuilt);
155 return true;
156 } else if (original instanceof Unit) {
157 checkUnit((Unit) original, (Unit) rebuilt);
158 return true;
159 } else if (original instanceof Vector3D) {
160 checkVector3D((Vector3D) original, (Vector3D) rebuilt);
161 return true;
162 } else if (original instanceof Quaternion) {
163 checkQuaternion((Quaternion) original, (Quaternion) rebuilt);
164 return true;
165 } else if (original instanceof RealMatrix) {
166 checkRealMatrix((RealMatrix) original, (RealMatrix) rebuilt);
167 return true;
168 } else if (original instanceof Rotation) {
169 checkRotation((Rotation) original, (Rotation) rebuilt);
170 return true;
171 } else if (original instanceof CcsdsFrameMapper) {
172 Assertions.assertEquals(original, rebuilt);
173 return true;
174 } else {
175 return false;
176 }
177
178 }
179
180 public static void checkContainer(final Object original, final Object rebuilt) {
181 Assertions.assertEquals(original.getClass(), rebuilt.getClass());
182 final Class<?> cls = original.getClass();
183 Stream.of(cls.getMethods()).
184 filter(m -> m.getName().startsWith("get") &&
185 !m.getName().equals("getClass") &&
186 !m.getName().equals("getPropagator") &&
187 !m.getName().equals("getLaunchYear") &&
188 !m.getName().equals("getLaunchNumber") &&
189 !m.getName().equals("getLaunchPiece") &&
190 !m.getName().equals("getAttitudeProvider") &&
191 m.getParameterCount() == 0).
192 forEach(getter -> {
193 try {
194 Assertions.assertTrue(recurseCheck(getter.invoke(original), getter.invoke(rebuilt)),
195 "failed to compare " + getter.getReturnType() + " from "
196 + getter.getName());
197 } catch (InvocationTargetException e) {
198 if (!((getter.getName().equals("getFrame") ||
199 getter.getName().equals("getReferenceFrame") ||
200 getter.getName().equals("getInertialFrame") ||
201 getter.getReturnType().equals(Frame.class) ||
202 getter.getName().equals("getAngularCoordinates")) &&
203 e.getCause() instanceof OrekitException &&
204 (((OrekitException) e.getCause()).getSpecifier() == OrekitMessages.NO_DATA_LOADED_FOR_CELESTIAL_BODY ||
205 ((OrekitException) e.getCause()).getSpecifier() == OrekitMessages.CCSDS_INVALID_FRAME ||
206 ((OrekitException) e.getCause()).getSpecifier() == OrekitMessages.CCSDS_UNSUPPORTED_ELEMENT_SET_TYPE))) {
207 throw new Error("failed to invoke getter: " + e.getLocalizedMessage(), e);
208 }
209 } catch (IllegalAccessException | IllegalArgumentException e) {
210 Assertions.fail(e.getLocalizedMessage());
211 }
212 });
213 }
214
215 public static void checkIntArray(final int[] original, final int[] rebuilt) {
216 Assertions.assertEquals(original.length, rebuilt.length);
217 for (int i = 0; i < original.length; ++i) {
218 Assertions.assertEquals(original[i], rebuilt[i]);
219 }
220 }
221
222 public static void checkDoubleArray(final double[] original, final double[] rebuilt) {
223 Assertions.assertEquals(original.length, rebuilt.length);
224 for (int i = 0; i < original.length; ++i) {
225 Assertions.assertTrue(Precision.equalsIncludingNaN(original[i], rebuilt[i], 1));
226 }
227 }
228
229 public static void checkList(final List<?> original, final List<?> rebuilt) {
230 Assertions.assertEquals(original.size(), rebuilt.size());
231 for (int i = 0; i < original.size(); ++i) {
232 Assertions.assertTrue(recurseCheck(original.get(i), rebuilt.get(i)));
233 }
234 }
235
236 public static void checkMap(final Map<?, ?> original, final Map<?, ?> rebuilt) {
237 Assertions.assertEquals(original.size(), rebuilt.size());
238 for (final Map.Entry<?, ?> entry : original.entrySet()) {
239 Assertions.assertTrue(rebuilt.containsKey(entry.getKey()));
240 Assertions.assertTrue(recurseCheck(entry.getValue(), rebuilt.get(entry.getKey())));
241 }
242 }
243
244 public static void checkFrameFacade(final FrameFacade original, final FrameFacade rebuilt) {
245 if (original.asFrame() == null) {
246 Assertions.assertNull(rebuilt.asFrame());
247 } else {
248 Assertions.assertEquals(original.asFrame().getName(),
249 rebuilt.asFrame().getName());
250 }
251 Assertions.assertEquals(original.asCelestialBodyFrame(),
252 rebuilt.asCelestialBodyFrame());
253 if (original.asOrbitRelativeFrame() == null) {
254 Assertions.assertNull(rebuilt.asOrbitRelativeFrame());
255 } else {
256 Assertions.assertEquals(original.asOrbitRelativeFrame().getLofType(),
257 rebuilt.asOrbitRelativeFrame().getLofType());
258 }
259 if (original.asSpacecraftBodyFrame() == null) {
260 Assertions.assertNull(rebuilt.asSpacecraftBodyFrame());
261 } else {
262 Assertions.assertEquals(original.asSpacecraftBodyFrame().getBaseEquipment(),
263 rebuilt.asSpacecraftBodyFrame().getBaseEquipment());
264 Assertions.assertEquals(original.asSpacecraftBodyFrame().getLabel(),
265 rebuilt.asSpacecraftBodyFrame().getLabel());
266 }
267 Assertions.assertEquals(original.getName(), rebuilt.getName());
268 }
269
270 public static void checkBodyFacade(final BodyFacade original, final BodyFacade rebuilt) {
271 if (original.getBody() == null) {
272 Assertions.assertNull(rebuilt.getBody());
273 } else {
274 Assertions.assertEquals(original.getBody().getName(),
275 rebuilt.getBody().getName());
276 }
277 Assertions.assertEquals(original.getName().toUpperCase(Locale.US), rebuilt.getName().toUpperCase(Locale.US));
278 }
279
280 public static void checkOdMethodFacade(final OdMethodFacade original, final OdMethodFacade rebuilt) {
281 Assertions.assertEquals(original.getName(), rebuilt.getName());
282 Assertions.assertEquals(original.getType(), rebuilt.getType());
283 Assertions.assertEquals(original.getTool(), rebuilt.getTool());
284 }
285
286 public static void checkPocMethodFacade(final PocMethodFacade original, final PocMethodFacade rebuilt) {
287 Assertions.assertEquals(original.getName(), rebuilt.getName());
288 Assertions.assertEquals(original.getType(), rebuilt.getType());
289 }
290
291 public static void checkOrbitStateHistory(final TrajectoryStateHistory original, final TrajectoryStateHistory rebuilt) {
292
293
294
295
296 Assertions.assertTrue(recurseCheck(original.getMetadata(), rebuilt.getMetadata()));
297 checkList(original.getTrajectoryStates(), rebuilt.getTrajectoryStates());
298 }
299
300 public static void checkDate(final AbsoluteDate original, final AbsoluteDate rebuilt) {
301 Assertions.assertEquals(0.0, rebuilt.durationFrom(original), 4.0e-12);
302 }
303
304 public static void checkUnit(final Unit original, final Unit rebuilt) {
305 Assertions.assertTrue(Precision.equals(original.getScale(), rebuilt.getScale(), 1));
306 Assertions.assertTrue(rebuilt.sameDimension(original));
307 }
308
309 public static void checkFrame(final Frame original, final Frame rebuilt) {
310 Assertions.assertEquals(original.getName(), rebuilt.getName());
311 }
312
313 public static void checkVector3D(final Vector3D original, final Vector3D rebuilt) {
314 double eps = ULPS * FastMath.ulp(FastMath.max(1.0, original.getNorm()));
315 Assertions.assertTrue(Precision.equalsIncludingNaN(original.getX(), rebuilt.getX(), eps));
316 Assertions.assertTrue(Precision.equalsIncludingNaN(original.getY(), rebuilt.getY(), eps));
317 Assertions.assertTrue(Precision.equalsIncludingNaN(original.getZ(), rebuilt.getZ(), eps));
318 }
319
320 public static void checkQuaternion(final Quaternion original, final Quaternion rebuilt) {
321 Assertions.assertTrue(Precision.equalsIncludingNaN(original.getQ0(), rebuilt.getQ0(), ULPS));
322 Assertions.assertTrue(Precision.equalsIncludingNaN(original.getQ1(), rebuilt.getQ1(), ULPS));
323 Assertions.assertTrue(Precision.equalsIncludingNaN(original.getQ2(), rebuilt.getQ2(), ULPS));
324 Assertions.assertTrue(Precision.equalsIncludingNaN(original.getQ3(), rebuilt.getQ3(), ULPS));
325 }
326
327 public static void checkRealMatrix(final RealMatrix original, final RealMatrix rebuilt) {
328 Assertions.assertEquals(original.getRowDimension(), rebuilt.getRowDimension());
329 Assertions.assertEquals(original.getColumnDimension(), rebuilt.getColumnDimension());
330 for (int i = 0; i < original.getRowDimension(); ++i) {
331 for (int j = 0; j < original.getColumnDimension(); ++j) {
332 Assertions.assertTrue(Precision.equalsIncludingNaN(original.getEntry(i, j), rebuilt.getEntry(i, j), ULPS));
333 }
334 }
335 }
336
337 public static void checkRotation(final Rotation original, final Rotation rebuilt) {
338 Assertions.assertEquals(0.0, Rotation.distance(original, rebuilt), 1.0e-12);
339 }
340
341 public static void checkDouble(final Double original, final Double rebuilt) {
342 Assertions.assertTrue(Precision.equalsIncludingNaN(original.doubleValue(), rebuilt.doubleValue(), ULPS));
343 }
344
345
346 }