Source code for irfpy.pep.pep_spice

''' 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')