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