aspect: test degenerate shapes and geodesic boundary modes#2746
Open
brendancol wants to merge 1 commit into
Open
aspect: test degenerate shapes and geodesic boundary modes#2746brendancol wants to merge 1 commit into
brendancol wants to merge 1 commit into
Conversation
Two test-coverage gaps from the deep-sweep pass, test-only: - Degenerate rasters (1x1, Nx1, 1xN) had no coverage. A 3x3 kernel has no interior cell below size 3, so the correct result is all-NaN with the input shape preserved. Added regression tests for aspect, northness, and eastness across numpy, cupy, dask+numpy, dask+cupy. - Geodesic boundary modes (nearest, reflect, wrap) were untested; only 'nan' ran. Added a numpy mode test plus numpy-vs-dask, cupy, and dask+cupy parity for the non-default modes. GPU-validated: all new cupy and dask+cupy cases ran and passed on a CUDA host.
brendancol
commented
May 30, 2026
Contributor
Author
brendancol
left a comment
There was a problem hiding this comment.
PR Review: aspect test coverage (degenerate shapes and geodesic boundary modes)
Test-only PR adding two missing coverage paths to the aspect module. No source changes.
Blockers
None.
Suggestions
One note for the record: in the degenerate-shape tests, the data[0, :] = 2.0 tweak only runs when shape[0] > 1, so the (1, 5) and (1, 3) cases feed a flat all-ones raster. The all-NaN assertion still holds there, but for the no-interior-cell reason rather than a flat-surface reason. That is the intended geometric edge case, so it is fine as written.
Nits
- The new
_to_numpyhelper in test_aspect.py duplicates the backend-unwrap logic that general_checks.py already does inline. Not worth extracting for three call sites, but it could fold into a shared helper later.
What looks good
- Both gaps are covered across all four backends (numpy, cupy, dask+numpy, dask+cupy) using the existing
create_test_rasterhelper and the standard skip decorators. - The cupy and dask+cupy cases ran on a CUDA host and passed, not just added behind a skip.
- Geodesic boundary tests assert the actual contract: non-default modes fill the edge ring,
nankeeps it NaN, plus numpy-vs-dask/cupy parity. - Dask chunks are clamped to the raster size for the degenerate shapes, so no chunk-larger-than-array warnings.
Checklist
- Algorithm matches reference: n/a (test-only)
- All implemented backends consistent: yes, parity asserted
- NaN handling correct: yes, that is what the tests check
- Edge cases covered: yes, that is the point of this PR
- Dask chunk boundaries handled: yes, chunks clamped
- No premature materialization: compute only at assertion time
- Benchmark: not needed (test-only)
- README matrix: not needed (no new function)
- Docstrings: n/a
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 #2742
Adds the two missing test paths the deep-sweep test-coverage pass found in the aspect module. Test-only; no source changes.
aspect,northness, andeastness. Below size 3 along a dimension the 3x3 kernel has no interior cell, so the correct output is all-NaN with the input shape preserved.nearest,reflect, andwrapare now exercised. Before this, onlyboundary='nan'ran through the geodesic path, leaving its lat/lon padding code untested.Backend coverage: both gaps are tested across numpy, cupy, dask+numpy, and dask+cupy. The cupy and dask+cupy cases were run and passed on a CUDA host (73 new cases, none skipped locally).
Test plan:
pytest xrspatial/tests/test_aspect.py xrspatial/tests/test_geodesic_aspect.py— 155 passed