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