Repository navigation
fix(spatial): accept [time, 1, lat, lon] singleton-depth arrays in polygon reader - #19
Merged
Merged
Conversation
…lygon reader Hydrodynamic current fields (current_vel, current_dir) from hidro/Delft3D datasets carry a degenerate depth dim of size 1 — shape [time, 1, lat, lon]. readPolygon / resolvePolygonCells required the array rank to match the layout exactly (2d/1d => rank 3), so these fields were rejected outright and dropped from area-aggregated reads. assertArrayRank now accepts rank = expected + k when the k middle dims (between the leading time axis and the trailing spatial dims) are all size 1, returning k; readPolygon selects index 0 for each, collapsing the dim so the block stays C-order [rows, cols] and the mask gather is untouched. A non-singleton middle dim still throws SliceError, now stating the size-1 rule. npoints (rank 2) and plain rank-3 behavior are unchanged. Closes #18
There was a problem hiding this comment.
Pull request overview
This PR updates the polygon reader to accept Zarr arrays that include one or more degenerate (size-1) middle dimensions between the leading time axis and trailing spatial axes (e.g. hydrodynamic fields shaped [time, 1, lat, lon]), collapsing those singleton dims deterministically by selecting index 0.
Changes:
- Extend
assertArrayRankto allowrank = expected + kwhen thek“middle” dims are all size1, and to throw a clearerSliceErrorwhen any middle dim is non-singleton. - Update
readPolygonto inject index-0selections for each singleton middle dim so per-step reads stream identically to the equivalent rank-3 arrays. - Add unit tests covering
[time, 1, lat, lon],[time, 1, 1, lat, lon],2dlayouts with singleton depth, and rejection of non-singleton middle dims; document the fix in the changelog.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/spatial/polygon-reader.ts |
Allows and collapses singleton middle dims during per-timestep polygon reads; improves rank-validation error messaging. |
tests/unit/polygon-reader.test.ts |
Adds coverage for singleton-middle-dim acceptance and ensures non-singleton middle dims still throw with the new rule. |
CHANGELOG.md |
Documents the polygon-reader fix for singleton-depth arrays and references issue #18. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
brandao-andre
approved these changes
Jul 14, 2026
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
Accept arrays with degenerate size-1 "middle" dims between the time axis and the
trailing spatial dims in the polygon reader — e.g.
[time, 1, lat, lon].assertArrayRanknow acceptsrank = expected + kwhen thekmiddle dimsare all size 1, and returns
k. A non-singleton middle dim (a genuinemulti-level axis, e.g. a depth profile) still throws
SliceError, now with amessage stating the size-1 rule.
readPolygonselects index0for each singleton middle dim in the per-stepread, collapsing the dim. The block stays C-order over
[rows, cols], so themask gather (
values[localR * rowStride + localC]) is untouched.(i4sea-aurora-ui#768).
npoints(rank 2) and plain rank-3 behavior unchanged.Motivation
Closes #18. Hydrodynamic current fields (
current_vel,current_dir) fromhidro/Delft3D datasets carry a degenerate depth dim of size 1 — shape
[time, 1, lat, lon]. The polygon reader asserted an exact rank match(
2d/1d⇒ rank 3), so these fields could not stream through it at all and wereskipped-with-warn consumer-side. That meant WATER_FLOW area meteograms served
water_levelbut lost the current speed + direction pair — a product-visiblegap, since direction-over-speed is a headline of that feature (i4sea-aurora-ui
spec 058 / #1049).
Index-0 selection of a size-1 dim is deterministic (one element), so no new API
surface is needed. An explicit per-dim selection (for non-singleton middle dims,
e.g. picking a depth level) would be a separate, bigger feature and is out of
scope here.
Test Plan
singleton middle dimssuite:[time, 1, lat, lon]streams identically to the equivalent rank-3 array(cells/bbox/stride/values);
2dlayout with a leading singleton depth dim;two singleton middle dims (
[time, 1, 1, lat, lon]); a non-singleton middledim (
[time, 3, lat, lon]) still throws with the size-1 rule in the message.npm test) — 391 passed; the one failings3-storetest is pre-existing and unrelated (missing optional peer@smithy/node-http-handlerin this environment), confirmed viagit stash.