Actually there are 4 more tests failing when I run the test suite against numpy 2.4.
I was planning to fix also those ones but I dint have time so far.
I will open a new PR if I manage for find a fix.
277s =================================== FAILURES ===================================
277s _ test_generic_filter_identity[<lambda>-1-None-generic_filter-generic_filter] __
277s
277s sp_func = <function generic_filter at 0x7f893219c680>
277s da_func = <function generic_filter at 0x7f89321cd440>
277s function = <function <lambda> at 0x7f8931f9ae80>, size = 1, footprint = None
277s
277s @pytest.mark.parametrize(
277s "sp_func, da_func",
277s [(scipy.ndimage.generic_filter, dask_image.ndfilters.generic_filter)],
277s )
277s @pytest.mark.parametrize(
277s "function, size, footprint",
277s [
277s (lambda x: x, 1, None),
277s (lambda x: x, (1, 1), None),
277s (lambda x: x, None, np.ones((1, 1))),
277s ],
277s )
277s def test_generic_filter_identity(sp_func, da_func, function, size, footprint):
277s a = np.arange(140.0).reshape(10, 14)
277s d = da.from_array(a, chunks=(5, 7))
277s
277s > da.utils.assert_eq(d, da_func(d, function, size=size, footprint=footprint))
277s
277s tests/test_dask_image/test_ndfilters/test__generic.py:82:
277s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
277s /usr/lib/python3/dist-packages/dask/array/utils.py:328: in assert_eq
277s b, bdt, b_meta, b_computed = _get_dt_meta_computed(
277s /usr/lib/python3/dist-packages/dask/array/utils.py:279: in _get_dt_meta_computed
277s x = _check_chunks(x, check_ndim=check_ndim, scheduler=scheduler)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s /usr/lib/python3/dist-packages/dask/array/utils.py:242: in _check_chunks
277s x = x.persist(scheduler=scheduler)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s /usr/lib/python3/dist-packages/dask/base.py:345: in persist
277s (result,) = persist(self, traverse=False, **kwargs)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s /usr/lib/python3/dist-packages/dask/base.py:999: in persist
277s results = schedule(dsk, keys, **kwargs)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
277s
277s input = array([[ 77., 78., 79., 80., 81., 82., 83.],
277s [ 91., 92., 93., 94., 95., 96., 97.],
277s [105., 10...9., 110., 111.],
277s [119., 120., 121., 122., 123., 124., 125.],
277s [133., 134., 135., 136., 137., 138., 139.]])
277s function = <function <lambda> at 0x7f8931f9ae80>, size = None
277s footprint = array([[ True]])
277s output = array([[-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.]])
277s mode = 2, cval = 0.0, origin = np.int64(0), extra_arguments = ()
277s extra_keywords = {}
277s
277s @_ni_docstrings.docfiller
277s def generic_filter(input, function, size=None, footprint=None,
277s output=None, mode="reflect", cval=0.0, origin=0,
277s extra_arguments=(), extra_keywords=None, *, axes=None):
277s """Calculate a multidimensional filter using the given function.
277s
277s At each element the provided function is called. The input values
277s within the filter footprint at that element are passed to the function
277s as a 1-D array of double values.
277s
277s Parameters
277s ----------
277s %(input)s
277s function : {callable, scipy.LowLevelCallable}
277s Function to apply at each element.
277s %(size_foot)s
277s %(output)s
277s %(mode_reflect)s
277s %(cval)s
277s %(origin_multiple)s
277s %(extra_arguments)s
277s %(extra_keywords)s
277s axes : tuple of int or None, optional
277s If None, `input` is filtered along all axes. Otherwise,
277s `input` is filtered along the specified axes. When `axes` is
277s specified, any tuples used for `size` or `origin` must match the length
277s of `axes`. The ith entry in any of these tuples corresponds to the ith
277s entry in `axes`.
277s
277s Returns
277s -------
277s output : ndarray
277s Filtered array. Has the same shape as `input`.
277s
277s See Also
277s --------
277s vectorized_filter : similar functionality, but optimized for vectorized callables
277s
277s Notes
277s -----
277s This function is ideal for use with instances of `scipy.LowLevelCallable`;
277s for vectorized, pure-Python callables, consider `vectorized_filter` for improved
277s performance.
277s
277s Low-level callback functions must have one of the following signatures:
277s
277s .. code:: c
277s
277s int callback(double *buffer, npy_intp filter_size,
277s double *return_value, void *user_data)
277s int callback(double *buffer, intptr_t filter_size,
277s double *return_value, void *user_data)
277s
277s The calling function iterates over the elements of the input and
277s output arrays, calling the callback function at each element. The
277s elements within the footprint of the filter at the current element are
277s passed through the ``buffer`` parameter, and the number of elements
277s within the footprint through ``filter_size``. The calculated value is
277s returned in ``return_value``. ``user_data`` is the data pointer provided
277s to `scipy.LowLevelCallable` as-is.
277s
277s The callback function must return an integer error status that is zero
277s if something went wrong and one otherwise. If an error occurs, you should
277s normally set the python error status with an informative message
277s before returning, otherwise a default error message is set by the
277s calling function.
277s
277s In addition, some other low-level function pointer specifications
277s are accepted, but these are for backward compatibility only and should
277s not be used in new code.
277s
277s Examples
277s --------
277s Import the necessary modules and load the example image used for
277s filtering.
277s
277s >>> import numpy as np
277s >>> from scipy import datasets
277s >>> from scipy.ndimage import zoom, generic_filter
277s >>> import matplotlib.pyplot as plt
277s >>> ascent = zoom(datasets.ascent(), 0.5)
277s
277s Compute a maximum filter with kernel size 5 by passing a simple NumPy
277s aggregation function as argument to `function`.
277s
277s >>> maximum_filter_result = generic_filter(ascent, np.amax, [5, 5])
277s
277s While a maximum filter could also directly be obtained using
277s `maximum_filter`, `generic_filter` allows generic Python function or
277s `scipy.LowLevelCallable` to be used as a filter. Here, we compute the
277s range between maximum and minimum value as an example for a kernel size
277s of 5.
277s
277s >>> def custom_filter(image):
277s ... return np.amax(image) - np.amin(image)
277s >>> custom_filter_result = generic_filter(ascent, custom_filter, [5, 5])
277s
277s Plot the original and filtered images.
277s
277s >>> fig, axes = plt.subplots(3, 1, figsize=(3, 9))
277s >>> plt.gray() # show the filtered result in grayscale
277s >>> top, middle, bottom = axes
277s >>> for ax in axes:
277s ... ax.set_axis_off() # remove coordinate system
277s >>> top.imshow(ascent)
277s >>> top.set_title("Original image")
277s >>> middle.imshow(maximum_filter_result)
277s >>> middle.set_title("Maximum filter, Kernel: 5x5")
277s >>> bottom.imshow(custom_filter_result)
277s >>> bottom.set_title("Custom filter, Kernel: 5x5")
277s >>> fig.tight_layout()
277s
277s """
277s if (size is not None) and (footprint is not None):
277s warnings.warn("ignoring size because footprint is set",
277s UserWarning, stacklevel=2)
277s if extra_keywords is None:
277s extra_keywords = {}
277s input = np.asarray(input)
277s if np.iscomplexobj(input):
277s raise TypeError('Complex type not supported')
277s axes = _ni_support._check_axes(axes, input.ndim)
277s num_axes = len(axes)
277s if footprint is None:
277s if size is None:
277s raise RuntimeError("no footprint or filter size provided")
277s sizes = _ni_support._normalize_sequence(size, num_axes)
277s footprint = np.ones(sizes, dtype=bool)
277s else:
277s footprint = np.asarray(footprint, dtype=bool)
277s
277s # expand origins, footprint if num_axes < input.ndim
277s footprint = _expand_footprint(input.ndim, axes, footprint)
277s origins = _expand_origin(input.ndim, axes, origin)
277s
277s fshape = [ii for ii in footprint.shape if ii > 0]
277s if len(fshape) != input.ndim:
277s raise RuntimeError(f"footprint.ndim ({footprint.ndim}) "
277s f"must match len(axes) ({num_axes})")
277s for origin, lenf in zip(origins, fshape):
277s if (lenf // 2 + origin < 0) or (lenf // 2 + origin >= lenf):
277s raise ValueError('invalid origin')
277s if not footprint.flags.contiguous:
277s footprint = footprint.copy()
277s output = _ni_support._get_output(output, input)
277s
277s mode = _ni_support._extend_mode_to_code(mode)
277s > _nd_image.generic_filter(input, function, footprint, output, mode,
277s cval, origins, extra_arguments, extra_keywords)
277s E TypeError: only 0-dimensional arrays can be converted to Python scalars
277s
277s /usr/lib/python3/dist-packages/scipy/ndimage/_filters.py:2420: TypeError
277s _ test_generic_filter_identity[<lambda>-size1-None-generic_filter-generic_filter] _
277s
277s sp_func = <function generic_filter at 0x7f893219c680>
277s da_func = <function generic_filter at 0x7f89321cd440>
277s function = <function <lambda> at 0x7f8931f9af20>, size = (1, 1)
277s footprint = None
277s
277s @pytest.mark.parametrize(
277s "sp_func, da_func",
277s [(scipy.ndimage.generic_filter, dask_image.ndfilters.generic_filter)],
277s )
277s @pytest.mark.parametrize(
277s "function, size, footprint",
277s [
277s (lambda x: x, 1, None),
277s (lambda x: x, (1, 1), None),
277s (lambda x: x, None, np.ones((1, 1))),
277s ],
277s )
277s def test_generic_filter_identity(sp_func, da_func, function, size, footprint):
277s a = np.arange(140.0).reshape(10, 14)
277s d = da.from_array(a, chunks=(5, 7))
277s
277s > da.utils.assert_eq(d, da_func(d, function, size=size, footprint=footprint))
277s
277s tests/test_dask_image/test_ndfilters/test__generic.py:82:
277s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
277s /usr/lib/python3/dist-packages/dask/array/utils.py:328: in assert_eq
277s b, bdt, b_meta, b_computed = _get_dt_meta_computed(
277s /usr/lib/python3/dist-packages/dask/array/utils.py:279: in _get_dt_meta_computed
277s x = _check_chunks(x, check_ndim=check_ndim, scheduler=scheduler)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s /usr/lib/python3/dist-packages/dask/array/utils.py:242: in _check_chunks
277s x = x.persist(scheduler=scheduler)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s /usr/lib/python3/dist-packages/dask/base.py:345: in persist
277s (result,) = persist(self, traverse=False, **kwargs)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s /usr/lib/python3/dist-packages/dask/base.py:999: in persist
277s results = schedule(dsk, keys, **kwargs)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
277s
277s input = array([[ 77., 78., 79., 80., 81., 82., 83.],
277s [ 91., 92., 93., 94., 95., 96., 97.],
277s [105., 10...9., 110., 111.],
277s [119., 120., 121., 122., 123., 124., 125.],
277s [133., 134., 135., 136., 137., 138., 139.]])
277s function = <function <lambda> at 0x7f8931f9af20>, size = None
277s footprint = array([[ True]])
277s output = array([[-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.]])
277s mode = 2, cval = 0.0, origin = np.int64(0), extra_arguments = ()
277s extra_keywords = {}
277s
277s @_ni_docstrings.docfiller
277s def generic_filter(input, function, size=None, footprint=None,
277s output=None, mode="reflect", cval=0.0, origin=0,
277s extra_arguments=(), extra_keywords=None, *, axes=None):
277s """Calculate a multidimensional filter using the given function.
277s
277s At each element the provided function is called. The input values
277s within the filter footprint at that element are passed to the function
277s as a 1-D array of double values.
277s
277s Parameters
277s ----------
277s %(input)s
277s function : {callable, scipy.LowLevelCallable}
277s Function to apply at each element.
277s %(size_foot)s
277s %(output)s
277s %(mode_reflect)s
277s %(cval)s
277s %(origin_multiple)s
277s %(extra_arguments)s
277s %(extra_keywords)s
277s axes : tuple of int or None, optional
277s If None, `input` is filtered along all axes. Otherwise,
277s `input` is filtered along the specified axes. When `axes` is
277s specified, any tuples used for `size` or `origin` must match the length
277s of `axes`. The ith entry in any of these tuples corresponds to the ith
277s entry in `axes`.
277s
277s Returns
277s -------
277s output : ndarray
277s Filtered array. Has the same shape as `input`.
277s
277s See Also
277s --------
277s vectorized_filter : similar functionality, but optimized for vectorized callables
277s
277s Notes
277s -----
277s This function is ideal for use with instances of `scipy.LowLevelCallable`;
277s for vectorized, pure-Python callables, consider `vectorized_filter` for improved
277s performance.
277s
277s Low-level callback functions must have one of the following signatures:
277s
277s .. code:: c
277s
277s int callback(double *buffer, npy_intp filter_size,
277s double *return_value, void *user_data)
277s int callback(double *buffer, intptr_t filter_size,
277s double *return_value, void *user_data)
277s
277s The calling function iterates over the elements of the input and
277s output arrays, calling the callback function at each element. The
277s elements within the footprint of the filter at the current element are
277s passed through the ``buffer`` parameter, and the number of elements
277s within the footprint through ``filter_size``. The calculated value is
277s returned in ``return_value``. ``user_data`` is the data pointer provided
277s to `scipy.LowLevelCallable` as-is.
277s
277s The callback function must return an integer error status that is zero
277s if something went wrong and one otherwise. If an error occurs, you should
277s normally set the python error status with an informative message
277s before returning, otherwise a default error message is set by the
277s calling function.
277s
277s In addition, some other low-level function pointer specifications
277s are accepted, but these are for backward compatibility only and should
277s not be used in new code.
277s
277s Examples
277s --------
277s Import the necessary modules and load the example image used for
277s filtering.
277s
277s >>> import numpy as np
277s >>> from scipy import datasets
277s >>> from scipy.ndimage import zoom, generic_filter
277s >>> import matplotlib.pyplot as plt
277s >>> ascent = zoom(datasets.ascent(), 0.5)
277s
277s Compute a maximum filter with kernel size 5 by passing a simple NumPy
277s aggregation function as argument to `function`.
277s
277s >>> maximum_filter_result = generic_filter(ascent, np.amax, [5, 5])
277s
277s While a maximum filter could also directly be obtained using
277s `maximum_filter`, `generic_filter` allows generic Python function or
277s `scipy.LowLevelCallable` to be used as a filter. Here, we compute the
277s range between maximum and minimum value as an example for a kernel size
277s of 5.
277s
277s >>> def custom_filter(image):
277s ... return np.amax(image) - np.amin(image)
277s >>> custom_filter_result = generic_filter(ascent, custom_filter, [5, 5])
277s
277s Plot the original and filtered images.
277s
277s >>> fig, axes = plt.subplots(3, 1, figsize=(3, 9))
277s >>> plt.gray() # show the filtered result in grayscale
277s >>> top, middle, bottom = axes
277s >>> for ax in axes:
277s ... ax.set_axis_off() # remove coordinate system
277s >>> top.imshow(ascent)
277s >>> top.set_title("Original image")
277s >>> middle.imshow(maximum_filter_result)
277s >>> middle.set_title("Maximum filter, Kernel: 5x5")
277s >>> bottom.imshow(custom_filter_result)
277s >>> bottom.set_title("Custom filter, Kernel: 5x5")
277s >>> fig.tight_layout()
277s
277s """
277s if (size is not None) and (footprint is not None):
277s warnings.warn("ignoring size because footprint is set",
277s UserWarning, stacklevel=2)
277s if extra_keywords is None:
277s extra_keywords = {}
277s input = np.asarray(input)
277s if np.iscomplexobj(input):
277s raise TypeError('Complex type not supported')
277s axes = _ni_support._check_axes(axes, input.ndim)
277s num_axes = len(axes)
277s if footprint is None:
277s if size is None:
277s raise RuntimeError("no footprint or filter size provided")
277s sizes = _ni_support._normalize_sequence(size, num_axes)
277s footprint = np.ones(sizes, dtype=bool)
277s else:
277s footprint = np.asarray(footprint, dtype=bool)
277s
277s # expand origins, footprint if num_axes < input.ndim
277s footprint = _expand_footprint(input.ndim, axes, footprint)
277s origins = _expand_origin(input.ndim, axes, origin)
277s
277s fshape = [ii for ii in footprint.shape if ii > 0]
277s if len(fshape) != input.ndim:
277s raise RuntimeError(f"footprint.ndim ({footprint.ndim}) "
277s f"must match len(axes) ({num_axes})")
277s for origin, lenf in zip(origins, fshape):
277s if (lenf // 2 + origin < 0) or (lenf // 2 + origin >= lenf):
277s raise ValueError('invalid origin')
277s if not footprint.flags.contiguous:
277s footprint = footprint.copy()
277s output = _ni_support._get_output(output, input)
277s
277s mode = _ni_support._extend_mode_to_code(mode)
277s > _nd_image.generic_filter(input, function, footprint, output, mode,
277s cval, origins, extra_arguments, extra_keywords)
277s E TypeError: only 0-dimensional arrays can be converted to Python scalars
277s
277s /usr/lib/python3/dist-packages/scipy/ndimage/_filters.py:2420: TypeError
277s _ test_generic_filter_identity[<lambda>-None-footprint2-generic_filter-generic_filter] _
277s
277s sp_func = <function generic_filter at 0x7f893219c680>
277s da_func = <function generic_filter at 0x7f89321cd440>
277s function = <function <lambda> at 0x7f8931f9afc0>, size = None
277s footprint = array([[1.]])
277s
277s @pytest.mark.parametrize(
277s "sp_func, da_func",
277s [(scipy.ndimage.generic_filter, dask_image.ndfilters.generic_filter)],
277s )
277s @pytest.mark.parametrize(
277s "function, size, footprint",
277s [
277s (lambda x: x, 1, None),
277s (lambda x: x, (1, 1), None),
277s (lambda x: x, None, np.ones((1, 1))),
277s ],
277s )
277s def test_generic_filter_identity(sp_func, da_func, function, size, footprint):
277s a = np.arange(140.0).reshape(10, 14)
277s d = da.from_array(a, chunks=(5, 7))
277s
277s > da.utils.assert_eq(d, da_func(d, function, size=size, footprint=footprint))
277s
277s tests/test_dask_image/test_ndfilters/test__generic.py:82:
277s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
277s /usr/lib/python3/dist-packages/dask/array/utils.py:328: in assert_eq
277s b, bdt, b_meta, b_computed = _get_dt_meta_computed(
277s /usr/lib/python3/dist-packages/dask/array/utils.py:279: in _get_dt_meta_computed
277s x = _check_chunks(x, check_ndim=check_ndim, scheduler=scheduler)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s /usr/lib/python3/dist-packages/dask/array/utils.py:242: in _check_chunks
277s x = x.persist(scheduler=scheduler)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s /usr/lib/python3/dist-packages/dask/base.py:345: in persist
277s (result,) = persist(self, traverse=False, **kwargs)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s /usr/lib/python3/dist-packages/dask/base.py:999: in persist
277s results = schedule(dsk, keys, **kwargs)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
277s
277s input = array([[ 77., 78., 79., 80., 81., 82., 83.],
277s [ 91., 92., 93., 94., 95., 96., 97.],
277s [105., 10...9., 110., 111.],
277s [119., 120., 121., 122., 123., 124., 125.],
277s [133., 134., 135., 136., 137., 138., 139.]])
277s function = <function <lambda> at 0x7f8931f9afc0>, size = None
277s footprint = array([[ True]])
277s output = array([[-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.]])
277s mode = 2, cval = 0.0, origin = np.int64(0), extra_arguments = ()
277s extra_keywords = {}
277s
277s @_ni_docstrings.docfiller
277s def generic_filter(input, function, size=None, footprint=None,
277s output=None, mode="reflect", cval=0.0, origin=0,
277s extra_arguments=(), extra_keywords=None, *, axes=None):
277s """Calculate a multidimensional filter using the given function.
277s
277s At each element the provided function is called. The input values
277s within the filter footprint at that element are passed to the function
277s as a 1-D array of double values.
277s
277s Parameters
277s ----------
277s %(input)s
277s function : {callable, scipy.LowLevelCallable}
277s Function to apply at each element.
277s %(size_foot)s
277s %(output)s
277s %(mode_reflect)s
277s %(cval)s
277s %(origin_multiple)s
277s %(extra_arguments)s
277s %(extra_keywords)s
277s axes : tuple of int or None, optional
277s If None, `input` is filtered along all axes. Otherwise,
277s `input` is filtered along the specified axes. When `axes` is
277s specified, any tuples used for `size` or `origin` must match the length
277s of `axes`. The ith entry in any of these tuples corresponds to the ith
277s entry in `axes`.
277s
277s Returns
277s -------
277s output : ndarray
277s Filtered array. Has the same shape as `input`.
277s
277s See Also
277s --------
277s vectorized_filter : similar functionality, but optimized for vectorized callables
277s
277s Notes
277s -----
277s This function is ideal for use with instances of `scipy.LowLevelCallable`;
277s for vectorized, pure-Python callables, consider `vectorized_filter` for improved
277s performance.
277s
277s Low-level callback functions must have one of the following signatures:
277s
277s .. code:: c
277s
277s int callback(double *buffer, npy_intp filter_size,
277s double *return_value, void *user_data)
277s int callback(double *buffer, intptr_t filter_size,
277s double *return_value, void *user_data)
277s
277s The calling function iterates over the elements of the input and
277s output arrays, calling the callback function at each element. The
277s elements within the footprint of the filter at the current element are
277s passed through the ``buffer`` parameter, and the number of elements
277s within the footprint through ``filter_size``. The calculated value is
277s returned in ``return_value``. ``user_data`` is the data pointer provided
277s to `scipy.LowLevelCallable` as-is.
277s
277s The callback function must return an integer error status that is zero
277s if something went wrong and one otherwise. If an error occurs, you should
277s normally set the python error status with an informative message
277s before returning, otherwise a default error message is set by the
277s calling function.
277s
277s In addition, some other low-level function pointer specifications
277s are accepted, but these are for backward compatibility only and should
277s not be used in new code.
277s
277s Examples
277s --------
277s Import the necessary modules and load the example image used for
277s filtering.
277s
277s >>> import numpy as np
277s >>> from scipy import datasets
277s >>> from scipy.ndimage import zoom, generic_filter
277s >>> import matplotlib.pyplot as plt
277s >>> ascent = zoom(datasets.ascent(), 0.5)
277s
277s Compute a maximum filter with kernel size 5 by passing a simple NumPy
277s aggregation function as argument to `function`.
277s
277s >>> maximum_filter_result = generic_filter(ascent, np.amax, [5, 5])
277s
277s While a maximum filter could also directly be obtained using
277s `maximum_filter`, `generic_filter` allows generic Python function or
277s `scipy.LowLevelCallable` to be used as a filter. Here, we compute the
277s range between maximum and minimum value as an example for a kernel size
277s of 5.
277s
277s >>> def custom_filter(image):
277s ... return np.amax(image) - np.amin(image)
277s >>> custom_filter_result = generic_filter(ascent, custom_filter, [5, 5])
277s
277s Plot the original and filtered images.
277s
277s >>> fig, axes = plt.subplots(3, 1, figsize=(3, 9))
277s >>> plt.gray() # show the filtered result in grayscale
277s >>> top, middle, bottom = axes
277s >>> for ax in axes:
277s ... ax.set_axis_off() # remove coordinate system
277s >>> top.imshow(ascent)
277s >>> top.set_title("Original image")
277s >>> middle.imshow(maximum_filter_result)
277s >>> middle.set_title("Maximum filter, Kernel: 5x5")
277s >>> bottom.imshow(custom_filter_result)
277s >>> bottom.set_title("Custom filter, Kernel: 5x5")
277s >>> fig.tight_layout()
277s
277s """
277s if (size is not None) and (footprint is not None):
277s warnings.warn("ignoring size because footprint is set",
277s UserWarning, stacklevel=2)
277s if extra_keywords is None:
277s extra_keywords = {}
277s input = np.asarray(input)
277s if np.iscomplexobj(input):
277s raise TypeError('Complex type not supported')
277s axes = _ni_support._check_axes(axes, input.ndim)
277s num_axes = len(axes)
277s if footprint is None:
277s if size is None:
277s raise RuntimeError("no footprint or filter size provided")
277s sizes = _ni_support._normalize_sequence(size, num_axes)
277s footprint = np.ones(sizes, dtype=bool)
277s else:
277s footprint = np.asarray(footprint, dtype=bool)
277s
277s # expand origins, footprint if num_axes < input.ndim
277s footprint = _expand_footprint(input.ndim, axes, footprint)
277s origins = _expand_origin(input.ndim, axes, origin)
277s
277s fshape = [ii for ii in footprint.shape if ii > 0]
277s if len(fshape) != input.ndim:
277s raise RuntimeError(f"footprint.ndim ({footprint.ndim}) "
277s f"must match len(axes) ({num_axes})")
277s for origin, lenf in zip(origins, fshape):
277s if (lenf // 2 + origin < 0) or (lenf // 2 + origin >= lenf):
277s raise ValueError('invalid origin')
277s if not footprint.flags.contiguous:
277s footprint = footprint.copy()
277s output = _ni_support._get_output(output, input)
277s
277s mode = _ni_support._extend_mode_to_code(mode)
277s > _nd_image.generic_filter(input, function, footprint, output, mode,
277s cval, origins, extra_arguments, extra_keywords)
277s E TypeError: only 0-dimensional arrays can be converted to Python scalars
277s
277s /usr/lib/python3/dist-packages/scipy/ndimage/_filters.py:2420: TypeError
277s ______________ test_generic_filter_comprehensions[generic_filter] ______________
277s
277s da_func = <function generic_filter at 0x7f89321cd440>
277s
277s @pytest.mark.parametrize(
277s "da_func",
277s [
277s dask_image.ndfilters.generic_filter,
277s ],
277s )
277s def test_generic_filter_comprehensions(da_func):
277s da_wfunc = lambda arr: da_func(arr, lambda x: x, 1) # noqa: E731
277s
277s np.random.seed(0)
277s
277s a = np.random.random((3, 12, 14))
277s d = da.from_array(a, chunks=(3, 6, 7))
277s
277s l2s = [da_wfunc(d[i]) for i in range(len(d))]
277s l2c = [da_wfunc(d[i])[None] for i in range(len(d))]
277s
277s > da.utils.assert_eq(np.stack(l2s), da.stack(l2s))
277s
277s tests/test_dask_image/test_ndfilters/test__generic.py:107:
277s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
277s /usr/lib/python3/dist-packages/dask/array/utils.py:320: in assert_eq
277s a, adt, a_meta, a_computed = _get_dt_meta_computed(
277s /usr/lib/python3/dist-packages/dask/array/utils.py:279: in _get_dt_meta_computed
277s x = _check_chunks(x, check_ndim=check_ndim, scheduler=scheduler)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s /usr/lib/python3/dist-packages/dask/array/utils.py:242: in _check_chunks
277s x = x.persist(scheduler=scheduler)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s /usr/lib/python3/dist-packages/dask/base.py:345: in persist
277s (result,) = persist(self, traverse=False, **kwargs)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s /usr/lib/python3/dist-packages/dask/base.py:999: in persist
277s results = schedule(dsk, keys, **kwargs)
277s ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
277s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
277s
277s input = array([[0.06530421, 0.78323444, 0.2883985 , 0.24141862, 0.66250457,
277s 0.24606318, 0.66585912],
277s [0.8286569...467, 0.5468849 ],
277s [0.40171354, 0.24841347, 0.50586638, 0.31038083, 0.37303486,
277s 0.52497044, 0.75059502]])
277s function = <function test_generic_filter_comprehensions.<locals>.<lambda>.<locals>.<lambda> at 0x7f892deac900>
277s size = None, footprint = array([[ True]])
277s output = array([[-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1...-1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.],
277s [-1., -1., -1., -1., -1., -1., -1.]])
277s mode = 2, cval = 0.0, origin = np.int64(0), extra_arguments = ()
277s extra_keywords = {}
277s
277s @_ni_docstrings.docfiller
277s def generic_filter(input, function, size=None, footprint=None,
277s output=None, mode="reflect", cval=0.0, origin=0,
277s extra_arguments=(), extra_keywords=None, *, axes=None):
277s """Calculate a multidimensional filter using the given function.
277s
277s At each element the provided function is called. The input values
277s within the filter footprint at that element are passed to the function
277s as a 1-D array of double values.
277s
277s Parameters
277s ----------
277s %(input)s
277s function : {callable, scipy.LowLevelCallable}
277s Function to apply at each element.
277s %(size_foot)s
277s %(output)s
277s %(mode_reflect)s
277s %(cval)s
277s %(origin_multiple)s
277s %(extra_arguments)s
277s %(extra_keywords)s
277s axes : tuple of int or None, optional
277s If None, `input` is filtered along all axes. Otherwise,
277s `input` is filtered along the specified axes. When `axes` is
277s specified, any tuples used for `size` or `origin` must match the length
277s of `axes`. The ith entry in any of these tuples corresponds to the ith
277s entry in `axes`.
277s
277s Returns
277s -------
277s output : ndarray
277s Filtered array. Has the same shape as `input`.
277s
277s See Also
277s --------
277s vectorized_filter : similar functionality, but optimized for vectorized callables
277s
277s Notes
277s -----
277s This function is ideal for use with instances of `scipy.LowLevelCallable`;
277s for vectorized, pure-Python callables, consider `vectorized_filter` for improved
277s performance.
277s
277s Low-level callback functions must have one of the following signatures:
277s
277s .. code:: c
277s
277s int callback(double *buffer, npy_intp filter_size,
277s double *return_value, void *user_data)
277s int callback(double *buffer, intptr_t filter_size,
277s double *return_value, void *user_data)
277s
277s The calling function iterates over the elements of the input and
277s output arrays, calling the callback function at each element. The
277s elements within the footprint of the filter at the current element are
277s passed through the ``buffer`` parameter, and the number of elements
277s within the footprint through ``filter_size``. The calculated value is
277s returned in ``return_value``. ``user_data`` is the data pointer provided
277s to `scipy.LowLevelCallable` as-is.
277s
277s The callback function must return an integer error status that is zero
277s if something went wrong and one otherwise. If an error occurs, you should
277s normally set the python error status with an informative message
277s before returning, otherwise a default error message is set by the
277s calling function.
277s
277s In addition, some other low-level function pointer specifications
277s are accepted, but these are for backward compatibility only and should
277s not be used in new code.
277s
277s Examples
277s --------
277s Import the necessary modules and load the example image used for
277s filtering.
277s
277s >>> import numpy as np
277s >>> from scipy import datasets
277s >>> from scipy.ndimage import zoom, generic_filter
277s >>> import matplotlib.pyplot as plt
277s >>> ascent = zoom(datasets.ascent(), 0.5)
277s
277s Compute a maximum filter with kernel size 5 by passing a simple NumPy
277s aggregation function as argument to `function`.
277s
277s >>> maximum_filter_result = generic_filter(ascent, np.amax, [5, 5])
277s
277s While a maximum filter could also directly be obtained using
277s `maximum_filter`, `generic_filter` allows generic Python function or
277s `scipy.LowLevelCallable` to be used as a filter. Here, we compute the
277s range between maximum and minimum value as an example for a kernel size
277s of 5.
277s
277s >>> def custom_filter(image):
277s ... return np.amax(image) - np.amin(image)
277s >>> custom_filter_result = generic_filter(ascent, custom_filter, [5, 5])
277s
277s Plot the original and filtered images.
277s
277s >>> fig, axes = plt.subplots(3, 1, figsize=(3, 9))
277s >>> plt.gray() # show the filtered result in grayscale
277s >>> top, middle, bottom = axes
277s >>> for ax in axes:
277s ... ax.set_axis_off() # remove coordinate system
277s >>> top.imshow(ascent)
277s >>> top.set_title("Original image")
277s >>> middle.imshow(maximum_filter_result)
277s >>> middle.set_title("Maximum filter, Kernel: 5x5")
277s >>> bottom.imshow(custom_filter_result)
277s >>> bottom.set_title("Custom filter, Kernel: 5x5")
277s >>> fig.tight_layout()
277s
277s """
277s if (size is not None) and (footprint is not None):
277s warnings.warn("ignoring size because footprint is set",
277s UserWarning, stacklevel=2)
277s if extra_keywords is None:
277s extra_keywords = {}
277s input = np.asarray(input)
277s if np.iscomplexobj(input):
277s raise TypeError('Complex type not supported')
277s axes = _ni_support._check_axes(axes, input.ndim)
277s num_axes = len(axes)
277s if footprint is None:
277s if size is None:
277s raise RuntimeError("no footprint or filter size provided")
277s sizes = _ni_support._normalize_sequence(size, num_axes)
277s footprint = np.ones(sizes, dtype=bool)
277s else:
277s footprint = np.asarray(footprint, dtype=bool)
277s
277s # expand origins, footprint if num_axes < input.ndim
277s footprint = _expand_footprint(input.ndim, axes, footprint)
277s origins = _expand_origin(input.ndim, axes, origin)
277s
277s fshape = [ii for ii in footprint.shape if ii > 0]
277s if len(fshape) != input.ndim:
277s raise RuntimeError(f"footprint.ndim ({footprint.ndim}) "
277s f"must match len(axes) ({num_axes})")
277s for origin, lenf in zip(origins, fshape):
277s if (lenf // 2 + origin < 0) or (lenf // 2 + origin >= lenf):
277s raise ValueError('invalid origin')
277s if not footprint.flags.contiguous:
277s footprint = footprint.copy()
277s output = _ni_support._get_output(output, input)
277s
277s mode = _ni_support._extend_mode_to_code(mode)
277s > _nd_image.generic_filter(input, function, footprint, output, mode,
277s cval, origins, extra_arguments, extra_keywords)
277s E TypeError: only 0-dimensional arrays can be converted to Python scalars
277s
277s /usr/lib/python3/dist-packages/scipy/ndimage/_filters.py:2420: TypeError
[CUT]
278s =========================== short test summary info ============================
278s FAILED tests/test_dask_image/test_ndfilters/test__generic.py::test_generic_filter_identity[<lambda>-1-None-generic_filter-generic_filter]
278s FAILED tests/test_dask_image/test_ndfilters/test__generic.py::test_generic_filter_identity[<lambda>-size1-None-generic_filter-generic_filter]
278s FAILED tests/test_dask_image/test_ndfilters/test__generic.py::test_generic_filter_identity[<lambda>-None-footprint2-generic_filter-generic_filter]
278s FAILED tests/test_dask_image/test_ndfilters/test__generic.py::test_generic_filter_comprehensions[generic_filter]
278s FAILED tests/test_dask_image/test_ndmeasure/test_core.py::test_measure_props[shape3-chunks3-True-0-median]
278s FAILED tests/test_dask_image/test_ndmeasure/test_core.py::test_measure_props[shape4-chunks4-True-1-median]
278s FAILED tests/test_dask_image/test_ndmeasure/test_core.py::test_measure_props[shape5-chunks5-True-ind5-median]
278s FAILED tests/test_dask_image/test_ndmeasure/test_core.py::test_measure_props[shape6-chunks6-True-ind6-median]
278s FAILED tests/test_dask_image/test_ndmeasure/test_core.py::test_measure_props[shape7-chunks7-True-ind7-median]
278s FAILED tests/test_dask_image/test_ndmeasure/test_core.py::test_measure_props[shape8-chunks8-True-ind8-median]
278s FAILED tests/test_dask_image/test_ndmeasure/test_core.py::test_measure_props[shape9-chunks9-True-ind9-median]
278s FAILED tests/test_dask_image/test_ndmeasure/test_core.py::test_measure_props[shape10-chunks10-True-ind10-median]
278s FAILED tests/test_dask_image/test_ndmeasure/test_core.py::test_measure_props[shape11-chunks11-True-ind11-median]
278s FAILED tests/test_dask_image/test_ndmeasure/test_core.py::test_measure_props[shape12-chunks12-True-ind12-median]
278s ==== 14 failed, 2159 passed, 175 skipped, 123 warnings in 74.39s (0:01:14) =====
Context: PR 425
@avalentino says...
Actually there are 4 more tests failing when I run the test suite against numpy 2.4.
I was planning to fix also those ones but I dint have time so far.
I will open a new PR if I manage for find a fix.
The full log is at: https://ci.debian.net/packages/d/dask-image/unstable/amd64/69506502/
Pease find below the relevant part:
Originally posted by @avalentino in #425 (comment)