Source code for irfpy.pep.galileo_orbit
''' Galileo orbital information based on PDS.
The data is downloaded from
http://ppi.pds.nasa.gov/search/view/?f=yes&id=pds://PPI/GOMW_5001/DATA/TRAJECT
.. warning::
Note that this file contains a browse data, thus, the orbit information
may have worse time resolution especially during the flyby.
In such a case you should use spice data with :mod:`galileo_spice` module.
Then the downloaded files are manually merged and processed.
.. todo::
Data file in the data repositry.
Raw data contains 12 columns.
..
Column 1 | UT
Column 2 | R in Rj (71492 km)
Column 3 | Latitude in System III
Column 4 | Longitude in System III
Column 5 | JSE_X
Column 6 | JSE_Y
Column 7 | JSE_Z
Column 8 | JSM_X
Column 9 | JSM_Y
Column 10 | JSM_Z
Column 11 | Local hour
Column 12 | Local magnetic hour
We only need the column 1, 5-7.
.. code-block:: sh
% cat /Users/futaana/Downloads/GOMW_5001/SURVEY/*.TAB > galileo_orbit_raw.txt
% awk '{print $1, $5, $6, $7}' < galileo_orbit_raw.txt > galileo_orbit_sample.txt
% gzip galileo_orbit_sample.txt
% vi .irfpyrc
[galileo]
galileo_orbit_browse = <path_to:galileo_orbit_sample.txt.gz>
'''
import os
import gzip
import io
import logging
logging.basicConfig()
from pkg_resources import resource_filename
import dateutil.parser
import numpy as np
import scipy as sp
from scipy import interpolate
import matplotlib.dates
from irfpy.util import irfpyrc
from irfpy.util import exception
[docs]class GalileoOrbit:
''' Galileo orbit from discretely sampled points
You may get the default instance by
.. code-block:: python
go = GalileoOrbit.get_default_instance()
Reading and parsing takes time.
>>> go = GalileoOrbit.get_default_instance()
>>> print(go.t0(), go.t1()) # Data coverage # doctest: +SKIP
1995-10-09 00:00:00 1997-05-03 23:50:00
>>> import datetime
>>> print(go.get_position(datetime.datetime(1995, 10, 25, 0, 0, 0)))
[ 8.769 -394.688 -36.523]
'''
__default_instance = None
__reduced_instance = None
[docs] @classmethod
def get_default_instance(cls):
if cls.__default_instance == None:
cls.__default_instance = GalileoOrbit()
return cls.__default_instance
[docs] @classmethod
def get_reduced_instance(cls):
import warnings
warnings.warn('Use of get_reduced_instance is not supported now.')
warnings.warn('Just return the full instance.')
return cls.get_default_instance()
def __init__(self, filename=None):
self.logger = logging.getLogger(self.__class__.__name__)
self.logger.setLevel(logging.INFO)
if filename:
fn = filename
else:
rc = irfpyrc.Rc()
fn = rc.get('galileo', 'galileo_orbit_browse')
if fn == None:
raise exception.PyanaException('No entry found: [galileo]-galileo_orbit_browse')
self.logger.info('File name: %s' % fn)
if not os.path.exists(fn):
raise IOError('File %s not found.' % fn)
# self.dat = np.loadtxt(fn, converters={0: dateutil.parser.parse})
self.tlist = [] # Stores datetime instnce
self.xlist = []
self.ylist = []
self.zlist = []
### Works only for Python3.3
# f = gzip.open(fn, 'rt')
### Better for Python3.
f = io.TextIOWrapper(gzip.open(fn))
for l in f:
tok = l.split()
t = dateutil.parser.parse(tok[0])
# p = np.array([float(tok[1]), float(tok[2]), float(tok[3])])
# self.posdict[t] = p
x = float(tok[1])
y = float(tok[2])
z = float(tok[3])
self.tlist.append(t)
self.xlist.append(x)
self.ylist.append(y)
self.zlist.append(z)
f.close()
self.tnlist = matplotlib.dates.date2num(self.tlist) # Stores float instance.
# Interpolation.
self.xfunc = interpolate.InterpolatedUnivariateSpline(self.tnlist, self.xlist)
self.yfunc = interpolate.InterpolatedUnivariateSpline(self.tnlist, self.ylist)
self.zfunc = interpolate.InterpolatedUnivariateSpline(self.tnlist, self.zlist)
[docs] def t0(self):
return min(self.tlist)
[docs] def t1(self):
return max(self.tlist)
[docs] def get_position(self, t):
''' Get the position of Galileo spacecraft at the time of *t*.
Interpolation by each component (x, y, z) is used to calculate.
The position is in the unit of Rj.
'''
tn = matplotlib.dates.date2num(t)
if tn < self.tnlist.min() or tn > self.tnlist.max():
raise ValueError('Given time %s is not in the range of data [%s %s]' %
(t, min(self.tlist), max(self.tlist)))
x = self.xfunc(tn)
y = self.yfunc(tn)
z = self.zfunc(tn)
return np.array([x, y, z])
[docs] def get_positions(self, t):
''' Same as get_position but t can be an array.
'''
if np.iterable(t):
return np.array([self.get_position(ti) for ti in t])
else:
return self.get_position(t)
[docs]def print_orbit_info():
''' Display orbit info.
'''
return '''
---------------------------------------------------------------------
Galileo Orbit Information
---------------------------------------------------------------------
Orbit Orbit <--- Periapsis Info ----> <-- Apoapsis Info -->
Num Start Periapsis Range Local Apoapsis Range Local
Date Date/Time <Rj**> Time Date <Rj> Time
---------------------------------------------------------------------
J0 95-12-03 95-12-07 21:54 4.00 16:21 96-03-29 267.7 03:39
G1 96-06-23 96-06-28 00:31 11.03 15:36 96-08-09 125.3 03:24
G2 96-09-01 96-09-07 13:38 10.65 15:22 96-10-07 113.0 03:12
C3 96-11-02 96-11-06 13:31 9.21 15:34 96-11-27 89.1 03:28
E4 96-12-15 96-12-19 03:22 9.16 15:21 97-01-04 72.1 03:00
J5* 97-01-15 97-01-20 00:26 9.05 14:54 97-02-04 72.1 02:48
E6 97-02-16 97-02-20 20:55 9.12 14:28 97-03-14 89.2 02:20
G7 97-03-30 97-04-04 11:03 9.12 14:14 97-04-21 75.9 01:56
G8 97-05-04 97-05-08 11:42 9.27 13:29 97-06-02 100.2 01:21
C9 97-06-22 97-06-27 11:52 10.77 12:35 97-08-08 143.0 00:21
C10 97-09-14 97-09-18 23:10 9.17 12:44 97-10-13 98.9 00:36
E11 97-11-02 97-11-06 23:02 9.03 12:36 97-11-26 84.1 00:29
E12 97-12-15 97-12-16 06:35 8.80 12:29 97-12-20 46.6 00:37
J13* 98-02-09 98-02-10 23:09 8.85 12:33 98-03-06 95.2 00:25
E14 98-03-28 98-03-29 07:59 8.83 12:17 98-04-30 199.7 00:16
E15 98-05-30 98-06-01 02:34 8.85 12:12 98-06-26 100.4 00:03
E16 98-07-20 98-07-20 17:18 9.93 11:54 98-08-23 124.4 23:51
E17 98-09-25 98-09-26 08:26 8.91 11:44 98-10-24 110.4 23:34
E18 98-11-21 98-11-22 03:57 9.23 11:24 98-12-27 129.0 23:17
E19 99-01-31 99-02-01 02:38 9.24 10:56 99-03-18 154.3 22:40
C20 99-05-02 99-05-03 17:00 9.37 10:24 99-06-02 114.5 21:46
C21 99-06-29 99-07-02 05:04 7.27 10:04 99-07-22 89.0 21:57
C22 99-08-11 99-08-12 10:58 7.32 09:50 99-08-29 77.1 21:23
C23 99-09-13 99-09-14 19:57 6.55 09:17 99-09-27 65.7 20:46
I24 99-10-10 99-10-11 03:31 5.68 08:41 99-11-01 97.7 20:47
I25 99-11-25 99-11-26 23:30 5.94 08:39 99-12-15 87.2 20:28
E26 00-01-01 00-01-04 03:33 5.78 08:14 00-01-28 102.7 20:05
I27 00-02-20 00-02-22 12:30 5.85 07:56 00-04-06 154.4 19:55
G28 00-05-17 00-05-21 04:52 6.68 07:18 00-09-08 289.9 18:37
G29 00-12-27 00-12-29 03:26 7.49 06:03 01-03-11 216.3 17:37
C30 01-05-07 01-05-23 17:33 7.28 05:11 01-06-29 136.8 16:27
I31 01-08-04 01-08-06 04:52 5.93 04:14 01-09-10 132.2 16:05
I32 01-10-14 01-10-15 23:56 5.78 03:53 01-12-01 160.7 15:39
I33 02-01-16 02-01-17 16:23 5.54 03:13 02-06-13 348.1 14:21
A34 02-11-04 02-11-05 07:23 1.99 01:40 03-04-14 336.7 12:49
J35 03-09-21 03-09-21 18: 1.00
* Solar Conjunction - no data from this orbit
** Rj = 71492 km
'''
[docs]def print_flyby_info():
print('''
------------------------------------------------------------
Satellite Flyby Characteristics*
------------------------------------------------------------
Satellite Planetocentric Coords
Range Lat E Lon
Orb Moon C/A Time (Rm**) (deg) (deg) Note
------------------------------------------------------------
0 IO 95-12-07 17:45:58 1.50 -9.6 258.9 W
24 IO 99-10-11 04:33:03 1.34 4.5 135.9 U
27 IO 00-02-22 13:46:41 1.11 18.5 157.4 U
31 IO 01-08-06 04:59:21 1.11 77.5 187.7 P
32 IO 01-10-16 01:23:21 1.10 -78.5 135.3 P
33 IO 02-01-17 14:08:28 1.06 -43.5 41.8 F
4 EUR 96-12-19 06:52:58 1.45 -1.7 322.4 F
6 EUR 97-02-20 17:06:10 1.38 -17.0 34.7 F
11 EUR 97-11-06 20:31:44 2.31 25.7 218.7 F
12 EUR 97-12-16 12:03:20 1.13 -8.7 134.4 U
14 EUR 98-03-29 13:21:05 2.06 12.2 131.2 U
15 EUR 98-05-31 21:12:57 2.62 15.0 225.4 W
19 EUR 99-02-01 02:19:50 1.93 30.5 28.1 U
26 EUR 00-01-03 17:59:43 1.22 -47.1 83.4 U
1 GAN 96-06-27 06:29:07 1.32 30.4 246.7 W
2 GAN 96-09-06 18:59:34 1.10 79.3 236.4 P
7 GAN 97-04-05 07:09:58 2.18 55.8 270.4 W
8 GAN 97-05-07 15:56:10 1.61 28.3 84.8 U
28 GAN 00-05-20 10:10:10 1.31 -19.0 92.4 U
29 GAN 00-12-28 08:25:27 1.89 62.2 269.0 P
3 CALL 96-11-04 13:34:28 1.47 13.2 282.3 W
9 CALL 97-06-25 13:47:50 1.17 2.0 101.0 U
10 CALL 97-09-17 00:18:55 1.22 4.6 281.3 W
30 CALL 01-05-25 11:23:58 1.06 13.6 254.6 W
34 AMA 02-11-05 06:18:40 2.89 -47.7 74.8 U
* Satellite encounters with recorded data only
J2000 reference, body fixed spherical coordinates.
** Moon Rm (km)
=======================
Amalthea 86.2
Io 1818
Europa 1560
Ganymede 2634
Callisto 2409
Notes: Negative latitudes are southern hemisphere,
U = upstream
F = flank
W = wake
P = polar
''')
import unittest
import doctest
[docs]def doctests():
return unittest.TestSuite((
doctest.DocTestSuite(),
))
if __name__ == '__main__':
unittest.main(defaultTest='doctests')