1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.orekit.models.earth.atmosphere.data;
19
20 import java.io.BufferedInputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.text.ParseException;
24 import java.util.List;
25 import java.util.stream.Collectors;
26
27 import org.hipparchus.exception.DummyLocalizable;
28 import org.orekit.annotation.DefaultDataContext;
29 import org.orekit.data.DataContext;
30 import org.orekit.data.DataProvidersManager;
31 import org.orekit.data.DataSource;
32 import org.orekit.errors.OrekitException;
33 import org.orekit.errors.OrekitMessages;
34 import org.orekit.models.earth.atmosphere.JB2008InputParameters;
35 import org.orekit.time.AbsoluteDate;
36 import org.orekit.time.TimeScale;
37 import org.orekit.utils.Constants;
38 import org.orekit.utils.ImmutableTimeStampedCache;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public class JB2008SpaceEnvironmentData implements JB2008InputParameters {
60
61
62 public static final String DEFAULT_SUPPORTED_NAMES_SOLFSMY = "(SOLFSMY)(.*)((\\.txt)|(\\.TXT))";
63
64
65 public static final String DEFAULT_SUPPORTED_NAMES_DTC = "DTCFILE.TXT";
66
67
68 private static final long serialVersionUID = 7735042547323407578L;
69
70
71 private static final int N_NEIGHBORS = 2;
72
73
74 private final transient ImmutableTimeStampedCache<SOLFSMYDataLoader.LineParameters> dataSOL;
75
76
77 private final transient ImmutableTimeStampedCache<DtcDataLoader.LineParameters> dataDTC;
78
79
80 private final AbsoluteDate firstDate;
81
82
83 private final AbsoluteDate lastDate;
84
85
86 private SOLFSMYDataLoader.LineParameters previousParamSOL;
87
88
89 private SOLFSMYDataLoader.LineParameters nextParamSOL;
90
91
92 private DtcDataLoader.LineParameters previousParamDTC;
93
94
95 private DtcDataLoader.LineParameters nextParamDTC;
96
97
98
99
100
101
102
103
104
105 @DefaultDataContext
106 public JB2008SpaceEnvironmentData(final String supportedNamesSOL, final String supportedNamesDTC) {
107 this(supportedNamesSOL, supportedNamesDTC, DataContext.getDefault().getDataProvidersManager(),
108 DataContext.getDefault().getTimeScales().getUTC());
109 }
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124 public JB2008SpaceEnvironmentData(final String supportedNamesSOL,
125 final String supportedNamesDTC,
126 final DataProvidersManager dataProvidersManager,
127 final TimeScale utc) {
128
129
130 final SOLFSMYDataLoader loaderSOL = new SOLFSMYDataLoader(utc);
131 dataProvidersManager.feed(supportedNamesSOL, loaderSOL);
132 dataSOL = new ImmutableTimeStampedCache<>(N_NEIGHBORS, loaderSOL.getDataSet());
133
134
135 final DtcDataLoader loaderDTC = new DtcDataLoader(utc);
136 dataProvidersManager.feed(supportedNamesDTC, loaderDTC);
137 dataDTC = new ImmutableTimeStampedCache<>(N_NEIGHBORS, loaderDTC.getDataSet());
138
139
140
141 firstDate = loaderSOL.getMinDate();
142 lastDate = loaderSOL.getMaxDate();
143
144 }
145
146
147
148
149
150
151
152
153 @DefaultDataContext
154 public JB2008SpaceEnvironmentData(final DataSource sourceSolfsmy,
155 final DataSource sourceDtc) {
156 this(sourceSolfsmy, sourceDtc, DataContext.getDefault().getTimeScales().getUTC());
157 }
158
159
160
161
162
163
164
165
166
167
168
169
170 public JB2008SpaceEnvironmentData(final DataSource sourceSolfsmy,
171 final DataSource sourceDtc,
172 final TimeScale utc) {
173 try {
174
175
176 final SOLFSMYDataLoader loaderSOL = new SOLFSMYDataLoader(utc);
177 try (InputStream is = sourceSolfsmy.getOpener().openStreamOnce();
178 BufferedInputStream bis = new BufferedInputStream(is)) {
179 loaderSOL.loadData(bis, sourceSolfsmy.getName());
180 }
181
182
183 final DtcDataLoader loaderDTC = new DtcDataLoader(utc);
184 try (InputStream is = sourceDtc.getOpener().openStreamOnce();
185 BufferedInputStream bis = new BufferedInputStream(is)) {
186 loaderDTC.loadData(bis, sourceDtc.getName());
187 }
188
189
190 dataSOL = new ImmutableTimeStampedCache<>(N_NEIGHBORS, loaderSOL.getDataSet());
191 dataDTC = new ImmutableTimeStampedCache<>(N_NEIGHBORS, loaderDTC.getDataSet());
192
193
194 firstDate = loaderSOL.getMinDate();
195 lastDate = loaderSOL.getMaxDate();
196
197 } catch (IOException | ParseException ioe) {
198 throw new OrekitException(ioe, new DummyLocalizable(ioe.getMessage()));
199 }
200
201 }
202
203
204 public AbsoluteDate getMinDate() {
205 return firstDate;
206 }
207
208
209 public AbsoluteDate getMaxDate() {
210 return lastDate;
211 }
212
213
214
215
216
217
218 private void bracketDateSOL(final AbsoluteDate date) {
219
220
221
222
223
224 final AbsoluteDate firstDateUsefulSOL = firstDate.shiftedBy(-5 * Constants.JULIAN_DAY);
225 if (date.durationFrom(firstDateUsefulSOL) < 0) {
226 throw new OrekitException(OrekitMessages.OUT_OF_RANGE_EPHEMERIDES_DATE_BEFORE,
227 date, firstDateUsefulSOL, lastDate, firstDateUsefulSOL.durationFrom(date));
228 }
229 if (date.durationFrom(lastDate) > 0) {
230 throw new OrekitException(OrekitMessages.OUT_OF_RANGE_EPHEMERIDES_DATE_AFTER,
231 date, firstDateUsefulSOL, lastDate, date.durationFrom(lastDate));
232 }
233
234
235 if (previousParamSOL != null && date.durationFrom(previousParamSOL.getDate()) > 0 &&
236 date.durationFrom(nextParamSOL.getDate()) <= 0) {
237 return;
238 }
239
240 final List<SOLFSMYDataLoader.LineParameters> neigbors = dataSOL.getNeighbors(date).collect(Collectors.toList());
241 previousParamSOL = neigbors.get(0);
242 nextParamSOL = neigbors.get(1);
243
244 }
245
246
247
248
249
250
251 private void bracketDateDTC(final AbsoluteDate date) {
252
253 final AbsoluteDate firstDateUsefulDTC = firstDate;
254 if (date.durationFrom(firstDateUsefulDTC) < 0) {
255 throw new OrekitException(OrekitMessages.OUT_OF_RANGE_EPHEMERIDES_DATE_BEFORE,
256 date, firstDateUsefulDTC, lastDate, firstDateUsefulDTC.durationFrom(date));
257 }
258 if (date.durationFrom(lastDate) > 0) {
259 throw new OrekitException(OrekitMessages.OUT_OF_RANGE_EPHEMERIDES_DATE_AFTER,
260 date, firstDateUsefulDTC, lastDate, date.durationFrom(lastDate));
261 }
262
263
264 if (previousParamDTC != null && date.durationFrom(previousParamDTC.getDate()) > 0 &&
265 date.durationFrom(nextParamDTC.getDate()) <= 0) {
266 return;
267 }
268
269 final List<DtcDataLoader.LineParameters> neigbors = dataDTC.getNeighbors(date).collect(Collectors.toList());
270 previousParamDTC = neigbors.get(0);
271 nextParamDTC = neigbors.get(1);
272
273 }
274
275
276
277
278
279
280
281
282
283
284 private double getLinearInterpolationSOL(final AbsoluteDate date, final double previousValue, final double nextValue) {
285
286 return linearInterpolation(date, previousValue, previousParamSOL.getDate(), nextValue, nextParamSOL.getDate());
287 }
288
289
290
291
292
293
294
295
296
297
298 private double getLinearInterpolationDTC(final AbsoluteDate date, final double previousValue, final double nextValue) {
299
300 return linearInterpolation(date, previousValue, previousParamDTC.getDate(), nextValue, nextParamDTC.getDate());
301 }
302
303
304
305
306
307
308
309
310
311
312 private double linearInterpolation(final AbsoluteDate date,
313 final double previousValue, final AbsoluteDate previousDate,
314 final double nextValue, final AbsoluteDate nextDate) {
315
316 final double dt = nextDate.durationFrom(previousDate);
317 final double previousWeight = nextDate.durationFrom(date) / dt;
318 final double nextWeight = date.durationFrom(previousDate) / dt;
319
320
321 return previousValue * previousWeight + nextValue * nextWeight;
322 }
323
324
325 public double getF10(final AbsoluteDate date) {
326
327 final AbsoluteDate workDate = date.shiftedBy(-Constants.JULIAN_DAY);
328 bracketDateSOL(workDate);
329 return getLinearInterpolationSOL(workDate, previousParamSOL.getF10(), nextParamSOL.getF10());
330 }
331
332
333 public double getF10B(final AbsoluteDate date) {
334
335 final AbsoluteDate workDate = date.shiftedBy(-Constants.JULIAN_DAY);
336 bracketDateSOL(workDate);
337 return getLinearInterpolationSOL(workDate, previousParamSOL.getF10B(), nextParamSOL.getF10B());
338 }
339
340
341 public double getS10(final AbsoluteDate date) {
342
343 final AbsoluteDate workDate = date.shiftedBy(-Constants.JULIAN_DAY);
344 bracketDateSOL(workDate);
345 return getLinearInterpolationSOL(workDate, previousParamSOL.getS10(), nextParamSOL.getS10());
346 }
347
348
349 public double getS10B(final AbsoluteDate date) {
350
351 final AbsoluteDate workDate = date.shiftedBy(-Constants.JULIAN_DAY);
352 bracketDateSOL(workDate);
353 return getLinearInterpolationSOL(workDate, previousParamSOL.getS10B(), nextParamSOL.getS10B());
354 }
355
356
357 public double getXM10(final AbsoluteDate date) {
358
359 final AbsoluteDate workDate = date.shiftedBy(-2.0 * Constants.JULIAN_DAY);
360 bracketDateSOL(workDate);
361 return getLinearInterpolationSOL(workDate, previousParamSOL.getXM10(), nextParamSOL.getXM10());
362 }
363
364
365 public double getXM10B(final AbsoluteDate date) {
366
367 final AbsoluteDate workDate = date.shiftedBy(-2.0 * Constants.JULIAN_DAY);
368 bracketDateSOL(workDate);;
369 return getLinearInterpolationSOL(workDate, previousParamSOL.getXM10B(), nextParamSOL.getXM10B());
370 }
371
372
373 public double getY10(final AbsoluteDate date) {
374
375 final AbsoluteDate workDate = date.shiftedBy(-5.0 * Constants.JULIAN_DAY);
376 bracketDateSOL(workDate);
377 return getLinearInterpolationSOL(workDate, previousParamSOL.getY10(), nextParamSOL.getY10());
378 }
379
380
381 public double getY10B(final AbsoluteDate date) {
382
383 final AbsoluteDate workDate = date.shiftedBy(-5.0 * Constants.JULIAN_DAY);
384 bracketDateSOL(workDate);
385 return getLinearInterpolationSOL(workDate, previousParamSOL.getY10B(), nextParamSOL.getY10B());
386 }
387
388
389 public double getDSTDTC(final AbsoluteDate date) {
390 bracketDateDTC(date);
391 return getLinearInterpolationDTC(date, previousParamDTC.getDSTDTC(), nextParamDTC.getDSTDTC());
392 }
393
394 }