1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.data;
18
19 import org.hipparchus.analysis.UnivariateFunction;
20 import org.hipparchus.analysis.differentiation.DSFactory;
21 import org.hipparchus.analysis.differentiation.DerivativeStructure;
22 import org.hipparchus.analysis.differentiation.FiniteDifferencesDifferentiator;
23 import org.hipparchus.analysis.differentiation.UnivariateDifferentiableFunction;
24 import org.hipparchus.analysis.differentiation.UnivariateDifferentiableVectorFunction;
25 import org.hipparchus.util.Binary64;
26 import org.hipparchus.util.Binary64Field;
27 import org.hipparchus.util.FastMath;
28 import org.junit.jupiter.api.Assertions;
29 import org.junit.jupiter.api.Test;
30 import org.orekit.Utils;
31 import org.orekit.errors.OrekitException;
32 import org.orekit.errors.OrekitMessages;
33 import org.orekit.frames.FramesFactory;
34 import org.orekit.time.AbsoluteDate;
35 import org.orekit.time.FieldAbsoluteDate;
36 import org.orekit.time.TimeScale;
37 import org.orekit.time.TimeScalesFactory;
38 import org.orekit.utils.Constants;
39 import org.orekit.utils.IERSConventions;
40
41 import java.io.ByteArrayInputStream;
42 import java.io.InputStream;
43 import java.lang.reflect.InvocationTargetException;
44 import java.lang.reflect.Method;
45
46
47 public class PoissonSeriesParserTest {
48
49 @Test
50 public void testEmptyData() {
51 Assertions.assertThrows(OrekitException.class, () -> {
52 buildData("");
53 });
54 }
55
56 @Test
57 public void testNoCoeffData() {
58 Assertions.assertThrows(OrekitException.class, () -> {
59 buildData("this is NOT an IERS nutation model file\n");
60 });
61 }
62
63 @Test
64 public void testEmptyArrayData() {
65 Assertions.assertThrows(OrekitException.class, () -> {
66 buildData(" 0.0 + 0.0 t - 0.0 t^2 - 0.0 t^3 - 0.0 t^4 + 0.0 t^5\n");
67 });
68 }
69
70 @Test
71 public void testMissingTermData() {
72 Assertions.assertThrows(OrekitException.class, () -> {
73 buildData(" 0.0 + 0.0 t - 0.0 t^2 - 0.0 t^3 - 0.0 t^4 + 0.0 t^5\n"
74 + "j = 0 Nb of terms = 1\n");
75 });
76 }
77
78 private PoissonSeries buildData(String data) {
79 return new PoissonSeriesParser(0).
80 withPolynomialPart('t', PolynomialParser.Unit.NO_UNITS).
81 parse(new ByteArrayInputStream(data.getBytes()),
82 "<file-content>" + data + "</file-content>");
83 }
84
85 @Test
86 public void testNoFile() {
87 Assertions.assertThrows(OrekitException.class, () -> {
88 InputStream stream =
89 PoissonSeriesParserTest.class.getResourceAsStream("/org/orekit/resources/missing");
90 new PoissonSeriesParser(17).
91 withPolynomialPart('t', PolynomialParser.Unit.NO_UNITS).
92 withFirstDelaunay(4).
93 withFirstPlanetary(9).
94 withSinCos(0, 2, 1.0, 3, 1.0).
95 parse(stream, "missing");
96 });
97 }
98
99 @Test
100 public void testMissingSeries() {
101 try {
102 String data =
103 " 0.0 + 0.0 x - 0.0 x^2 - 0.0 x^3 - 0.0 x^4 + 0.0 x^5\n"
104 + "j = 0 Nb of terms = 1\n"
105 + "1 1.0 0.0 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n"
106 + "j = 1 Nb of terms = 1\n"
107 + "2 1.0 0.0 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n"
108 + "j = 3 Nb of terms = 1\n"
109 + "3 1.0 0.0 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n";
110 new PoissonSeriesParser(17).
111 withPolynomialPart('x', PolynomialParser.Unit.NO_UNITS).
112 withFirstDelaunay(4).
113 withFirstPlanetary(9).
114 withSinCos(0, 2, 1.0, 3, 1.0).
115 parse(new ByteArrayInputStream(data.getBytes()), "");
116 Assertions.fail("an exception should have been thrown");
117 } catch (OrekitException oe) {
118 Assertions.assertEquals(OrekitMessages.MISSING_SERIE_J_IN_FILE, oe.getSpecifier());
119 Assertions.assertEquals(2, oe.getParts()[0]);
120 Assertions.assertEquals(6, oe.getParts()[2]);
121 }
122 }
123
124 @Test
125 public void testMissingTerms() {
126 try {
127 String data =
128 " 0.0 + 0.0 x - 0.0 x^2 - 0.0 x^3 - 0.0 x^4 + 0.0 x^5\n"
129 + "j = 0 Nb of terms = 1\n"
130 + "1 1.0 0.0 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n"
131 + "j = 1 Nb of terms = 3\n"
132 + "2 1.0 0.0 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n"
133 + "3 1.0 0.0 0 0 0 0 0 2 0 0 0 0 0 0 0 0\n"
134 + "j = 2 Nb of terms = 1\n"
135 + "4 1.0 0.0 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n";
136 new PoissonSeriesParser(17).
137 withPolynomialPart('x', PolynomialParser.Unit.NO_UNITS).
138 withFirstDelaunay(4).
139 withFirstPlanetary(9).
140 withSinCos(0, 2, 1.0, 3, 1.0).
141 parse(new ByteArrayInputStream(data.getBytes()), "");
142 Assertions.fail("an exception should have been thrown");
143 } catch (OrekitException oe) {
144 Assertions.assertEquals(OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE, oe.getSpecifier());
145 }
146 }
147
148 @Test
149 public void testSmall() {
150 String data =
151 " 0.0 + 0.0 x - 0.0 x^2 - 0.0 x^3 - 0.0 x^4 + 0.0 x^5\n"
152 + "j = 0 Nb of terms = 1\n"
153 + "1 1.0 0.0 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n";
154 PoissonSeries nd = new PoissonSeriesParser(17).
155 withPolynomialPart('x', PolynomialParser.Unit.NO_UNITS).
156 withFirstDelaunay(4).
157 withFirstPlanetary(9).
158 withSinCos(0, 2, 1.0, 3, 1.0).
159 parse(new ByteArrayInputStream(data.getBytes()), "");
160 Assertions.assertEquals(1, nd.getNonPolynomialSize());
161 }
162
163 @Test
164 public void testSecondsMarkers() {
165 String data =
166 " 0''.0 + 0''.0 t - 0''.0 t^2 - 0''.0 t^3 - 0''.0 t^4 + 0''.0 t^5\n"
167 + "j = 0 Nb of terms = 1\n"
168 + "1 1.0 0.0 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n";
169 PoissonSeries nd = new PoissonSeriesParser(17).
170 withFirstPlanetary(9).
171 withSinCos(0, 2, 1.0, 3, 1.0).
172 withPolynomialPart('t', PolynomialParser.Unit.NO_UNITS).
173 withFirstDelaunay(4).
174 parse(new ByteArrayInputStream(data.getBytes()), "");
175 Assertions.assertEquals(1, nd.getNonPolynomialSize());
176 }
177
178 @Test
179 public void testExtract() {
180 String data =
181 "Expression for the X coordinate of the CIP in the GCRS based on the IAU2000A\n"
182 + "precession-nutation model\n"
183 + "\n"
184 + "\n"
185 + "----------------------------------------------------------------------\n"
186 + "\n"
187 + "X = polynomial part + non-polynomial part\n"
188 + "\n"
189 + "----------------------------------------------------------------------\n"
190 + "\n"
191 + "Polynomial part (unit microarcsecond)\n"
192 + "\n"
193 + " -16616.99 + 2004191742.88 t - 427219.05 t^2 - 198620.54 t^3 - 46.05 t^4 + 5.98 t^5\n"
194 + "\n"
195 + "----------------------------------------------------------------------\n"
196 + "\n"
197 + "Non-polynomial part (unit microarcsecond)\n"
198 + "(ARG being for various combination of the fundamental arguments of the nutation theory)\n"
199 + "\n"
200 + " Sum_i[a_{s,0})_i * sin(ARG) + a_{c,0})_i * cos(ARG)] \n"
201 + "\n"
202 + "+ Sum_i)j=1,4 [a_{s,j})_i * t^j * sin(ARG) + a_{c,j})_i * cos(ARG)] * t^j]\n"
203 + "\n"
204 + "The Table below provides the values for a_{s,j})_i and a_{c,j})_i\n"
205 + "\n"
206 + "The expressions for the fundamental arguments appearing in columns 4 to 8 (luni-solar part) \n"
207 + "and in columns 6 to 17 (planetary part) are those of the IERS Conventions 2000\n"
208 + "\n"
209 + "----------------------------------------------------------------------\n"
210 + "\n"
211 + " i a_{s,j})_i a_{c,j})_i l l' F D Om L_Me L_Ve L_E L_Ma L_J L_Sa L_U L_Ne p_A\n"
212 + "\n"
213 + "----------------------------------------------------------------------\n"
214 + "-16616.99 + 2004191742.88 t - 427219.05 t^2 - 198620.54 t^3 - 46.05 t^4 + 5.98 t^5\n"
215 + "j = 0 Nb of terms = 2\n"
216 + "\n"
217 + " 1 -6844318.44 1328.67 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n"
218 + " 2 0.11 0.00 0 0 4 -4 4 0 0 0 0 0 0 0 0 0\n"
219 + "\n"
220 + "j = 1 Nb of terms = 2\n"
221 + "\n"
222 + " 3 -3328.48 205833.15 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n"
223 + " 4 0.00 -0.10 1 -1 -2 -2 -1 0 0 0 0 0 0 0 0 0\n"
224 + "\n"
225 + " j = 2 Nb of terms = 2\n"
226 + "\n"
227 + " 5 2038.00 82.26 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n"
228 + " 6 -0.12 0.00 1 0 -2 -2 -1 0 0 0 0 0 0 0 0 0\n"
229 + " \n"
230 + " j = 3 Nb of terms = 2\n"
231 + "\n"
232 + " 7 1.76 -20.39 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n"
233 + " 8 0.00 0.20 0 0 0 0 2 0 0 0 0 0 0 0 0 0\n"
234 + "\n"
235 + " j = 4 Nb of terms = 1\n"
236 + " \n"
237 + " 9 -0.10 -0.02 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n";
238
239
240
241
242 Assertions.assertEquals(5,
243 new PoissonSeriesParser(17).
244 withPolynomialPart('t', PolynomialParser.Unit.NO_UNITS).
245 withFirstDelaunay(4).
246 withFirstPlanetary(9).
247 withSinCos(0, 2, 1.0, 3, 1.0).
248 parse(new ByteArrayInputStream(data.getBytes()), "dummy").getNonPolynomialSize());
249 }
250
251 @Test
252 public void testWrongIndex() {
253 String data =
254 "Expression for the X coordinate of the CIP in the GCRS based on the IAU2000A\n"
255 + "precession-nutation model\n"
256 + "\n"
257 + "\n"
258 + "----------------------------------------------------------------------\n"
259 + "\n"
260 + "X = polynomial part + non-polynomial part\n"
261 + "\n"
262 + "----------------------------------------------------------------------\n"
263 + "\n"
264 + "Polynomial part (unit microarcsecond)\n"
265 + "\n"
266 + " -16616.99 + 2004191742.88 t - 427219.05 t^2 - 198620.54 t^3 - 46.05 t^4 + 5.98 t^5\n"
267 + "\n"
268 + "----------------------------------------------------------------------\n"
269 + "\n"
270 + "Non-polynomial part (unit microarcsecond)\n"
271 + "(ARG being for various combination of the fundamental arguments of the nutation theory)\n"
272 + "\n"
273 + " Sum_i[a_{s,0})_i * sin(ARG) + a_{c,0})_i * cos(ARG)] \n"
274 + "\n"
275 + "+ Sum_i)j=1,4 [a_{s,j})_i * t^j * sin(ARG) + a_{c,j})_i * cos(ARG)] * t^j]\n"
276 + "\n"
277 + "The Table below provides the values for a_{s,j})_i and a_{c,j})_i\n"
278 + "\n"
279 + "The expressions for the fundamental arguments appearing in columns 4 to 8 (luni-solar part) \n"
280 + "and in columns 6 to 17 (planetary part) are those of the IERS Conventions 2000\n"
281 + "\n"
282 + "----------------------------------------------------------------------\n"
283 + "\n"
284 + " i a_{s,j})_i a_{c,j})_i l l' F D Om L_Me L_Ve L_E L_Ma L_J L_Sa L_U L_Ne p_A\n"
285 + "\n"
286 + "----------------------------------------------------------------------\n"
287 + "-16616.99 + 2004191742.88 t - 427219.05 t^2 - 198620.54 t^3 - 46.05 t^4 + 5.98 t^5\n"
288 + "j = 0 Nb of terms = 2\n"
289 + "\n"
290 + " 1 -6844318.44 1328.67 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n"
291 + " 2 0.11 0.00 0 0 4 -4 4 0 0 0 0 0 0 0 0 0\n"
292 + "\n"
293 + "j = 1 Nb of terms = 2\n"
294 + "\n"
295 + " 3 -3328.48 205833.15 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n"
296 + " 4 0.00 -0.10 1 -1 -2 -2 -1 0 0 0 0 0 0 0 0 0\n"
297 + "\n"
298 + " j = 2 Nb of terms = 2\n"
299 + "\n"
300 + " 5 2038.00 82.26 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n"
301 + " 6 -0.12 0.00 1 0 -2 -2 -1 0 0 0 0 0 0 0 0 0\n"
302 + " \n"
303 + " j = 3 Nb of terms = 2\n"
304 + "\n"
305 + " 7 1.76 -20.39 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n"
306 + " 999 0.00 0.20 0 0 0 0 2 0 0 0 0 0 0 0 0 0\n"
307 + "\n"
308 + " j = 4 Nb of terms = 1\n"
309 + " \n"
310 + " 9 -0.10 -0.02 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n";
311 try {
312 new PoissonSeriesParser(17).
313 withPolynomialPart('t', PolynomialParser.Unit.NO_UNITS).
314 withFirstDelaunay(4).
315 withFirstPlanetary(9).
316 withSinCos(0, 2, 1.0, 3, 1.0).
317 parse(new ByteArrayInputStream(data.getBytes()), "dummy");
318 Assertions.fail("an exception should have been thrown");
319 } catch (OrekitException oe) {
320 Assertions.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, oe.getSpecifier());
321 Assertions.assertEquals(53, oe.getParts()[0]);
322 Assertions.assertTrue(((String) oe.getParts()[2]).startsWith(" 999 0.00"));
323 }
324 }
325
326 @Test
327 public void testTruncated() {
328 String data =
329 "Expression for the X coordinate of the CIP in the GCRS based on the IAU2000A\n"
330 + "precession-nutation model\n"
331 + "\n"
332 + "\n"
333 + "----------------------------------------------------------------------\n"
334 + "\n"
335 + "X = polynomial part + non-polynomial part\n"
336 + "\n"
337 + "----------------------------------------------------------------------\n"
338 + "\n"
339 + "Polynomial part (unit microarcsecond)\n"
340 + "\n"
341 + " -16616.99 + 2004191742.88 t - 427219.05 t^2 - 198620.54 t^3 - 46.05 t^4 + 5.98 t^5\n"
342 + "\n"
343 + "----------------------------------------------------------------------\n"
344 + "\n"
345 + "Non-polynomial part (unit microarcsecond)\n"
346 + "(ARG being for various combination of the fundamental arguments of the nutation theory)\n"
347 + "\n"
348 + " Sum_i[a_{s,0})_i * sin(ARG) + a_{c,0})_i * cos(ARG)] \n"
349 + "\n"
350 + "+ Sum_i)j=1,4 [a_{s,j})_i * t^j * sin(ARG) + a_{c,j})_i * cos(ARG)] * t^j]\n"
351 + "\n"
352 + "The Table below provides the values for a_{s,j})_i and a_{c,j})_i\n"
353 + "\n"
354 + "The expressions for the fundamental arguments appearing in columns 4 to 8 (luni-solar part) \n"
355 + "and in columns 6 to 17 (planetary part) are those of the IERS Conventions 2000\n"
356 + "\n"
357 + "----------------------------------------------------------------------\n"
358 + "\n"
359 + " i a_{s,j})_i a_{c,j})_i l l' F D Om L_Me L_Ve L_E L_Ma L_J L_Sa L_U L_Ne p_A\n"
360 + "\n"
361 + "----------------------------------------------------------------------\n"
362 + "-16616.99 + 2004191742.88 t - 427219.05 t^2 - 198620.54 t^3 - 46.05 t^4 + 5.98 t^5\n"
363 + "j = 0 Nb of terms = 2\n"
364 + "\n"
365 + " 1 -6844318.44 1328.67 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n"
366 + " 2 0.11 0.00 0 0 4 -4 4 0 0 0 0 0 0 0 0 0\n"
367 + "\n"
368 + "j = 1 Nb of terms = 2\n"
369 + "\n"
370 + " 3 -3328.48 205833.15 0 0 0 0 1 0 0 0 0 0 0 0 0 0\n";
371 try {
372 new PoissonSeriesParser(17).
373 withPolynomialPart('t', PolynomialParser.Unit.NO_UNITS).
374 withFirstDelaunay(4).
375 withFirstPlanetary(9).
376 withSinCos(0, 2, 1.0, 3, 1.0).
377 parse(new ByteArrayInputStream(data.getBytes()), "dummy");
378 Assertions.fail("an exception should have been thrown");
379 } catch (OrekitException oe) {
380 Assertions.assertEquals(OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE, oe.getSpecifier());
381 }
382 }
383
384 @Test
385 public void testTrue1996Files() {
386 String directory = "/assets/org/orekit/IERS-conventions/";
387 PoissonSeriesParser parser =
388 new PoissonSeriesParser(10).
389 withFirstDelaunay(1).
390 withSinCos(0, 7, 1.0, -1, 1.0).
391 withSinCos(1, 8, 1.0, -1, 1.0);
392 InputStream psiStream =
393 getClass().getResourceAsStream(directory + "1996/tab5.1.txt");
394 Assertions.assertEquals(106,
395 parser.parse(psiStream, "1996/tab5.1.txt").getNonPolynomialSize());
396 parser = parser.withSinCos(0, -1, 1.0, 9, 1.0).withSinCos(1, -1, 1.0, 10, 1.0);
397 InputStream epsilonStream =
398 getClass().getResourceAsStream(directory + "1996/tab5.1.txt");
399 Assertions.assertNotNull(parser.parse(epsilonStream, "1996/tab5.1.txt"));
400 }
401
402 @Test
403 public void testTrue2003Files() {
404 String directory = "/assets/org/orekit/IERS-conventions/";
405 PoissonSeriesParser parser =
406 new PoissonSeriesParser(17).withPolynomialPart('t', PolynomialParser.Unit.NO_UNITS).
407 withFirstDelaunay(4).withFirstPlanetary(9).withSinCos(0, 2, 1.0, 3, 1.0);
408 InputStream xStream =
409 getClass().getResourceAsStream(directory + "2003/tab5.2a.txt");
410 Assertions.assertNotNull(parser.parse(xStream, "2003/tab5.2a.txt"));
411 InputStream yStream =
412 getClass().getResourceAsStream(directory + "2003/tab5.2b.txt");
413 Assertions.assertNotNull(parser.parse(yStream, "2003/tab5.2b.txt"));
414 InputStream zStream =
415 getClass().getResourceAsStream(directory + "2003/tab5.2c.txt");
416 Assertions.assertNotNull(parser.parse(zStream, "2003/tab5.2c.txt"));
417 }
418
419 @Test
420 public void testTrue2010Files() {
421 String directory = "/assets/org/orekit/IERS-conventions/";
422 PoissonSeriesParser parser =
423 new PoissonSeriesParser(17).withPolynomialPart('t', PolynomialParser.Unit.NO_UNITS).
424 withFirstDelaunay(4).withFirstPlanetary(9).withSinCos(0, 2, 1.0, 3, 1.0);
425 InputStream xStream =
426 getClass().getResourceAsStream(directory + "2010/tab5.2a.txt");
427 Assertions.assertNotNull(parser.parse(xStream, "2010/tab5.2a.txt"));
428 InputStream yStream =
429 getClass().getResourceAsStream(directory + "2010/tab5.2b.txt");
430 Assertions.assertNotNull(parser.parse(yStream, "2010/tab5.2b.txt"));
431 InputStream zStream =
432 getClass().getResourceAsStream(directory + "2010/tab5.2d.txt");
433 Assertions.assertNotNull(parser.parse(zStream, "2010/tab5.2d.txt"));
434
435 PoissonSeriesParser correctionParser =
436 new PoissonSeriesParser(14).withFirstDelaunay(4).withSinCos(0, 11, 1.0, 12, 1.0);
437 InputStream xCorrectionStream =
438 getClass().getResourceAsStream(directory + "2010/tab5.1a.txt");
439 Assertions.assertNotNull(correctionParser.parse(xCorrectionStream, "2010/tab5.1a.txt"));
440 correctionParser = correctionParser.withSinCos(0, 13, 1.0, 14, 1.0);
441 InputStream yCorrectionStream =
442 getClass().getResourceAsStream(directory + "2010/tab5.1a.txt");
443 Assertions.assertNotNull(correctionParser.parse(yCorrectionStream, "2010/tab5.1a.txt"));
444
445
446 }
447
448 @Test
449 public void testCorruptedLDelaunayMultiplier() {
450 checkCorrupted("/tides/tab6.5a-corrupted-l-Delaunay-multiplier.txt", "σ₁");
451 }
452
453 @Test
454 public void testCorruptedLPrimeDelaunayMultiplier() {
455 checkCorrupted("/tides/tab6.5a-corrupted-lPrime-Delaunay-multiplier.txt", "Q₁");
456 }
457
458 @Test
459 public void testCorruptedFDelaunayMultiplier() {
460 checkCorrupted("/tides/tab6.5a-corrupted-F-Delaunay-multiplier.txt", "Nτ₁");
461 }
462
463 @Test
464 public void testCorruptedDDelaunayMultiplier() {
465 checkCorrupted("/tides/tab6.5a-corrupted-D-Delaunay-multiplier.txt", "2Q₁");
466 }
467
468 @Test
469 public void testCorruptedOmegaDelaunayMultiplier() {
470 checkCorrupted("/tides/tab6.5a-corrupted-Omega-Delaunay-multiplier.txt", "τ₁");
471 }
472
473 @Test
474 public void testCorruptedDoodsonMultiplier() {
475 checkCorrupted("/tides/tab6.5a-corrupted-Doodson-multiplier.txt", "Lk₁");
476 }
477
478 @Test
479 public void testCorruptedDoodsonNumber() {
480 checkCorrupted("/tides/tab6.5a-corrupted-Doodson-number.txt", "No₁");
481 }
482
483 private void checkCorrupted(String resourceName, String lineStart) {
484 try {
485 PoissonSeriesParser parser =
486 new PoissonSeriesParser(18).
487 withOptionalColumn(1).
488 withDoodson(4, 3).
489 withFirstDelaunay(10).
490 withSinCos(0, 18, 1.0e-12, 17, 1.0e-12);
491 parser.parse(getClass().getResourceAsStream(resourceName), resourceName);
492 Assertions.fail("an exception should have been thrown");
493 } catch (OrekitException oe) {
494 if (lineStart == null) {
495 Assertions.assertEquals(OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE, oe.getSpecifier());
496 } else {
497 Assertions.assertEquals(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE, oe.getSpecifier());
498 Assertions.assertTrue(((String) oe.getParts()[2]).trim().startsWith(lineStart));
499 }
500 } catch (Exception e) {
501 Assertions.fail("wrong exception caught: " + e);
502 }
503 }
504
505 @Test
506 public void testGammaTauForbidden() {
507 try {
508 new PoissonSeriesParser(18).withGamma(4).withDoodson(4, 3);
509 Assertions.fail("an exception should have been thrown");
510 } catch (OrekitException oe) {
511 Assertions.assertEquals(OrekitMessages.CANNOT_PARSE_BOTH_TAU_AND_GAMMA, oe.getSpecifier());
512 }
513 }
514
515 @Test
516 public void testTauGammaForbidden() {
517 try {
518 new PoissonSeriesParser(18).withDoodson(4, 3).withGamma(4);
519 Assertions.fail("an exception should have been thrown");
520 } catch (OrekitException oe) {
521 Assertions.assertEquals(OrekitMessages.CANNOT_PARSE_BOTH_TAU_AND_GAMMA, oe.getSpecifier());
522 }
523 }
524
525 @Test
526 public void testCompile() throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
527 String directory = "/assets/org/orekit/IERS-conventions/";
528 PoissonSeriesParser parser =
529 new PoissonSeriesParser(17).withPolynomialPart('t', PolynomialParser.Unit.NO_UNITS).
530 withFirstDelaunay(4).withFirstPlanetary(9).withSinCos(0, 2, 1.0, 3, 1.0);
531 InputStream xStream =
532 getClass().getResourceAsStream(directory + "2010/tab5.2a.txt");
533 PoissonSeries xSeries = parser.parse(xStream, "2010/tab5.2a.txt");
534 InputStream yStream =
535 getClass().getResourceAsStream(directory + "2010/tab5.2b.txt");
536 PoissonSeries ySeries = parser.parse(yStream, "2010/tab5.2b.txt");
537 InputStream zStream =
538 getClass().getResourceAsStream(directory + "2010/tab5.2d.txt");
539 PoissonSeries sSeries = parser.parse(zStream, "2010/tab5.2d.txt");
540 PoissonSeries.CompiledSeries xysSeries =
541 PoissonSeries.compile(xSeries, ySeries, sSeries);
542
543 Method m = IERSConventions.class.getDeclaredMethod("getNutationArguments", TimeScale.class);
544 m.setAccessible(true);
545 FundamentalNutationArguments arguments =
546 (FundamentalNutationArguments) m.invoke(IERSConventions.IERS_2010, (TimeScale) null);
547
548 for (double dt = 0; dt < Constants.JULIAN_YEAR; dt += Constants.JULIAN_DAY) {
549 AbsoluteDate date = AbsoluteDate.J2000_EPOCH.shiftedBy(dt);
550 BodiesElements elements = arguments.evaluateAll(date);
551 double x = xSeries.value(elements);
552 double y = ySeries.value(elements);
553 double s = sSeries.value(elements);
554 double[] xys = xysSeries.value(elements);
555 Assertions.assertEquals(x, xys[0], 1.0e-15 * FastMath.abs(x));
556 Assertions.assertEquals(y, xys[1], 1.0e-15 * FastMath.abs(y));
557 Assertions.assertEquals(s, xys[2], 1.0e-15 * FastMath.abs(s));
558 }
559
560 }
561
562 @Test
563 public void testDerivativesAsField() {
564
565 Utils.setDataRoot("regular-data");
566 String directory = "/assets/org/orekit/IERS-conventions/";
567 PoissonSeriesParser parser =
568 new PoissonSeriesParser(17).withPolynomialPart('t', PolynomialParser.Unit.NO_UNITS).
569 withFirstDelaunay(4).withFirstPlanetary(9).withSinCos(0, 2, 1.0, 3, 1.0);
570 PoissonSeries xSeries =
571 parser.parse(getClass().getResourceAsStream(directory + "2010/tab5.2a.txt"), "2010/tab5.2a.txt");
572 PoissonSeries ySeries =
573 parser.parse(getClass().getResourceAsStream(directory + "2010/tab5.2b.txt"), "2010/tab5.2b.txt");
574 PoissonSeries zSeries =
575 parser.parse(getClass().getResourceAsStream(directory + "2010/tab5.2d.txt"), "2010/tab5.2d.txt");
576
577 TimeScale ut1 = TimeScalesFactory.getUT1(FramesFactory.getEOPHistory(IERSConventions.IERS_2010, true));
578 FundamentalNutationArguments arguments = IERSConventions.IERS_2010.getNutationArguments(ut1);
579
580 Coordinate xCoordinate = new Coordinate(xSeries, arguments);
581 Coordinate yCoordinate = new Coordinate(ySeries, arguments);
582 Coordinate zCoordinate = new Coordinate(zSeries, arguments);
583 UnivariateDifferentiableFunction dx = new FiniteDifferencesDifferentiator(4, 0.4).differentiate(xCoordinate);
584 UnivariateDifferentiableFunction dy = new FiniteDifferencesDifferentiator(4, 0.4).differentiate(yCoordinate);
585 UnivariateDifferentiableFunction dz = new FiniteDifferencesDifferentiator(4, 0.4).differentiate(zCoordinate);
586
587 DSFactory factory = new DSFactory(1, 1);
588 FieldAbsoluteDate<DerivativeStructure> ds2000 = FieldAbsoluteDate.getJ2000Epoch(factory.getDerivativeField());
589 for (double t = 0; t < Constants.JULIAN_DAY; t += 120) {
590
591 final FieldAbsoluteDate<DerivativeStructure> date = ds2000.shiftedBy(factory.variable(0, t));
592
593
594 FieldBodiesElements<DerivativeStructure> elements = arguments.evaluateAll(date);
595 Assertions.assertEquals(0.0, elements.getDate().durationFrom(date).getValue(), 1.0e-15);
596 DerivativeStructure xDirect = xSeries.value(elements);
597 DerivativeStructure yDirect = ySeries.value(elements);
598 DerivativeStructure zDirect = zSeries.value(elements);
599
600
601 DerivativeStructure zero = factory.variable(0, 0.0);
602 xCoordinate.setDate(date.toAbsoluteDate());
603 DerivativeStructure xFinite = dx.value(zero);
604 yCoordinate.setDate(date.toAbsoluteDate());
605 DerivativeStructure yFinite = dy.value(zero);
606 zCoordinate.setDate(date.toAbsoluteDate());
607 DerivativeStructure zFinite = dz.value(zero);
608
609 Assertions.assertEquals(xFinite.getValue(), xDirect.getValue(), FastMath.abs(7.0e-15 * xFinite.getValue()));
610 Assertions.assertEquals(xFinite.getPartialDerivative(1), xDirect.getPartialDerivative(1), FastMath.abs(2.0e-07 * xFinite.getPartialDerivative(1)));
611 Assertions.assertEquals(yFinite.getValue(), yDirect.getValue(), FastMath.abs(7.0e-15 * yFinite.getValue()));
612 Assertions.assertEquals(yFinite.getPartialDerivative(1), yDirect.getPartialDerivative(1), FastMath.abs(2.0e-07 * yFinite.getPartialDerivative(1)));
613 Assertions.assertEquals(zFinite.getValue(), zDirect.getValue(), FastMath.abs(7.0e-15 * zFinite.getValue()));
614 Assertions.assertEquals(zFinite.getPartialDerivative(1), zDirect.getPartialDerivative(1), FastMath.abs(2.0e-07 * zFinite.getPartialDerivative(1)));
615
616 }
617
618 }
619
620 @Test
621 public void testDerivativesFromDoubleAPI() {
622 Utils.setDataRoot("regular-data");
623 String directory = "/assets/org/orekit/IERS-conventions/";
624 PoissonSeriesParser parser =
625 new PoissonSeriesParser(17).withPolynomialPart('t', PolynomialParser.Unit.NO_UNITS).
626 withFirstDelaunay(4).withFirstPlanetary(9).withSinCos(0, 2, 1.0, 3, 1.0);
627 InputStream xStream =
628 getClass().getResourceAsStream(directory + "2010/tab5.2a.txt");
629 PoissonSeries xSeries = parser.parse(xStream, "2010/tab5.2a.txt");
630 InputStream yStream =
631 getClass().getResourceAsStream(directory + "2010/tab5.2b.txt");
632 PoissonSeries ySeries = parser.parse(yStream, "2010/tab5.2b.txt");
633 InputStream zStream =
634 getClass().getResourceAsStream(directory + "2010/tab5.2d.txt");
635 PoissonSeries zSeries = parser.parse(zStream, "2010/tab5.2d.txt");
636
637 final PoissonSeries.CompiledSeries compiled =
638 PoissonSeries.compile(xSeries, ySeries, zSeries);
639
640 TimeScale ut1 = TimeScalesFactory.getUT1(FramesFactory.getEOPHistory(IERSConventions.IERS_2010, true));
641 final FundamentalNutationArguments arguments = IERSConventions.IERS_2010.getNutationArguments(ut1);
642
643 UnivariateDifferentiableVectorFunction finite = new FiniteDifferencesDifferentiator(4, 0.4).differentiate((double t) ->
644 compiled.value(arguments.evaluateAll(AbsoluteDate.J2000_EPOCH.shiftedBy(t))));
645
646 DSFactory factory = new DSFactory(1, 1);
647 for (double t = 0; t < Constants.JULIAN_DAY; t += 120) {
648
649
650 double[] dAPI = compiled.derivative(arguments.evaluateAll(AbsoluteDate.J2000_EPOCH.shiftedBy(t)));
651
652
653 DerivativeStructure[] d = finite.value(factory.variable(0, t));
654
655 Assertions.assertEquals(d.length, dAPI.length);
656 for (int i = 0; i < d.length; ++i) {
657 Assertions.assertEquals(d[i].getPartialDerivative(1), dAPI[i], FastMath.abs(2.0e-7 * d[i].getPartialDerivative(1)));
658 }
659
660 }
661
662 }
663
664 @Test
665 public void testDerivativesFromFieldAPI() {
666 Utils.setDataRoot("regular-data");
667 String directory = "/assets/org/orekit/IERS-conventions/";
668 PoissonSeriesParser parser =
669 new PoissonSeriesParser(17).withPolynomialPart('t', PolynomialParser.Unit.NO_UNITS).
670 withFirstDelaunay(4).withFirstPlanetary(9).withSinCos(0, 2, 1.0, 3, 1.0);
671 InputStream xStream =
672 getClass().getResourceAsStream(directory + "2010/tab5.2a.txt");
673 PoissonSeries xSeries = parser.parse(xStream, "2010/tab5.2a.txt");
674 InputStream yStream =
675 getClass().getResourceAsStream(directory + "2010/tab5.2b.txt");
676 PoissonSeries ySeries = parser.parse(yStream, "2010/tab5.2b.txt");
677 InputStream zStream =
678 getClass().getResourceAsStream(directory + "2010/tab5.2d.txt");
679 PoissonSeries zSeries = parser.parse(zStream, "2010/tab5.2d.txt");
680
681 final PoissonSeries.CompiledSeries compiled =
682 PoissonSeries.compile(xSeries, ySeries, zSeries);
683
684 TimeScale ut1 = TimeScalesFactory.getUT1(FramesFactory.getEOPHistory(IERSConventions.IERS_2010, true));
685 final FundamentalNutationArguments arguments = IERSConventions.IERS_2010.getNutationArguments(ut1);
686
687 UnivariateDifferentiableVectorFunction finite = new FiniteDifferencesDifferentiator(4, 0.4).differentiate((double t) ->
688 compiled.value(arguments.evaluateAll(AbsoluteDate.J2000_EPOCH.shiftedBy(t))));
689
690 DSFactory factory = new DSFactory(1, 1);
691 for (double t = 0; t < Constants.JULIAN_DAY; t += 120) {
692
693
694 Binary64[] dAPI = compiled.derivative(arguments.evaluateAll(FieldAbsoluteDate.getJ2000Epoch(Binary64Field.getInstance()).shiftedBy(t)));
695
696
697 DerivativeStructure[] d = finite.value(factory.variable(0, t));
698
699 Assertions.assertEquals(d.length, dAPI.length);
700 for (int i = 0; i < d.length; ++i) {
701 Assertions.assertEquals(d[i].getPartialDerivative(1), dAPI[i].getReal(), FastMath.abs(2.0e-7 * d[i].getPartialDerivative(1)));
702 }
703
704 }
705
706 }
707
708 private static class Coordinate implements UnivariateFunction {
709 private final PoissonSeries series;
710 private final FundamentalNutationArguments arguments;
711 private AbsoluteDate date;
712 Coordinate(PoissonSeries series, FundamentalNutationArguments arguments) {
713 this.series = series;
714 this.arguments = arguments;
715 this.date = AbsoluteDate.J2000_EPOCH;
716 }
717 void setDate(AbsoluteDate date) {
718 this.date = date;
719 }
720 public double value(double x) {
721 return series.value(arguments.evaluateAll(date.shiftedBy(x)));
722 }
723 }
724
725 }