1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.forces.gravity.potential;
18
19 import java.io.BufferedReader;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.InputStreamReader;
23 import java.text.ParseException;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.regex.Matcher;
27 import java.util.regex.Pattern;
28
29 import org.hipparchus.util.FastMath;
30 import org.hipparchus.util.Precision;
31 import org.orekit.errors.OrekitException;
32 import org.orekit.errors.OrekitMessages;
33 import org.orekit.errors.OrekitParseException;
34 import org.orekit.time.DateComponents;
35 import org.orekit.utils.Constants;
36
37
38
39
40
41
42
43
44
45
46
47 public class GRGSFormatReader extends PotentialCoefficientsReader {
48
49
50 private static final Pattern[] LINES;
51
52
53 private DateComponents referenceDate;
54
55
56 private final List<List<Double>> cDot;
57
58
59 private final List<List<Double>> sDot;
60
61 static {
62
63
64 final String real = "[-+]?\\d?\\.\\d+[eEdD][-+]\\d\\d";
65 final String sep = ")\\s*(";
66
67
68 final String[] header = {
69 "^\\s*FIELD - .*$",
70 "^\\s+AE\\s+1/F\\s+GM\\s+OMEGA\\s*$",
71 "^\\s*(" + real + sep + real + sep + real + sep + real + ")\\s*$",
72 "^\\s*REFERENCE\\s+DATE\\s+:\\s+(\\d+)\\.0+\\s*$",
73 "^\\s*MAXIMAL\\s+DEGREE\\s+:\\s+(\\d+)\\s.*$",
74 "^\\s*L\\s+M\\s+DOT\\s+CBAR\\s+SBAR\\s+SIGMA C\\s+SIGMA S(\\s+LIB)?\\s*$"
75 };
76
77
78 final String data = "^([ 0-9]{3})([ 0-9]{3})( |DOT)\\s*(" +
79 real + sep + real + sep + real + sep + real +
80 ")(\\s+[0-9]+)?\\s*$";
81
82
83 LINES = new Pattern[header.length + 1];
84 for (int i = 0; i < header.length; ++i) {
85 LINES[i] = Pattern.compile(header[i]);
86 }
87 LINES[LINES.length - 1] = Pattern.compile(data);
88
89 }
90
91
92
93
94
95 public GRGSFormatReader(final String supportedNames, final boolean missingCoefficientsAllowed) {
96 super(supportedNames, missingCoefficientsAllowed);
97 referenceDate = null;
98 cDot = new ArrayList<List<Double>>();
99 sDot = new ArrayList<List<Double>>();
100 }
101
102
103 public void loadData(final InputStream input, final String name)
104 throws IOException, ParseException, OrekitException {
105
106
107 setReadComplete(false);
108 referenceDate = null;
109 cDot.clear();
110 sDot.clear();
111
112
113
114
115
116
117
118
119
120
121
122
123
124 final BufferedReader r = new BufferedReader(new InputStreamReader(input, "UTF-8"));
125 int lineNumber = 0;
126 double[][] c = null;
127 double[][] s = null;
128 for (String line = r.readLine(); line != null; line = r.readLine()) {
129
130 ++lineNumber;
131
132
133 final Matcher matcher = LINES[FastMath.min(LINES.length, lineNumber) - 1].matcher(line);
134 if (!matcher.matches()) {
135 throw new OrekitParseException(OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE,
136 lineNumber, name, line);
137 }
138
139 if (lineNumber == 3) {
140
141 setAe(parseDouble(matcher.group(1)));
142 setMu(parseDouble(matcher.group(3)));
143 } else if (lineNumber == 4) {
144
145 referenceDate = new DateComponents(Integer.parseInt(matcher.group(1)), 1, 1);
146 } else if (lineNumber == 5) {
147
148 final int degree = FastMath.min(getMaxParseDegree(), Integer.parseInt(matcher.group(1)));
149 final int order = FastMath.min(getMaxParseOrder(), degree);
150 c = buildTriangularArray(degree, order, missingCoefficientsAllowed() ? 0.0 : Double.NaN);
151 s = buildTriangularArray(degree, order, missingCoefficientsAllowed() ? 0.0 : Double.NaN);
152 } else if (lineNumber > 6) {
153
154 final int i = Integer.parseInt(matcher.group(1).trim());
155 final int j = Integer.parseInt(matcher.group(2).trim());
156 if (i < c.length && j < c[i].length) {
157 if ("DOT".equals(matcher.group(3).trim())) {
158
159
160 extendListOfLists(cDot, i, j, 0.0);
161 extendListOfLists(sDot, i, j, 0.0);
162 parseCoefficient(matcher.group(4), cDot, i, j, "Cdot", name);
163 parseCoefficient(matcher.group(5), sDot, i, j, "Sdot", name);
164
165 } else {
166
167
168 parseCoefficient(matcher.group(4), c, i, j, "C", name);
169 parseCoefficient(matcher.group(5), s, i, j, "S", name);
170
171 }
172 }
173 }
174
175 }
176
177 if (missingCoefficientsAllowed() && c.length > 0 && c[0].length > 0) {
178
179 if (Precision.equals(c[0][0], 0.0, 0)) {
180 c[0][0] = 1.0;
181 }
182 }
183
184 setRawCoefficients(true, c, s, name);
185 setTideSystem(TideSystem.UNKNOWN);
186 setReadComplete(true);
187
188 }
189
190
191
192
193
194
195
196
197
198
199
200
201
202 public RawSphericalHarmonicsProvider getProvider(final boolean wantNormalized,
203 final int degree, final int order) {
204
205
206 RawSphericalHarmonicsProvider provider = getConstantProvider(wantNormalized, degree, order);
207
208 if (!cDot.isEmpty()) {
209
210
211 final double[][] cArray = toArray(cDot);
212 final double[][] sArray = toArray(sDot);
213 rescale(1.0 / Constants.JULIAN_YEAR, true, cArray, sArray, wantNormalized, cArray, sArray);
214 provider = new SecularTrendSphericalHarmonics(provider, referenceDate, cArray, sArray);
215
216 }
217
218 return provider;
219
220 }
221
222 }