''' Top-level module of PEP-dedicated spice information.
.. warning::
Deprecated and replaced by :mod:`irfpy.juice.jspice`.
:class:`PepSpice` provides all the functionality for PEP-dedicated spice.
Also refer to the document :ref:`pep-spice-readme`.
The module includes natural bodies' position and directions.
Also, natural body related frames are handled.
You may need to use :mod:`irfpy.pep.galileo_spice` for Galileo spacecraft
or :mod:`irfpy.pep.juice_spice` for JUICE mission orbit data..
The work flow is as follows.
First, one can get :class:`PepSpice` instance using
:func:`get_default_pepspice` function.
>>> spep = get_default_pepspice()
Then, you can use :meth:`PepSpice.get_posvel` method to get the position and
velocity of the respective bodies.
Note that the kernels to be loaded should be added to the ``.irfpyrc``.
Section [pep] and the entry ``spicekernels`` is the corresponding one.
You can specify the files as a comma separated list.
::
[pep]
spicekernels = /Jupiter/spice/naif0009.tls, /Jupiter/spice/pck00010.tpc , /Jupiter/spice/de421.bsp , /Jupiter/spice/jup230l.bsp
**Spice Kernels**
Spice kernels below must be downloaded from
ftp://naif.jpl.nasa.gov/pub/naif/generic_kernels
- naif0009.tls
- pck00010.tpc
- de421.bsp
- jup230l.bsp
Version of above files may be changed without notification in the future.
In such cases, you can download the latest version,
and change the ``.irfpyrc`` file.
**Private spice kernels**
Private spice kernel to convert JSE frame is made and loaded automatically.
Refer to :ref:`pep_spice_private_kernel`.
'''
import os
import datetime
import logging
logging.basicConfig()
import numpy as np
try:
import spiceypy as spice
except ImportError:
import spice
from irfpy.util.irfpyrc import Rc
import warnings
warnings.warn('This module is deprecated and replced by irfpy.juice.jspice module.',
DeprecationWarning)
[docs]class PepSpice:
''' Class handling PEP-dedicated SPICE kernels.
'''
default_pepspice = None
def __init__(self, rcfilenames=None):
self.logger = logging.getLogger('PepSpice')
self.logger.setLevel(logging.INFO)
self.rc = Rc()
if rcfilenames != None:
self.rc.erase() # Once remove
for rcfile in rcfilenames:
self.rc.append(rcfile)
spicekernels = self.rc.get('pep', 'spicekernels')
if spicekernels == None:
raise ValueError('No entry of [pep] spicekernels to load' +
'in irfpyrc files (./.irfpyrc or ~/.irfpyrc as default)')
spicekernels = spicekernels.split(',')
spicekernels = [s.strip() for s in spicekernels]
for spicekernel in spicekernels:
self.logger.info('furnsh %s' % spicekernel)
spice.furnsh(spicekernel)
self.__add_private()
def __add_private(self):
''' Add a private kernel.
'''
from pkg_resources import resource_filename
jsekernel = resource_filename(__name__,
os.path.join('spice', 'jse_111130.tf'))
self.logger.info('furnsh %s' % jsekernel)
spice.furnsh(jsekernel)
[docs] def get_posvel(self, object, t, frame, center):
''' Get the position and velocity of bodies
Get position and velocity for the given object at the time of t
in the specified frame with the origin of the given body.
A wrapper to SPICE function of ``spkezr``.
Kernels should be read prior to this method (normally done during
the instancing).
Easy way of adding your kernels is to specify the kernel path
into the .irfpyrc entry ([pep] spicekernel).
:param object: A body name in SPICE
:param t: Time
:type t: ``datetime.datetime``
:param frame: A frame name defined in SPICE
:param center: A object name in SPICE to specify the origin.
>>> spep = PepSpice()
>>> t0 = datetime.datetime(2025, 1, 1, 0, 0, 0)
>>> pos, vel = spep.get_posvel('Jupiter', t0, "J2000", "Sun")
>>> print('%.3e %.3e %.3e' % (pos[0], pos[1], pos[2]))
1.580e+08 6.850e+08 2.898e+08
>>> print('%.2f %.2f %.2f' % (vel[0], vel[1], vel[2]))
-12.94 2.95 1.58
'''
t0 = t.strftime('%FT%T')
et0 = spice.str2et(t0)
posvel, lt = spice.spkezr(object, et0, frame, "LT+S", center)
return np.array(posvel[:3]), np.array(posvel[3:])
[docs] def convert_vector(self, vector, from_frame, to_frame, t):
''' Convert vector from a frame to another frame.
A wrapper to SPICE function ``pxform``.
:param vector: Numpy array of the vector in ``from_frame``.
:type vector: ``np.array`` with shape of ``(3, )``.
:param from_frame: Frame name defined in SPICE.
:param to_frame: Frame name defined in SPICE.
:param t: Time
:type t: ``datetime.datetime`` instance
:returns: A vector in ``to_frame``
:rtype: ``np.array`` with shape of ``(3, )``.
'''
t0 = t.strftime('%FT%T')
et0 = spice.str2et(t0)
conv = spice.pxform(from_frame, to_frame, et0)
return np.array(conv).dot(vector)
[docs] @classmethod
def get_default_pepspice(cls):
if cls.default_pepspice == None:
cls.default_pepspice = PepSpice()
return cls.default_pepspice
[docs]def get_default_pepspice():
'''Return the default pepspice instance.
A high-level function that produces a default :class:`PepSpice`.
'''
return PepSpice.get_default_pepspice()
import unittest
import doctest
[docs]def doctests():
return unittest.TestSuite((
doctest.DocTestSuite(),
))
if __name__ == '__main__':
unittest.main(defaultTest='doctests')