fix(origin): correct the map window at +180 and after rotating back - #142
Merged
Merged
Conversation
Two defects in the map-origin feature, both on the dycore (np4) path. Setting the origin to +180 blanked the map. EAMCenterMeridian's passthrough shortcut tested the origins modulo a turn, so with the dycore reader's [-180, 180) input a +180 origin looked like a window already in place and the filter did nothing. A window a whole turn away covers the same meridians but names them 360 degrees apart, and everything downstream reads coordinates, not residues: EAMProject then subtracted a full turn and clipped, collapsing the mesh onto the left rim. The passthrough now requires the two origins to match exactly, and a whole-turn offset takes a new branch in the rebuild -- the cut would land on the window's own edge and leave one side empty, so the mesh is simply translated rather than clipped. That is also ~14x cheaper per tick than the clip path it replaces. Rotating away, cropping latitude and rotating back to -180 produced a mesh cropped along the wrong cells. EAMExtract validated its cell-centre cache by comparing modified times, which only order events within one object; upstream legitimately hands back an *older* object than the cache was built from, because EAMCenterMeridian passes the reader's own points straight through once the map is back in the reader's window. Centres computed from the rotated mesh therefore looked fresh against the unrotated one, and the ghost mask was applied to a mesh it was not computed for. The cell-centre and output caches are now keyed on the identity of the geometry they were built from, plus the crop ranges, with a strong reference held so no other object can land on those addresses -- the same anchoring EAMProject already uses. Also lets SetMeridian drop the cached output, as SetLongitudeOrigin already does; it sets the same state and had the same staleness hole. Verified by sweeping 14 origin/crop combinations, including +/-180, +/-179 and seam-crossing crops, on both ne30np4 and ne30pg2, comparing point/cell counts and bounds against a freshly built pipeline at the same settings: all 28 match, and every stage still takes its cache-hit branch on a slicing tick.
Collaborator
Author
|
@jourdain can you review? |
jourdain
approved these changes
Sep 22, 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.
Two defects in the map-origin feature, both on the dycore (np4) path.
Setting the origin to +180 blanked the map. EAMCenterMeridian's passthrough shortcut tested the origins modulo a turn, so with the dycore reader's [-180, 180) input a +180 origin looked like a window already in place and the filter did nothing. A window a whole turn away covers the same meridians but names them 360 degrees apart, and everything downstream reads coordinates, not residues: EAMProject then subtracted a full turn and clipped, collapsing the mesh onto the left rim. The passthrough now requires the two origins to match exactly, and a whole-turn offset takes a new branch in the rebuild -- the cut would land on the window's own edge and leave one side empty, so the mesh is simply translated rather than clipped. That is also ~14x cheaper per tick than the clip path it replaces.
Rotating away, cropping latitude and rotating back to -180 produced a mesh cropped along the wrong cells. EAMExtract validated its cell-centre cache by comparing modified times, which only order events within one object; upstream legitimately hands back an older object than the cache was built from, because EAMCenterMeridian passes the reader's own points straight through once the map is back in the reader's window. Centres computed from the rotated mesh therefore looked fresh against the unrotated one, and the ghost mask was applied to a mesh it was not computed for. The cell-centre and output caches are now keyed on the identity of the geometry they were built from, plus the crop ranges, with a strong reference held so no other object can land on those addresses -- the same anchoring EAMProject already uses.
Also lets SetMeridian drop the cached output, as SetLongitudeOrigin already does; it sets the same state and had the same staleness hole.
Verified by sweeping 14 origin/crop combinations, including +/-180, +/-179 and seam-crossing crops, on both ne30np4 and ne30pg2, comparing point/cell counts and bounds against a freshly built pipeline at the same settings: all 28 match, and every stage still takes its cache-hit branch on a slicing tick.