Integrate subject mapping and exact replay - #1503
Conversation
📖 Docs PreviewPreview of the documentation for this PR: 🔗 https://smokeshow.helpmanual.io/6j3t43153s2y2a1g066r/ Built from 1c8b785 |
There was a problem hiding this comment.
Pull request overview
This PR extends TorchIO’s batching/transform infrastructure to support exact parameter replay and per-subject mapping within batches, and updates adapter implementations to use the new batch mapping lifecycle while tightening probability semantics (p=0 is always a no-op).
Changes:
- Add
Transform.apply_with_params()and refactorTransform.forward()through a shared execution path that supports exact replay without sampling. - Add
SubjectsBatch.map_subjects()to apply per-subject callbacks (with optional tensor cloning) and rebuild batches with schema validation. - Update MONAI/Cornucopia adapters and select transforms to reject exact replay where it’s incompatible, and standardize strict
p=0behavior (including lazyCropOrPad).
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_transforms_base.py | Adds coverage for apply_with_params() replay, history behavior, and batched-param validation. |
| tests/test_monai_adapter.py | Adds adapter tests for metadata updates, history/annotation preservation, strict p=0, and in-place behavior. |
| tests/test_crop_or_pad.py | Updates probability test to ensure p=0 is a strict no-op even when RNG draws 0. |
| tests/test_cornucopia_adapter.py | Adds adapter tests for history/annotations, strict p=0, result validation, and in-place behavior. |
| tests/test_batch.py | Adds coverage for SubjectsBatch.map_subjects() schema, history retention, and copy semantics. |
| src/torchio/transforms/transform.py | Introduces apply_with_params(), shared _execute() lifecycle, and batched-param validation helpers. |
| src/torchio/data/batch.py | Implements SubjectsBatch.map_subjects() built on unbatch() + rebuild with schema checks. |
| src/torchio/transforms/monai_adapter.py | Refactors adapter to use map_subjects() and validates dict-transform outputs/metadata updates. |
| src/torchio/transforms/cornucopia_adapter.py | Refactors adapter to use map_subjects() and validates result arity/types. |
| src/torchio/transforms/spatial/crop_or_pad.py | Makes lazy probability check strict (>=) and disables apply_with_params(). |
| src/torchio/transforms/spatial/ensure_shape_multiple.py | Disables apply_with_params() for this spatial transform. |
| src/torchio/transforms/compose.py | Disables apply_with_params() for composition/transforms with incompatible replay semantics. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
f992093 to
c49206f
Compare
bde5bcd to
dc67be7
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
src/torchio/transforms/transform.py:480
- In
_build_history_traces,_batched_keysbeing present implicitly means batched bookkeeping is active, but_batch_sizeis only read viaparams.get(...). If a custom transform returns_batched_keyswithout a valid_batch_size, the current error becomesParameter batch size None does not match input batch size ..., which is misleading and doesn’t catch non-int/bool values. Consider validating_batch_sizehere (similar to_get_expected_batch_size) to produce a clear error for transform authors.
expected_size = params.get("_batch_size")
if expected_size != batch_size:
msg = (
f"Parameter batch size {expected_size} does not match"
f" input batch size {batch_size}"
dc67be7 to
4ff3671
Compare
9d4a1f0 to
a2250fc
Compare
4ff3671 to
1936a5a
Compare
a2250fc to
61c539c
Compare
1936a5a to
813693a
Compare
61c539c to
fa4ffb3
Compare
11d47fe to
c5f8d49
Compare
9823221 to
80f7b1a
Compare
c5f8d49 to
77a7350
Compare
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: baf5f11a-f67c-44dc-804e-6be849fa9160
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: baf5f11a-f67c-44dc-804e-6be849fa9160
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: baf5f11a-f67c-44dc-804e-6be849fa9160
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: baf5f11a-f67c-44dc-804e-6be849fa9160
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: baf5f11a-f67c-44dc-804e-6be849fa9160
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: baf5f11a-f67c-44dc-804e-6be849fa9160
99ae9a8 to
1c8b785
Compare
[Generated by a coding agent]
What
Integrate subject-wise mapping, exact parameter replay, and MONAI/Cornucopia adapters with the simplified batch model.
Why
Non-vectorizable operations need a supported per-subject path, and exact replay must retain the normal copy/wrap/history lifecycle. Adapters previously duplicated unbatch/rebatch code and silently ignored unsupported outputs.
How
SubjectsBatch.map_subjects(copy=...)Transform.apply_with_params()through the shared execution pathp=0behavior, including lazyCropOrPadValidation
Replacement stack