perlin: preserve input x/y coordinates on the output#3470
Open
brendancol wants to merge 3 commits into
Open
Conversation
perlin() carried the input attrs (including crs/res) but built the result with dims=agg.dims and no coords, so a georeferenced input produced an output that kept its crs attribute with no coordinate values. Pass coords=agg.coords so the output stays consistent and downstream coord-based ops keep working. Verified on numpy, cupy, dask+numpy, and dask+cupy. Adds a regression test asserting coord pass-through. Records the perlin row in the sweep-metadata state CSV.
brendancol
commented
Jun 23, 2026
brendancol
left a comment
Contributor
Author
There was a problem hiding this comment.
PR Review: perlin: preserve input x/y coordinates on the output
Blockers (must fix before merge)
None.
Suggestions (should fix, not blocking)
- The new
test_perlin_preserves_coordsonly runs on numpy. The GPU and dask tests (test_perlin_gpu,test_perlin_dask_cpu,test_perlin_dask_gpu) build coord-less rasters, so nothing asserts coord pass-through on cupy/dask. The fix is in one shared wrap path so all backends behave the same, and it was verified manually, but a coord-bearing assertion on at least the dask backend would lock it in. Low priority.
Nits (optional improvements)
None.
What looks good
- One-line fix at the source of the bug (xrspatial/perlin.py:354): coords were dropped while attrs were kept, so the output claimed a crs with no coordinates.
coords=agg.coordsmatches how attrs are already handled. - Output shape always equals input shape (perlin writes into a same-shape buffer or rebuilds it), so coords align directly with no off-by-one or half-pixel risk.
- The numpy in-place write touches only
.data, not.coords, so reusingagg.coordsis safe. - Regression test uses
general_output_checksplus explicit coord-value and attrs assertions.
Checklist
- Algorithm unchanged; only result wrapping touched
- Four backends share the wrap path; coords verified on numpy/cupy/dask/dask+cupy
- NaN handling unchanged
- Coord pass-through covered on numpy; GPU/dask coverage relies on the shared path
- No premature materialization introduced
- No benchmark needed (no perf change)
- No README change needed (no API change)
- No new public API; docstring unchanged
brendancol
commented
Jun 23, 2026
brendancol
left a comment
Contributor
Author
There was a problem hiding this comment.
Follow-up review
The one suggestion from the prior pass is addressed: test_perlin_preserves_coords_dask now asserts coord pass-through on the dask backend with ragged chunks, alongside the numpy test. Full perlin suite passes (14 tests, GPU and dask+GPU ran live).
No remaining blockers, suggestions, or nits.
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.
Summary
perlin()carried the input's attrs (includingcrs/res) but built the result withdims=agg.dimsand nocoords. A georeferenced input produced an output that kept itscrsattribute while dropping the coordinate values, an internally inconsistent DataArray that breaks downstream coord-based ops (clip, interp, reproject).coords=agg.coordswhen constructing the result. The output has the same shape as the input, so coords align directly.Backend coverage
Verified on numpy, cupy, dask+numpy, and dask+cupy. The result is wrapped in one shared code path, so the fix applies to all four.
Test plan
test_perlin_preserves_coordsasserts x/y coords and attrs pass throughpytest xrspatial/tests/test_perlin.py-- 13 passed (GPU and dask+GPU tests ran live)Note: GitHub issues are disabled on the source fork, so this PR has no linked issue. Found by the metadata propagation sweep.