Describe the bug
The direct reader backends default to masking nodata, but the public open_geotiff defaults to unmasked reads. Call a backend directly with no mask_nodata argument and you get a different dtype and different values than open_geotiff returns. The divergence is silent.
open_geotiff sets masked: bool = False and documents rioxarray-compatible unmasked reads. The wrapper forwards mask_nodata=masked to the backends explicitly on every dispatch path (GPU, dask, VRT, eager). But the three backend entry points each keep mask_nodata: bool = True as their own default:
_read_geotiff_dask in xrspatial/geotiff/_backends/dask.py
_read_geotiff_gpu in xrspatial/geotiff/_backends/gpu.py
_read_vrt in xrspatial/geotiff/_backends/vrt.py
To Reproduce
A public chunked read returns int16 with -9999 preserved (unmasked). A direct _read_geotiff_dask() call on the same file returns float64 with NaN (masked). Same split for _read_geotiff_gpu and _read_vrt.
Expected behavior
A bare backend call with no mask_nodata argument should match open_geotiff: keep the source dtype, preserve the nodata sentinel, don't substitute NaN. The three backend defaults should be False.
Additional context
The public wrapper always passes mask_nodata=masked explicitly, so the default only affects direct callers. The internal callers (GPU-to-dask fallback, dask-to-VRT dispatch) forward the value explicitly too, so flipping the default only touches code that calls a backend directly without the kwarg.
Describe the bug
The direct reader backends default to masking nodata, but the public
open_geotiffdefaults to unmasked reads. Call a backend directly with nomask_nodataargument and you get a different dtype and different values thanopen_geotiffreturns. The divergence is silent.open_geotiffsetsmasked: bool = Falseand documents rioxarray-compatible unmasked reads. The wrapper forwardsmask_nodata=maskedto the backends explicitly on every dispatch path (GPU, dask, VRT, eager). But the three backend entry points each keepmask_nodata: bool = Trueas their own default:_read_geotiff_daskinxrspatial/geotiff/_backends/dask.py_read_geotiff_gpuinxrspatial/geotiff/_backends/gpu.py_read_vrtinxrspatial/geotiff/_backends/vrt.pyTo Reproduce
A public chunked read returns int16 with -9999 preserved (unmasked). A direct
_read_geotiff_dask()call on the same file returns float64 with NaN (masked). Same split for_read_geotiff_gpuand_read_vrt.Expected behavior
A bare backend call with no
mask_nodataargument should matchopen_geotiff: keep the source dtype, preserve the nodata sentinel, don't substitute NaN. The three backend defaults should beFalse.Additional context
The public wrapper always passes
mask_nodata=maskedexplicitly, so the default only affects direct callers. The internal callers (GPU-to-dask fallback, dask-to-VRT dispatch) forward the value explicitly too, so flipping the default only touches code that calls a backend directly without the kwarg.