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