Fix split sub-volume affine origins for s02 and s03#561
Closed
mhalle wants to merge 4 commits intowasserth:masterfrom
Closed
Fix split sub-volume affine origins for s02 and s03#561mhalle wants to merge 4 commits intowasserth:masterfrom
mhalle wants to merge 4 commits intowasserth:masterfrom
Conversation
When splitting a large image into three parts along the z-axis, all three sub-volumes were saved with the same affine from the original image. Parts s02 and s03 start at deeper z-offsets, so their affine origin must be shifted accordingly. Compute the world-space origin offset for each sub-volume by multiplying the starting voxel index by the affine's z-column vector, then adjust the translation component of each part's affine. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The previous commit corrected the affine origin on the split input files (s02_0000/s03_0000), but the multimodel merge path still saved the per-part prediction outputs with img_in_rsp.affine, overwriting the corrected origins on s02.nii.gz and s03.nii.gz. Build a part_affines dict and use the correct per-part affine when saving merged predictions, so sub-volume metadata is consistent from split through merge. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tests verify: - s01 origin is unchanged, s02/s03 origins are shifted correctly - voxel-to-world mapping is consistent between parts and original - correction works with rotated (off-diagonal) affines - split/reassemble roundtrip preserves data exactly - affines written to disk match expected values Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract split_image_into_parts(), save_merged_predictions(), and reassemble_image() from inline code in nnUNet_predict_image() so they can be tested directly. Rewrite test_split_affine.py to import and call these production functions instead of local reimplementations. The key addition is TestSaveMergedPredictions::test_merged_outputs_have_correct_affines, which exercises the exact code path that previously regressed (merged predictions being saved with the wrong affine). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Owner
|
Thank you for these PRs. I will check them as soon as possible. |
Contributor
Author
|
Sure. Most of them are very focused and straightforward.
… On Mar 27, 2026, at 12:33 PM, Jakob Wasserthal ***@***.***> wrote:
wasserth left a comment (wasserth/TotalSegmentator#561)
Thank you for these PRs. I will check them as soon as possible.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you authored the thread.Message ID: ***@***.***>
|
Owner
|
Thank you again for these PRs. The PRs are very valuable and I merge all except for this one. This one is not needed since TotalSEgmentator splits and combines the image while ignoring the offset. Therefore, we do not have to correct for it. |
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
start_index * affine[:3, 2](the z-column vector), and carry the corrected affines through the merge step.split_image_into_parts(),save_merged_predictions(), andreassemble_image()as standalone functions so the split/merge logic is testable without nnU-Net or GPU.tests/mock_imports.pycontext manager for importing modules with heavy dependencies mocked, with full sys.modules cleanup.Test plan
test_split_affine.py— verifies affine origins for all parts, voxel-to-world consistency, rotated affines, merged prediction affines (the regression path), roundtrip data integrity, and sys.modules cleanuptest_mock_imports.py— verifies mock injection, removal, transitive cleanup, and pre-existing module preservationforce_split=Trueon a test image and verify predictions are consistent with non-split inference🤖 Generated with Claude Code