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