Skip to content

refactor: extract the tail repeated in nine apply_transform methods - #63

Open
Hendrik-code wants to merge 1 commit into
hm/dedup-torchiofrom
hm/dedup-tails
Open

refactor: extract the tail repeated in nine apply_transform methods#63
Hendrik-code wants to merge 1 commit into
hm/dedup-torchiofrom
hm/dedup-tails

Conversation

@Hendrik-code

Copy link
Copy Markdown
Collaborator

Stacked on #62.

gpu/contrast.py ended nine of its apply_transform loops with the same three things, written out in full every time:

  1. capture the per-sample mean/std when retain_stats is set,
  2. restore them afterwards,
  3. run region selection, then drop the channel if the result went non-finite.

Those are _channel_stats, _restore_stats and _select_and_check now. −173 / +92.

How I know it changes nothing

Not by inspection. I pushed a fixed volume through all 24 shipped GPU configs under a fixed seed and hashed the output, before and after:

IDENTICAL: all 24 config digests unchanged

That matters more than the test suite passing here: the suite would not notice a reordered RNG draw, which is the realistic way to break this refactor. The per-transform loop structure is deliberately left alone rather than inverted into a callback — every draw in this file happens inside those loops, so keeping them means the consumption order is unchanged by construction.

A note on the helper signature

_select_and_check takes the transform itself, not its three region attributes. My first attempt spelled them out as keyword arguments and came to +224 / −174 — longer than the code it replaced, which is not a simplification. All nine call sites read exactly self.in_seg, self.out_seg and self.mix_in_out, so passing self is both shorter and more honest about the coupling that already existed.

Scope

The trainer tail — the same nnU-Net transform sequence repeated across eight get_training_transforms methods — is deliberately not in this PR. nnunetv2 is an optional extra and is not installed in CI, so that extraction cannot be verified the same way and deserves its own review. It's the next PR in the stack.

Testing

Five new tests in test_region_and_stats.py pin the extracted helpers directly (per-sample stats, round-tripping mean/std through _restore_stats, and _select_and_check rejecting a non-finite result while passing a finite one through).

Full suite: 105 passed, 200 subtests. ruff and mypy clean.

gpu/contrast.py ended nine of its apply_transform loops with the same three
things: capture the per-sample mean/std when retain_stats is set, restore them
afterwards, then run region selection and drop the channel if the result went
non-finite. Written out in full every time. That is _channel_stats,
_restore_stats and _select_and_check now: -173 lines, +92.

The per-transform loop structure is deliberately left alone rather than inverted
into a callback. Every draw in this file happens inside those loops, so keeping
them means the RNG consumption order is unchanged by construction, which is what
makes the claim below checkable.

Verified byte-for-byte rather than by inspection: pushing a fixed volume through
all 24 shipped GPU configs under a fixed seed and hashing the output gives
identical digests before and after. The test suite would not have caught a
reordered draw; this does.

_select_and_check takes the transform rather than its three region attributes.
All nine call sites read exactly self.in_seg, self.out_seg and self.mix_in_out,
and spelling them out as keyword arguments made the call longer than the code it
replaced -- the first attempt at this was +224/-174, which is not a
simplification.

The trainer tail (the same nnU-Net transform sequence in eight
get_training_transforms methods) is left for the next commit: nnunetv2 is an
optional extra and is not installed in CI, so that one cannot be verified the
same way and deserves its own review.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 20, 2026 12:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants