From b76ccc28f9d124eb965145f9933117cf4139dc47 Mon Sep 17 00:00:00 2001 From: Dar Dahlen Date: Tue, 28 May 2024 15:26:19 -0700 Subject: [PATCH] SpiceKernels can load external SPK files (#32) * Load spice kernels from specified files. * Add support for printing header information * spk info can now be retrieved --- CHANGELOG.md | 5 ++++ src/neospy/spice.py | 63 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ced0932..92b3059 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,10 +13,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added support for NEOS Visit FOVs, which are joint FOVs containing 4 rectangles. - Added python interface to WISE Color Correction functions. - Added support for querying static sky sources in FOVs. +- SpiceKernels can now load SPK files directly, without needing the files to be in the + cache. +- SpiceKernels now supports displaying the contents of the headers of SPk/PCK files. +- SpiceKernels can now return the available loaded SPK segments of an object. ### Changed - Restructured the Rust FOVs to be organized by observatory. +- Renamed `SpiceKernels.cache_kernel_reload` to `kernel_reload` and changed it's args. ## [0.2.2] - 2024 - 5 - 20 diff --git a/src/neospy/spice.py b/src/neospy/spice.py index f2a7d94..e3deb66 100644 --- a/src/neospy/spice.py +++ b/src/neospy/spice.py @@ -1,5 +1,6 @@ from __future__ import annotations from typing import Union, Optional +from collections import namedtuple import base64 import glob import os @@ -14,6 +15,8 @@ __all__ = ["SpiceKernels"] +SpkInfo = namedtuple("SpkInfo", "name, jd_start, jd_end, center, frame, spk_type") + def _validate_time(time: Union[float, Time]) -> float: """ @@ -172,6 +175,19 @@ def loaded_objects() -> list[tuple[str, int]]: objects = _core.spk_loaded() return [(_core.spk_get_name_from_id(o), o) for o in objects] + @classmethod + def loaded_object_info(cls, desig: Union[int, str]) -> list[SpkInfo]: + """ + Return the available SPK information for the target object. + + Parameters + ---------- + name : + Name or integer id value of the object. + """ + name, naif = cls.name_lookup(desig) + return [SpkInfo(name, *k) for k in _core.spk_available_info(naif)] + @staticmethod def cached_kernel_url_download(url, force_download: bool = False): """ @@ -297,20 +313,49 @@ def cached_kernel_ls(): return glob.glob(path) @staticmethod - def cache_kernel_reload(): + def kernel_reload(filenames: list[str], include_cache=False): """ - Load all kernels in the cache folder and within the neospy data folder. + Load the specified spice kernels into memory, this resets the currently loaded + kernels. - This will load objects found in all `.bsp` and `.bpc` files found in both - folders into the spice loaded memory. + If `include_cache` is true, this will reload the kernels contained within the + neospy cache folder as well. + + Parameters + ---------- + filenames : + Paths to the specified files to load, this must be a list of filenames. + include_cache: + This decides if all of the files contained within the neospy cache should + be loaded in addition to the specified files. """ - cache_files = glob.glob(os.path.join(cache_path(), "kernels", "**.bsp")) _core.spk_reset() - _core.spk_load(cache_files) - - cache_files = glob.glob(os.path.join(cache_path(), "kernels", "**.bpc")) _core.pck_reset() - _core.pck_load(cache_files) + + if include_cache: + cache_files = glob.glob(os.path.join(cache_path(), "kernels", "**.bsp")) + _core.spk_load(cache_files) + + cache_files = glob.glob(os.path.join(cache_path(), "kernels", "**.bpc")) + _core.pck_load(cache_files) + + _core.spk_load(filenames) + + @staticmethod + def spk_header_info(filename: str): + """ + Return the comments contained within the header of the provided DAF file, this + includes SPK and PCK files. + + This does not load the contents of the file into memory, it only prints the + header contents. + + Parameters + ---------- + filename : + Path to a DAF file. + """ + return _core.daf_header_info(filename).replace("\x04", "\n").strip() @classmethod def mpc_code_to_ecliptic(