Describe the issue
The five edge detection functions (sobel_x, sobel_y, prewitt_x, prewitt_y, laplacian) propagate input NaNs: any output cell whose 3x3 neighborhood contains a NaN becomes NaN. This is intentional (TestNanHandling::test_nan_in_input_propagates pins it down) and behaves the same on all four backends, but none of the five docstrings mention it. Run edge detection on a raster with sparse nodata and you get a 3x3 NaN blot around every nodata cell, with nothing in the docs explaining where it came from.
Reproduction
import numpy as np
import xarray as xr
from xrspatial.edge_detection import sobel_x
data = np.ones((5, 6), dtype=np.float64)
data[2, 3] = np.nan
result = sobel_x(xr.DataArray(data, dims=['y', 'x']), boundary='reflect')
print(np.isnan(result.data).sum()) # 9 -- one NaN in, nine NaN out
Same 3x3 footprint on numpy, dask+numpy, cupy, and dask+cupy.
Expected behavior
The docstrings should say that NaN cells propagate to their 3x3 neighborhood, and that with the default boundary='nan' the outer one-cell ring of the output is also NaN.
Found during an error-handling audit of xrspatial/edge_detection.py.
Describe the issue
The five edge detection functions (
sobel_x,sobel_y,prewitt_x,prewitt_y,laplacian) propagate input NaNs: any output cell whose 3x3 neighborhood contains a NaN becomes NaN. This is intentional (TestNanHandling::test_nan_in_input_propagatespins it down) and behaves the same on all four backends, but none of the five docstrings mention it. Run edge detection on a raster with sparse nodata and you get a 3x3 NaN blot around every nodata cell, with nothing in the docs explaining where it came from.Reproduction
Same 3x3 footprint on numpy, dask+numpy, cupy, and dask+cupy.
Expected behavior
The docstrings should say that NaN cells propagate to their 3x3 neighborhood, and that with the default
boundary='nan'the outer one-cell ring of the output is also NaN.Found during an error-handling audit of
xrspatial/edge_detection.py.