libera_utils.libera_spice.spice_utils#

Core SPICE utilities for kernel creation, inspection, and time conversions.

This module is home to the core SPICE and kernel utilities in libera_utils, providing the make_kernel() wrapper around Curryer’s KernelCreator, kernel file caching and furnishing via KernelFileCache, the ensure_spice decorator, SPICE-based time conversion wrappers, and kernel inspection helpers.

Functions

ensure_spice(...)

Before trying to understand this piece of code, read this: https://stackoverflow.com/questions/5929107/decorators-with-parameters/60832711#60832711

et2utc_wrapper(et, fmt, prec)

Convert ephemeris times to UTC ISO strings.

et_2_datetime(et)

Convert ephemeris time to a python datetime object by first converting it to a UTC timestamp.

et_2_timestamp(et[, fmt])

Convert ephemeris time to a custom formatted timestamp (default is lowercase version of ISO).

find_most_recent_naif_kernel(naif_base_url, ...)

Retrieves the name of the most recent kernel at NAIF.

ls_all_kernel_coverage([as_datetime, verbose])

List time coverage of all furnished kernels

ls_kernel_coverage(kernel_type[, verbose])

List time coverage of all furnished kernels of a given type

ls_kernels([verbose, log])

List all furnished spice kernels.

ls_spice_constants([verbose])

List all constants in the Spice constant pool

make_kernel(config_file, output_kernel[, ...])

Create a binary SPICE kernel (CK or SPK) from a JSON configuration file and input data.

sce2s_wrapper(et)

Convert ephemeris times to SCLK string https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/sce2s_c.html Decorated wrapper for spiceypy.sce2s that will automatically furnish the latest metakernel and retry if the first call raises an exception.

scs2e_wrapper(sclk_str)

Convert SCLK strings to ephemeris time.

utc2et_wrapper(iso_str)

Convert UTC ISO strings to ephemeris times.

Classes

KernelFileCache(kernel_url[, max_cache_age, ...])

Download, cache, and furnish SPICE kernel files under the user cache directory.

KernelFileRecord(kernel_type, file_name)

Tuple for keeping track of kernel files with default kernel_level

SpiceBody(value)

Enum containing SPICE IDs for ephemeris bodies that we use.

SpiceId(strid, numid)

Class that represents a unique identifier in the NAIF SPICE library

SpiceInstrument(value)

Enum containing SPICE IDs for instrument geometries configured in the Instrument Kernel (IK)

class libera_utils.libera_spice.spice_utils.KernelFileCache(kernel_url: str | Path | S3Path, max_cache_age: timedelta = datetime.timedelta(days=1), fallback_kernel: Path | None = None)#

Download, cache, and furnish SPICE kernel files under the user cache directory.

On first access of kernel_path, a valid cached copy (younger than max_cache_age) is reused; otherwise the kernel is materialized from its source into the cache and that path is returned.

Supported sources for kernel_url:

If materialization fails and fallback_kernel is set, kernel_path may return that path instead (not recommended for production).

Attributes:
cache_dir

Directory where cached kernel files are stored.

kernel_basename

Base filename of the kernel used in the cache directory.

kernel_path

Path to the kernel in the cache, materializing it if necessary.

Methods

clear()

Remove the cached kernel file from the cache directory if it exists.

download_kernel(kernel_url[, allowed_attempts])

Copy or download a kernel into the user cache directory.

is_cached([include_stale])

Return whether a usable cached copy of the kernel exists.

static _resolve_local_kernel_file(kernel_url: Path | str) Path#

Return an absolute path to an existing local kernel file.

Parameters:

kernel_url (pathlib.Path or str) – Path to a kernel file (not a directory).

Returns:

Resolved path suitable as the copy source.

Return type:

pathlib.Path

Raises:

FileNotFoundError – If the resolved path is not a regular file.

property cache_dir: Path#

Directory where cached kernel files are stored.

Returns:

User-specific cache directory for this application.

Return type:

pathlib.Path

clear() None#

Remove the cached kernel file from the cache directory if it exists.

download_kernel(kernel_url: str | Path | S3Path, allowed_attempts: int = 3) Path#

Copy or download a kernel into the user cache directory.

Parameters:
Returns:

Path to the file in the cache directory.

Return type:

pathlib.Path

Raises:
  • FileNotFoundError – If kernel_url denotes a local path that does not exist or is not a file.

  • requests.exceptions.RequestException – If the HTTP download fails after all retries.

  • ValueError – If kernel_url is not a supported type or not an HTTP(S) URL when given as str.

is_cached(include_stale: bool = False) bool#

Return whether a usable cached copy of the kernel exists.

Parameters:

include_stale (bool, optional) – If True, treat kernels older than max_cache_age as still cached.

Returns:

True if the cache file exists and is not stale (unless include_stale is True).

Return type:

bool

property kernel_basename: str#

Base filename of the kernel used in the cache directory.

Returns:

Filename only (no directory components).

Return type:

str

property kernel_path: Path#

