1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit;
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.Calendar;
25 import java.util.GregorianCalendar;
26 import java.util.SortedSet;
27 import java.util.TimeZone;
28 import java.util.TreeSet;
29
30 import org.apache.commons.math3.exception.util.DummyLocalizable;
31 import org.orekit.errors.OrekitException;
32 import org.orekit.errors.OrekitMessages;
33 import org.orekit.forces.drag.DTM2000InputParameters;
34 import org.orekit.forces.drag.JB2006InputParameters;
35 import org.orekit.time.AbsoluteDate;
36 import org.orekit.time.ChronologicalComparator;
37 import org.orekit.time.TimeScalesFactory;
38 import org.orekit.time.TimeStamped;
39 import org.orekit.utils.Constants;
40
41
42
43
44
45
46
47
48
49 public class SolarInputs97to05 implements JB2006InputParameters, DTM2000InputParameters {
50
51
52 private static final long serialVersionUID = -3687601846334870069L;
53
54 private static final double third = 1.0/3.0;
55
56 private static final double[] kpTab = new double[] {
57 0, 0+third, 1-third, 1, 1+third, 2-third, 2, 2+third,
58 3-third, 3, 3+third, 4-third, 4, 4+third, 5-third, 5,
59 5+third, 6-third, 6, 6+third, 7-third, 7, 7+third,
60 8-third, 8, 8+third, 9-third, 9
61 };
62
63 private static final double[] apTab = new double[] {
64 0, 2, 3, 4, 5, 6, 7, 9, 12, 15, 18, 22, 27, 32,
65 39, 48, 56, 67, 80, 94, 111, 132, 154 , 179, 207, 236, 300, 400
66 };
67
68
69 private SortedSet<TimeStamped> data;
70
71 private LineParameters currentParam;
72 private AbsoluteDate firstDate;
73 private AbsoluteDate lastDate;
74
75
76
77
78
79
80 private SolarInputs97to05() throws OrekitException {
81
82 data = new TreeSet<TimeStamped>(new ChronologicalComparator());
83 InputStream in = SolarInputs97to05.class.getResourceAsStream("/atmosphere/JB_All_97-05.txt");
84 BufferedReader rFlux = new BufferedReader(new InputStreamReader(in));
85
86
87 in = SolarInputs97to05.class.getResourceAsStream("/atmosphere/NOAA_ap_97-05.dat.txt");
88 BufferedReader rAp = new BufferedReader(new InputStreamReader(in));
89
90 try {
91 read(rFlux, rAp);
92 } catch (IOException e) {
93 throw new RuntimeException(e);
94 }
95 }
96
97
98
99
100
101 public static SolarInputs97to05 getInstance() throws OrekitException {
102 if (LazyHolder.instance == null) {
103 throw LazyHolder.orekitException;
104 }
105 return LazyHolder.instance;
106 }
107
108 private void read(BufferedReader rFlux, BufferedReader rAp) throws IOException, OrekitException {
109
110 rFlux.readLine();
111 rFlux.readLine();
112 rFlux.readLine();
113 rFlux.readLine();
114 rAp.readLine();
115 String lineAp;
116 String[] flux;
117 String[] ap;
118 Calendar cal = new GregorianCalendar();
119 cal.setTimeZone(TimeZone.getTimeZone("UTC"));
120 cal.set(0, 0, 0, 0, 0, 0);
121 cal.set(Calendar.MILLISECOND, 0);
122
123 AbsoluteDate date = null;
124 boolean first = true;
125
126 for (String lineFlux = rFlux.readLine(); lineFlux != null; lineFlux = rFlux.readLine()) {
127
128 flux = lineFlux.trim().split("\\s+");
129
130 lineAp = rAp.readLine();
131 if (lineAp == null) {
132 throw new OrekitException(new DummyLocalizable("inconsistent JB2006 and geomagnetic indices files"));
133 }
134 ap = lineAp.trim().split("\\s+");
135
136 int fluxYear = Integer.parseInt(flux[0]);
137 int fluxDay = Integer.parseInt(flux[1]);
138 int apYear = Integer.parseInt(ap[11]);
139
140 if (fluxDay != Integer.parseInt(ap[0])) {
141 throw new OrekitException(new DummyLocalizable("inconsistent JB2006 and geomagnetic indices files"));
142 }
143 if (((fluxYear < 2000) && ((fluxYear - 1900) != apYear)) ||
144 ((fluxYear >= 2000) && ((fluxYear - 2000) != apYear))) {
145 throw new OrekitException(new DummyLocalizable("inconsistent JB2006 and geomagnetic indices files"));
146 }
147
148 cal.set(Calendar.YEAR, fluxYear);
149 cal.set(Calendar.DAY_OF_YEAR, fluxDay);
150
151 date = new AbsoluteDate(cal.getTime(), TimeScalesFactory.getUTC());
152
153 if (first) {
154 first = false;
155 firstDate = date;
156 }
157
158 data.add(new LineParameters(date,
159 new double[] {
160 Double.parseDouble(ap[3]),
161 Double.parseDouble(ap[4]),
162 Double.parseDouble(ap[5]),
163 Double.parseDouble(ap[6]),
164 Double.parseDouble(ap[7]),
165 Double.parseDouble(ap[8]),
166 Double.parseDouble(ap[9]),
167 Double.parseDouble(ap[10]),
168
169 },
170 Double.parseDouble(flux[3]),
171 Double.parseDouble(flux[4]),
172 Double.parseDouble(flux[5]),
173 Double.parseDouble(flux[6]),
174 Double.parseDouble(flux[7]),
175 Double.parseDouble(flux[8])));
176
177 }
178 lastDate = date;
179
180 }
181
182 private void findClosestLine(AbsoluteDate date) throws OrekitException {
183
184 if ((date.durationFrom(firstDate) < 0) || (date.durationFrom(lastDate) > Constants.JULIAN_DAY)) {
185 throw new OrekitException(OrekitMessages.OUT_OF_RANGE_EPHEMERIDES_DATE, date, firstDate, lastDate);
186 }
187
188
189 if ((currentParam != null) && (date.durationFrom(currentParam.date) >= 0) &&
190 (date.durationFrom(currentParam.date) < Constants.JULIAN_DAY )) {
191 return;
192 }
193 LineParameters before = new LineParameters(date.shiftedBy(-Constants.JULIAN_DAY), null, 0, 0, 0, 0, 0, 0);
194
195
196 SortedSet<TimeStamped> tailSet = data.tailSet(before);
197 if (tailSet != null) {
198 currentParam = (LineParameters) tailSet.first();
199 if (currentParam.date.durationFrom(date) == -Constants.JULIAN_DAY) {
200 currentParam = (LineParameters) data.tailSet(date).first();
201 }
202 } else {
203 throw new OrekitException(new DummyLocalizable("unable to find data for date {0}"), date);
204 }
205 }
206
207
208 private static class LineParameters implements TimeStamped, Serializable {
209
210
211 private static final long serialVersionUID = -1127762834954768272L;
212
213
214 private final AbsoluteDate date;
215 private final double[] ap;
216 private final double f10;
217 private final double f10B;
218 private final double s10;
219 private final double s10B;
220 private final double xm10;
221 private final double xm10B;
222
223
224
225 private LineParameters(AbsoluteDate date, double[] ap, double f10,
226 double f10B, double s10, double s10B,
227 double xm10, double xm10B) {
228 this.date = date;
229 this.ap = ap;
230 this.f10 = f10;
231 this.f10B = f10B;
232 this.s10 = s10;
233 this.s10B = s10B;
234 this.xm10 = xm10;
235 this.xm10B = xm10B;
236
237 }
238
239
240 public AbsoluteDate getDate() {
241 return date;
242 }
243
244 }
245
246 public double getAp(AbsoluteDate date) {
247 double result = Double.NaN;
248 try {
249 findClosestLine(date);
250 Calendar cal = new GregorianCalendar();
251 cal.setTimeZone(TimeZone.getTimeZone("UTC"));
252 cal.setTime(date.toDate(TimeScalesFactory.getUTC()));
253 int hour = cal.get(Calendar.HOUR_OF_DAY);
254 for(int i= 0; i<8; i++) {
255 if ((hour >= (i * 3)) && (hour < ((i + 1) * 3))) {
256 result = currentParam.ap[i];
257 }
258 }
259 }
260 catch (OrekitException e) {
261
262 }
263 return result;
264 }
265
266 public double getF10(AbsoluteDate date) {
267 double result = Double.NaN;
268 try {
269 findClosestLine(date);
270 result=currentParam.f10;
271 }
272 catch (OrekitException e) {
273
274 }
275 return result;
276 }
277
278 public double getF10B(AbsoluteDate date) {
279 double result = Double.NaN;
280 try {
281 findClosestLine(date);
282 result=currentParam.f10B;
283 }
284 catch (OrekitException e) {
285
286 }
287 return result;
288 }
289
290 public AbsoluteDate getMaxDate() {
291 return lastDate.shiftedBy(Constants.JULIAN_DAY);
292 }
293
294 public AbsoluteDate getMinDate() {
295 return firstDate;
296 }
297
298 public double getS10(AbsoluteDate date) {
299 double result = Double.NaN;
300 try {
301 findClosestLine(date);
302 result=currentParam.s10;
303 }
304 catch (OrekitException e) {
305
306 }
307 return result;
308 }
309
310 public double getS10B(AbsoluteDate date) {
311 double result = Double.NaN;
312 try {
313 findClosestLine(date);
314 result=currentParam.s10B;
315 }
316 catch (OrekitException e) {
317
318 }
319 return result;
320 }
321
322 public double getXM10(AbsoluteDate date) {
323 double result = Double.NaN;
324 try {
325 findClosestLine(date);
326 result=currentParam.xm10;
327 }
328 catch (OrekitException e) {
329
330 }
331 return result;
332 }
333
334 public double getXM10B(AbsoluteDate date) {
335 double result = Double.NaN;
336 try {
337 findClosestLine(date);
338 result=currentParam.xm10B;
339 }
340 catch (OrekitException e) {
341
342 }
343 return result;
344 }
345
346 public double get24HoursKp(AbsoluteDate date) {
347 double result = 0;
348 AbsoluteDate myDate = date;
349
350 for(int i=0; i<8; i++) {
351 result += getThreeHourlyKP(date);
352 myDate = myDate.shiftedBy(3 * 3600);
353 }
354
355 return result/8;
356 }
357
358 public double getInstantFlux(AbsoluteDate date) {
359 return getF10(date);
360 }
361
362 public double getMeanFlux(AbsoluteDate date) {
363 return getF10B(date);
364 }
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383 public double getThreeHourlyKP(AbsoluteDate date) {
384
385 double ap = getAp(date);
386 int i = 0;
387 for ( i= 0; ap>=apTab[i]; i++) {
388 if(i==apTab.length-1) {
389 i++;
390 break;
391 }
392 }
393 return kpTab[i-1];
394 }
395
396
397
398
399
400
401 private static class LazyHolder {
402 private static final SolarInputs97to05 instance;
403 private static final OrekitException orekitException;
404 static {
405 SolarInputs97to05 tmpInstance = null;
406 OrekitException tmpException = null;
407 try {
408 tmpInstance = new SolarInputs97to05();
409 } catch (OrekitException oe) {
410 tmpException = oe;
411 }
412 instance = tmpInstance;
413 orekitException = tmpException;
414 }
415 }
416
417 }