Source code for irfpy.vexpvat.orbnum
''' Module for orbit number
*Preparation*
The orbit number data is retrieved from SPICE kernel.
The needed file is usually with the name of ``ORVV_MERGED_xxxxx.ORB`` where
xxxxx is a version number.
Prepare the ``irfpy`` setting file, ``~/.irfpyrc`` with the following::
[vexpvat]
orbnruri = /path/to/the/directory/including/kernel/file/
*Usage*
Simply call the following functions
- :func:`get_orbit_nr`: to get the orbit number corresponding to the specified time
- :func:`get_pericenter`: To get the time of the pericenter for the given orbit number
- :func:`get_start_time`: To get the start time of the given orbit number
- :func:`get_stop_time`: To get the stop time of the given orbit number
>>> import datetime
>>> print(get_orbit_nr(datetime.datetime(2009, 3, 15, 13, 0, 0)))
1059
>>> print(get_pericenter(1059))
2009-03-15 05:14:59
'''
import os as _os
import glob as _glob
import dateutil.parser as _dateutil_parser
import bisect as _bisect
import logging as _logging
_logger = _logging.getLogger(__name__)
from irfpy.util.irfpyrc import Rc as _Rc
[docs]class OrbnumKernel:
""" Orbit number kernel.
.. note::
This class provides low-level handling of kernel file.
Use high level functions as
- :func:`get_orbit_nr`
- :func:`get_pericenter`
- :func:`get_start_time` and :func:`get_stop_time`
"""
def __init__(self, orvvuri):
''' Open the ORVV file.
:param orvv: ORVV file name, or the directory that contains the file. Orbit number kernel file.
If ``orvv`` is a local directory name, the file with the largest version number is used.
>>> s = orbnum.OrbnumKernel('/Volumes/scidata/data/venus/spice/kernels/orbnum/ORVV_MERGED_00356.ORB') # doctest: +SKIP
>>> s = orbnum.OrbnumKernel('/Volumes/scidata/data/venus/spice/kernels/orbnum/') # doctest: +SKIP
'''
if _os.path.isdir(orvvuri):
orvvfiles = _glob.glob(_os.path.join(orvvuri, 'ORVV_MERGED_?????.ORB'))
if len(orvvfiles) != 0:
orvvfiles.sort()
orvv = orvvfiles[-1]
else:
raise IOError('No orbit file found')
else:
orvv = orvvuri
self.orvv = orvv
_logger.info('File = %s' % self.orvv)
self.start = {}
self.peri = {}
self.stop = {}
with open(self.orvv) as fp:
for line in fp:
elem = line.split()
if len(elem) != 21: # Headers.
continue
onr = int(elem[0])
per = _dateutil_parser.parse(' '.join(elem[1:5]))
apo = _dateutil_parser.parse(' '.join(elem[6:10]))
self.peri[onr] = per
self.start[onr+1] = apo
self.stop[onr] = apo
minorb = min(self.peri.keys())
maxorb = max(self.peri.keys())
self.start = [self.start.get(onr, self.peri[minorb]) for onr in range(maxorb+1)]
self.peri = [self.peri.get(onr, self.peri[minorb]) for onr in range(maxorb+1)]
self.stop = [self.stop.get(onr, self.peri[minorb]) for onr in range(maxorb+1)]
[docs] def show_list(self):
for idx, (t0, tc, t1) in enumerate(zip(self.start, self.peri, self.stop)):
print(idx, t0, tc, t1)
[docs] def get_pericenter(self, onr):
''' Return the pericenter time in datetime instance.
:param onr: Orbit number
'''
return self.peri[onr]
[docs] def get_orbit_nr(self, t):
''' Return the orbit number corresponding to the given time.
:param t: Time
:type t: ``datetime.datetime``
'''
return _bisect.bisect(self.stop, t)
[docs] def get_start(self, onr):
""" Start time of the corresponding orbit number
:param onr: Orbit number
:return: The start time
"""
return self.start[onr]
[docs] def get_stop(self, onr):
""" End time of the corresponding orbit number
:param onr: Orbit number
:return: The end time
"""
return self.stop[onr]
[docs]def default_orbnum():
''' Return the Orbnum class with default setting.
You have to add vexpvat orbnrfile entry in RC.
>>> onr = default_orbnum()
'''
rc = _Rc()
default = rc.get('vexpvat', 'orbnruri')
if default is None:
raise RuntimeError('RC entry vexpvat orbnruri not found')
return OrbnumKernel(default)
_onr = None
[docs]def get_orbit_nr(t):
""" Return the orbit number for the specified time.
:param t: Time
:return: The orbit number
>>> import datetime
>>> t = datetime.datetime(2011, 3, 15, 10, 30)
>>> onr = get_orbit_nr(t)
>>> print(onr)
1789
"""
global _onr
if _onr is None:
_onr = default_orbnum()
return _onr.get_orbit_nr(t)
[docs]def get_pericenter(onr):
""" Return the time of pericener
:param onr: Orbit number
:return: The time of the pericenter
>>> t = get_pericenter(1789)
>>> print(t)
2011-03-15 03:33:07
"""
global _onr
if _onr is None:
_onr = default_orbnum()
return _onr.get_pericenter(onr)
[docs]def get_start_time(onr):
""" Return the start time of the orbit
:param onr: Orbit number.
:return: The start time
>>> print(get_start_time(1789))
2011-03-14 15:32:39
"""
global _onr
if _onr is None:
_onr = default_orbnum()
return _onr.get_start(onr)
[docs]def get_stop_time(onr):
""" Return the stop time of the orbit
:param onr: Orbit number.
:return: The stop time
>>> print(get_stop_time(1789))
2011-03-15 15:33:36
"""
global _onr
if _onr is None:
_onr = default_orbnum()
return _onr.get_stop(onr)