Path to the kernel in the cache, materializing it if necessary.

Returns:

Path to the cached file, or fallback_kernel if materialization failed and a fallback was set.

Return type:

pathlib.Path

class libera_utils.libera_spice.spice_utils.KernelFileRecord(kernel_type: str, file_name: str)#

Tuple for keeping track of kernel files with default kernel_level

Methods

count(value, /)

Return number of occurrences of value.

index(value[, start, stop])

Return first index of value.

file_name: str#

Alias for field number 1

kernel_type: str#

Alias for field number 0

class libera_utils.libera_spice.spice_utils.SpiceBody(value)#

Enum containing SPICE IDs for ephemeris bodies that we use.

class libera_utils.libera_spice.spice_utils.SpiceId(strid: str, numid: int)#

Class that represents a unique identifier in the NAIF SPICE library

Methods

count(value, /)

Return number of occurrences of value.

index(value[, start, stop])

Return first index of value.

numid: int#

Alias for field number 1

strid: str#

Alias for field number 0

class libera_utils.libera_spice.spice_utils.SpiceInstrument(value)#

Enum containing SPICE IDs for instrument geometries configured in the Instrument Kernel (IK)

libera_utils.libera_spice.spice_utils.ensure_spice(f_py: _F, time_kernels_only: bool = False) _F#
libera_utils.libera_spice.spice_utils.ensure_spice(f_py: None = None, *, time_kernels_only: bool = False) Callable[[Callable[[...], Any]], Callable[[...], Any]]

Before trying to understand this piece of code, read this: https://stackoverflow.com/questions/5929107/decorators-with-parameters/60832711#60832711

Decorator/wrapper that tries to ensure that a metakernel is furnished in as complete a way as possible.

Control flow overview:

  1. Try simply calling the wrapped function naively.
    • SUCCESS? Great! We’re done.

    • SpiceyError? Go to step 2.

  2. Furnish metakernel at SPICE_METAKERNEL
    • SUCCESS? Great, return the original function again (so it can be re-run).

    • KeyError? Seems like SPICE_METAKERNEL isn’t set, no problem. Go to step 3.

Usage:

Three ways to use this object

  1. A decorator with no arguments

@ensure_spice
def my_spicey_func(a, b):
    pass

2. A decorator with parameters. This is useful if we only need the latest SCLK and LSK kernels for the function involved.

@ensure_spice(time_kernels_only=True)
def my_spicey_time_func(a, b):
    pass
  1. An explicit wrapper function, providing a dynamically set value for parameters, e.g. time_kernels_only

