Source code for irfpy.mexpvat.orbnum
''' Module for orbit number
This module depends on the spice kernel file.
The file name is ``ORMM_MERGED_xxxxx.ORB`` where
xxxxx is a version number.
You can specify the file name or give
only directory name for auto detection.
Normally you cn start the OrbnumKernel class to instance, or
simple use of method default_orbnum().
.. note::
Note that the script is a copy from vex version.
Refactoring may construct simple structure, but
due to time constraint, I kept it as independent module.
'''
import os
import glob
import dateutil.parser
#import urllib.request, urllib.parse, urllib.error
import bisect
import logging
from irfpy.util.irfpyrc import Rc
[docs]class OrbnumKernel:
def __init__(self, ormmuri):
''' Open the ORMM file from a given URI.
:param ormm: ORMM uri. Orbit kernel file.
If ``ormm`` specifies a file or a uri, the
If ``ormm`` is a local directory name (not starting with "file://"), the largest version number
file inside the given directory is used as a file.
They are ok.
> s = orbnum.OrbnumKernel('http://rhea.umea.irf.se/~peje/mex/MEX/kernels/orbnum/ORMM_MERGED_00784.ORB')
> s = orbnum.OrbnumKernel('/Users/futaana/mnt/mars/spice/kernels/orbnum/ORMM_MERGED_00784.ORB')
> s = orbnum.OrbnumKernel('/Users/futaana/mnt/mars/spice/kernels/orbnum/')
The last example is the most robust way of programing, as the
update of the kernel file is automatically considered.
Note that this is not ok.
> s = orbnum.OrbnumKernel('file:///Users/futaana/mnt/venus/spice/kernels/orbnum/')
'''
self.logger = logging.getLogger('OrbnumKernel')
# self.logger.setLevel(logging.DEBUG)
if os.path.isdir(ormmuri):
ormmfiles = glob.glob(os.path.join(ormmuri, 'ORMM_MERGED_?????.ORB'))
if len(ormmfiles) != 0:
ormmfiles.sort()
ormm = ormmfiles[-1]
else:
raise IOError("No Orbit File Found.")
else:
ormm = ormmuri
self.ormm = ormm
self.logger.info('File = %s' % self.ormm)
self.start = {}
self.peri = {}
self.stop = {}
with open(self.ormm) 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.logger.debug('%d: %s %s' % (onr, per, apo))
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_start(self, onr):
return self.start[onr]
[docs] def get_stop(self, onr):
return self.stop[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 default_orbnum():
''' Return the Orbnum class with default setting.
You have to add mexpvat orbnrfile entry in RC.
'''
rc = Rc()
default = rc.get('mexpvat', 'orbnruri')
# print default
if default is None:
raise RuntimeError('RC entry mexpvat 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)
9197
"""
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)
2005-06-07 16:37:52
"""
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))
2005-06-07 13:16:15
"""
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))
2005-06-07 19:59:27
"""
global _onr
if _onr is None:
_onr = default_orbnum()
return _onr.get_stop(onr)