def test_sliced_ND_input(wcs_4d, sub_wcs, wcs_slice, plt_close):
    slices_wcsaxes = [0, 'x', 'y']

    for sub_wcs in (sub_wcs, SlicedLowLevelWCS(wcs_4d, wcs_slice)):
        with warnings.catch_warnings():
            warnings.filterwarnings('ignore', category=FutureWarning)
            _, coord_meta = transform_coord_meta_from_wcs(
                sub_wcs, RectangularFrame, slices=slices_wcsaxes)

        assert all(len(x) == 3 for x in coord_meta.values())

        assert coord_meta['name'] == [
            'time', ('custom:pos.helioprojective.lat', 'hplt-tan', 'hplt'),
            ('custom:pos.helioprojective.lon', 'hpln-tan', 'hpln')
        ]
        assert coord_meta['type'] == ['scalar', 'latitude', 'longitude']
        assert coord_meta['wrap'] == [None, None, 180.0]
        assert coord_meta['unit'] == [
            u.Unit("min"), u.Unit("deg"),
            u.Unit("deg")
        ]
        assert coord_meta['visible'] == [False, True, True]
        assert coord_meta['format_unit'] == [
            u.Unit("min"), u.Unit("arcsec"),
            u.Unit("arcsec")
        ]
        assert coord_meta['default_axislabel_position'] == ['', 'b', 'l']
        assert coord_meta['default_ticklabel_position'] == ['', 'b', 'l']
        assert coord_meta['default_ticks_position'] == ['', 'bltr', 'bltr']

        # Validate the axes initialize correctly
        plt.subplot(projection=sub_wcs, slices=slices_wcsaxes)
Beispiel #2
0
def apply_slices(wcs, slices):
    """
    Take the input WCS and slices and return a sliced WCS for the transform and
    a mapping of world axes in the sliced WCS to the input WCS.
    """
    if isinstance(wcs, SlicedLowLevelWCS):
        world_keep = list(wcs._world_keep)
    else:
        world_keep = list(range(wcs.world_n_dim))

    # world_map is the index of the world axis in the input WCS for a given
    # axis in the transform_wcs
    world_map = list(range(wcs.world_n_dim))
    transform_wcs = wcs
    invert_xy = False
    if slices is not None:
        wcs_slice = list(slices)
        wcs_slice[wcs_slice.index("x")] = slice(None)
        if 'y' in slices:
            wcs_slice[wcs_slice.index("y")] = slice(None)
            invert_xy = slices.index('x') > slices.index('y')

        transform_wcs = SlicedLowLevelWCS(wcs, wcs_slice[::-1])
        world_map = tuple(
            world_keep.index(i) for i in transform_wcs._world_keep)

    return transform_wcs, invert_xy, world_map
Beispiel #3
0
def test_wcs_type_transform_regression():
    wcs = WCS(TARGET_HEADER)
    sliced_wcs = SlicedLowLevelWCS(wcs, np.s_[1:-1, 1:-1])
    ax = plt.subplot(1, 1, 1, projection=wcs)
    ax.get_transform(sliced_wcs)

    high_wcs = HighLevelWCSWrapper(sliced_wcs)
    ax.get_transform(sliced_wcs)
Beispiel #4
0
    def _slice_wcs(self, item):
        if self.wcs is None:
            return None

        try:
            llwcs = SlicedLowLevelWCS(self.wcs.low_level_wcs, item)
            return HighLevelWCSWrapper(llwcs)
        except Exception as err:
            self._handle_wcs_slicing_error(err, item)
Beispiel #5
0
def test_nddata_wcs_setter_with_low_level_wcs():
    ndd = NDData(np.ones((5, 5)))
    wcs = WCS()
    # If the wcs property is set with a low level WCS it should get
    # wrapped to high level.
    low_level = SlicedLowLevelWCS(wcs, 5)
    assert not isinstance(low_level, BaseHighLevelWCS)

    ndd.wcs = low_level

    assert isinstance(ndd.wcs, BaseHighLevelWCS)
Beispiel #6
0
    def __init__(self, original_data, indices):

        super(IndexedData, self).__init__()

        if len(indices) != original_data.ndim:
            raise ValueError("The 'indices' tuple should have length {0}"
                             .format(original_data.ndim))

        if hasattr(original_data, 'coords'):
            if original_data.coords is None:
                self._coords = None
            else:
                slices = [slice(None) if idx is None else idx for idx in indices]
                self._coords = SlicedLowLevelWCS(original_data.coords, slices)

        self._original_data = original_data
        self._cid_to_original_cid = {}
        self._original_cid_to_cid = {}
        self.indices = indices
Beispiel #7
0
    def _stokes_slice(self, stokes_ix, normalize=False):
        """Return a 3D NDCube (wavelength, coord1, coord2) for a given Stokes parameter"""

        # Construct the WCS object for the smaller 3D cube.
        # This function should only called if the
        d_sh = self.data.shape
        wcs_slice = [0] * self.wcs.pixel_n_dim
        wcs_slice[0] = stokes_ix
        wcs_slice[1] = slice(0, d_sh[1])
        wcs_slice[2] = slice(0, d_sh[2])
        wcs_slice[3] = slice(0, d_sh[3])
        #print(wcs_slice)
        wcs_slice = SlicedLowLevelWCS(self.wcs.low_level_wcs, wcs_slice)
        #newcube = StokesParamCube(self.data[stokes_ix,:,:,:], HighLevelWCSWrapper(wcs_slice), self._stokes_axis[stokes_ix])
        #cube_meta = {'stokes': self._stokes_axis[stokes_ix]}

        cube_meta = self.meta.copy()
        cube_meta['stokes'] = self._stokes_axis[stokes_ix]
        newcube = StokesParamCube(self.data[stokes_ix, :, :, :],
                                  HighLevelWCSWrapper(wcs_slice),
                                  meta=cube_meta)

        # Normalize the spectra if wanted.
        if stokes_ix != 0:
            if self.normalize is True:
                # Normalize by I
                I = self._stokes_slice(0)
                newcube = StokesParamCube(newcube.data / I.data,
                                          newcube.wcs,
                                          self._stokes_axis[stokes_ix],
                                          meta=newcube.meta)
            elif self.normalize:
                # normalize by non-zero float
                # TODO: sanity check input
                newcube = StokesParamCube(newcube.data / self.normalize,
                                          newcube.wcs,
                                          self._stokes_axis[stokes_ix],
                                          meta=newcube.meta)

        #newcube.meta = {'stokes': self._stokes_axis[stokes_ix]}

        return newcube
Beispiel #8
0
def sub_wcs(wcs_4d, wcs_slice):
    return SlicedLowLevelWCS(wcs_4d, wcs_slice)
Beispiel #9
0
def get_crop_item_from_points(points, wcs, crop_by_values):
    """
    Find slice item that crops to minimum cube in array-space containing specified world points.

    Parameters
    ----------
    points : iterable of iterables
        Each iterable represents a point in real world space.
        Each element in a point gives the real world coordinate value of the point
        in high-level coordinate objects or quantities.
        (Must be consistenly high or low level within and across points.)
        Objects must be in the order required by
        wcs.world_to_array_index/world_to_array_index_values.

    wcs : `~astropy.wcs.wcsapi.BaseHighLevelWCS`, `~astropy.wcs.wcsapi.BaseLowLevelWCS`
        The WCS to use to convert the world coordinates to array indices.

    crop_by_values : `bool`
        Denotes whether cropping is done using high-level objects or "values",
        i.e. low-level objects.

    Returns
    -------
    item : `tuple` of `slice`
        The slice item for each axis of the cube which, when applied to the cube,
        will return the minimum cube in array-index-space that contains all the
        input world points.
    """
    # Define a list of lists to hold the array indices of the points
    # where each inner list gives the index of all points for that array axis.
    combined_points_array_idx = [[]] * wcs.pixel_n_dim
    # For each point compute the corresponding array indices.
    for point in points:
        # Get the arrays axes associated with each element in point.
        if crop_by_values:
            point_inputs_array_axes = []
            for i in range(wcs.world_n_dim):
                pix_axes = np.array(
                    wcs_utils.world_axis_to_pixel_axes(
                        i, wcs.axis_correlation_matrix))
                point_inputs_array_axes.append(
                    tuple(
                        wcs_utils.convert_between_array_and_pixel_axes(
                            pix_axes, wcs.pixel_n_dim)))
            point_inputs_array_axes = tuple(point_inputs_array_axes)
        else:
            point_inputs_array_axes = wcs_utils.array_indices_for_world_objects(
                HighLevelWCSWrapper(wcs))
        # Get indices of array axes which correspond to only None inputs in point
        # as well as those that correspond to a coord.
        point_indices_with_inputs = []
        array_axes_with_input = []
        for i, coord in enumerate(point):
            if coord is not None:
                point_indices_with_inputs.append(i)
                array_axes_with_input.append(point_inputs_array_axes[i])
        array_axes_with_input = set(chain.from_iterable(array_axes_with_input))
        array_axes_without_input = set(range(
            wcs.pixel_n_dim)) - array_axes_with_input
        # Slice out the axes that do not correspond to a coord
        # from the WCS and the input point.
        wcs_slice = np.array([slice(None)] * wcs.pixel_n_dim)
        if len(array_axes_without_input):
            wcs_slice[np.array(list(array_axes_without_input))] = 0
        sliced_wcs = SlicedLowLevelWCS(wcs, slices=tuple(wcs_slice))
        sliced_point = np.array(
            point, dtype=object)[np.array(point_indices_with_inputs)]
        # Derive the array indices of the input point and place each index
        # in the list corresponding to its axis.
        if crop_by_values:
            point_array_indices = sliced_wcs.world_to_array_index_values(
                *sliced_point)
            # If returned value is a 0-d array, convert to a length-1 tuple.
            if isinstance(point_array_indices,
                          np.ndarray) and point_array_indices.ndim == 0:
                point_array_indices = (point_array_indices.item(), )
            else:
                # Convert from scalar arrays to scalars
                point_array_indices = tuple(a.item()
                                            for a in point_array_indices)
        else:
            point_array_indices = HighLevelWCSWrapper(
                sliced_wcs).world_to_array_index(*sliced_point)
            # If returned value is a 0-d array, convert to a length-1 tuple.
            if isinstance(point_array_indices,
                          np.ndarray) and point_array_indices.ndim == 0:
                point_array_indices = (point_array_indices.item(), )
        for axis, index in zip(array_axes_with_input, point_array_indices):
            combined_points_array_idx[
                axis] = combined_points_array_idx[axis] + [index]
    # Define slice item with which to slice cube.
    item = []
    result_is_scalar = True
    for axis_indices in combined_points_array_idx:
        if axis_indices == []:
            result_is_scalar = False
            item.append(slice(None))
        else:
            min_idx = min(axis_indices)
            max_idx = max(axis_indices) + 1
            if max_idx - min_idx == 1:
                item.append(min_idx)
            else:
                item.append(slice(min_idx, max_idx))
                result_is_scalar = False
    # If item will result in a scalar cube, raise an error as this is not currently supported.
    if result_is_scalar:
        raise ValueError(
            "Input points causes cube to be cropped to a single pixel. "
            "This is not supported.")
    return tuple(item)
Beispiel #10
0
def as_high_level_wcs(wcs):
    return HighLevelWCSWrapper(SlicedLowLevelWCS(wcs, Ellipsis))
Beispiel #11
0
    def __init__(self, data1=None, data2=None, cids1=None, cids2=None):

        wcs1, wcs2 = data1.coords, data2.coords

        forwards = backwards = None
        if wcs1.pixel_n_dim == wcs2.pixel_n_dim and wcs1.world_n_dim == wcs2.world_n_dim:
            if (wcs1.world_axis_physical_types.count(None) == 0
                    and wcs2.world_axis_physical_types.count(None) == 0):

                # The easiest way to check if the WCSes are compatible is to simply try and
                # see if values can be transformed for a single pixel. In future we might
                # find that this requires optimization performance-wise, but for now let's
                # not do premature optimization.

                pixel_cids1, pixel_cids2, forwards, backwards = get_cids_and_functions(
                    wcs1, wcs2, data1.pixel_component_ids[::-1],
                    data2.pixel_component_ids[::-1])

                self._physical_types_1 = wcs1.world_axis_physical_types
                self._physical_types_2 = wcs2.world_axis_physical_types

        if not forwards or not backwards:
            # A generalized APE 14-compatible way
            # Handle also the extra-spatial axes such as those of the time and wavelength dimensions

            wcs1_celestial_physical_types = wcs2_celestial_physical_types = []

            slicing_axes1 = slicing_axes2 = []

            cids1 = data1.pixel_component_ids
            cids2 = data2.pixel_component_ids

            if wcs1.has_celestial and wcs2.has_celestial:
                wcs1_celestial_physical_types = wcs1.celestial.world_axis_physical_types
                wcs2_celestial_physical_types = wcs2.celestial.world_axis_physical_types

                cids1_celestial = [
                    cids1[wcs1.wcs.naxis - wcs1.wcs.lng - 1],
                    cids1[wcs1.wcs.naxis - wcs1.wcs.lat - 1]
                ]
                cids2_celestial = [
                    cids2[wcs2.wcs.naxis - wcs2.wcs.lng - 1],
                    cids2[wcs2.wcs.naxis - wcs2.wcs.lat - 1]
                ]

                if wcs1.celestial.wcs.lng > wcs1.celestial.wcs.lat:
                    cids1_celestial = cids1_celestial[::-1]

                if wcs2.celestial.wcs.lng > wcs2.celestial.wcs.lat:
                    cids2_celestial = cids2_celestial[::-1]

                slicing_axes1 = [
                    cids1_celestial[0].axis, cids1_celestial[1].axis
                ]
                slicing_axes2 = [
                    cids2_celestial[0].axis, cids2_celestial[1].axis
                ]

            wcs1_sliced_physical_types = wcs2_sliced_physical_types = []

            if wcs1_celestial_physical_types is not None:
                wcs1_sliced_physical_types = wcs1_celestial_physical_types

            if wcs2_celestial_physical_types is not None:
                wcs2_sliced_physical_types = wcs2_celestial_physical_types

            for i, physical_type1 in enumerate(wcs1.world_axis_physical_types):
                for j, physical_type2 in enumerate(
                        wcs2.world_axis_physical_types):
                    if physical_type1 == physical_type2:
                        if physical_type1 not in wcs1_sliced_physical_types:
                            slicing_axes1.append(wcs1.world_n_dim - i - 1)
                            wcs1_sliced_physical_types.append(physical_type1)
                        if physical_type2 not in wcs2_sliced_physical_types:
                            slicing_axes2.append(wcs2.world_n_dim - j - 1)
                            wcs2_sliced_physical_types.append(physical_type2)

            slicing_axes1 = sorted(slicing_axes1, key=str, reverse=True)
            slicing_axes2 = sorted(slicing_axes2, key=str, reverse=True)

            # Generate slices for the wcs slicing
            slices1 = [slice(None)] * wcs1.world_n_dim
            slices2 = [slice(None)] * wcs2.world_n_dim

            for i in range(wcs1.world_n_dim):
                if i not in slicing_axes1:
                    slices1[i] = 0

            for j in range(wcs2.world_n_dim):
                if j not in slicing_axes2:
                    slices2[j] = 0

            wcs1_sliced = SlicedLowLevelWCS(wcs1, tuple(slices1))
            wcs2_sliced = SlicedLowLevelWCS(wcs2, tuple(slices2))
            wcs1_final = HighLevelWCSWrapper(copy.copy(wcs1_sliced))
            wcs2_final = HighLevelWCSWrapper(copy.copy(wcs2_sliced))

            cids1_sliced = [cids1[x] for x in slicing_axes1]
            cids1_sliced = sorted(cids1_sliced, key=str, reverse=True)

            cids2_sliced = [cids2[x] for x in slicing_axes2]
            cids2_sliced = sorted(cids2_sliced, key=str, reverse=True)

            pixel_cids1, pixel_cids2, forwards, backwards = get_cids_and_functions(
                wcs1_final, wcs2_final, cids1_sliced, cids2_sliced)

            self._physical_types_1 = wcs1_sliced_physical_types
            self._physical_types_2 = wcs2_sliced_physical_types

        if pixel_cids1 is None:
            raise IncompatibleWCS(
                "Can't create WCS link between {0} and {1}".format(
                    data1.label, data2.label))

        super(WCSLink, self).__init__(pixel_cids1,
                                      pixel_cids2,
                                      forwards=forwards,
                                      backwards=backwards)

        self.data1 = data1
        self.data2 = data2
Beispiel #12
0
def transform_coord_meta_from_wcs(wcs, frame_class, slices=None):

    if slices is not None:
        slices = tuple(slices)

    if wcs.pixel_n_dim > 2:
        if slices is None:
            raise ValueError("WCS has more than 2 pixel dimensions, so "
                             "'slices' should be set")
        elif len(slices) != wcs.pixel_n_dim:
            raise ValueError("'slices' should have as many elements as WCS "
                             "has pixel dimensions (should be {})".format(
                                 wcs.pixel_n_dim))

    is_fits_wcs = isinstance(wcs, WCS)

    coord_meta = {}
    coord_meta['name'] = []
    coord_meta['type'] = []
    coord_meta['wrap'] = []
    coord_meta['unit'] = []
    coord_meta['visible'] = []
    coord_meta['format_unit'] = []

    for idx in range(wcs.world_n_dim):

        axis_type = wcs.world_axis_physical_types[idx]
        axis_unit = u.Unit(wcs.world_axis_units[idx])
        coord_wrap = None
        format_unit = axis_unit

        coord_type = 'scalar'

        if axis_type is not None:

            axis_type_split = axis_type.split('.')

            if "pos.helioprojective.lon" in axis_type:
                coord_wrap = 180.
                format_unit = u.arcsec
                coord_type = "longitude"
            elif "pos.helioprojective.lat" in axis_type:
                format_unit = u.arcsec
                coord_type = "latitude"
            elif "pos.heliographic.stonyhurst.lon" in axis_type:
                coord_wrap = 180.
                format_unit = u.arcsec
                coord_type = "longitude"
            elif "pos.heliographic.stonyhurst.lat" in axis_type:
                format_unit = u.arcsec
                coord_type = "latitude"
            elif "pos.heliographic.carrington.lon" in axis_type:
                coord_wrap = 360.
                format_unit = u.arcsec
                coord_type = "longitude"
            elif "pos.heliographic.carrington.lat" in axis_type:
                format_unit = u.arcsec
                coord_type = "latitude"
            elif "pos" in axis_type_split:
                if "lon" in axis_type_split:
                    coord_type = "longitude"
                elif "lat" in axis_type_split:
                    coord_type = "latitude"
                elif "ra" in axis_type_split:
                    coord_type = "longitude"
                    format_unit = u.hourangle
                elif "dec" in axis_type_split:
                    coord_type = "latitude"
                elif "alt" in axis_type_split:
                    coord_type = "longitude"
                elif "az" in axis_type_split:
                    coord_type = "latitude"
                elif "long" in axis_type_split:
                    coord_type = "longitude"

        coord_meta['type'].append(coord_type)
        coord_meta['wrap'].append(coord_wrap)
        coord_meta['format_unit'].append(format_unit)
        coord_meta['unit'].append(axis_unit)

        # For FITS-WCS, for backward-compatibility, we need to make sure that we
        # provide aliases based on CTYPE for the name.
        if is_fits_wcs:
            if isinstance(wcs, WCS):
                alias = wcs.wcs.ctype[idx][:4].replace('-', '').lower()
            elif isinstance(wcs, SlicedLowLevelWCS):
                alias = wcs._wcs.wcs.ctype[wcs._world_keep[idx]][:4].replace(
                    '-', '').lower()
            name = (axis_type, alias) if axis_type else alias
        else:
            name = axis_type or ''

        coord_meta['name'].append(name)

    coord_meta['default_axislabel_position'] = [''] * wcs.world_n_dim
    coord_meta['default_ticklabel_position'] = [''] * wcs.world_n_dim
    coord_meta['default_ticks_position'] = [''] * wcs.world_n_dim

    invert_xy = False
    if slices is not None:
        wcs_slice = list(slices)
        wcs_slice[wcs_slice.index("x")] = slice(None)
        if 'y' in slices:
            wcs_slice[wcs_slice.index("y")] = slice(None)
            invert_xy = slices.index('x') > slices.index('y')
        wcs = SlicedLowLevelWCS(wcs, wcs_slice[::-1])
        world_keep = wcs._world_keep
    else:
        world_keep = list(range(wcs.world_n_dim))

    for i in range(len(coord_meta['type'])):
        coord_meta['visible'].append(i in world_keep)

    transform = WCSPixel2WorldTransform(wcs, invert_xy=invert_xy)

    m = wcs.axis_correlation_matrix.copy()
    if invert_xy:
        m = m[:, ::-1]

    if frame_class is RectangularFrame:

        for i, spine_name in enumerate('bltr'):
            pos = np.nonzero(m[:, i % 2])[0]
            if len(pos) > 0:
                index = world_keep[pos[0]]
                coord_meta['default_axislabel_position'][index] = spine_name
                coord_meta['default_ticklabel_position'][index] = spine_name
                coord_meta['default_ticks_position'][index] = spine_name
                m[pos[0], :] = 0

        # In the special and common case where the frame is rectangular and
        # we are dealing with 2-d WCS (after slicing), we show all ticks on
        # all axes for backward-compatibility.
        if len(world_keep) == 2:
            for index in world_keep:
                coord_meta['default_ticks_position'][index] = 'bltr'

    elif frame_class is RectangularFrame1D:

        for i, spine_name in enumerate('bt'):
            pos = np.nonzero(m[:, 0])[0]
            if len(pos) > 0:
                index = world_keep[pos[0]]
                coord_meta['default_axislabel_position'][index] = spine_name
                coord_meta['default_ticklabel_position'][index] = spine_name
                coord_meta['default_ticks_position'][index] = spine_name
                m[pos[0], :] = 0

        # In the special and common case where the frame is rectangular and
        # we are dealing with 2-d WCS (after slicing), we show all ticks on
        # all axes for backward-compatibility.
        if len(world_keep) == 1:
            for index in world_keep:
                coord_meta['default_ticks_position'][index] = 'bt'

    elif frame_class is EllipticalFrame:

        if 'longitude' in coord_meta['type']:
            lon_idx = coord_meta['type'].index('longitude')
            coord_meta['default_axislabel_position'][lon_idx] = 'h'
            coord_meta['default_ticklabel_position'][lon_idx] = 'h'
            coord_meta['default_ticks_position'][lon_idx] = 'h'

        if 'latitude' in coord_meta['type']:
            lat_idx = coord_meta['type'].index('latitude')
            coord_meta['default_axislabel_position'][lat_idx] = 'c'
            coord_meta['default_ticklabel_position'][lat_idx] = 'c'
            coord_meta['default_ticks_position'][lat_idx] = 'c'

    else:

        for i in range(len(coord_meta['type'])):
            if i in world_keep:
                index = world_keep[i]
                coord_meta['default_axislabel_position'][
                    index] = frame_class.spine_names
                coord_meta['default_ticklabel_position'][
                    index] = frame_class.spine_names
                coord_meta['default_ticks_position'][
                    index] = frame_class.spine_names

    return transform, coord_meta
Beispiel #13
0
def test_nddata_init_with_low_level_wcs():
    wcs = WCS()
    low_level = SlicedLowLevelWCS(wcs, 5)
    ndd = NDData(np.ones((5, 5)), wcs=low_level)
    assert isinstance(ndd.wcs, BaseHighLevelWCS)
Beispiel #14
0
def transform_coord_meta_from_wcs(wcs, frame_class, aslice=None):

    is_fits_wcs = isinstance(wcs, WCS)

    coord_meta = {}
    coord_meta['name'] = []
    coord_meta['type'] = []
    coord_meta['wrap'] = []
    coord_meta['unit'] = []
    coord_meta['format_unit'] = []

    invert_xy = False
    if aslice is not None:
        wcs_slice = list(aslice)
        wcs_slice[wcs_slice.index("x")] = slice(None)
        wcs_slice[wcs_slice.index("y")] = slice(None)
        wcs = SlicedLowLevelWCS(wcs, wcs_slice[::-1])
        invert_xy = aslice.index('x') > aslice.index('y')

    transform = WCSPixel2WorldTransform(wcs, invert_xy=invert_xy)

    for idx in range(wcs.world_n_dim):

        axis_type = wcs.world_axis_physical_types[idx]
        axis_unit = u.Unit(wcs.world_axis_units[idx])
        coord_wrap = None
        format_unit = axis_unit

        coord_type = 'scalar'

        if axis_type is not None:

            axis_type_split = axis_type.split('.')

            if "pos.helioprojective.lon" in axis_type:
                coord_wrap = 180.
                format_unit = u.arcsec
                coord_type = "longitude"
            elif "pos.helioprojective.lat" in axis_type:
                format_unit = u.arcsec
                coord_type = "latitude"
            elif "pos" in axis_type_split:
                if "lon" in axis_type_split:
                    coord_type = "longitude"
                elif "lat" in axis_type_split:
                    coord_type = "latitude"
                elif "ra" in axis_type_split:
                    coord_type = "longitude"
                    format_unit = u.hourangle
                elif "dec" in axis_type_split:
                    coord_type = "latitude"
                elif "alt" in axis_type_split:
                    coord_type = "longitude"
                elif "az" in axis_type_split:
                    coord_type = "latitude"
                elif "long" in axis_type_split:
                    coord_type = "longitude"

        coord_meta['type'].append(coord_type)
        coord_meta['wrap'].append(coord_wrap)
        coord_meta['format_unit'].append(format_unit)
        coord_meta['unit'].append(axis_unit)

        # For FITS-WCS, for backward-compatibility, we need to make sure that we
        # provide aliases based on CTYPE for the name.
        if is_fits_wcs:
            if isinstance(wcs, WCS):
                alias = wcs.wcs.ctype[idx][:4].replace('-', '').lower()
            elif isinstance(wcs, SlicedLowLevelWCS):
                alias = wcs._wcs.wcs.ctype[wcs._world_keep[idx]][:4].replace('-', '').lower()
            name = (axis_type, alias) if axis_type else alias
        else:
            name = axis_type or ''

        coord_meta['name'].append(name)

    coord_meta['default_axislabel_position'] = [''] * wcs.world_n_dim
    coord_meta['default_ticklabel_position'] = [''] * wcs.world_n_dim
    coord_meta['default_ticks_position'] = [''] * wcs.world_n_dim

    m = wcs.axis_correlation_matrix.copy()
    if invert_xy:
        m = m[:, ::-1]

    if frame_class is RectangularFrame:

        for i, spine_name in enumerate('bltr'):
            pos = np.nonzero(m[:, i % 2])[0]
            if len(pos) > 0:
                coord_meta['default_axislabel_position'][pos[0]] = spine_name
                coord_meta['default_ticklabel_position'][pos[0]] = spine_name
                coord_meta['default_ticks_position'][pos[0]] = spine_name
                m[pos[0], :] = 0

        # In the special and common case where the frame is rectangular and
        # we are dealing with 2-d WCS, we show all ticks on all axes for
        # backward-compatibility.
        if len(coord_meta['type']) == 2:
            coord_meta['default_ticks_position'] = ['bltr'] * wcs.world_n_dim

    elif frame_class is EllipticalFrame:

        if 'longitude' in coord_meta['type']:
            lon_idx = coord_meta['type'].index('longitude')
            coord_meta['default_axislabel_position'][lon_idx] = 'h'
            coord_meta['default_ticklabel_position'][lon_idx] = 'h'
            coord_meta['default_ticks_position'][lon_idx] = 'h'

        if 'latitude' in coord_meta['type']:
            lat_idx = coord_meta['type'].index('latitude')
            coord_meta['default_axislabel_position'][lat_idx] = 'c'
            coord_meta['default_ticklabel_position'][lat_idx] = 'c'
            coord_meta['default_ticks_position'][lat_idx] = 'c'

    else:

        for i in range(wcs.world_n_dim):
            coord_meta['default_axislabel_position'][i] = frame_class.spine_names
            coord_meta['default_ticklabel_position'][i] = frame_class.spine_names
            coord_meta['default_ticks_position'][i] = frame_class.spine_names

    return transform, coord_meta
Beispiel #15
0
 def _spectral_slice(self):
     """Slice of the WCS containing only the spectral axis"""
     wcs_slice = [0] * self.wcs.pixel_n_dim
     wcs_slice[0] = slice(0, self.n_spectral)
     wcs_slice = SlicedLowLevelWCS(self.wcs.low_level_wcs, wcs_slice)
     return wcs_slice