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