Skip to content
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

Add module to use SkyCoord for SPICE computations #7237

Merged
merged 21 commits into from
Nov 7, 2023
Merged

Conversation

ayshih
Copy link
Member

@ayshih ayshih commented Oct 16, 2023

At the recent DASH meeting, there was a lot interest expressed in having SunPy support SPICE kernels at some level. The now-archived astrospice package covered a little of what people use SPICE for, but is still missing many things.

This PR wraps the SPICE computations using the API of our coordinates framework (i.e., using SkyCoord). Here's an example using Solar Orbiter's predicted set of SPICE kernels:

>>> import astropy.units as u
>>> from astropy.coordinates import SkyCoord

>>> from sunpy.coordinates import spice

# Load the meta-kernel and create lots of frames
>>> spice.initialize('solo_ANC_soc-pred-mk.tm')
...
INFO: Installing SOLO_STIX_ILS CK frame (-144851) as 'spice_SOLO_STIX_ILS' [sunpy.coordinates.spice]
...
INFO: Installing SOLO_EUI_FSI_ILS CK frame (-144211) as 'spice_SOLO_EUI_FSI_ILS' [sunpy.coordinates.spice]
...
INFO: Installing SOLO_HEE_NASA dynamic frame (-144982) as 'spice_SOLO_HEE_NASA' [sunpy.coordinates.spice]
...
INFO: Installing SOLO_GSM dynamic frame (-144962) as 'spice_SOLO_GSM' [sunpy.coordinates.spice]
...

# Use SPICE to get the location of Solar Orbiter in a particular SPICE frame
>>> solo = spice.get_body('SOLO', '2024-01-01', spice_frame='SOLO_HEE_NASA')
>>> solo
<SkyCoord (spice_SOLO_HEE_NASA: obstime=2024-01-01T00:00:00.000): (lon, lat, distance) in (deg, deg, km)
    (-17.54823605, 4.15617429, 1.42506511e+08)>

# Transform the location to a different SPICE frame
>>> solo.spice_SOLO_GSM
<SkyCoord (spice_SOLO_GSM: obstime=2024-01-01T00:00:00.000): (lon, lat, distance) in (deg, deg, km)
    (73.47437224, 26.6713468, 45577871.53062959)>

# Retrieve the instrument line-of-sight (boresight) for STIX
>>> stix_ils = SkyCoord(0*u.deg, 0*u.deg, frame='spice_SOLO_STIX_ILS', obstime='2024-01-01')
>>> stix_ils
<SkyCoord (spice_SOLO_STIX_ILS: obstime=2024-01-01T00:00:00.000): (lon, lat) in (deg, deg)
    (0., 0.)>

# Transform the STIX boresight to the instrument frame of EUI FSI
>>> stix_ils.spice_SOLO_EUI_FSI_ILS
<SkyCoord (spice_SOLO_EUI_FSI_ILS: obstime=2024-01-01T00:00:00.000): (lon, lat) in (deg, deg)
    (-0.03, 0.035)>

TODO for this PR:

  • Better document the existence of to_helioprojective()
  • Write a unit tests for get_fov()
  • Write a unit test for to_helioprojective()
  • Add more implementation-approach details so that other developers can actually understand and maintain this
  • Add a way to install a built-in SPICE frame (install_frame())

