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.analysis.differentiation.DerivativeStructure;
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.TimeFunction;
40 import org.orekit.time.TimeScale;
41 import org.orekit.utils.IERSConventions;
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public class FundamentalNutationArguments implements Serializable {
59
60
61 private static final long serialVersionUID = 20131209L;
62
63
64 private final IERSConventions conventions;
65
66
67 private final TimeScale timeScale;
68
69
70 private final transient TimeFunction<DerivativeStructure> gmstFunction;
71
72
73
74
75 private final double[] lCoefficients;
76
77
78 private final double[] lPrimeCoefficients;
79
80
81 private final double[] fCoefficients;
82
83
84 private final double[] dCoefficients;
85
86
87 private final double[] omegaCoefficients;
88
89
90
91
92 private final double[] lMeCoefficients;
93
94
95 private final double[] lVeCoefficients;
96
97
98 private final double[] lECoefficients;
99
100
101 private final double[] lMaCoefficients;
102
103
104 private final double[] lJCoefficients;
105
106
107 private final double[] lSaCoefficients;
108
109
110 private final double[] lUCoefficients;
111
112
113 private final double[] lNeCoefficients;
114
115
116 private final double[] paCoefficients;
117
118
119
120
121
122
123
124
125
126 public FundamentalNutationArguments(final IERSConventions conventions,
127 final TimeScale timeScale,
128 final InputStream stream, final String name)
129 throws OrekitException {
130 this(conventions, timeScale, parseCoefficients(stream, name));
131 }
132
133
134
135
136
137
138
139
140
141
142 public FundamentalNutationArguments(final IERSConventions conventions, final TimeScale timeScale,
143 final List<double[]> coefficients)
144 throws OrekitException {
145 this.conventions = conventions;
146 this.timeScale = timeScale;
147 this.gmstFunction = (timeScale == null) ? null : conventions.getGMSTFunction(timeScale);
148 this.lCoefficients = coefficients.get( 0);
149 this.lPrimeCoefficients = coefficients.get( 1);
150 this.fCoefficients = coefficients.get( 2);
151 this.dCoefficients = coefficients.get( 3);
152 this.omegaCoefficients = coefficients.get( 4);
153 this.lMeCoefficients = coefficients.get( 5);
154 this.lVeCoefficients = coefficients.get( 6);
155 this.lECoefficients = coefficients.get( 7);
156 this.lMaCoefficients = coefficients.get( 8);
157 this.lJCoefficients = coefficients.get( 9);
158 this.lSaCoefficients = coefficients.get(10);
159 this.lUCoefficients = coefficients.get(11);
160 this.lNeCoefficients = coefficients.get(12);
161 this.paCoefficients = coefficients.get(13);
162 }
163
164
165
166
167
168
169
170 private static List<double[]> parseCoefficients(final InputStream stream, final String name)
171 throws OrekitException {
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
238 private static double[] getCoefficients(final FundamentalName argument,
239 final Map<FundamentalName, double[]> polynomials,
240 final String fileName)
241 throws OrekitException {
242 if (!polynomials.containsKey(argument)) {
243 throw new OrekitException(OrekitMessages.NOT_A_SUPPORTED_IERS_DATA_FILE, fileName);
244 }
245 return polynomials.get(argument);
246 }
247
248
249
250
251
252
253 private double value(final double tc, final double[] coefficients) {
254 double value = 0;
255 for (int i = coefficients.length - 1; i >= 0; --i) {
256 value = coefficients[i] + tc * value;
257 }
258 return value;
259 }
260
261
262
263
264
265 public BodiesElements evaluateAll(final AbsoluteDate date) {
266
267 final double tc = conventions.evaluateTC(date);
268 final double gamma = gmstFunction == null ?
269 Double.NaN : gmstFunction.value(date).getValue() + FastMath.PI;
270
271 return new BodiesElements(date, tc, gamma,
272 value(tc, lCoefficients),
273 value(tc, lPrimeCoefficients),
274 value(tc, fCoefficients),
275 value(tc, dCoefficients),
276 value(tc, omegaCoefficients),
277 value(tc, lMeCoefficients),
278 value(tc, lVeCoefficients),
279 value(tc, lECoefficients),
280 value(tc, lMaCoefficients),
281 value(tc, lJCoefficients),
282 value(tc, lSaCoefficients),
283 value(tc, lUCoefficients),
284 value(tc, lNeCoefficients),
285 value(tc, paCoefficients));
286
287 }
288
289
290
291
292
293
294 private DerivativeStructure value(final DerivativeStructure tc, final double[] coefficients) {
295 DerivativeStructure value = tc.getField().getZero();
296 for (int i = coefficients.length - 1; i >= 0; --i) {
297 value = value.multiply(tc).add(coefficients[i]);
298 }
299 return value;
300 }
301
302
303
304
305
306
307
308 public FieldBodiesElements<DerivativeStructure> evaluateDerivative(final AbsoluteDate date) {
309
310 final DerivativeStructure tc = conventions.dsEvaluateTC(date);
311
312 return new FieldBodiesElements<DerivativeStructure>(date, tc,
313 gmstFunction.value(date).add(FastMath.PI),
314 value(tc, lCoefficients),
315 value(tc, lPrimeCoefficients),
316 value(tc, fCoefficients),
317 value(tc, dCoefficients),
318 value(tc, omegaCoefficients),
319 value(tc, lMeCoefficients),
320 value(tc, lVeCoefficients),
321 value(tc, lECoefficients),
322 value(tc, lMaCoefficients),
323 value(tc, lJCoefficients),
324 value(tc, lSaCoefficients),
325 value(tc, lUCoefficients),
326 value(tc, lNeCoefficients),
327 value(tc, paCoefficients));
328
329 }
330
331
332
333
334
335
336
337 private Object writeReplace() {
338 return new DataTransferObject(conventions, timeScale,
339 Arrays.asList(lCoefficients, lPrimeCoefficients, fCoefficients,
340 dCoefficients, omegaCoefficients,
341 lMeCoefficients, lVeCoefficients, lECoefficients,
342 lMaCoefficients, lJCoefficients, lSaCoefficients,
343 lUCoefficients, lNeCoefficients, paCoefficients));
344 }
345
346
347 private static class DataTransferObject implements Serializable {
348
349
350 private static final long serialVersionUID = 20131209L;
351
352
353 private final IERSConventions conventions;
354
355
356 private final TimeScale timeScale;
357
358
359 private final List<double[]> coefficients;
360
361
362
363
364
365
366 DataTransferObject(final IERSConventions conventions, final TimeScale timeScale,
367 final List<double[]> coefficients) {
368 this.conventions = conventions;
369 this.timeScale = timeScale;
370 this.coefficients = coefficients;
371 }
372
373
374
375
376 private Object readResolve() {
377 try {
378
379 return new FundamentalNutationArguments(conventions, timeScale, coefficients);
380 } catch (OrekitException oe) {
381 throw new OrekitInternalError(oe);
382 }
383 }
384
385 }
386
387
388 private enum FundamentalName {
389
390
391 L() {
392
393 public String getArgumentName() {
394 return "l";
395 }
396 },
397
398
399 L_PRIME() {
400
401 public String getArgumentName() {
402 return "l'";
403 }
404 },
405
406
407 F() {
408
409 public String getArgumentName() {
410 return "F";
411 }
412 },
413
414
415 D() {
416
417 public String getArgumentName() {
418 return "D";
419 }
420 },
421
422
423 OMEGA() {
424
425 public String getArgumentName() {
426 return "\u03a9";
427 }
428 },
429
430
431 L_ME() {
432
433 public String getArgumentName() {
434 return "LMe";
435 }
436 },
437
438
439 L_VE() {
440
441 public String getArgumentName() {
442 return "LVe";
443 }
444 },
445
446
447 L_E() {
448
449 public String getArgumentName() {
450 return "LE";
451 }
452 },
453
454
455 L_MA() {
456
457 public String getArgumentName() {
458 return "LMa";
459 }
460 },
461
462
463 L_J() {
464
465 public String getArgumentName() {
466 return "LJ";
467 }
468 },
469
470
471 L_SA() {
472
473 public String getArgumentName() {
474 return "LSa";
475 }
476 },
477
478
479 L_U() {
480
481 public String getArgumentName() {
482 return "LU";
483 }
484 },
485
486
487 L_NE() {
488
489 public String getArgumentName() {
490 return "LNe";
491 }
492 },
493
494
495 PA() {
496
497 public String getArgumentName() {
498 return "pA";
499 }
500 };
501
502
503
504
505 public abstract String getArgumentName();
506
507 }
508
509
510 private static class DefinitionParser {
511
512
513 private final Pattern pattern;
514
515
516 private PolynomialParser polynomialParser;
517
518
519 private FundamentalName parsedName;
520
521
522 private double[] parsedPolynomial;
523
524
525 DefinitionParser() {
526
527
528
529
530
531 final String unicodeIdenticalTo = "\u2261";
532
533
534 final StringBuilder builder = new StringBuilder();
535 for (final FundamentalName fn : FundamentalName.values()) {
536 if (builder.length() > 0) {
537 builder.append('|');
538 }
539 builder.append(fn.getArgumentName());
540 }
541 final String fundamentalName = "\\p{Space}*((?:" + builder.toString() + ")+)";
542 pattern = Pattern.compile("\\p{Space}*F\\p{Digit}+\\p{Space}*" + unicodeIdenticalTo +
543 fundamentalName + "\\p{Space}*=\\p{Space}*(.*)");
544
545 polynomialParser = new PolynomialParser('t', PolynomialParser.Unit.NO_UNITS);
546
547 }
548
549
550
551
552
553
554
555 public boolean parseDefinition(final String line, final int lineNumber, final String fileName) {
556
557 parsedName = null;
558 parsedPolynomial = null;
559
560 final Matcher matcher = pattern.matcher(line);
561 if (matcher.matches()) {
562 for (FundamentalName fn : FundamentalName.values()) {
563 if (fn.getArgumentName().equals(matcher.group(1))) {
564 parsedName = fn;
565 }
566 }
567
568
569 parsedPolynomial = polynomialParser.parse(matcher.group(2));
570
571 return true;
572
573 } else {
574 return false;
575 }
576
577 }
578
579
580
581
582 public FundamentalName getParsedName() {
583 return parsedName;
584 }
585
586
587
588
589 public double[] getParsedPolynomial() {
590 return parsedPolynomial.clone();
591 }
592
593 }
594
595 }