-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Foundational SPICE tools #279
Foundational SPICE tools #279
Conversation
pre-commit.ci autofix |
tools/spice/spice_utils.py
Outdated
|
||
def furnsh(self): | ||
"""Load a kernel file into the SPICE system.""" | ||
self.clear() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this do? does it clear spice kernel pool?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you could add a note about why it's important to clear spice kernel pool, it will help when someone new reads it.
tools/spice/spice_utils.py
Outdated
# 0 : starting from first match | ||
# 1000 : num variable names retrieved in call | ||
# 81 : max len of variable name | ||
kervars = spice.gnpool("*", 0, 1000, 81) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you change kervars
to kernel_vars
?
tools/spice/spice_utils.py
Outdated
# retrieve names of kernel variables | ||
# * means matches all variables | ||
# 0 : starting from first match | ||
# 1000 : num variable names retrieved in call | ||
# 81 : max len of variable name | ||
kervars = spice.gnpool("*", 0, 1000, 81) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could include the link in the comment too if someone like to dive deeper.
# retrieve names of kernel variables | |
# * means matches all variables | |
# 0 : starting from first match | |
# 1000 : num variable names retrieved in call | |
# 81 : max len of variable name | |
kervars = spice.gnpool("*", 0, 1000, 81) | |
# retrieve names of kernel variables using below inputs per https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/cspice/gdpool_c.html | |
# name = '*', means name of the variable whose value is to be returned. | |
# start = 0, Which component to start retrieving for `name'. | |
# room = 1000, The largest number of values to return. | |
# n = 81, Number of values returned for `name'. |
tools/spice/spice_utils.py
Outdated
return result | ||
|
||
|
||
def ls_attitude_coverage(custom_pattern=None) -> tuple: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to be sure ls
here means list, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's right
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like Greg made suggestion above to spell it out. can we do same here? ty!
|
||
matching_pattern = re.match(pattern, basename) | ||
if matching_pattern: | ||
parts = matching_pattern.groups() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a comment here would be helpful.
|
||
# Historical attitude kernels only | ||
if custom_pattern is None: | ||
pattern = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a comment would be helpful
tools/tests/unit/test_spice_utils.py
Outdated
n_files_before_clear = spice.ktotal("ALL") | ||
assert n_files_before_clear > 0 | ||
|
||
# Clear loaded kernels and verify |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These comments are helpful. ty!
tools/tests/unit/test_spice_utils.py
Outdated
assert n_files_loaded_after_clear == 0 | ||
|
||
|
||
def test_furnsh_type(caplog): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's caplog? just curious
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main comment would be that this seems like it'd be nice to have your kernel manager be a contextmanager (you already have manager in the name even ;) ). Let me know if you have thoughts for/against that or any questions and I'd be happy to chat.
The other question I have since I haven't tried this PR out locally is with the spice files you uploaded and whether they would even work for me because they have some hard-coded paths associated with them. Will this cause issues for people in the future?
PATH_SYMBOLS += ( 'GENERIC' ) | ||
PATH_VALUES += ( '/project/mini-rf/poc/LRO/data/storage/ancillary/spice/frames' ) | ||
|
||
PATH_SYMBOLS += ( 'IMAP' ) | ||
PATH_VALUES += ( '/project/sis/users/duttont1/software/imap/lib' ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem like they'd work? Should we change them to be relative to the project somehow, like: /mnt/spice/...
Or can they be removed altogether?
@@ -0,0 +1,17 @@ | |||
KPL/MK | |||
|
|||
Meta kernel that loads the arecibo configuration kernels into the sarbeta program. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meta kernel that loads the arecibo configuration kernels into the sarbeta program. | |
Meta kernel that loads the IMAP configuration kernels. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering if arecibo
was some sort of spice-specific buzz word or the actual arecibo telescope 😅
\begindata | ||
|
||
PATH_SYMBOLS += ( 'IMAP' ) | ||
PATH_VALUES += ( '/Users/lasa6858/Desktop/ultra/ultra_prototype_v1/kernels' ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't work for other users, make more general?
tools/spice/spice_utils.py
Outdated
logger = logging.getLogger(__name__) | ||
|
||
|
||
class SpiceKernelManager: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like it'd be nice to be a context manager, so the loading/closing of the kernels was all taken care of within the scope of when you're using it. Then a user wouldn't need to call furnsh()
or clear()
directly. Thoughts on that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this might even already be implemented in spiceypy? So, do we need our own version here or can you expose that somehow instead.
https://github.com/AndrewAnnex/SpiceyPy/blob/22f7aaa0944d01994540f0acd5136a54ed239efe/src/spiceypy/spiceypy.py#L289
https://spiceypy.readthedocs.io/en/main/contextmanager.html
tools/spice/spice_utils.py
Outdated
extensions : list of str, optional | ||
A list of file extensions to be considered as valid SPICE kernel files. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additional extensions? If I add one entry .greg
to the extension list, I wouldn't necessarily want to have to add all the other default extensions too.
Are there other extensions we need to consider even, or can we just only allow default ones?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could only allow the default ones. I think it's useful during development to be able to select a single extension that I want to furnish and then view the constants for only that kernel type. But this could totally be used without passing the extensions and just relying on the default ones.
tools/spice/spice_utils.py
Outdated
result = {} | ||
for kervar in sorted(kervars): | ||
# retrieve data about a kernel variable | ||
n, kernel_type = spice.dtpool(kervar) # pylint: disable=W0632 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to look up W0632, can you balance the tuple instead of ignoring the linter?
tools/spice/spice_utils.py
Outdated
|
||
|
||
def ls_attitude_coverage(custom_pattern=None) -> tuple: | ||
"""Process attitude kernels to extract and convert dates to UTC format. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not following what this function is being used for. Do we need a custom pattern, or can we prescribe the pattern directly? I think you might be trying to be too nice and flexible, but that can come later if we need to add it.
Maybe more basic is why we are getting this data out of the filename instead of the kernel data itself? i.e. can we query the object within spicepy somehow to get this information instead of parsing filenames.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might change. It was my first attempt at figuring out how we would select the most recent historical attitude kernel. I will put a TODO here in case we find that symlink can do that. I don't want to delete it quite yet though.
tools/tests/unit/test_spice_utils.py
Outdated
|
||
expected = [str(directory / "imap_spk_demo.bsp")] | ||
|
||
assert sorted(result) == sorted(expected) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are length-1 lists, so don't need to sort.
tools/tests/unit/test_spice_utils.py
Outdated
|
||
# Test with valid extensions | ||
result = ls_attitude_coverage() | ||
assert result is not None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are doing an isinstance right below this, so that will also ensure result is not None.
assert result is not None |
tools/tests/unit/test_spice_utils.py
Outdated
|
||
# Test with an empty directory | ||
kernel_object.clear() | ||
empty_result = ls_attitude_coverage() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this raise or be an empty tuple instead?
if extensions is None: | ||
result.append(file) | ||
# Check if the file ends with any of the specified extensions | ||
elif any(file.endswith(ext) for ext in extensions): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this filtering be done using a file type input for ktotal()
and kdata()
instead of passing in "ALL"
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is definitely more than one way to do this. kdata gives information about the ith kernels loaded of a certain type. Instead of using extensions I could use kernel type (SPK instead of .bsp for example). I started using extensions in SpiceKernelManager and just continued using it in list_loaded_kernels. Would it be more helpful for you if I added a way to use kernel type instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work here, this is super useful! I just had mostly nit-picky naming and formatting suggestions.
tools/spice/spice_utils.py
Outdated
|
||
Parameters | ||
---------- | ||
extensions: list of str, optional |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extensions: list of str, optional | |
extensions: list of str or None, optional |
tools/spice/spice_utils.py
Outdated
return result | ||
|
||
|
||
def ls_spice_constants() -> dict: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def ls_spice_constants() -> dict: | |
def list_all_constants() -> dict: |
tools/spice/spice_utils.py
Outdated
: tuple | ||
Tuple giving the most recent start and end time in ET. | ||
""" | ||
att_kernels = ls_kernels([".ah.bc", ".ah.a"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
att_kernels = ls_kernels([".ah.bc", ".ah.a"]) | |
attitude_kernels = ls_kernels([".ah.bc", ".ah.a"]) |
@@ -0,0 +1,17 @@ | |||
KPL/MK | |||
|
|||
Meta kernel that loads the arecibo configuration kernels into the sarbeta program. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering if arecibo
was some sort of spice-specific buzz word or the actual arecibo telescope 😅
@@ -0,0 +1,30 @@ | |||
KPL/MK | |||
|
|||
Meta kernel that loads the arecibo configuration kernels into the sarbeta program. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meta kernel that loads the arecibo configuration kernels into the sarbeta program. | |
Meta kernel that loads the IMAP configuration kernels. |
tools/tests/unit/test_spice_utils.py
Outdated
assert n_files_loaded == n_test_files | ||
|
||
|
||
def test_clear(kernel_object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def test_clear(kernel_object): | |
def test_clear(kernel_object): | |
"""Tests the clearing of kernels via the ``clear`` method""" |
tools/tests/unit/test_spice_utils.py
Outdated
assert n_files_loaded_after_clear == 0 | ||
|
||
|
||
def test_furnsh_type(caplog): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit confused as to what this test is checking for. It looks more like it is making sure that an invalid kernel type is resulting in an expected error message? If so, might want to rename the test to something like test_invalid_kernel
. It would also be helpful to include a docstring.
tools/tests/unit/test_spice_utils.py
Outdated
kernel_object.clear() | ||
|
||
|
||
def test_ls_kernels(kernel_object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def test_ls_kernels(kernel_object): | |
def test_ls_kernels(kernel_object): | |
"""Tests the ``ls_kernels`` function""" |
tools/tests/unit/test_spice_utils.py
Outdated
assert sorted(result) == sorted(expected) | ||
|
||
|
||
def test_ls_spice_constants(kernel_object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def test_ls_spice_constants(kernel_object): | |
def test_ls_spice_constants(kernel_object): | |
"""Tests the ``ls_spice_constants`` function""" |
tools/tests/unit/test_spice_utils.py
Outdated
assert list(result.keys()) == expected_keys | ||
|
||
|
||
def test_ls_attitude_coverage(kernel_object): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def test_ls_attitude_coverage(kernel_object): | |
def test_ls_attitude_coverage(kernel_object): | |
"""Tests the ``ls_attitude_coverage`` function""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks good to me. I had one comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this brought in by mistake?
* add spice tools
Change Summary
Overview
-Added some basic tools.
New Dependencies
None
New Files
Testing
Note: there are other test files in: smb://lasp-store.lasp.colorado.edu/projects/Phase_Development/IMAP-SOC/Technical/POC/MOC Interface/PRELIM_SPICE_TEST1.zip that I have not yet added to the repo.
closes #66
closes IMAP-Science-Operations-Center/sds-data-manager#82