wrapped = ensure_spice(spicey_func, time_kernels_only=True)
result = wrapped(*args, **kwargs)
Parameters:
  • f_py (Callable) – The function requiring SPICE that we are going to wrap if being used explicitly, Otherwise None, in which case ensure_spice is being used, not as a function wrapper (see l2a_processing.py) but as a true decorator without an explicit function argument.

  • time_kernels_only (bool, Optional) – Specify that we only need to furnish time kernels (if SPICE_METAKERNEL is set, we still just furnish that metakernel and assume the time kernels are included.

Returns:

Decorated function, with spice error handling

Return type:

Callable

libera_utils.libera_spice.spice_utils.et2utc_wrapper(et: float | Collection[float] | ndarray, fmt: str, prec: int) str | ndarray#

Convert ephemeris times to UTC ISO strings. https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/et2utc_c.html Decorated wrapper for spiceypy.et2utc that will automatically furnish the latest metakernel and retry if the first call raises an exception.

Parameters:
  • et (Union[float, Collection[float], numpy.ndarray]) – The ephemeris time value to be converted to UTC.

  • fmt (str) – Format string defines the format of the output time string. See CSPICE docs.

  • prec (int) – Number of digits of precision for fractional seconds.

Returns:

UTC time string(s)

Return type:

str or numpy.ndarray

libera_utils.libera_spice.spice_utils.et_2_datetime(et: float | Collection[float] | ndarray) datetime | ndarray#

Convert ephemeris time to a python datetime object by first converting it to a UTC timestamp.

Parameters:

et (float or Collection or numpy.ndarray) – Ephemeris times to be converted.

Returns:

Object representation of ephemeris times.

Return type:

datetime.datetime or numpy.ndarray

libera_utils.libera_spice.spice_utils.et_2_timestamp(et: float | Collection[float] | ndarray, fmt: str = '%Y%m%dT%H%M%S.%f') str | ndarray#

Convert ephemeris time to a custom formatted timestamp (default is lowercase version of ISO).

Parameters:
  • et (float | Collection[float] | numpy.ndarray) – Ephemeris Time to be converted.

  • fmt (str, Optional) – Format string as defined by the datetime.strftime() function.

Returns:

Formatted timestamps

Return type:

str | numpy.ndarray

libera_utils.libera_spice.spice_utils.find_most_recent_naif_kernel(naif_base_url: str, kernel_file_regex: str, allowed_attempts: int = 3) str#

Retrieves the name of the most recent kernel at NAIF.

Parameters:
  • naif_base_url (str) – URL to search for filenames matching kernel_file_regex

  • kernel_file_regex (str) – Regular expression to match filenames on the naif website

  • allowed_attempts (int, Optional) – Number of allowed download times for naif page default = 3

Returns:

Returns the file name of the latest kernel on the naif page (e.g., “naif0012.tls”)

Return type:

str

libera_utils.libera_spice.spice_utils.ls_all_kernel_coverage(as_datetime: bool = True, verbose: bool = False) dict[str, Any]#

List time coverage of all furnished kernels

Parameters:

verbose (bool) – If True, print to stdout also

Returns:

Key is filename, value is a list of tuples giving the start and end times in ET.

Return type:

dict

libera_utils.libera_spice.spice_utils.ls_kernel_coverage(kernel_type: str, verbose: bool = False) dict[str, list[tuple[float, float]]]#

List time coverage of all furnished kernels of a given type

Parameters:
  • kernel_type (str) – Either ‘CK’ or ‘SPK’

  • verbose (bool) – If True, print to stdout also

Returns:

Key is filename, value is a list of tuples giving the start and end times in ET.

Return type:

dict

libera_utils.libera_spice.spice_utils.ls_kernels(verbose: bool = False, log: bool = False) list[KernelFileRecord]#

List all furnished spice kernels.

Parameters:
  • verbose (bool) – If True, print to stdout also

  • log (bool) – Whether or not to log the current kernel pool (this gets called a lot)

Returns:

A list of KernelFileRecord named tuples.

Return type:

list

libera_utils.libera_spice.spice_utils.ls_spice_constants(verbose: bool = False) dict[str, Any]#

List all constants in the Spice constant pool

Parameters:

verbose – If true, print to stdout also

Returns:

Dictionary of kernel constants

Return type:

dict

libera_utils.libera_spice.spice_utils.make_kernel(config_file: str | Path, output_kernel: str | CloudPath | Path, input_data: DataFrame | None = None, overwrite: bool = False, append: bool | int = False) CloudPath | Path#

Create a binary SPICE kernel (CK or SPK) from a JSON configuration file and input data.

This is a low-level utility that wraps Curryer’s KernelCreator, which drives the NAIF command-line tools mkspk (for SPK ephemeris kernels) and msopck (for CK attitude kernels). It is used for creating binary CK and SPK kernels, including fixed-offset static SPKs and dynamic CK/SPK kernels.

This function does NOT create text kernels such as LSKs (.tls), PCKs (.tpc), frame kernels (.tf), instrument kernels (.ti), or clock kernels (.tsc). Those are plain-text files managed separately.

Callers are responsible for ensuring required kernels (especially LSK and any relevant frame kernels) are furnished before calling this function.

Parameters:
  • config_file (str | Path) – JSON configuration file defining how to create the kernel.

  • output_kernel (str | PathType) – Output directory or file to create the kernel. If a directory, the file name will be based on the config_file, but with the SPICE file extension.

  • input_data (pd.DataFrame | None) – pd.DataFrame containing kernel input data. If not supplied, the config is assumed to reference an input data file.

  • overwrite (bool) – Option to overwrite an existing file.

  • append (bool | int) – Option to append to an existing file. Anything truthy will be treated as True.

Returns:

Output kernel file path

Return type:

PathType

Notes

This function requires a leap second kernel (LSK) to be furnished by SPICE before it can convert times. Callers should use KernelManager.load_naif_kernels() or similar to ensure kernels are ready before calling this function.

libera_utils.libera_spice.spice_utils.sce2s_wrapper(et: float | Collection[float] | ndarray) str | ndarray#

Convert ephemeris times to SCLK string https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/sce2s_c.html Decorated wrapper for spiceypy.sce2s that will automatically furnish the latest metakernel and retry if the first call raises an exception.

Parameters:

et (Union[float, Collection[float], numpy.ndarray]) – Ephemeris time

Returns:

SCLK string

Return type:

str or numpy.ndarray

libera_utils.libera_spice.spice_utils.scs2e_wrapper(sclk_str: str | Collection[str]) float | ndarray#

Convert SCLK strings to ephemeris time. https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/scs2e_c.html Decorated wrapper for spiceypy.scs2e that will automatically furnish the latest metakernel and retry if the first call raises an exception.

Parameters:

sclk_str (str or Collection[str]) – Spacecraft clock string

Returns:

Ephemeris time

Return type:

float or numpy.ndarray

libera_utils.libera_spice.spice_utils.utc2et_wrapper(iso_str: str | Collection[str]) float | ndarray#

Convert UTC ISO strings to ephemeris times. https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/utc2et_c.html Decorated wrapper for spiceypy.utc2et that will automatically furnish the latest metakernel and retry if the first call raises an exception.

Parameters:

iso_str (str or Collection[str]) – The UTC to convert to ephemeris time

Returns:

Ephemeris time

Return type:

float or numpy.ndarray