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

Fix support of custom WCS mapping. #15630

Merged
merged 4 commits into from Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 43 additions & 1 deletion astropy/wcs/tests/test_utils.py
Expand Up @@ -29,6 +29,8 @@
from astropy.utils.exceptions import AstropyUserWarning
from astropy.wcs import _wcs
from astropy.wcs.utils import (
FRAME_WCS_MAPPINGS,
WCS_FRAME_MAPPINGS,
_pixel_to_pixel_correlation_matrix,
_pixel_to_world_correlation_matrix,
_split_matrix,
Expand Down Expand Up @@ -417,7 +419,10 @@ def test_wcs_to_body_frame():

unknown_wcs = WCS(naxis=2)
unknown_wcs.wcs.ctype = ["UTLN-TAN", "UTLT-TAN"]
with pytest.raises(KeyError, match="unknown solar system object abbreviation UT"):
with pytest.raises(
ValueError,
match="Could not determine celestial frame corresponding to the specified WCS object",
):
frame = wcs_to_celestial_frame(unknown_wcs)

triaxial_wcs = WCS(naxis=2)
Expand Down Expand Up @@ -1593,3 +1598,40 @@ def test_obsgeo_infinite(dkist_location):
def test_obsgeo_invalid(obsgeo):
with pytest.raises(ValueError):
obsgeo_to_frame(obsgeo, None)


def test_custom_wcs_to_from_frame():
# See https://github.com/astropy/astropy/issues/15625
# test from Sam van Kooten

class CustomFrame(BaseCoordinateFrame):
obstime = Time("2017-08-17T12:41:04.43")

def custom_wcs_frame_mapping(wcs):
ctypes = {c[:4] for c in wcs.wcs.ctype}
if not ({"CSLN", "CSLT"} <= ctypes):
return None

dateobs = wcs.wcs.dateavg or wcs.wcs.dateobs or None
custom_frame = CustomFrame()
return custom_frame

def custom_frame_wcs_mapping(frame, projection="TAN"):
if not isinstance(frame, CustomFrame):
return None
wcs = WCS(naxis=2)
wcs.wcs.ctype = [f"CSLN-{projection}", f"CSLT-{projection}"]
return wcs

WCS_FRAME_MAPPINGS.append([custom_wcs_frame_mapping])
FRAME_WCS_MAPPINGS.append([custom_frame_wcs_mapping])

mywcs = WCS(naxis=2)
mywcs.wcs.ctype = ["CSLN-TAN", "CSLT-TAN"]
custom_frame = custom_wcs_frame_mapping(mywcs)
assert isinstance(custom_frame, CustomFrame)

custom_wcs = custom_frame_wcs_mapping(custom_frame)
print(custom_wcs.wcs.ctype)
assert custom_wcs.wcs.ctype[0] == "CSLN-TAN"
assert custom_wcs.wcs.ctype[1] == "CSLT-TAN"
4 changes: 1 addition & 3 deletions astropy/wcs/utils.py
Expand Up @@ -158,13 +158,11 @@ def _wcs_to_celestial_frame_builtin(wcs):
representation_type=SphericalRepresentation,
obstime=wcs.wcs.dateobs or None,
)
elif xcoord[2:4] in ("LN", "LT") and "H" not in xcoord and "CR" not in xcoord:
elif xcoord[2:4] in ("LN", "LT") and xcoord[:2] in SOLAR_SYSTEM_OBJ_DICT.keys():
# Coordinates on a planetary body, as defined in
# https://agupubs.onlinelibrary.wiley.com/doi/10.1029/2018EA000388

object_name = SOLAR_SYSTEM_OBJ_DICT.get(xcoord[:2])
if object_name is None:
raise KeyError(f"unknown solar system object abbreviation {xcoord[:2]}")

a_radius = wcs.wcs.aux.a_radius
b_radius = wcs.wcs.aux.b_radius
Expand Down
2 changes: 2 additions & 0 deletions docs/changes/wcs/15630.bugfix.rst
@@ -0,0 +1,2 @@
Fix a regression in custom WCS mapping due to the recent introduction of
Solar System frames.