Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ Built-in Numba JIT and CUDA projection kernels bypass pyproj for per-pixel coord
| [rechunk_no_shuffle](xrspatial/utils.py) | Rechunk dask arrays using whole-chunk multiples (no shuffle) | Custom | 🔼 | 🔼 | 🔼 | 🔼 |
| [fused_overlap](xrspatial/utils.py) | Fuse sequential map_overlap calls into a single pass | Custom | 🔼 | 🔼 | 🔼 | 🔼 |
| [multi_overlap](xrspatial/utils.py) | Run multi-output kernel in a single overlap pass | Custom | 🔼 | 🔼 | 🔼 | 🔼 |
| [validate](xrspatial/validate.py) | Check a raster against the xarray-spatial input contract (`.xrs.validate()`) | Custom | ✅ | 🔼 | 🔼 | 🔼 |

-----------

Expand Down
10 changes: 10 additions & 0 deletions docs/source/reference/utilities.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,13 @@ Diagnostics
:toctree: _autosummary

xrspatial.diagnostics.diagnose

Validation
==========
Check a raster against the xarray-spatial input contract. Also available
on the accessor as ``da.xrs.validate()`` and ``ds.xrs.validate()``.

.. autosummary::
:toctree: _autosummary

xrspatial.validate.validate
1 change: 1 addition & 0 deletions xrspatial/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
from xrspatial.terrain_metrics import roughness # noqa
from xrspatial.terrain_metrics import tpi # noqa
from xrspatial.terrain_metrics import tri # noqa
from xrspatial.validate import validate # noqa
from xrspatial.hydro import twi # noqa: unified wrapper
from xrspatial.hydro import twi_d8 # noqa
from xrspatial.polygon_clip import clip_polygon # noqa
Expand Down
46 changes: 46 additions & 0 deletions xrspatial/accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,30 @@ def multi_overlap(self, func, n_outputs, **kwargs):
from .utils import multi_overlap
return multi_overlap(self._obj, func, n_outputs, **kwargs)

# ---- Diagnostics ----

def validate(self, *, raise_on_error=False):
"""Check this DataArray against the xarray-spatial input contract.

Returns a :class:`~xrspatial.validate.ValidationReport` listing
every contract violation as an error (a spatial op will fail) or
a warning (behavior degrades), each with a suggested fix. The
report is truthy when there are no error-level issues, so
``if not da.xrs.validate(): ...`` reads naturally.

Parameters
----------
raise_on_error : bool, default False
If True, raise :class:`~xrspatial.validate.XrsContractError`
when any error-level issue is found instead of only
recording it in the report.
"""
from .validate import validate
report = validate(self._obj)
if raise_on_error:
report.raise_if_errors()
return report


@xr.register_dataset_accessor("xrs")
class XrsSpatialDatasetAccessor:
Expand Down Expand Up @@ -2116,6 +2140,28 @@ def rechunk_no_shuffle(self, **kwargs):
from .utils import rechunk_no_shuffle
return rechunk_no_shuffle(self._obj, **kwargs)

# ---- Diagnostics ----

def validate(self, *, raise_on_error=False):
"""Check each data variable against the xarray-spatial contract.

Returns a
:class:`~xrspatial.validate.DatasetValidationReport` holding a
per-variable :class:`~xrspatial.validate.ValidationReport`. The
report is truthy when every variable is compliant.

Parameters
----------
raise_on_error : bool, default False
If True, raise :class:`~xrspatial.validate.XrsContractError`
when any variable has an error-level issue.
"""
from .validate import validate_dataset
report = validate_dataset(self._obj)
if raise_on_error:
report.raise_if_errors()
return report


# ---------------------------------------------------------------------------
# Surface standalone-function docstrings on accessor methods so that, e.g.,
Expand Down
2 changes: 2 additions & 0 deletions xrspatial/tests/test_accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ def test_dataarray_accessor_has_expected_methods(elevation):
'rechunk_no_shuffle',
'fused_overlap',
'multi_overlap',
'validate',
]
for name in expected:
assert name in names, f"Missing method: {name}"
Expand All @@ -118,6 +119,7 @@ def test_dataset_accessor_has_expected_methods():
'proximity', 'allocation', 'direction', 'cost_distance',
'ndvi', 'evi', 'arvi', 'savi', 'nbr', 'sipi',
'rasterize',
'validate',
]
for name in expected:
assert name in names, f"Missing method: {name}"
Expand Down
Loading
Loading