Fix clip_domain broadcasting error for extents strictly inside the domain#558
Open
martinguthrie93 wants to merge 2 commits into
Open
Fix clip_domain broadcasting error for extents strictly inside the domain#558martinguthrie93 wants to merge 2 commits into
martinguthrie93 wants to merge 2 commits into
Conversation
clip_domain determined the source and destination copy windows
independently, using strict pixel-center comparisons against two
different reference boxes (the requested extent vs. the full source
domain). Whenever the requested extent lay strictly inside the source
domain, the two windows could end up with different sizes, raising
ValueError: could not broadcast input array from shape (a,b)
into shape (c,d)
The previous tests only exercised extents whose edge coincided with the
source domain boundary, which happened to produce matching window sizes,
so the bug went unnoticed.
Because clip_domain preserves the pixel size, clipping is an
integer-pixel window operation. Recompute it from a single pixel offset
between the clipped grid and the source array, so the source and
destination windows always match in size. This also makes extents that
extend beyond the source domain pad with the zero value instead of
raising, and keeps the returned metadata consistent with the pixel grid.
Add regression tests for interior clips (both yorigin conventions),
out-of-domain padding, and the returned metadata.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove the unused `x2` local (unused-variable) and drop the `num, nt, ny, nx = R.shape` unpacking in favour of indexing `R.shape` directly, which keeps the local-variable count at or below the previous implementation. No behavioural change; all clip_domain tests still pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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
Fixes #557.
pysteps.utils.dimension.clip_domainraisedwhenever the requested clipping extent lay strictly inside the source domain. Since
clip_domainis the standard way to crop a precipitation field to a geographic bounding box, any workflow that clips to an interior region of interest hit this.Root cause
The source and destination copy windows were computed independently, using strict pixel-center comparisons (
x_coord < right_/> left_) against two different reference boxes (the requested extent vs. the full source domain). When the extent was strictly interior, the strict comparison dropped a pixel on one side and the two windows ended up with different sizes, so the final assignment failed to broadcast.The previous tests only used extents whose edge coincided with the source-domain boundary, a special case where the window sizes happened to match, so the bug went unnoticed.
Fix
Because
clip_domainpreserves the pixel size, clipping is an integer-pixel window operation. The window is now recomputed from a single pixel offset between the clipped grid and the source array (col_offset/row_offset, the latter accounting for theyoriginconvention), so the source and destination windows always match in size.Additional benefits of the offset-based formulation:
metadata["zerovalue"]instead of raising;x1,x2,y1,y2) stays consistent with the clipped pixel grid and preserves the pixel size.For the fully-contained case used elsewhere in the test suite (e.g. the 512x512 MCH clip in
helpers.py), the returned array is byte-for-byte identical to the previous behaviour.Tests
pysteps/tests/test_utils_dimension.py:yorigin="upper"andyorigin="lower";All existing
clip_domaincases still pass, andblackreports no changes.