The polygonize() docstring says the mask parameter takes bool, integer, or float values ("Pixels to include should have mask values of 1 or True, pixels to exclude should have 0 or False"). Integer masks work on every raster dtype, but a float-dtype mask on a float-dtype raster crashes with a TypeError instead of polygonizing.
Reproduce
import numpy as np
import xarray as xr
from xrspatial.polygonize import polygonize
raster = xr.DataArray(np.array([[1.0, 1.0, 2.0],
[1.0, 3.0, 2.0],
[1.0, 1.0, 2.0]], dtype=np.float64))
mask = xr.DataArray(np.array([[1, 1, 1],
[1, 0, 1],
[1, 1, 1]], dtype=np.float64))
polygonize(raster, mask=mask)
TypeError: ufunc 'bitwise_and' not supported for the input types, and the
inputs could not be safely coerced to any supported types according to the
casting rule 'safe'
Cause
In _polygonize_numpy (xrspatial/polygonize.py:918) the float-raster branch runs mask = mask & nan_mask. & (bitwise_and) is undefined between a float array and the boolean nan_mask, so it raises. A bool or int mask coerces fine; a float one does not. The cupy and dask backends send float rasters through _polygonize_numpy, so they hit the same line.
A float mask on an integer raster is fine, because that branch never runs the mask & nan_mask line. Only the float-raster + float-mask combination breaks.
Possible fix
Cast the mask to bool before the &, e.g. mask = mask.astype(bool) & nan_mask. That matches the truthiness already used in _calculate_regions (mask[ij]).
Found during the deep-sweep test-coverage sweep. The companion test PR pins the integer-mask paths (which work today) and xfails the float-mask case against this issue.
The
polygonize()docstring says themaskparameter takes bool, integer, or float values ("Pixels to include should have mask values of 1 or True, pixels to exclude should have 0 or False"). Integer masks work on every raster dtype, but a float-dtype mask on a float-dtype raster crashes with a TypeError instead of polygonizing.Reproduce
Cause
In
_polygonize_numpy(xrspatial/polygonize.py:918) the float-raster branch runsmask = mask & nan_mask.&(bitwise_and) is undefined between a float array and the booleannan_mask, so it raises. A bool or int mask coerces fine; a float one does not. The cupy and dask backends send float rasters through_polygonize_numpy, so they hit the same line.A float mask on an integer raster is fine, because that branch never runs the
mask & nan_maskline. Only the float-raster + float-mask combination breaks.Possible fix
Cast the mask to bool before the
&, e.g.mask = mask.astype(bool) & nan_mask. That matches the truthiness already used in_calculate_regions(mask[ij]).Found during the deep-sweep test-coverage sweep. The companion test PR pins the integer-mask paths (which work today) and xfails the float-mask case against this issue.