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

Check area slices for correct step #275

Merged
merged 2 commits into from
May 13, 2020
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions pyresample/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
from pyresample._spatial_mp import Cartesian, Cartesian_MP, Proj, Proj_MP
from pyresample.boundary import AreaDefBoundary, Boundary, SimpleBoundary
from pyresample.utils import (proj4_str_to_dict, proj4_dict_to_str,
convert_proj_floats, proj4_radius_parameters)
convert_proj_floats, proj4_radius_parameters,
check_slice_orientation)
from pyresample.area_config import create_area_def

try:
Expand Down Expand Up @@ -1961,15 +1962,11 @@ def get_area_slices(self, area_to_cover, shape_divisible_by=None):

xstart = 0 if x[0] is np.ma.masked else x[0]
ystart = 0 if y[1] is np.ma.masked else y[1]
if self.area_extent[0] > self.area_extent[2]:
xstop = self.width if x[0] is np.ma.masked else x[0] + 1
else:
xstop = self.width if x[1] is np.ma.masked else x[1] + 1
if self.area_extent[1] > self.area_extent[3]:
ystop = self.height if y[1] is np.ma.masked else y[1] + 1
else:
ystop = self.height if y[0] is np.ma.masked else y[0] + 1
return slice(xstart, xstop), slice(ystart, ystop)
xstop = self.width if x[1] is np.ma.masked else x[1] + 1
ystop = self.height if y[0] is np.ma.masked else y[0] + 1

return (check_slice_orientation(slice(xstart, xstop)),
check_slice_orientation(slice(ystart, ystop)))

if self.proj_dict.get('proj') != 'geos':
raise NotImplementedError("Source projection must be 'geos' if "
Expand Down Expand Up @@ -1999,7 +1996,8 @@ def get_area_slices(self, area_to_cover, shape_divisible_by=None):
y_slice = _make_slice_divisible(y_slice, self.height,
factor=shape_divisible_by)

return (x_slice, y_slice)
return (check_slice_orientation(x_slice),
check_slice_orientation(y_slice))

def crop_around(self, other_area):
"""Crop this area around `other_area`."""
Expand Down
29 changes: 29 additions & 0 deletions pyresample/test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,3 +645,32 @@ def test_norotation_yaml(self):
test_area = load_area(f.name, 'regionB')
self.assertEqual(test_area.rotation, 0)
os.remove(f.name)


def test_check_slice_orientation():
"""Test that slicing fix is doing what it should."""
from pyresample.utils import check_slice_orientation

# Forward slicing should not be changed
start, stop, step = 0, 10, None
slice_in = slice(start, stop, step)
res = check_slice_orientation(slice_in)
assert res is slice_in

# Reverse slicing should not be changed if the step is negative
start, stop, step = 10, 0, -1
slice_in = slice(start, stop, step)
res = check_slice_orientation(slice_in)
assert res is slice_in

# Reverse slicing should be fixed if step is positive
start, stop, step = 10, 0, 2
slice_in = slice(start, stop, step)
res = check_slice_orientation(slice_in)
assert res == slice(start, stop, -step)

# Reverse slicing should be fixed if step is None
start, stop, step = 10, 0, None
slice_in = slice(start, stop, step)
res = check_slice_orientation(slice_in)
assert res == slice(start, stop, -1)
10 changes: 10 additions & 0 deletions pyresample/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,13 @@ def recursive_dict_update(d, u):
def is_pyproj2():
"""Determine whether the current pyproj version is >= 2.0"""
return pyproj.__version__ >= '2'


def check_slice_orientation(sli):
"""Check that the slice is slicing the right way."""
if sli.start > sli.stop:
if sli.step is None or sli.step > 0:
step = -(sli.step or 1)
sli = slice(sli.start, sli.stop, step)

return sli