From 065d4ced816efdb23fd10107b7360f9899067dfa Mon Sep 17 00:00:00 2001 From: Nadia Dencheva Date: Mon, 20 Nov 2023 09:45:36 -0500 Subject: [PATCH] make tests pass, ecept slicing --- gwcs/coordinate_frames.py | 153 ++++++++++++++++++-------- gwcs/tests/conftest.py | 8 +- gwcs/tests/test_api.py | 4 +- gwcs/tests/test_api_slicing.py | 14 +-- gwcs/tests/test_coordinate_systems.py | 2 +- gwcs/tests/test_wcs.py | 39 ++++--- 6 files changed, 145 insertions(+), 75 deletions(-) diff --git a/gwcs/coordinate_frames.py b/gwcs/coordinate_frames.py index 4c464ea6..834b1e71 100644 --- a/gwcs/coordinate_frames.py +++ b/gwcs/coordinate_frames.py @@ -302,7 +302,7 @@ def __post_init__(self, naxes): raise ValueError("Number of axes names does not match number of axes.") else: self.axes_names = tuple([""] * naxes) - + if self.axis_physical_types is not None: if isinstance(self.axis_physical_types, str): self.axis_physical_types = (self.axis_physical_types,) @@ -313,12 +313,22 @@ def __post_init__(self, naxes): ph_type = [] for axt in self.axis_physical_types: if axt not in VALID_UCDS and not axt.startswith("custom:"): - ph_type.append("custom:{axt}") + ph_type.append(f"custom:{axt}") else: ph_type.append(axt) validate_physical_types(ph_type) - self.axes_physical_types = tuple(ph_type) + self.axis_physical_types = tuple(ph_type) + #self.world_axis_physical_types = tuple(ph_type) + + @property + def _default_axis_physical_type(self): + """ + The default physical types to use for this frame if none are specified + by the user. + """ + return tuple("custom:{}".format(t) for t in self.axes_type) + class CoordinateFrame(BaseCoordinateFrame): @@ -360,17 +370,25 @@ def __init__(self, naxes, axes_type, axes_order, reference_frame=None, if isinstance(axes_type, str): axes_type = (axes_type,) - default_apt = tuple([f"custom:{t}" for t in axes_type]) + self._prop = FrameProperties( naxes, axes_type, unit, axes_names, - axis_physical_types or default_apt, + axis_physical_types or self._default_axis_physical_type(axes_type) + #axis_physical_types# or default_apt, ) super().__init__() + def _default_axis_physical_type(self, axes_type): + """ + The default physical types to use for this frame if none are specified + by the user. + """ + return tuple("custom:{}".format(t) for t in axes_type) + def __repr__(self): fmt = '<{0}(name="{1}", unit={2}, axes_names={3}, axes_order={4}'.format( self.__class__.__name__, self.name, @@ -386,8 +404,11 @@ def __str__(self): return self.__class__.__name__ def _sort_property(self, property): - return tuple(dict(sorted(zip(property, self.axes_order), - key=lambda x: x[1])).keys()) + #return tuple(dict(sorted(zip(property, self.axes_order), + # key=lambda x: x[1])).keys()) + sorted_prop = sorted(zip(property, self.axes_order), + key=lambda x: x[1]) + return tuple([t[0] for t in sorted_prop]) @property def name(self): @@ -408,6 +429,7 @@ def naxes(self): def unit(self): """The unit of this frame.""" return self._sort_property(self._prop.unit) + #return self._prop.unit @property def axes_names(self): @@ -436,21 +458,21 @@ def axis_physical_types(self): These physical types are the types in frame order, not transform order. """ - return self._sort_property(self._prop.axis_physical_types) + return self._prop.axis_physical_types or self._default_axis_physical_types @property def world_axis_object_classes(self): return {f"{at}{i}" if i != 0 else at: (u.Quantity, (), {'unit': unit}) - for i, (at, unit) in enumerate(zip(self._axes_type, self.unit))} + for i, (at, unit) in enumerate(zip(self.axes_type, self.unit))} @property def world_axis_object_components(self): return [(f"{at}{i}" if i != 0 else at, 0, 'value') for i, at in enumerate(self._prop.axes_type)] @property - def _native_world_axis_object_components(self): + def _native_world_axis_object_components(self): """Defines the target component ordering (i.e. not taking into account axes_order)""" return self.world_axis_object_components @@ -486,16 +508,19 @@ def __init__(self, axes_order=None, reference_frame=None, if axes_names is None: axes_names = _axes_names naxes = len(_axes_names) - _unit = list(reference_frame.representation_component_units.values()) - if unit is None and _unit: - unit = _unit + #_unit = list(reference_frame.representation_component_units.values()) + #if unit is None and _unit: + # unit = _unit + + self.native_axes_order = tuple(range(naxes)) if axes_order is None: - axes_order = tuple(range(naxes)) + axes_order = self.native_axes_order if unit is None: unit = tuple([u.degree] * naxes) axes_type = ['SPATIAL'] * naxes + pht = axis_physical_types or self._default_axis_physical_types(reference_frame, axes_names) super().__init__(naxes=naxes, axes_type=axes_type, axes_order=axes_order, @@ -503,30 +528,30 @@ def __init__(self, axes_order=None, reference_frame=None, unit=unit, axes_names=axes_names, name=name, - axis_physical_types=axis_physical_types) + axis_physical_types=pht) - @property - def _default_axis_physical_types(self): - if isinstance(self.reference_frame, coord.Galactic): + def _default_axis_physical_types(self, reference_frame, axes_names): + if isinstance(reference_frame, coord.Galactic): return "pos.galactic.lon", "pos.galactic.lat" - elif isinstance(self.reference_frame, (coord.GeocentricTrueEcliptic, - coord.GCRS, - coord.PrecessedGeocentric)): + elif isinstance(reference_frame, (coord.GeocentricTrueEcliptic, + coord.GCRS, + coord.PrecessedGeocentric)): return "pos.bodyrc.lon", "pos.bodyrc.lat" - elif isinstance(self.reference_frame, coord.builtin_frames.BaseRADecFrame): + elif isinstance(reference_frame, coord.builtin_frames.BaseRADecFrame): return "pos.eq.ra", "pos.eq.dec" - elif isinstance(self.reference_frame, coord.builtin_frames.BaseEclipticFrame): + elif isinstance(reference_frame, coord.builtin_frames.BaseEclipticFrame): return "pos.ecliptic.lon", "pos.ecliptic.lat" else: return tuple("custom:{}".format(t) for t in self.axes_names) @property def world_axis_object_classes(self): + unit = np.array(self.unit)[np.argsort(self.axes_order)] return {'celestial': ( coord.SkyCoord, (), {'frame': self.reference_frame, - 'unit': self.unit})} + 'unit': unit})} @property def _native_world_axis_object_components(self): @@ -563,28 +588,34 @@ class SpectralFrame(CoordinateFrame): def __init__(self, axes_order=(0,), reference_frame=None, unit=None, axes_names=None, name=None, axis_physical_types=None): - + + if not isiterable(unit): + unit = (unit,) + + pht = axis_physical_types or self._default_axis_physical_types(unit) + super().__init__(naxes=1, axes_type="SPECTRAL", axes_order=axes_order, axes_names=axes_names, reference_frame=reference_frame, unit=unit, name=name, - axis_physical_types=axis_physical_types) + #axis_physical_types="em.wl") + axis_physical_types=pht) - @property - def _default_axis_physical_types(self): - if self.unit[0].physical_type == "frequency": + + def _default_axis_physical_types(self, unit): + if unit[0].physical_type == "frequency": return ("em.freq",) - elif self.unit[0].physical_type == "length": + elif unit[0].physical_type == "length": return ("em.wl",) - elif self.unit[0].physical_type == "energy": + elif unit[0].physical_type == "energy": return ("em.energy",) - elif self.unit[0].physical_type == "speed": + elif unit[0].physical_type == "speed": return ("spect.dopplerVeloc",) logging.warning("Physical type may be ambiguous. Consider " "setting the physical type explicitly as " "either 'spect.dopplerVeloc.optical' or " "'spect.dopplerVeloc.radio'.") else: - return ("custom:{}".format(self.unit[0].physical_type),) + return ("custom:{}".format(unit[0].physical_type),) @property def world_axis_object_classes(self): @@ -625,9 +656,11 @@ def __init__(self, reference_frame, unit=None, axes_order=(0,), reference_frame.scale, reference_frame.location) + pht = axis_physical_types or self._default_axis_physical_types() + super().__init__(naxes=1, axes_type="TIME", axes_order=axes_order, axes_names=axes_names, reference_frame=reference_frame, - unit=unit, name=name, axis_physical_types=axis_physical_types) + unit=unit, name=name, axis_physical_types=pht) self._attrs = {} for a in self.reference_frame.info._represent_as_dict_extra_attrs: try: @@ -635,7 +668,7 @@ def __init__(self, reference_frame, unit=None, axes_order=(0,), except AttributeError: pass - @property + #@property def _default_axis_physical_types(self): return ("time",) @@ -686,13 +719,16 @@ class CompositeFrame(CoordinateFrame): def __init__(self, frames, name=None): self._frames = frames[:] naxes = sum([frame._naxes for frame in self._frames]) + axes_type = list(range(naxes)) unit = list(range(naxes)) axes_names = list(range(naxes)) - axes_order = [] ph_type = list(range(naxes)) + axes_order = [] + for frame in frames: axes_order.extend(frame.axes_order) + for frame in frames: unsorted_prop = zip( frame.axes_order, @@ -706,6 +742,8 @@ def __init__(self, frames, name=None): axes_names[ind] = n unit[ind] = un ph_type[ind] = pht + + if len(np.unique(axes_order)) != len(axes_order): raise ValueError("Incorrect numbering of axes, " "axes_order should contain unique numbers, " @@ -714,6 +752,7 @@ def __init__(self, frames, name=None): super().__init__(naxes, axes_type=axes_type, axes_order=axes_order, unit=unit, axes_names=axes_names, + axis_physical_types=tuple(ph_type), name=name) self._axis_physical_types = tuple(ph_type) @@ -721,6 +760,22 @@ def __init__(self, frames, name=None): def frames(self): return self._frames + @property + def unit(self): + return self._prop.unit + + @property + def axes_(self): + return self._prop.axes_names + + @property + def axes_type(self): + return self._prop.axes_type + + @property + def axis_physical_types(self): + return self._prop.axis_physical_types + def __repr__(self): return repr(self.frames) @@ -767,12 +822,14 @@ def world_axis_object_components(self): We need to generate the components respecting the axes_order. """ out = [None] * self.naxes + for frame, components in self._wao_renamed_components_iter: for i, ao in enumerate(frame.axes_order): out[ao] = components[i] if any([o is None for o in out]): raise ValueError("axes_order leads to incomplete world_axis_object_components") + return out @property @@ -793,11 +850,13 @@ class StokesFrame(CoordinateFrame): """ def __init__(self, axes_order=(0,), axes_names=("stokes",), name=None, axis_physical_types=None): + + pht = axis_physical_types or self._default_axis_physical_types() + super().__init__(1, ["STOKES"], axes_order, name=name, axes_names=axes_names, unit=u.one, - axis_physical_types=axis_physical_types) + axis_physical_types=pht) - @property def _default_axis_physical_types(self): return ("phys.polarization.stokes",) @@ -831,17 +890,19 @@ class Frame2D(CoordinateFrame): """ def __init__(self, axes_order=(0, 1), unit=(u.pix, u.pix), axes_names=('x', 'y'), - name=None, axis_physical_types=None): + name=None, axes_type=["SPATIAL", "SPATIAL"], axis_physical_types=None): + + pht = axis_physical_types or self._default_axis_physical_types(axes_names, axes_type) - super().__init__(naxes=2, axes_type=["SPATIAL", "SPATIAL"], + super().__init__(naxes=2, axes_type=axes_type, axes_order=axes_order, name=name, axes_names=axes_names, unit=unit, - axis_physical_types=axis_physical_types) + axis_physical_types=pht) - @property - def _default_axis_physical_types(self): - if all(self.axes_names): - ph_type = self.axes_names + def _default_axis_physical_types(self, axes_names, axes_type): + if axes_names is not None and all(axes_names): + ph_type = axes_names else: - ph_type = self.axes_type + ph_type = axes_type + return tuple("custom:{}".format(t) for t in ph_type) diff --git a/gwcs/tests/conftest.py b/gwcs/tests/conftest.py index 0b0a8878..b776786c 100644 --- a/gwcs/tests/conftest.py +++ b/gwcs/tests/conftest.py @@ -10,10 +10,10 @@ from astropy import coordinates as coord from astropy.modeling import models -from .. import coordinate_frames as cf -from .. import spectroscopy as sp -from .. import wcs -from .. import geometry +from gwcs import coordinate_frames as cf +from gwcs import spectroscopy as sp +from gwcs import wcs +from gwcs import geometry # frames detector_1d = cf.CoordinateFrame(name='detector', axes_order=(0,), naxes=1, axes_type="detector") diff --git a/gwcs/tests/test_api.py b/gwcs/tests/test_api.py index 0c5b5c4e..53661d6c 100644 --- a/gwcs/tests/test_api.py +++ b/gwcs/tests/test_api.py @@ -195,7 +195,7 @@ def test_world_axis_object_classes_2d(gwcs_2d_spatial_shift): assert 'frame' in waoc['celestial'][2] assert 'unit' in waoc['celestial'][2] assert isinstance(waoc['celestial'][2]['frame'], coord.ICRS) - assert waoc['celestial'][2]['unit'] == (u.deg, u.deg) + assert tuple(waoc['celestial'][2]['unit']) == (u.deg, u.deg) def test_world_axis_object_classes_2d_generic(gwcs_2d_quantity_shift): @@ -217,7 +217,7 @@ def test_world_axis_object_classes_4d(gwcs_4d_identity_units): assert 'frame' in waoc['celestial'][2] assert 'unit' in waoc['celestial'][2] assert isinstance(waoc['celestial'][2]['frame'], coord.ICRS) - assert waoc['celestial'][2]['unit'] == (u.deg, u.deg) + assert tuple(waoc['celestial'][2]['unit']) == (u.deg, u.deg) temporal = waoc['temporal'] assert temporal[0] is time.Time diff --git a/gwcs/tests/test_api_slicing.py b/gwcs/tests/test_api_slicing.py index d4866242..071c110a 100644 --- a/gwcs/tests/test_api_slicing.py +++ b/gwcs/tests/test_api_slicing.py @@ -51,7 +51,7 @@ def test_ellipsis(gwcs_3d_galactic_spectral): assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) - assert wcs.world_axis_object_classes['celestial'][2]['unit'] == (u.deg, u.deg) + assert tuple(wcs.world_axis_object_classes['celestial'][2]['unit']) == (u.deg, u.deg) assert wcs.world_axis_object_classes['spectral'][0] is SpectralCoord assert wcs.world_axis_object_classes['spectral'][1] == () @@ -112,7 +112,7 @@ def test_spectral_slice(gwcs_3d_galactic_spectral): assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) - assert wcs.world_axis_object_classes['celestial'][2]['unit'] == (u.deg, u.deg) + assert tuple(wcs.world_axis_object_classes['celestial'][2]['unit']) == (u.deg, u.deg) assert_allclose(wcs.pixel_to_world_values(29, 44), (10, 25)) assert_allclose(wcs.array_index_to_world_values(44, 29), (10, 25)) @@ -173,7 +173,7 @@ def test_spectral_range(gwcs_3d_galactic_spectral): assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) - assert wcs.world_axis_object_classes['celestial'][2]['unit'] == (u.deg, u.deg) + assert tuple(wcs.world_axis_object_classes['celestial'][2]['unit']) == (u.deg, u.deg) assert wcs.world_axis_object_classes['spectral'][0] is SpectralCoord assert wcs.world_axis_object_classes['spectral'][1] == () @@ -237,7 +237,7 @@ def test_celestial_slice(gwcs_3d_galactic_spectral): assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) - assert wcs.world_axis_object_classes['celestial'][2]['unit'] == (u.deg, u.deg) + assert tuple(wcs.world_axis_object_classes['celestial'][2]['unit']) == (u.deg, u.deg) assert wcs.world_axis_object_classes['spectral'][0] is SpectralCoord assert wcs.world_axis_object_classes['spectral'][1] == () @@ -302,7 +302,7 @@ def test_celestial_range(gwcs_3d_galactic_spectral): assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) - assert wcs.world_axis_object_classes['celestial'][2]['unit'] == (u.deg, u.deg) + assert tuple(wcs.world_axis_object_classes['celestial'][2]['unit']) == (u.deg, u.deg) assert wcs.world_axis_object_classes['spectral'][0] is SpectralCoord assert wcs.world_axis_object_classes['spectral'][1] == () @@ -370,7 +370,7 @@ def test_no_array_shape(gwcs_3d_galactic_spectral): assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) - assert wcs.world_axis_object_classes['celestial'][2]['unit'] == (u.deg, u.deg) + assert tuple(wcs.world_axis_object_classes['celestial'][2]['unit']) == (u.deg, u.deg) assert wcs.world_axis_object_classes['spectral'][0] is SpectralCoord assert wcs.world_axis_object_classes['spectral'][1] == () @@ -438,7 +438,7 @@ def test_ellipsis_none_types(gwcs_3d_galactic_spectral): assert wcs.world_axis_object_classes['celestial'][0] is SkyCoord assert wcs.world_axis_object_classes['celestial'][1] == () assert isinstance(wcs.world_axis_object_classes['celestial'][2]['frame'], Galactic) - assert wcs.world_axis_object_classes['celestial'][2]['unit'] == (u.deg, u.deg) + assert tuple(wcs.world_axis_object_classes['celestial'][2]['unit']) == (u.deg, u.deg) assert_allclose(wcs.pixel_to_world_values(29, 39, 44), (10, 20, 25)) assert_allclose(wcs.array_index_to_world_values(44, 39, 29), (10, 20, 25)) diff --git a/gwcs/tests/test_coordinate_systems.py b/gwcs/tests/test_coordinate_systems.py index 88035b10..6f556c4a 100644 --- a/gwcs/tests/test_coordinate_systems.py +++ b/gwcs/tests/test_coordinate_systems.py @@ -375,7 +375,7 @@ def test_axis_physical_type(): assert comp.axis_physical_types == ('pos.eq.ra', 'pos.eq.dec', 'em.freq', 'em.wl') spec6 = cf.SpectralFrame(name='waven', axes_order=(1,), - axis_physical_types='em.wavenumber') + axis_physical_types='em.wavenumber', unit=u.Unit(1)) assert spec6.axis_physical_types == ('em.wavenumber',) t = cf.TemporalFrame(reference_frame=Time("2018-01-01T00:00:00"), unit=u.s) diff --git a/gwcs/tests/test_wcs.py b/gwcs/tests/test_wcs.py index b1c40f2a..3ff28b9a 100644 --- a/gwcs/tests/test_wcs.py +++ b/gwcs/tests/test_wcs.py @@ -16,12 +16,12 @@ from astropy.time import Time import asdf -from .. import wcs -from ..wcstools import (wcs_from_fiducial, grid_from_bounding_box, wcs_from_points) -from .. import coordinate_frames as cf -from ..utils import CoordinateFrameError -from .utils import _gwcs_from_hst_fits_wcs -from . import data +from gwcs import wcs +from gwcs.wcstools import (wcs_from_fiducial, grid_from_bounding_box, wcs_from_points) +from gwcs import coordinate_frames as cf +from gwcs.utils import CoordinateFrameError +from . utils import _gwcs_from_hst_fits_wcs +from gwcs.tests import data data_path = os.path.split(os.path.abspath(data.__file__))[0] @@ -31,7 +31,7 @@ m2 = models.Scale(2) & models.Scale(-2) m = m1 | m2 -icrs = cf.CelestialFrame(reference_frame=coord.ICRS(), name='icrs') +icrs = cf.CelestialFrame(reference_frame=coord.ICRS(), name='icrs', unit=(u.deg, u.deg)) detector = cf.Frame2D(name='detector', axes_order=(0, 1)) focal = cf.Frame2D(name='focal', axes_order=(0, 1), unit=(u.m, u.m)) spec = cf.SpectralFrame(name='wave', unit=[u.m, ], axes_order=(2, ), axes_names=('lambda', )) @@ -1284,27 +1284,35 @@ def test_split_frame_wcs(): # We setup a model which is pretending to be a celestial transform. Note # that we are pretending that this model is ordered lon, lat because that's # what the projections require in astropy. + + # Input is (lat, wave, lon) + # lat: multuply by 20 arcsec, lon: multiply by 15 deg + # result should be 20 arcsec, 10nm, 45 deg spatial = models.Multiply(20*u.arcsec/u.pix) & models.Multiply(15*u.deg/u.pix) compound = models.Linear1D(intercept=0*u.nm, slope=10*u.nm/u.pix) & spatial # This forward transforms uses mappings to be (lat, wave, lon) - forward = models.Mapping((1, 2, 0)) | compound | models.Mapping((2, 0, 1)) + forward = models.Mapping((1, 0, 2)) | compound | models.Mapping((1, 0, 2)) # Setup the output frame - celestial_frame = cf.CelestialFrame(axes_order=(2, 0), unit=(u.arcsec, u.deg), - reference_frame=coord.ICRS()) - spectral_frame = cf.SpectralFrame(axes_order=(1,), unit=u.nm) + celestial_frame = cf.CelestialFrame(axes_order=(2, 0), unit=(u.deg, u.arcsec), + reference_frame=coord.ICRS(), axes_names=('lon', 'lat')) + #celestial_frame = cf.CelestialFrame(axes_order=(2, 0), unit=(u.arcsec, u.deg), + # reference_frame=coord.ICRS()) + spectral_frame = cf.SpectralFrame(axes_order=(1,), unit=u.nm, axes_names='wave') output_frame = cf.CompositeFrame([spectral_frame, celestial_frame]) + #output_frame = cf.CompositeFrame([celestial_frame, spectral_frame]) input_frame = cf.CoordinateFrame(3, ["PIXEL"]*3, axes_order=list(range(3)), unit=[u.pix]*3) iwcs = wcs.WCS(forward, input_frame, output_frame) - input_pixel = [1*u.pix, 2*u.pix, 3*u.pix] + input_pixel = [1*u.pix, 1*u.pix, 3*u.pix] output_world = iwcs.pixel_to_world_values(*input_pixel) output_pixel = iwcs.world_to_pixel_values(*output_world) assert_allclose(output_pixel, u.Quantity(input_pixel).to_value(u.pix)) - expected_world = [15*u.deg, 20*u.nm, 60*u.arcsec] + expected_world = [20*u.arcsec, 10*u.nm, 45*u.deg] + #expected_world = [15*u.deg, 20*u.nm, 60*u.arcsec] for expected, output in zip(expected_world, output_world): assert_allclose(output, expected.value) @@ -1322,7 +1330,8 @@ def test_split_frame_wcs(): def test_reordered_celestial(): # This is a spatial model which is ordered lat, lon for the purposes of this test. - spatial = models.Multiply(20*u.arcsec/u.pix) & models.Multiply(15*u.deg/u.pix) + # Expected lat=45 deg, lon=20 arcsec + spatial = models.Multiply(20*u.arcsec/u.pix) & models.Multiply(15*u.deg/u.pix) | models.Mapping((1,0)) celestial_frame = cf.CelestialFrame(axes_order=(1, 0), unit=(u.arcsec, u.deg), reference_frame=coord.ICRS()) @@ -1337,7 +1346,7 @@ def test_reordered_celestial(): output_pixel = iwcs.world_to_pixel_values(*output_world) assert_allclose(output_pixel, u.Quantity(input_pixel).to_value(u.pix)) - expected_world = [20*u.arcsec, 45*u.deg] + expected_world = [45*u.deg, 20*u.arcsec]#, 45*u.deg] assert_allclose(output_world, [e.value for e in expected_world]) world_obj = iwcs.pixel_to_world(*input_pixel)