From 7e5fc16016dede328c0e5e1bb60a700ea68476fc Mon Sep 17 00:00:00 2001 From: Panu Lahtinen Date: Mon, 2 Sep 2024 14:16:17 +0300 Subject: [PATCH 01/13] Fix docstring --- pyresample/test/test_gradient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyresample/test/test_gradient.py b/pyresample/test/test_gradient.py index 0a7b8c37..db75edcf 100644 --- a/pyresample/test/test_gradient.py +++ b/pyresample/test/test_gradient.py @@ -496,7 +496,7 @@ def test_resample_area_to_area_nn(self): class TestRBGradientSearchResamplerArea2Swath: - """Test RBGradientSearchResampler for the Swath to Area case.""" + """Test RBGradientSearchResampler for the Area to Swath case.""" def setup_method(self): """Set up the test case.""" From 27e04a4bbd22ffb51d6d7e19de25503e2fe77b38 Mon Sep 17 00:00:00 2001 From: Panu Lahtinen Date: Mon, 2 Sep 2024 14:32:32 +0300 Subject: [PATCH 02/13] Return the result as the same dtype as the input for swath->area case --- pyresample/gradient/__init__.py | 2 +- pyresample/test/test_gradient.py | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/pyresample/gradient/__init__.py b/pyresample/gradient/__init__.py index 4e2aa3b8..f4de8a4b 100644 --- a/pyresample/gradient/__init__.py +++ b/pyresample/gradient/__init__.py @@ -421,7 +421,7 @@ def parallel_gradient_search(data, src_x, src_y, dst_x, dst_y, dst_x[i], dst_y[i], method=method) res = da.from_delayed(res, (num_bands, ) + dst_x[i].shape, - dtype=np.float64) + dtype=np.float64).astype(arr.dtype) if dst_mosaic_locations[i] in chunks: if not is_pad: chunks[dst_mosaic_locations[i]].append(res) diff --git a/pyresample/test/test_gradient.py b/pyresample/test/test_gradient.py index db75edcf..e4e405a6 100644 --- a/pyresample/test/test_gradient.py +++ b/pyresample/test/test_gradient.py @@ -249,25 +249,29 @@ def test_resample_area_to_area_3d_single_channel(self): assert res.shape == (1, ) + self.dst_area.shape assert np.allclose(res[0, :, :], 1.0) - def test_resample_swath_to_area_2d(self): + @pytest.mark.parametrize("input_dtype", (np.float32, np.float64)) + def test_resample_swath_to_area_2d(self, input_dtype): """Resample swath to area, 2d.""" - data = xr.DataArray(da.ones(self.src_swath.shape, dtype=np.float64), + data = xr.DataArray(da.ones(self.src_swath.shape, dtype=input_dtype), dims=['y', 'x']) with np.errstate(invalid="ignore"): # 'inf' space pixels cause runtime warnings res = self.swath_resampler.compute( data, method='bil').compute(scheduler='single-threaded') + assert res.dtype == data.dtype assert res.shape == self.dst_area.shape assert not np.all(np.isnan(res)) - def test_resample_swath_to_area_3d(self): + @pytest.mark.parametrize("input_dtype", (np.float32, np.float64)) + def test_resample_swath_to_area_3d(self, input_dtype): """Resample area to area, 3d.""" data = xr.DataArray(da.ones((3, ) + self.src_swath.shape, - dtype=np.float64) * + dtype=input_dtype) * np.array([1, 2, 3])[:, np.newaxis, np.newaxis], dims=['bands', 'y', 'x']) with np.errstate(invalid="ignore"): # 'inf' space pixels cause runtime warnings res = self.swath_resampler.compute( data, method='bil').compute(scheduler='single-threaded') + assert res.dtype == data.dtype assert res.shape == (3, ) + self.dst_area.shape for i in range(res.shape[0]): arr = np.ravel(res[i, :, :]) From 03cec672c60042622abdac5d482b40661aa38c3a Mon Sep 17 00:00:00 2001 From: Martin Raspaud Date: Tue, 3 Sep 2024 11:31:05 +0200 Subject: [PATCH 03/13] Allow float32 in gradient search --- pyresample/gradient/__init__.py | 4 +- pyresample/gradient/_gradient_search.pyx | 54 +++++++++++++++--------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/pyresample/gradient/__init__.py b/pyresample/gradient/__init__.py index f4de8a4b..bb4fefd5 100644 --- a/pyresample/gradient/__init__.py +++ b/pyresample/gradient/__init__.py @@ -414,14 +414,14 @@ def parallel_gradient_search(data, src_x, src_y, dst_x, dst_y, else: is_pad = False res = dask.delayed(_gradient_resample_data)( - arr.astype(np.float64), + arr, src_x[i], src_y[i], src_gradient_xl[i], src_gradient_xp[i], src_gradient_yl[i], src_gradient_yp[i], dst_x[i], dst_y[i], method=method) res = da.from_delayed(res, (num_bands, ) + dst_x[i].shape, - dtype=np.float64).astype(arr.dtype) + dtype=arr.dtype) if dst_mosaic_locations[i] in chunks: if not is_pad: chunks[dst_mosaic_locations[i]].append(res) diff --git a/pyresample/gradient/_gradient_search.pyx b/pyresample/gradient/_gradient_search.pyx index 838c73b3..51075490 100644 --- a/pyresample/gradient/_gradient_search.pyx +++ b/pyresample/gradient/_gradient_search.pyx @@ -23,18 +23,26 @@ import numpy as np +cimport cython cimport numpy as np +from libc.math cimport fabs, isinf -DTYPE = np.double ctypedef np.double_t DTYPE_t -cimport cython -from libc.math cimport fabs, isinf + +ctypedef fused data_type: + double + float + +ctypedef double float_index +f_index_dtype = float +ctypedef int i_index_type + np.import_array() @cython.boundscheck(False) @cython.wraparound(False) -cdef inline void nn(const DTYPE_t[:, :, :] data, int l0, int p0, double dl, double dp, int lmax, int pmax, DTYPE_t[:] res) noexcept nogil: +cdef inline void nn(const data_type[:, :, :] data, i_index_type l0, int p0, double dl, double dp, int lmax, int pmax, data_type[:] res) noexcept nogil: cdef int nnl, nnp cdef size_t z_size = res.shape[0] cdef size_t i @@ -54,7 +62,7 @@ cdef inline void nn(const DTYPE_t[:, :, :] data, int l0, int p0, double dl, doub @cython.boundscheck(False) @cython.wraparound(False) -cdef inline void bil(const DTYPE_t[:, :, :] data, int l0, int p0, double dl, double dp, int lmax, int pmax, DTYPE_t[:] res) noexcept nogil: +cdef inline void bil(const data_type[:, :, :] data, int l0, int p0, double dl, double dp, int lmax, int pmax, data_type[:] res) noexcept nogil: cdef int l_a, l_b, p_a, p_b cdef double w_l, w_p cdef size_t z_size = res.shape[0] @@ -84,18 +92,18 @@ cdef inline void bil(const DTYPE_t[:, :, :] data, int l0, int p0, double dl, dou @cython.boundscheck(False) @cython.wraparound(False) -cdef inline void indices_xy(const DTYPE_t[:, :, :] data, int l0, int p0, double dl, double dp, int lmax, int pmax, DTYPE_t[:] res) noexcept nogil: +cdef inline void indices_xy(const data_type[:, :, :] data, int l0, int p0, double dl, double dp, int lmax, int pmax, data_type[:] res) noexcept nogil: cdef int nnl, nnp cdef size_t z_size = res.shape[0] cdef size_t i res[1] = dl + l0 res[0] = dp + p0 -ctypedef void (*FN)(const DTYPE_t[:, :, :] data, int l0, int p0, double dl, double dp, int lmax, int pmax, DTYPE_t[:] res) noexcept nogil +ctypedef void (*FN)(const data_type[:, :, :] data, int l0, int p0, double dl, double dp, int lmax, int pmax, data_type[:] res) noexcept nogil @cython.boundscheck(False) @cython.wraparound(False) -cpdef one_step_gradient_search(const DTYPE_t [:, :, :] data, +cpdef one_step_gradient_search(const data_type[:, :, :] data, DTYPE_t [:, :] src_x, DTYPE_t [:, :] src_y, DTYPE_t [:, :] xl, @@ -118,10 +126,14 @@ cpdef one_step_gradient_search(const DTYPE_t [:, :, :] data, cdef size_t y_size = dst_y.shape[0] cdef size_t x_size = dst_x.shape[1] + if data_type is double: + dtype = np.float64 + else: + dtype = np.float32 # output image array --> needs to be (lines, pixels) --> y,x - image = np.full([z_size, y_size, x_size], np.nan, dtype=DTYPE) - cdef DTYPE_t [:, :, :] image_view = image + image = np.full([z_size, y_size, x_size], np.nan, dtype=dtype) + cdef data_type[:, :, :] image_view = image with nogil: one_step_gradient_search_no_gil(data, src_x, src_y, @@ -135,7 +147,7 @@ cpdef one_step_gradient_search(const DTYPE_t [:, :, :] data, @cython.boundscheck(False) @cython.wraparound(False) @cython.cdivision(True) -cdef void one_step_gradient_search_no_gil(const DTYPE_t[:, :, :] data, +cdef void one_step_gradient_search_no_gil(const data_type[:, :, :] data, const DTYPE_t[:, :] src_x, const DTYPE_t[:, :] src_y, const DTYPE_t[:, :] xl, @@ -147,7 +159,7 @@ cdef void one_step_gradient_search_no_gil(const DTYPE_t[:, :, :] data, const size_t x_size, const size_t y_size, FN fun, - DTYPE_t[:, :, :] result_array) noexcept nogil: + data_type[:, :, :] result_array) noexcept nogil: # pixel max ---> data is expected in [lines, pixels] cdef int pmax = src_x.shape[1] - 1 @@ -239,17 +251,17 @@ cpdef one_step_gradient_indices(DTYPE_t [:, :] src_x, cdef size_t x_size = dst_x.shape[1] # output indices arrays --> needs to be (lines, pixels) --> y,x - indices = np.full([2, y_size, x_size], np.nan, dtype=DTYPE) - cdef DTYPE_t [:, :, :] indices_view = indices + indices = np.full([2, y_size, x_size], np.nan, dtype=f_index_dtype) + cdef float_index [:, :, :] indices_view_result = indices # fake_data is not going to be used anyway as we just fill in the indices - cdef DTYPE_t [:, :, :] fake_data = np.full([1, 1, 1], np.nan, dtype=DTYPE) + cdef float_index [:, :, :] fake_data = np.full([1, 1, 1], np.nan, dtype=f_index_dtype) with nogil: - one_step_gradient_search_no_gil(fake_data, - src_x, src_y, - xl, xp, yl, yp, - dst_x, dst_y, - x_size, y_size, - indices_xy, indices_view) + one_step_gradient_search_no_gil[float_index](fake_data, + src_x, src_y, + xl, xp, yl, yp, + dst_x, dst_y, + x_size, y_size, + indices_xy, indices_view_result) return indices From fdea6884af489e53c450d0f5caf698bf40eb82bc Mon Sep 17 00:00:00 2001 From: Martin Raspaud Date: Tue, 3 Sep 2024 12:05:46 +0200 Subject: [PATCH 04/13] Refactor gradient search cython --- pyresample/gradient/_gradient_search.pyx | 95 +++++++++++++----------- 1 file changed, 51 insertions(+), 44 deletions(-) diff --git a/pyresample/gradient/_gradient_search.pyx b/pyresample/gradient/_gradient_search.pyx index 51075490..ccf39699 100644 --- a/pyresample/gradient/_gradient_search.pyx +++ b/pyresample/gradient/_gradient_search.pyx @@ -27,22 +27,19 @@ cimport cython cimport numpy as np from libc.math cimport fabs, isinf -ctypedef np.double_t DTYPE_t - ctypedef fused data_type: double float -ctypedef double float_index -f_index_dtype = float -ctypedef int i_index_type - +ctypedef fused float_index: + double + float np.import_array() @cython.boundscheck(False) @cython.wraparound(False) -cdef inline void nn(const data_type[:, :, :] data, i_index_type l0, int p0, double dl, double dp, int lmax, int pmax, data_type[:] res) noexcept nogil: +cdef inline void nn(const data_type[:, :, :] data, int l0, int p0, float_index dl, float_index dp, int lmax, int pmax, data_type[:] res) noexcept nogil: cdef int nnl, nnp cdef size_t z_size = res.shape[0] cdef size_t i @@ -62,9 +59,9 @@ cdef inline void nn(const data_type[:, :, :] data, i_index_type l0, int p0, doub @cython.boundscheck(False) @cython.wraparound(False) -cdef inline void bil(const data_type[:, :, :] data, int l0, int p0, double dl, double dp, int lmax, int pmax, data_type[:] res) noexcept nogil: +cdef inline void bil(const data_type[:, :, :] data, int l0, int p0, float_index dl, float_index dp, int lmax, int pmax, data_type[:] res) noexcept nogil: cdef int l_a, l_b, p_a, p_b - cdef double w_l, w_p + cdef float_index w_l, w_p cdef size_t z_size = res.shape[0] cdef size_t i if dl < 0: @@ -92,26 +89,28 @@ cdef inline void bil(const data_type[:, :, :] data, int l0, int p0, double dl, d @cython.boundscheck(False) @cython.wraparound(False) -cdef inline void indices_xy(const data_type[:, :, :] data, int l0, int p0, double dl, double dp, int lmax, int pmax, data_type[:] res) noexcept nogil: +cdef inline void indices_xy(const data_type[:, :, :] data, int l0, int p0, float_index dl, float_index dp, int lmax, int pmax, data_type[:] res) noexcept nogil: cdef int nnl, nnp cdef size_t z_size = res.shape[0] cdef size_t i res[1] = dl + l0 res[0] = dp + p0 -ctypedef void (*FN)(const data_type[:, :, :] data, int l0, int p0, double dl, double dp, int lmax, int pmax, data_type[:] res) noexcept nogil + +ctypedef void (*FN)(const data_type[:, :, :] data, int l0, int p0, float_index dl, float_index dp, int lmax, int pmax, data_type[:] res) noexcept nogil + @cython.boundscheck(False) @cython.wraparound(False) cpdef one_step_gradient_search(const data_type[:, :, :] data, - DTYPE_t [:, :] src_x, - DTYPE_t [:, :] src_y, - DTYPE_t [:, :] xl, - DTYPE_t [:, :] xp, - DTYPE_t [:, :] yl, - DTYPE_t [:, :] yp, - DTYPE_t [:, :] dst_x, - DTYPE_t [:, :] dst_y, + float_index [:, :] src_x, + float_index [:, :] src_y, + float_index [:, :] xl, + float_index [:, :] xp, + float_index [:, :] yl, + float_index [:, :] yp, + float_index [:, :] dst_x, + float_index [:, :] dst_y, str method='bilinear'): """Gradient search, simple case variant.""" cdef FN fun @@ -144,18 +143,19 @@ cpdef one_step_gradient_search(const data_type[:, :, :] data, # return the output image return image + @cython.boundscheck(False) @cython.wraparound(False) @cython.cdivision(True) cdef void one_step_gradient_search_no_gil(const data_type[:, :, :] data, - const DTYPE_t[:, :] src_x, - const DTYPE_t[:, :] src_y, - const DTYPE_t[:, :] xl, - const DTYPE_t[:, :] xp, - const DTYPE_t[:, :] yl, - const DTYPE_t[:, :] yp, - const DTYPE_t[:, :] dst_x, - const DTYPE_t[:, :] dst_y, + const float_index[:, :] src_x, + const float_index[:, :] src_y, + const float_index[:, :] xl, + const float_index[:, :] xp, + const float_index[:, :] yl, + const float_index[:, :] yp, + const float_index[:, :] dst_x, + const float_index[:, :] dst_y, const size_t x_size, const size_t y_size, FN fun, @@ -173,7 +173,7 @@ cdef void one_step_gradient_search_no_gil(const data_type[:, :, :] data, # intermediate variables: cdef int l_a, l_b, p_a, p_b cdef size_t i, j, elt - cdef double dx, dy, d, dl, dp + cdef float_index dx, dy, d, dl, dp cdef int col_step = -1 # number of iterations cdef int cnt = 0 @@ -230,16 +230,17 @@ cdef void one_step_gradient_search_no_gil(const data_type[:, :, :] data, p0 = int(p0 + dp) j += col_step + @cython.boundscheck(False) @cython.wraparound(False) -cpdef one_step_gradient_indices(DTYPE_t [:, :] src_x, - DTYPE_t [:, :] src_y, - DTYPE_t [:, :] xl, - DTYPE_t [:, :] xp, - DTYPE_t [:, :] yl, - DTYPE_t [:, :] yp, - DTYPE_t [:, :] dst_x, - DTYPE_t [:, :] dst_y): +cpdef one_step_gradient_indices(float_index [:, :] src_x, + float_index [:, :] src_y, + float_index [:, :] xl, + float_index [:, :] xp, + float_index [:, :] yl, + float_index [:, :] yp, + float_index [:, :] dst_x, + float_index [:, :] dst_y): """Gradient search, simple case variant, returning float indices. This is appropriate for monotonous gradients only, i.e. not modis or viirs in satellite projection. @@ -250,18 +251,24 @@ cpdef one_step_gradient_indices(DTYPE_t [:, :] src_x, cdef size_t y_size = dst_y.shape[0] cdef size_t x_size = dst_x.shape[1] + + if float_index is double: + dtype = np.float64 + else: + dtype = np.float32 + # output indices arrays --> needs to be (lines, pixels) --> y,x - indices = np.full([2, y_size, x_size], np.nan, dtype=f_index_dtype) + indices = np.full([2, y_size, x_size], np.nan, dtype=dtype) cdef float_index [:, :, :] indices_view_result = indices # fake_data is not going to be used anyway as we just fill in the indices - cdef float_index [:, :, :] fake_data = np.full([1, 1, 1], np.nan, dtype=f_index_dtype) + cdef float_index [:, :, :] fake_data = np.full([1, 1, 1], np.nan, dtype=dtype) with nogil: - one_step_gradient_search_no_gil[float_index](fake_data, - src_x, src_y, - xl, xp, yl, yp, - dst_x, dst_y, - x_size, y_size, - indices_xy, indices_view_result) + one_step_gradient_search_no_gil[float_index, float_index](fake_data, + src_x, src_y, + xl, xp, yl, yp, + dst_x, dst_y, + x_size, y_size, + indices_xy, indices_view_result) return indices From 98cec0b2ca50151c0c80232eab257f2c228a3663 Mon Sep 17 00:00:00 2001 From: Martin Raspaud Date: Tue, 3 Sep 2024 15:25:26 +0200 Subject: [PATCH 05/13] Remove fused type for coordinates --- pyresample/gradient/_gradient_search.pyx | 26 +++++++++--------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/pyresample/gradient/_gradient_search.pyx b/pyresample/gradient/_gradient_search.pyx index ccf39699..e3793fdc 100644 --- a/pyresample/gradient/_gradient_search.pyx +++ b/pyresample/gradient/_gradient_search.pyx @@ -31,9 +31,8 @@ ctypedef fused data_type: double float -ctypedef fused float_index: - double - float +ctypedef double float_index +float_index_dtype = np.float64 np.import_array() @@ -252,23 +251,18 @@ cpdef one_step_gradient_indices(float_index [:, :] src_x, cdef size_t x_size = dst_x.shape[1] - if float_index is double: - dtype = np.float64 - else: - dtype = np.float32 - # output indices arrays --> needs to be (lines, pixels) --> y,x - indices = np.full([2, y_size, x_size], np.nan, dtype=dtype) + indices = np.full([2, y_size, x_size], np.nan, dtype=float_index_dtype) cdef float_index [:, :, :] indices_view_result = indices # fake_data is not going to be used anyway as we just fill in the indices - cdef float_index [:, :, :] fake_data = np.full([1, 1, 1], np.nan, dtype=dtype) + cdef float_index [:, :, :] fake_data = np.full([1, 1, 1], np.nan, dtype=float_index_dtype) with nogil: - one_step_gradient_search_no_gil[float_index, float_index](fake_data, - src_x, src_y, - xl, xp, yl, yp, - dst_x, dst_y, - x_size, y_size, - indices_xy, indices_view_result) + one_step_gradient_search_no_gil[float_index](fake_data, + src_x, src_y, + xl, xp, yl, yp, + dst_x, dst_y, + x_size, y_size, + indices_xy, indices_view_result) return indices From f2fed1a7ad1e6b4dabda43e5b41f0fed073bc378 Mon Sep 17 00:00:00 2001 From: Martin Raspaud Date: Mon, 16 Sep 2024 13:08:39 +0200 Subject: [PATCH 06/13] Update pyresample/gradient/_gradient_search.pyx Co-authored-by: David Hoese --- pyresample/gradient/_gradient_search.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyresample/gradient/_gradient_search.pyx b/pyresample/gradient/_gradient_search.pyx index e3793fdc..ddee062d 100644 --- a/pyresample/gradient/_gradient_search.pyx +++ b/pyresample/gradient/_gradient_search.pyx @@ -31,7 +31,7 @@ ctypedef fused data_type: double float -ctypedef double float_index +ctypedef np.float64_t float_index float_index_dtype = np.float64 np.import_array() From ff4f3fcd7a3fda09c44db9f6631655fc4801a5df Mon Sep 17 00:00:00 2001 From: Martin Raspaud Date: Mon, 16 Sep 2024 13:09:11 +0200 Subject: [PATCH 07/13] Update pyresample/gradient/_gradient_search.pyx Co-authored-by: David Hoese --- pyresample/gradient/_gradient_search.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyresample/gradient/_gradient_search.pyx b/pyresample/gradient/_gradient_search.pyx index ddee062d..e291866e 100644 --- a/pyresample/gradient/_gradient_search.pyx +++ b/pyresample/gradient/_gradient_search.pyx @@ -28,8 +28,8 @@ cimport numpy as np from libc.math cimport fabs, isinf ctypedef fused data_type: - double - float + np.float64_t + np.float32_t ctypedef np.float64_t float_index float_index_dtype = np.float64 From 01bbc92596cb8b5a364a9a87829b40ce0967aa31 Mon Sep 17 00:00:00 2001 From: Martin Raspaud Date: Mon, 16 Sep 2024 13:19:51 +0200 Subject: [PATCH 08/13] Update pyresample/gradient/__init__.py Co-authored-by: David Hoese --- pyresample/gradient/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyresample/gradient/__init__.py b/pyresample/gradient/__init__.py index bb4fefd5..5a90b8cc 100644 --- a/pyresample/gradient/__init__.py +++ b/pyresample/gradient/__init__.py @@ -421,6 +421,7 @@ def parallel_gradient_search(data, src_x, src_y, dst_x, dst_y, dst_x[i], dst_y[i], method=method) res = da.from_delayed(res, (num_bands, ) + dst_x[i].shape, + meta=np.array((), dtype=dtype), dtype=arr.dtype) if dst_mosaic_locations[i] in chunks: if not is_pad: From 542de8388faa379d0c1714eb691786d49de867bf Mon Sep 17 00:00:00 2001 From: Martin Raspaud Date: Mon, 16 Sep 2024 13:20:44 +0200 Subject: [PATCH 09/13] Fix typo --- pyresample/gradient/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyresample/gradient/__init__.py b/pyresample/gradient/__init__.py index 5a90b8cc..41c98846 100644 --- a/pyresample/gradient/__init__.py +++ b/pyresample/gradient/__init__.py @@ -421,7 +421,7 @@ def parallel_gradient_search(data, src_x, src_y, dst_x, dst_y, dst_x[i], dst_y[i], method=method) res = da.from_delayed(res, (num_bands, ) + dst_x[i].shape, - meta=np.array((), dtype=dtype), + meta=np.array((), dtype=arr.dtype), dtype=arr.dtype) if dst_mosaic_locations[i] in chunks: if not is_pad: From fa79864e7f1be78c8824f7cffabad1de2bce5630 Mon Sep 17 00:00:00 2001 From: Martin Raspaud Date: Mon, 16 Sep 2024 13:37:25 +0200 Subject: [PATCH 10/13] Add type checks for computed results --- pyresample/test/test_gradient.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyresample/test/test_gradient.py b/pyresample/test/test_gradient.py index e4e405a6..604e6c02 100644 --- a/pyresample/test/test_gradient.py +++ b/pyresample/test/test_gradient.py @@ -258,6 +258,7 @@ def test_resample_swath_to_area_2d(self, input_dtype): res = self.swath_resampler.compute( data, method='bil').compute(scheduler='single-threaded') assert res.dtype == data.dtype + assert res.values.dtype == data.dtype assert res.shape == self.dst_area.shape assert not np.all(np.isnan(res)) @@ -272,6 +273,7 @@ def test_resample_swath_to_area_3d(self, input_dtype): res = self.swath_resampler.compute( data, method='bil').compute(scheduler='single-threaded') assert res.dtype == data.dtype + assert res.values.dytpe == data.dtype assert res.shape == (3, ) + self.dst_area.shape for i in range(res.shape[0]): arr = np.ravel(res[i, :, :]) From 6ad5092f5989b6b5a546c8d8ef636f5fe82e2243 Mon Sep 17 00:00:00 2001 From: Martin Raspaud Date: Mon, 16 Sep 2024 14:04:51 +0200 Subject: [PATCH 11/13] Fix typo --- pyresample/test/test_gradient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyresample/test/test_gradient.py b/pyresample/test/test_gradient.py index 604e6c02..b6c16061 100644 --- a/pyresample/test/test_gradient.py +++ b/pyresample/test/test_gradient.py @@ -273,7 +273,7 @@ def test_resample_swath_to_area_3d(self, input_dtype): res = self.swath_resampler.compute( data, method='bil').compute(scheduler='single-threaded') assert res.dtype == data.dtype - assert res.values.dytpe == data.dtype + assert res.values.dtype == data.dtype assert res.shape == (3, ) + self.dst_area.shape for i in range(res.shape[0]): arr = np.ravel(res[i, :, :]) From 77576e70637afd2b164afacc66b7fb325f62d15c Mon Sep 17 00:00:00 2001 From: Martin Raspaud Date: Mon, 16 Sep 2024 15:57:58 +0200 Subject: [PATCH 12/13] Fix tests --- pyresample/test/test_gradient.py | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/pyresample/test/test_gradient.py b/pyresample/test/test_gradient.py index b6c16061..bf2205f9 100644 --- a/pyresample/test/test_gradient.py +++ b/pyresample/test/test_gradient.py @@ -255,12 +255,14 @@ def test_resample_swath_to_area_2d(self, input_dtype): data = xr.DataArray(da.ones(self.src_swath.shape, dtype=input_dtype), dims=['y', 'x']) with np.errstate(invalid="ignore"): # 'inf' space pixels cause runtime warnings - res = self.swath_resampler.compute( - data, method='bil').compute(scheduler='single-threaded') - assert res.dtype == data.dtype - assert res.values.dtype == data.dtype - assert res.shape == self.dst_area.shape - assert not np.all(np.isnan(res)) + res_dask = self.swath_resampler.compute(data, method='bil') + res_np = res_dask.compute(scheduler='single-threaded') + + assert res_dask.dtype == data.dtype + assert res_np.dtype == data.dtype + assert res_dask.shape == self.dst_area.shape + assert res_np.shape == self.dst_area.shape + assert not np.all(np.isnan(res_np)) @pytest.mark.parametrize("input_dtype", (np.float32, np.float64)) def test_resample_swath_to_area_3d(self, input_dtype): @@ -270,13 +272,15 @@ def test_resample_swath_to_area_3d(self, input_dtype): np.array([1, 2, 3])[:, np.newaxis, np.newaxis], dims=['bands', 'y', 'x']) with np.errstate(invalid="ignore"): # 'inf' space pixels cause runtime warnings - res = self.swath_resampler.compute( - data, method='bil').compute(scheduler='single-threaded') - assert res.dtype == data.dtype - assert res.values.dtype == data.dtype - assert res.shape == (3, ) + self.dst_area.shape - for i in range(res.shape[0]): - arr = np.ravel(res[i, :, :]) + res_dask = self.swath_resampler.compute(data, method='bil') + res_np = res_dask.compute(scheduler='single-threaded') + + assert res_dask.dtype == data.dtype + assert res_np.dtype == data.dtype + assert res_dask.shape == (3, ) + self.dst_area.shape + assert res_np.shape == (3, ) + self.dst_area.shape + for i in range(res_np.shape[0]): + arr = np.ravel(res_np[i, :, :]) assert np.allclose(arr[np.isfinite(arr)], float(i + 1)) From 8cc6ec8eb68eae635831b36bee3ac87567166558 Mon Sep 17 00:00:00 2001 From: Martin Raspaud Date: Tue, 17 Sep 2024 08:51:29 +0200 Subject: [PATCH 13/13] Test output array type for resampling --- pyresample/test/test_gradient.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/pyresample/test/test_gradient.py b/pyresample/test/test_gradient.py index bf2205f9..5b915be2 100644 --- a/pyresample/test/test_gradient.py +++ b/pyresample/test/test_gradient.py @@ -255,13 +255,15 @@ def test_resample_swath_to_area_2d(self, input_dtype): data = xr.DataArray(da.ones(self.src_swath.shape, dtype=input_dtype), dims=['y', 'x']) with np.errstate(invalid="ignore"): # 'inf' space pixels cause runtime warnings - res_dask = self.swath_resampler.compute(data, method='bil') - res_np = res_dask.compute(scheduler='single-threaded') + res_xr = self.swath_resampler.compute(data, method='bil') + res_np = res_xr.compute(scheduler='single-threaded') - assert res_dask.dtype == data.dtype + assert res_xr.dtype == data.dtype assert res_np.dtype == data.dtype - assert res_dask.shape == self.dst_area.shape + assert res_xr.shape == self.dst_area.shape assert res_np.shape == self.dst_area.shape + assert type(res_xr) is type(data) + assert type(res_xr.data) is type(data.data) assert not np.all(np.isnan(res_np)) @pytest.mark.parametrize("input_dtype", (np.float32, np.float64)) @@ -272,13 +274,15 @@ def test_resample_swath_to_area_3d(self, input_dtype): np.array([1, 2, 3])[:, np.newaxis, np.newaxis], dims=['bands', 'y', 'x']) with np.errstate(invalid="ignore"): # 'inf' space pixels cause runtime warnings - res_dask = self.swath_resampler.compute(data, method='bil') - res_np = res_dask.compute(scheduler='single-threaded') + res_xr = self.swath_resampler.compute(data, method='bil') + res_np = res_xr.compute(scheduler='single-threaded') - assert res_dask.dtype == data.dtype + assert res_xr.dtype == data.dtype assert res_np.dtype == data.dtype - assert res_dask.shape == (3, ) + self.dst_area.shape + assert res_xr.shape == (3, ) + self.dst_area.shape assert res_np.shape == (3, ) + self.dst_area.shape + assert type(res_xr) is type(data) + assert type(res_xr.data) is type(data.data) for i in range(res_np.shape[0]): arr = np.ravel(res_np[i, :, :]) assert np.allclose(arr[np.isfinite(arr)], float(i + 1))