Expose coregistered reads through the xarray engine via like= (#3376)#3377
Merged
Conversation
Add a like= backend kwarg to the xrspatial engine. When supplied, the engine routes the read through like's .xrs.open_geotiff accessor, so coregister / auto_reproject / resampling / var become available through xr.open_dataset and open_mfdataset. Without like=, those kwargs raise a pointed ValueError instead of the standalone reader's opaque TypeError.
brendancol
commented
Jun 17, 2026
brendancol
left a comment
Contributor
Author
There was a problem hiding this comment.
PR Review: Expose coregistered reads through the xarray engine via like=
Blockers (must fix before merge)
None.
Suggestions (should fix, not blocking)
_xarray_backend.py:106— whenlikeis not a DataArray or Dataset (say a path or a bare numpy array),like.xrsraises a genericAttributeError, which is harder to read than the pointedValueErrorthe no-likepath gives. A shortisinstance(like, (xr.DataArray, xr.Dataset))guard with a clear message would round out the error handling.
Nits (optional improvements)
_xarray_backend.py:110-115— when the only offending kwarg isvar, the message ("reproject/resample a source onto a target grid") doesn't quite fit, sincevarjust selects the inference variable on a Dataset target. Thelike=pointer is still correct, so this is cosmetic.
What looks good
- The routing is a thin wrapper:
likepresent → accessor, else standalone, with the variable-naming anddrop_variablespromotion shared across both paths. No duplicated read logic. - Tests assert parity against the accessor output rather than just "it runs", and cover same-CRS, CRS-mismatch reproject, Dataset
var=, naming,open_mfdataset, the per-kwarg guard, and the inherited GPU rejection. - GPU /
.vrt/allow_rotatedrejections are inherited from the accessor instead of being re-implemented, so they can't drift out of sync. open_dataset_parametersis left untouched, soliketravels throughbackend_kwargslike the other read options and doesn't trip xarray's CF decoder collision.
Checklist
- Routing matches the accessor (parity asserted in tests)
- All implemented backends consistent (CPU-only path; GPU rejection inherited)
- NaN handling unchanged (delegated to accessor)
- Edge cases covered by tests (guards, naming, mfdataset)
- Dask path exercised via
open_mfdataset - No premature materialization or extra copies
- Benchmark not needed (thin routing wrapper)
- README feature matrix not applicable (no new function)
- Docstrings / docs updated
- Raise TypeError when like= is not a DataArray/Dataset, instead of an opaque AttributeError on .xrs. - Reword the no-like guard so it reads correctly for var= too.
brendancol
commented
Jun 17, 2026
brendancol
left a comment
Contributor
Author
There was a problem hiding this comment.
Follow-up review (after 7f47195)
Both findings from the first pass are addressed:
- Suggestion (like= type guard) — fixed.
_xarray_backend.py:102-107now raisesTypeErrornaming the expected type whenlikeis not a DataArray/Dataset, instead of falling through to anAttributeErroron.xrs. Covered bytest_non_array_like_raises_typeerror. - Nit (guard wording) — fixed.
_xarray_backend.py:117-122reads "only apply when reading onto a target grid", which fitsvaras well as the reproject/resample kwargs.
No new issues. Tests: 15 coregister cases plus the 17 existing backend tests pass locally.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3376.
Adds a
like=backend kwarg to thexrspatialxarray engine. When you pass it, the engine routes the read throughlike's.xrs.open_geotiffaccessor instead of the standalone reader, so the coregistered-read options work through the standardxr.open_dataset/open_mfdatasetAPI.What changed
like=(a DataArray or Dataset) triggers the coregister path.coregister,auto_reproject,resampling, andvarare forwarded to the accessor.likedispatches to the Dataset accessor, sovar=picks the variable used for backend/CRS inference.default_name/ source-stem rule as the plain engine path.open_mfdatasetwith a sharedlike=coregisters every source onto one grid in a single call..vrt/allow_rotatedrejections apply through the engine without extra code.coregister/auto_reproject/resampling/varwithoutlike=raises aValueErrorthat nameslike=, instead of the opaqueTypeErrorthe standalone reader would throw for an unknown kwarg.Design decisions
The issue left two questions open. I went with
like=for the kwarg name (the issue's first option, and it matches thexr.zeros_like/ones_likeconvention), and madelike=the trigger: the coregister kwargs without it raise the pointed error rather than silently doing nothing.Backend coverage
The coregister path is CPU-only (numpy and dask+numpy). GPU and
.vrtsources already raise on the accessor, and the engine inherits that. The plain read path's backend support is unchanged.Test plan
likewithvar=default_nameoverride)open_mfdatasetcoregisters two files onto one gridValueErrorfor each coregister kwarg passed withoutlike=