SPICE Pool#

The SPICE calculations are performed on a pre-loaded set of kernels, usually with the spiceypy.furnsh() function. These kernels are cached in the SPICE pool and accessible to all the SPICE functions.

To easily manipulate this pool, to add or remove kernels and to quickly check its content, we created a python SpicePool object that acts as a singleton.

from planetary_coverage import SpicePool

The SpicePool contains the list of all the pre-loaded kernels:

SpicePool
<SpicePool> EMPTY

Add and remove kernels to the pool#

You can add one or many kernel(s) with:

Download

naif0012.tls kernel

SpicePool.add('naif0012.tls')

SpicePool
<SpicePool> 1 kernels loaded:
 - naif0012.tls
SpicePool.kernels
('naif0012.tls',)
SpicePool.remove('naif0012.tls')

SpicePool
<SpicePool> EMPTY

You can check if a kernel is already in the pool:

'naif0012.tls' in SpicePool
False

And you can also check the full content of the pool against a list of expected kernels:

SpicePool == ['naif0012.tls']
False

Note

If the kernel is already present in the pool, it will throw a ValueError exception but a kernel can only be loaded once.

You can also use logical operations to add/remove a kernel(s) to/from the pool:

SpicePool + 'naif0012.tls'
SpicePool - 'naif0012.tls'

If needed, you can purge the whole pool at once:

SpicePool.purge()

SpicePool
<SpicePool> EMPTY

Get values from pool#

Download

pck00010.tpc kernel

SpicePool.add(['naif0012.tls', 'pck00010.tpc'])

When your set of kernels is loaded, you can request any values in the pool with the python getter syntax:

SpicePool['DELTET/DELTA_T_A']
32.184
SpicePool['BODY503_RADII']
array([2631.2, 2631.2, 2631.2])

If the value is not present in the pool a ValueError will be thrown:

SpicePool['FOO']
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In[13], line 1
----> 1 SpicePool['FOO']

File ~/checkouts/readthedocs.org/user_builds/planetary-coverage/checkouts/1.0.0/src/planetary_coverage/spice/pool.py:65, in MetaSpicePool.__getitem__(cls, item)
     64 def __getitem__(cls, item):
---> 65     return get_item(item)

File ~/checkouts/readthedocs.org/user_builds/planetary-coverage/checkouts/1.0.0/src/planetary_coverage/spice/kernel.py:431, in get_item(item)
    428         arr = sp.gcpool(item, 0, 1_000)
    430     except sp.stypes.NotFoundError:
--> 431         raise KeyError(f'`{item}` was not found in the kernel pool.') from None
    433 return arr if len(arr) > 1 else arr[0]

KeyError: '`FOO` was not found in the kernel pool.'

Kernels temporal coverage#

Sometime it can be difficult to get the complete range of valid times that can be use with the kernels loaded in the pool. The SpicePool provide a helper that will search all CK, PCK and SPK kernels to find the coverage window associated with a given body:

SpicePool.windows('GANYMEDE')
array([['2031-01-19T00:00:00.000', '2035-06-03T00:00:00.000'],
       ['2031-01-19T00:00:00.000', '2035-06-03T00:00:00.000']],
      dtype='datetime64[ms]')

You can select different types of output format, with the fmt argument:

SpicePool.windows('GANYMEDE', fmt='ET')
array([[9.79819269e+08, 1.11771367e+09],
       [9.79819269e+08, 1.11771367e+09]])

You can also provide a list of bodies to get all their coverage windows:

SpicePool.windows('JUICE', 'GANYMEDE')
array([['2031-01-19T00:00:00.000', '2035-06-03T00:00:00.000'],
       ['2031-01-19T00:00:00.000', '2035-06-03T00:00:00.000'],
       ['2023-04-05T12:40:24.151', '2035-06-03T00:00:00.000']],
      dtype='datetime64[ms]')

If you need the overlapping coverage (i.e. max start time and min stop time), you can use the .coverage() function:

SpicePool.coverage('JUICE', 'GANYMEDE', fmt='TDB')
('2031-01-19 00:01:09.184 TDB', '2035-06-03 00:01:09.184 TDB')

Enable pool debugger#

If you need to debug the SPICE pool, you can increase the level of the verbose with the debug_spice_pool() function.

from planetary_coverage.debug import debug_spice_pool

debug_spice_pool(True)
[Spice Pool] Change logger level to DEBUG

Tip

If you want purge the pool before loading a new set of kernels, you can add purge=True argument.

SpicePool.add('naif0012.tls', purge=True)
[Spice Pool] Purge the pool
[Spice Pool] Add `naif0012.tls` in the SPICE pool
SpicePool.remove('naif0012.tls')
[Spice Pool] Remove naif0012.tls
SpicePool.purge()
[Spice Pool] Purge the pool

You can decrease the verbose level to INFO with an 'info' key:

debug_spice_pool('info')
[Spice Pool] Change logger level to INFO

Now only, the purge of the pool will trigger a log output:

SpicePool.add('naif0012.tls')
SpicePool.remove('naif0012.tls')
SpicePool.purge()
[Spice Pool] Purge the pool

To disable the SPICE pool verbose, pass a False key:

debug_spice_pool(False)