1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.data;
18
19 import java.io.BufferedReader;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.InputStreamReader;
23 import java.io.Serializable;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
31
32 import org.hipparchus.RealFieldElement;
33 import org.hipparchus.exception.DummyLocalizable;
34 import org.hipparchus.util.FastMath;
35 import org.orekit.errors.OrekitException;
36 import org.orekit.errors.OrekitInternalError;
37 import org.orekit.errors.OrekitMessages;
38 import org.orekit.time.AbsoluteDate;
39 import org.orekit.time.FieldAbsoluteDate;
40 import org.orekit.time.TimeScalarFunction;
41 import org.orekit.time.TimeScale;
42 import org.orekit.utils.Constants;
43 import org.orekit.utils.IERSConventions;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public class FundamentalNutationArguments implements Serializable {
61
62
63 private static final long serialVersionUID = 20131209L;
64
65
66 private final IERSConventions conventions;
67
68
69 private final TimeScale timeScale;
70
71
72 private final transient TimeScalarFunction gmstFunction;
73
74
75 private final transient TimeScalarFunction gmstRateFunction;
76
77
78
79
80 private final double[] lCoefficients;
81
82
83 private final double[] lPrimeCoefficients;
84
85
86 private final double[] fCoefficients;
87
88
89 private final double[] dCoefficients;
90
91
92 private final double[] omegaCoefficients;
93
94
95
96
97 private final double[] lMeCoefficients;
98
99
100 private final double[] lVeCoefficients;
101
102
103 private final double[] lECoefficients;
104
105
106 private final double[] lMaCoefficients;
107
108
109 private final double[] lJCoefficients;
110
111
112 private final double[] lSaCoefficients;
113
114
115 private final double[] lUCoefficients;
116
117
118 private final double[] lNeCoefficients;
119
120
121 private final double[] paCoefficients;
122
123
124
125
126
127
128
129
130 public FundamentalNutationArguments(final IERSConventions conventions,
131 final TimeScale timeScale,
132 final InputStream stream, final String name) {
133 this(conventions, timeScale, parseCoefficients(stream, name));
134 }
135
136
137
138
139
140
141
142
143
144 public FundamentalNutationArguments(final IERSConventions conventions, final TimeScale timeScale,
145 final List<double[]> coefficients) {
146 this.conventions = conventions;
147 this.timeScale = timeScale;
148 this.gmstFunction = (timeScale == null) ? null : conventions.getGMSTFunction(timeScale);
149 this.gmstRateFunction = (timeScale == null) ? null : conventions.getGMSTRateFunction(timeScale);
150 this.lCoefficients = coefficients.get( 0);
151 this.lPrimeCoefficients = coefficients.get( 1);
152 this.fCoefficients = coefficients.get( 2);
153 this.dCoefficients = coefficients.get( 3);
154 this.omegaCoefficients = coefficients.get( 4);
155 this.lMeCoefficients = coefficients.get( 5);
156 this.lVeCoefficients = coefficients.get( 6);
157 this.lECoefficients = coefficients.get( 7);
158 this.lMaCoefficients = coefficients.get( 8);
159 this.lJCoefficients = coefficients.get( 9);
160 this.lSaCoefficients = coefficients.get(10);
161 this.lUCoefficients = coefficients.get(11);
162 this.lNeCoefficients = coefficients.get(12);
163 this.paCoefficients = coefficients.get(13);
164 }
165
166
167
168
169
170
171 private static List<double[]> parseCoefficients(final InputStream stream, final String name) {
172
173 if (stream == null) {
174 throw new OrekitException(OrekitMessages.UNABLE_TO_FIND_FILE, name);
175 }
176
177 try {
178
179 final DefinitionParser definitionParser = new DefinitionParser();
180
181
182 final BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
183 int lineNumber = 0;
184
185
186 final int n = FundamentalName.values().length;
187 final Map<FundamentalName, double[]> polynomials = new HashMap<FundamentalName, double[]>(n);
188 for (String line = reader.readLine(); line != null; line = reader.readLine()) {
189 lineNumber++;
190 if (definitionParser.parseDefinition(line, lineNumber, name)) {
191 polynomials.put(definitionParser.getParsedName(),
192 definitionParser.getParsedPolynomial());
193 }
194 }
195
196 final List<double[]> coefficients = new ArrayList<double[]>(n);
197 coefficients.add(getCoefficients(FundamentalName.L, polynomials, name));
198 coefficients.add(getCoefficients(FundamentalName.L_PRIME, polynomials, name));
199 coefficients.add(getCoefficients(FundamentalName.F, polynomials, name));
200 coefficients.add(getCoefficients(FundamentalName.D, polynomials, name));
201 coefficients.add(getCoefficients(FundamentalName.OMEGA, polynomials, name));
202 if (polynomials.containsKey(FundamentalName.L_ME)) {
203
204 coefficients.add(getCoefficients(FundamentalName.L_ME, polynomials, name));
205 coefficients.add(getCoefficients(FundamentalName.L_VE, polynomials, name));
206 coefficients.add(getCoefficients(FundamentalName.L_E, polynomials, name));
207 coefficients.add(getCoefficients(FundamentalName.L_MA, polynomials, name));
208 coefficients.add(getCoefficients(FundamentalName.L_J, polynomials, name));
209 coefficients.add(getCoefficients(FundamentalName.L_SA, polynomials, name));
210 coefficients.add(getCoefficients(FundamentalName.L_U, polynomials, name));
211 coefficients.add(getCoefficients(FundamentalName.L_NE, polynomials, name));
212 coefficients.add(getCoefficients(FundamentalName.PA, polynomials, name));
213 } else {
214
215 final double[] zero = new double[] {
216 0.0
217 };
218 while (coefficients.size() < n) {
219 coefficients.add(zero);
220 }
221 }
222
223 return coefficients;
224
225 } catch (IOException ioe) {
226 throw new OrekitException(ioe, new DummyLocalizable(ioe.getMessage()));
227 }
228
229 }
230
231
232
233
234
235
236
237 private static double[] getCoefficients(final FundamentalName argument,
238 final Map<FundamentalName, double[]> polynomials,
239 final String fileName) {
240 if (!polynomials.containsKey(argument)) {
241 throw new OrekitException(OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE, fileName);
242 }
243 return polynomials.get(argument);
244 }
245
246
247
248
249
250
251 private double value(final double tc, final double[] coefficients) {
252 double value = 0;
253 for (int i = coefficients.length - 1; i >= 0; --i) {
254 value = coefficients[i] + tc * value;
255 }
256 return value;
257 }
258
259
260
261
262
263
264 private double derivative(final double tc, final double[] coefficients) {
265 double derivative = 0;
266 for (int i = coefficients.length - 1; i > 0; --i) {
267 derivative = i * coefficients[i] + tc * derivative;
268 }
269 return derivative / Constants.JULIAN_CENTURY;
270 }
271
272
273
274
275
276
277
278 private <T extends RealFieldElement<T>> T value(final T tc, final double[] coefficients) {
279 T value = tc.getField().getZero();
280 for (int i = coefficients.length - 1; i >= 0; --i) {
281 value = tc.multiply(value).add(coefficients[i]);
282 }
283 return value;
284 }
285
286
287
288
289
290
291
292 private <T extends RealFieldElement<T>> T derivative(final T tc, final double[] coefficients) {
293 T derivative = tc.getField().getZero();
294 for (int i = coefficients.length - 1; i > 0; --i) {
295 derivative = tc.multiply(derivative).add(i * coefficients[i]);
296 }
297 return derivative.divide(Constants.JULIAN_CENTURY);
298 }
299
300
301
302
303
304 public BodiesElements evaluateAll(final AbsoluteDate date) {
305
306 final double tc = conventions.evaluateTC(date);
307 final double gamma = gmstFunction == null ?
308 Double.NaN : gmstFunction.value(date) + FastMath.PI;
309 final double gammaDot = gmstRateFunction == null ?
310 Double.NaN : gmstRateFunction.value(date);
311
312 return new BodiesElements(date, tc, gamma, gammaDot,
313 value(tc, lCoefficients),
314 derivative(tc, lCoefficients),
315 value(tc, lPrimeCoefficients),
316 derivative(tc, lPrimeCoefficients),
317 value(tc, fCoefficients),
318 derivative(tc, fCoefficients),
319 value(tc, dCoefficients),
320 derivative(tc, dCoefficients),
321 value(tc, omegaCoefficients),
322 derivative(tc, omegaCoefficients),
323 value(tc, lMeCoefficients),
324 derivative(tc, lMeCoefficients),
325 value(tc, lVeCoefficients),
326 derivative(tc, lVeCoefficients),
327 value(tc, lECoefficients),
328 derivative(tc, lECoefficients),
329 value(tc, lMaCoefficients),
330 derivative(tc, lMaCoefficients),
331 value(tc, lJCoefficients),
332 derivative(tc, lJCoefficients),
333 value(tc, lSaCoefficients),
334 derivative(tc, lSaCoefficients),
335 value(tc, lUCoefficients),
336 derivative(tc, lUCoefficients),
337 value(tc, lNeCoefficients),
338 derivative(tc, lNeCoefficients),
339 value(tc, paCoefficients),
340 derivative(tc, paCoefficients));
341
342 }
343
344
345
346
347
348
349 public <T extends RealFieldElement<T>> FieldBodiesElements<T> evaluateAll(final FieldAbsoluteDate<T> date) {
350
351 final T tc = conventions.evaluateTC(date);
352 final T gamma = gmstFunction == null ?
353 tc.getField().getZero().add(Double.NaN) : gmstFunction.value(date).add(FastMath.PI);
354 final T gammaDot = gmstRateFunction == null ?
355 tc.getField().getZero().add(Double.NaN) : gmstRateFunction.value(date);
356
357 return new FieldBodiesElements<>(date, tc, gamma, gammaDot,
358 value(tc, lCoefficients),
359 derivative(tc, lCoefficients),
360 value(tc, lPrimeCoefficients),
361 derivative(tc, lPrimeCoefficients),
362 value(tc, fCoefficients),
363 derivative(tc, fCoefficients),
364 value(tc, dCoefficients),
365 derivative(tc, dCoefficients),
366 value(tc, omegaCoefficients),
367 derivative(tc, omegaCoefficients),
368 value(tc, lMeCoefficients),
369 derivative(tc, lMeCoefficients),
370 value(tc, lVeCoefficients),
371 derivative(tc, lVeCoefficients),
372 value(tc, lECoefficients),
373 derivative(tc, lECoefficients),
374 value(tc, lMaCoefficients),
375 derivative(tc, lMaCoefficients),
376 value(tc, lJCoefficients),
377 derivative(tc, lJCoefficients),
378 value(tc, lSaCoefficients),
379 derivative(tc, lSaCoefficients),
380 value(tc, lUCoefficients),
381 derivative(tc, lUCoefficients),
382 value(tc, lNeCoefficients),
383 derivative(tc, lNeCoefficients),
384 value(tc, paCoefficients),
385 derivative(tc, paCoefficients));
386
387 }
388
389
390
391
392
393
394
395 private Object writeReplace() {
396 return new DataTransferObject(conventions, timeScale,
397 Arrays.asList(lCoefficients, lPrimeCoefficients, fCoefficients,
398 dCoefficients, omegaCoefficients,
399 lMeCoefficients, lVeCoefficients, lECoefficients,
400 lMaCoefficients, lJCoefficients, lSaCoefficients,
401 lUCoefficients, lNeCoefficients, paCoefficients));
402 }
403
404
405 private static class DataTransferObject implements Serializable {
406
407
408 private static final long serialVersionUID = 20131209L;
409
410
411 private final IERSConventions conventions;
412
413
414 private final TimeScale timeScale;
415
416
417 private final List<double[]> coefficients;
418
419
420
421
422
423
424 DataTransferObject(final IERSConventions conventions, final TimeScale timeScale,
425 final List<double[]> coefficients) {
426 this.conventions = conventions;
427 this.timeScale = timeScale;
428 this.coefficients = coefficients;
429 }
430
431
432
433
434 private Object readResolve() {
435 try {
436
437 return new FundamentalNutationArguments(conventions, timeScale, coefficients);
438 } catch (OrekitException oe) {
439 throw new OrekitInternalError(oe);
440 }
441 }
442
443 }
444
445
446 private enum FundamentalName {
447
448
449 L() {
450
451 public String getArgumentName() {
452 return "l";
453 }
454 },
455
456
457 L_PRIME() {
458
459 public String getArgumentName() {
460 return "l'";
461 }
462 },
463
464
465 F() {
466
467 public String getArgumentName() {
468 return "F";
469 }
470 },
471
472
473 D() {
474
475 public String getArgumentName() {
476 return "D";
477 }
478 },
479
480
481 OMEGA() {
482
483 public String getArgumentName() {
484 return "\u03a9";
485 }
486 },
487
488
489 L_ME() {
490
491 public String getArgumentName() {
492 return "LMe";
493 }
494 },
495
496
497 L_VE() {
498
499 public String getArgumentName() {
500 return "LVe";
501 }
502 },
503
504
505 L_E() {
506
507 public String getArgumentName() {
508 return "LE";
509 }
510 },
511
512
513 L_MA() {
514
515 public String getArgumentName() {
516 return "LMa";
517 }
518 },
519
520
521 L_J() {
522
523 public String getArgumentName() {
524 return "LJ";
525 }
526 },
527
528
529 L_SA() {
530
531 public String getArgumentName() {
532 return "LSa";
533 }
534 },
535
536
537 L_U() {
538
539 public String getArgumentName() {
540 return "LU";
541 }
542 },
543
544
545 L_NE() {
546
547 public String getArgumentName() {
548 return "LNe";
549 }
550 },
551
552
553 PA() {
554
555 public String getArgumentName() {
556 return "pA";
557 }
558 };
559
560
561
562
563 public abstract String getArgumentName();
564
565 }
566
567
568 private static class DefinitionParser {
569
570
571 private final Pattern pattern;
572
573
574 private PolynomialParser polynomialParser;
575
576
577 private FundamentalName parsedName;
578
579
580 private double[] parsedPolynomial;
581
582
583 DefinitionParser() {
584
585
586
587
588
589 final String unicodeIdenticalTo = "\u2261";
590
591
592 final StringBuilder builder = new StringBuilder();
593 for (final FundamentalName fn : FundamentalName.values()) {
594 if (builder.length() > 0) {
595 builder.append('|');
596 }
597 builder.append(fn.getArgumentName());
598 }
599 final String fundamentalName = "\\p{Space}*((?:" + builder.toString() + ")+)";
600 pattern = Pattern.compile("\\p{Space}*F\\p{Digit}+\\p{Space}*" + unicodeIdenticalTo +
601 fundamentalName + "\\p{Space}*=\\p{Space}*(.*)");
602
603 polynomialParser = new PolynomialParser('t', PolynomialParser.Unit.NO_UNITS);
604
605 }
606
607
608
609
610
611
612
613 public boolean parseDefinition(final String line, final int lineNumber, final String fileName) {
614
615 parsedName = null;
616 parsedPolynomial = null;
617
618 final Matcher matcher = pattern.matcher(line);
619 if (matcher.matches()) {
620 for (FundamentalName fn : FundamentalName.values()) {
621 if (fn.getArgumentName().equals(matcher.group(1))) {
622 parsedName = fn;
623 }
624 }
625
626
627 parsedPolynomial = polynomialParser.parse(matcher.group(2));
628
629 return true;
630
631 } else {
632 return false;
633 }
634
635 }
636
637
638
639
640 public FundamentalName getParsedName() {
641 return parsedName;
642 }
643
644
645
646
647 public double[] getParsedPolynomial() {
648 return parsedPolynomial.clone();
649 }
650
651 }
652
653 }