Skip to content

Commit

Permalink
Remove vendored obsgeo_to_frame in favor of using Astropy (#7470)
Browse files Browse the repository at this point in the history
* remove outdated tests

* remove vendored obsgeo_to_frame

* remove test_obsgeo_invalid

* pre-commit changes
  • Loading branch information
ahmedhosssam committed Mar 7, 2024
1 parent 431bbba commit 07b1637
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 121 deletions.
61 changes: 1 addition & 60 deletions sunpy/coordinates/tests/test_wcs_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pytest

import astropy.units as u
from astropy.coordinates import ITRS, BaseCoordinateFrame, SkyCoord
from astropy.coordinates import BaseCoordinateFrame, SkyCoord
from astropy.coordinates.earth import EarthLocation
from astropy.tests.helper import assert_quantity_allclose
from astropy.time import Time
Expand All @@ -18,7 +18,6 @@
)
from sunpy.coordinates.wcs_utils import (
_set_wcs_aux_obs_coord,
obsgeo_to_frame,
solar_frame_to_wcs_mapping,
solar_wcs_frame_mapping,
)
Expand Down Expand Up @@ -343,64 +342,6 @@ def test_frame_mapping_obsgeo_spherical(dkist_location, caplog):
assert not caplog.records


# TODO: Remove all these tests after Astropy 5.0 when we can just import obsgeo_to_frame.
def test_obsgeo_cartesian(dkist_location):
obstime = Time("2021-05-21T03:00:00")
wcs = WCS(naxis=2)
# tolist() returns a tuple.
wcs.wcs.obsgeo = list(dkist_location.to_value(u.m).tolist()) + [0, 0, 0]
wcs.wcs.dateobs = obstime.isot

frame = obsgeo_to_frame(wcs.wcs.obsgeo, obstime)

assert isinstance(frame, ITRS)
assert frame.x == dkist_location.x
assert frame.y == dkist_location.y
assert frame.z == dkist_location.z


def test_obsgeo_spherical(dkist_location):
obstime = Time("2021-05-21T03:00:00")
dkist_location = dkist_location.get_itrs(obstime)
loc_sph = dkist_location.spherical

wcs = WCS(naxis=2)
wcs.wcs.obsgeo = [0, 0, 0] + [loc_sph.lon.to_value(u.deg), loc_sph.lat.to_value(u.deg), loc_sph.distance.to_value(u.m)]
wcs.wcs.dateobs = obstime.isot

frame = obsgeo_to_frame(wcs.wcs.obsgeo, obstime)

assert isinstance(frame, ITRS)
assert u.allclose(frame.x, dkist_location.x)
assert u.allclose(frame.y, dkist_location.y)
assert u.allclose(frame.z, dkist_location.z)


def test_obsgeo_nonfinite(dkist_location):
obstime = Time("2021-05-21T03:00:00")
dkist_location = dkist_location.get_itrs(obstime)
loc_sph = dkist_location.spherical

wcs = WCS(naxis=2)
wcs.wcs.obsgeo = [1, 1, np.nan] + [loc_sph.lon.value, loc_sph.lat.value, loc_sph.distance.value]
wcs.wcs.dateobs = obstime.isot
wcs.wcs.set()

frame = obsgeo_to_frame(wcs.wcs.obsgeo, obstime)

assert isinstance(frame, ITRS)
assert u.allclose(frame.x, dkist_location.x)
assert u.allclose(frame.y, dkist_location.y)
assert u.allclose(frame.z, dkist_location.z)


@pytest.mark.parametrize("obsgeo", ([np.nan] * 6, None, [0] * 6, [54] * 5))
def test_obsgeo_invalid(obsgeo):

with pytest.raises(ValueError):
obsgeo_to_frame(obsgeo, None)


def test_observer_hgln_crln_priority():
"""
When extracting the observer information from a FITS header, ensure
Expand Down
63 changes: 2 additions & 61 deletions sunpy/coordinates/wcs_utils.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import numpy as np

import astropy.units as u
import astropy.wcs.utils
from astropy.coordinates import (
ITRS,
BaseCoordinateFrame,
CartesianRepresentation,
SkyCoord,
SphericalRepresentation,
)
from astropy.coordinates import BaseCoordinateFrame, SkyCoord
from astropy.wcs import WCS
from astropy.wcs.utils import obsgeo_to_frame

from sunpy import log
from .frames import (
Expand All @@ -22,59 +16,6 @@

__all__ = ['solar_wcs_frame_mapping', 'solar_frame_to_wcs_mapping']

try:
# TODO: Remove vendored version after Astropy 5.0
from astropy.wcs.utils import obsgeo_to_frame
except ImportError:
def obsgeo_to_frame(obsgeo, obstime):
"""
Convert a WCS obsgeo property into an `~builtin_frames.ITRS` coordinate frame.
Parameters
----------
obsgeo : array-like
A shape ``(6, )`` array representing ``OBSGEO-[XYZ], OBSGEO-[BLH]`` as
returned by ``WCS.wcs.obsgeo``.
obstime : time-like
The time associated with the coordinate, will be passed to
`~.builtin_frames.ITRS` as the obstime keyword.
Returns
-------
`~.builtin_frames.ITRS`
An `~.builtin_frames.ITRS` coordinate frame
representing the coordinates.
Notes
-----
The obsgeo array as accessed in a `.WCS` object is a length 6 numpy array
where the first three elements are the coordinate in a cartesian
representation and the second 3 are the coordinate in a spherical
representation.
This function priorities reading the cartesian coordinates, and will only
read the spherical coordinates if the cartesian coordinates are either all
zero or any of the cartesian coordinates are non-finite.
In the case where both the spherical and cartesian coordinates have some
non-finite values the spherical coordinates will be returned with the
non-finite values included.
"""
if obsgeo is None or len(obsgeo) != 6 or np.all(np.array(obsgeo) == 0) or np.all(~np.isfinite(obsgeo)):
raise ValueError(f"Can not parse the 'obsgeo' location ({obsgeo}). "
"obsgeo should be a length 6 non-zero, finite numpy array")

# If the cartesian coords are zero or have NaNs in them use the spherical ones
if np.all(obsgeo[:3] == 0) or np.any(~np.isfinite(obsgeo[:3])):
data = SphericalRepresentation(*(obsgeo[3:] * (u.deg, u.deg, u.m)))

# Otherwise we assume the cartesian ones are valid
else:
data = CartesianRepresentation(*obsgeo[:3] * u.m)

return ITRS(data, obstime=obstime)


def solar_wcs_frame_mapping(wcs):
"""
Expand Down

0 comments on commit 07b1637

Please sign in to comment.