Deferred to future PRs:

  • Create custom test SPICE kernels rather than downloading "live" ones so that at least some of the tests can be run offline
  • Figure out whether the transformation of velocities is consistent with how Astropy does it
  • Add support for elliptical FOVs (I'd like a "live" instrument kernel that actually defines such an FOV)

@ayshih ayshih added coordinates Affects the coordinates submodule No Backport A PR that isn't to be backported to any release branch. (To be used as a flag to other maintainers) labels Oct 16, 2023
@ayshih ayshih force-pushed the spice branch 2 times, most recently from 6d6981d to 84b5951 Compare October 16, 2023 07:37
@hayesla
Copy link
Member

hayesla commented Oct 16, 2023

this is very nice

@dstansby
Copy link
Member

Given SPICE is used by a wider set of people (/ communities) than just solar physics, I think it's worth having a conversation about whether putting this in sunpy is the best way forward, compared to a separate package or in astropy core. In particular, having a separate package might encourange a wider set of contributors and eyes on the code from different research communities.

(I appreciate astrospice is archived, but that doesn't stop someone forking it and continuing development)

@Cadair
Copy link
Member

Cadair commented Oct 16, 2023

First off, this is awesome.

astrospice also has helpers for getting kernels etc from the net iirc, which is probably useful additional functionality to go along with this? We could resurrect astrospice if we think that's the best place for this to live, but I am not sure I know enough about SPICE and how hard all this is going to be to maintain that I can make a very qualified decision.

@ayshih
Copy link
Member Author

ayshih commented Oct 16, 2023

In the long term, a mature version of this bridging module should probably live in Astropy core. I feel that it is too few code lines and too integrated into the coordinates framework to separate out to its own package (e.g., astrospice). (Downloading SPICE kernels should probably always be a separate package, regardless of where this bridging module lives.)

In the short term, I think maturing this module in SunPy core is the most effective approach. Development can be agile while also automatically distributing the module to the community where the module will have the most impact, and thus get the relevant feedback. Solar missions are the special nexus where scientists both are actively using the SkyCoord API (which planetary folks aren't really yet) and are actively using SPICE kernels (which the non-solar astrophysicists aren't really yet).

setup.cfg Outdated Show resolved Hide resolved
@ayshih ayshih force-pushed the spice branch 6 times, most recently from 4f34122 to 8cb5b2f Compare October 18, 2023 05:07
sunpy/coordinates/spice.py Outdated Show resolved Hide resolved
sunpy/coordinates/spice.py Outdated Show resolved Hide resolved
sunpy/coordinates/tests/test_spice.py Outdated Show resolved Hide resolved
@dstansby
Copy link
Member

dstansby commented Oct 18, 2023

In the long term, a mature version of this bridging module should probably live in Astropy core.

If that's the case, isn't it worth PR'ing this to astropy to get eyes on it from the start from the developers of where we want it to end up? Short term it might be easier for us (sunpy develoeprs) to quickly put something in sunpy, but since this is a major new feature I think it's worth putting the effort in to have design decisions with people outside the solar physics community before jumping in, or putting this in another package that is not mature and constrained to a release cycle like sunpy is that would actually allow for faster iteration and development.

@dstansby
Copy link
Member

Discussed briefly on the weekly call, and consesnus was to go ahead and put this in sunpy core

@dstansby dstansby added the Whats New? Needs a section added to the current Whats New? page. label Oct 18, 2023
Copy link
Member

@Cadair Cadair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than a few coverage gaps (primarily get_body with an observer by the looks of it) I think this looks good to go.

sunpy/coordinates/spice.py Outdated Show resolved Hide resolved
new_pos = shifted_new_pos + CartesianRepresentation(icrs_offset.T)
return to_icrs_frame.realize_frame(new_pos)

frame_transform_graph._add_merged_transform(spice_frame, ICRS, spice_frame)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Random aside, but we are making heavy use of this method in sunpy, should we open a PR to astropy to make it not private?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, not exactly "heavy use", as this would be the first time that we actually use the method in sunpy. (We needed our minimum Astropy dependency to be 5.0, and I didn't want to start refactoring until transformations.py to turned private.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh maybe I am getting confused between your geo frames PR and the merged code lol. Either way, I think that if we are going to rely on it we should ask astropy to mark it as public, mainly so someone doesn't change it somehow thinking that's a safe thing to do?

sunpy/coordinates/spice.py Outdated Show resolved Hide resolved
sunpy/coordinates/tests/test_spice.py Show resolved Hide resolved
@ayshih ayshih force-pushed the spice branch 5 times, most recently from f46bae5 to 24b657c Compare October 22, 2023 03:51
@ayshih ayshih force-pushed the spice branch 4 times, most recently from 72424ab to 1ca2c6c Compare October 31, 2023 04:16
@nabobalis nabobalis merged commit ef9b401 into sunpy:main Nov 7, 2023
23 of 26 checks passed
@nabobalis nabobalis removed the Needs Review Needs reviews before merge label Nov 7, 2023
@ayshih ayshih deleted the spice branch November 8, 2023 04:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
coordinates Affects the coordinates submodule No Backport A PR that isn't to be backported to any release branch. (To be used as a flag to other maintainers) Whats New? Needs a section added to the current Whats New? page.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants