Prevent slicing SlicedLowLevelWCS to length-0 axes #18519
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
This PR provides an optional way to overcome a bug in
SlicedLowLevelWCS
, whereby slices that would reduce a data array associated with the WCS to length-0 axes is not caught. WCS cannot describe scalars or length-0 array axes. However, the current sanitization of inputs toSlicedLowLevelWCS
currently allows such scenarios. This PR introduces a new optional kwarg toSlicedLowLevelWCS
(presliced_shape
) and another tosanitize_slices
(shape
), which give the shape of the data array described by the WCS. If either are set, an additional set of sanitization checks is performed to catch the cases below.(This bug was identified by @hayesla when using
ndcube
.)Case 1: Slices with stop >= start
Slice items like
slice(3, 2)
,slice(-2, -4)
, andslice(1, 1)
can be applied to a data array and will returnarray([])
. However, this is an array that cannot be validly described by a WCS. This PR solves this problem by erroring ifstop - start <= 0
.Case 2: Slices with mixed positive and negative indices
If the slice item mixes and matches positive and negative indices, e.g.
slice(3, -2)
orslice(-4, 5)
, the above check cannot be done without knowing the length of the relevant axis. In this case, the shape info is combined with the info in the slice object to perform the same check as in Case 1.Case 3: Indices or slices whose range are entirely outside the data array
If we have an array of length 3, and we apply an index or slice whose range is beyond this, e.g.
6
,-6
,slice(5, 8)
orslice(-20, -15)
, this will again lead to an array ofarray([])
being returned which cannot be described by a WCS. A separate check is performed to catch these cases. But, like Case 2, this requires the data shape information provided by the new kwargs.Discussion on Making These Checks Optional
The reason for making the checks of Cases 2 and 3 optional is that a WCS can be a standalone object without associated with a data array. If such a WCS would like to be sliced for some reason, shape information may not be available.
The check in Case 1 can actually be performed without the shape information and so could be performed every time. I think this is a valid choice, but the reasons I didn't go that way here are:
shape
is set, is not.shape
is set, simplifies the code somewhat. (A less crucial consideration)Fixes #