Skip to content

Finished feature for test_set_split - #446

Merged
JoshuaSiraj merged 2 commits into
bhklab:JoshuaSiraj/nnunet_updatesfrom
kellofoggs:kelly/test_set_size
Jun 29, 2026
Merged

JoshuaSiraj merged 2 commits into
bhklab:JoshuaSiraj/nnunet_updatesfrom
kellofoggs:kelly/test_set_size

Conversation

@kellofoggs

@kellofoggs kellofoggs commented Jun 29, 2026 •

Copy link
Copy Markdown

Hi sorry issue took a little while, but I wrote up a minimal way of implementing a test_set_split for nnunet-pipeline.

The feature takes the successfully processed images and moves a proportion of the images/labels to the appropriate dirs in the output dir. I could not find any tests for nnunet-pipeline but this should probably be added to them when they're ready. There is CLI support for the feature as well as hints. Please let me know if there's anything II should change style wise.

Fixes #443

Summary by CodeRabbit

  • New Features

    • Added a test-set-ratio option to the command-line workflow, letting you split a portion of successfully processed data into a test set.
    • The pipeline now automatically moves the selected files into the appropriate test folders after processing.
  • Bug Fixes

    • Added validation for the new ratio value to keep it within a valid range and prevent invalid dataset splits.

@coderabbitai

coderabbitai Bot commented Jun 29, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@kellofoggs, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 42 minutes

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable usage-based reviews in Billing to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information, and refer to the rate limits docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9ff5d2ba-57a7-438e-8144-fda7cfe1cb6e

📥 Commits

Reviewing files that changed from the base of the PR and between d6e6818 and 513888d.

📒 Files selected for processing (1)
  • src/imgtools/io/nnunet_output.py
📝 Walkthrough

Walkthrough

Adds a test_set_ratio parameter to the nnUNet pipeline that splits a proportion of successfully processed samples into imagesTs/labelsTs directories. The parameter is exposed via a CLI option, validated in the pipeline constructor, and applied by new split_dataset and _move_file_to_test_split methods on nnUNetOutput.

nnUNet Test Set Partitioning

Layer / File(s) Summary
nnUNetOutput split logic
src/imgtools/io/nnunet_output.py
Adds _move_file_to_test_split (validates source dir against a map, constructs *Ts destination, moves files) and split_dataset (samples ceil(ratio × n) results, calls the helper for each output file to relocate from *Tr to *Ts).
Pipeline constructor and run() wiring
src/imgtools/nnunet_pipeline.py
nnUNetPipeline.__init__ accepts test_set_ratio: float = 0.0, raises ValueError when negative, clamps to 1. run() calls self.output.split_dataset(self.test_set_ratio, successful_results) after parallel processing completes.
CLI --test-set-ratio option
src/imgtools/cli/nnunet_pipeline.py
Adds --test-set-ratio Click option with FloatRange(0.0, 1.0), default 0.0, and passes it into the nnUNetPipeline constructor.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and clearly points to the new test set split feature.
Linked Issues check ✅ Passed The PR adds nnunet-pipeline test-set partitioning and imagesTs/labelsTs output handling as requested in #443.
Out of Scope Changes check ✅ Passed The changes appear focused on the requested test set split feature and related CLI wiring.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/imgtools/io/nnunet_output.py (1)

311-318: 🗄️ Data Integrity & Integration | 🔵 Trivial | 💤 Low value

Clarify that labelsTs is a local bookkeeping folder. nnU-Net doesn’t consume it as part of the raw dataset layout, so a short note here would keep readers from assuming it’s required or used downstream.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/imgtools/io/nnunet_output.py` around lines 311 - 318, Add a brief inline
note near the dir_map setup in the nnunet output handling logic to clarify that
labelsTs is only used as a local bookkeeping destination and is not part of the
nnU-Net raw dataset layout consumed downstream. Keep the guidance close to the
relevant logic in the split/move flow around the successful_results test_set
handling so readers understand the purpose of labelsTs without changing
behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/imgtools/cli/nnunet_pipeline.py`:
- Around line 126-130: The help text for the --test-set-ratio option in the
click option definition is misleading because split_dataset() applies the ratio
to processed samples (successful_results), not raw image files. Update the help
string near the CLI option in nnunet_pipeline.py to describe the split as being
based on processed samples/output results rather than “valid images,” keeping
the wording aligned with the actual behavior of split_dataset().

In `@src/imgtools/io/nnunet_output.py`:
- Around line 313-315: The split logic in finalize_dataset() can place every
successful sample into test_set, leaving imagesTr empty and breaking training.
Adjust the test_set selection so it always leaves at least one successful case
in the training split, by capping the sampled test count below success_count
when success_count is nonzero. Use the existing success_count, test_set_ratio,
and random_sample logic in finalize_dataset() to implement the safeguard.

---

Nitpick comments:
In `@src/imgtools/io/nnunet_output.py`:
- Around line 311-318: Add a brief inline note near the dir_map setup in the
nnunet output handling logic to clarify that labelsTs is only used as a local
bookkeeping destination and is not part of the nnU-Net raw dataset layout
consumed downstream. Keep the guidance close to the relevant logic in the
split/move flow around the successful_results test_set handling so readers
understand the purpose of labelsTs without changing behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e9b0dc9e-6924-4926-a133-2400b3b97c1b

📥 Commits

Reviewing files that changed from the base of the PR and between b53e726 and d6e6818.

📒 Files selected for processing (3)
  • src/imgtools/cli/nnunet_pipeline.py
  • src/imgtools/io/nnunet_output.py
  • src/imgtools/nnunet_pipeline.py

Comment on lines +126 to +130
@click.option(
"--test-set-ratio",
type=click.FloatRange(0.0,1.0),
default=0.0,
help="The proportion of valid images that are to be used in the test set.",

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Align the help text with the actual split unit.

split_dataset() applies the ratio to processed samples (successful_results), not individual image files, so this wording is misleading when one sample produces multiple outputs.

Suggested change
-    help="The proportion of valid images that are to be used in the test set.",
+    help="The proportion of successfully processed samples to place in the test set.",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@click.option(
"--test-set-ratio",
type=click.FloatRange(0.0,1.0),
default=0.0,
help="The proportion of valid images that are to be used in the test set.",
`@click.option`(
"--test-set-ratio",
type=click.FloatRange(0.0,1.0),
default=0.0,
help="The proportion of successfully processed samples to place in the test set.",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/imgtools/cli/nnunet_pipeline.py` around lines 126 - 130, The help text
for the --test-set-ratio option in the click option definition is misleading
because split_dataset() applies the ratio to processed samples
(successful_results), not raw image files. Update the help string near the CLI
option in nnunet_pipeline.py to describe the split as being based on processed
samples/output results rather than “valid images,” keeping the wording aligned
with the actual behavior of split_dataset().

Comment thread src/imgtools/io/nnunet_output.py Outdated
Comment on lines +313 to +315
success_count = len(successful_results)
test_set = random_sample(successful_results, ceil(test_set_ratio * success_count))

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Keep at least one case in imagesTr.

Using ceil(test_set_ratio * success_count) can move all successful samples into the test split. For example, success_count == 1 with any positive ratio yields 1, and test_set_ratio == 1.0 yields success_count. finalize_dataset() then computes num_training_cases from an empty imagesTr, which makes the generated dataset unusable for training.

Suggested change
         success_count = len(successful_results)
-        test_set = random_sample(successful_results, ceil(test_set_ratio * success_count))
+        if success_count < 2 or test_set_ratio <= 0:
+            return
+
+        requested_test_count = ceil(test_set_ratio * success_count)
+        test_count = min(requested_test_count, success_count - 1)
+        test_set = random_sample(successful_results, test_count)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
success_count = len(successful_results)
test_set = random_sample(successful_results, ceil(test_set_ratio * success_count))
success_count = len(successful_results)
if success_count < 2 or test_set_ratio <= 0:
return
requested_test_count = ceil(test_set_ratio * success_count)
test_count = min(requested_test_count, success_count - 1)
test_set = random_sample(successful_results, test_count)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/imgtools/io/nnunet_output.py` around lines 313 - 315, The split logic in
finalize_dataset() can place every successful sample into test_set, leaving
imagesTr empty and breaking training. Adjust the test_set selection so it always
leaves at least one successful case in the training split, by capping the
sampled test count below success_count when success_count is nonzero. Use the
existing success_count, test_set_ratio, and random_sample logic in
finalize_dataset() to implement the safeguard.

@JoshuaSiraj

Copy link
Copy Markdown
Collaborator

Hi sorry issue took a little while, but I wrote up a minimal way of implementing a test_set_split for nnunet-pipeline.

The feature takes the successfully processed images and moves a proportion of the images/labels to the appropriate dirs in the output dir. I could not find any tests for nnunet-pipeline but this should probably be added to them when they're ready. There is CLI support for the feature as well as hints. Please let me know if there's anything II should change style wise.

Fixes #443

Summary by CodeRabbit

* **New Features**
  
  * Added a `test-set-ratio` option to the command-line workflow, letting you split a portion of successfully processed data into a test set.
  * The pipeline now automatically moves the selected files into the appropriate test folders after processing.

* **Bug Fixes**
  
  * Added validation for the new ratio value to keep it within a valid range and prevent invalid dataset splits.

Hey this looks great! I'll put some time aside to put together some tests for the full nnunet-pipeline + these changes and merge ASAP. Thank you again for your help!

@JoshuaSiraj
JoshuaSiraj changed the base branch from main to JoshuaSiraj/nnunet_updates June 29, 2026 20:36
@JoshuaSiraj
JoshuaSiraj merged commit 2c174e7 into bhklab:JoshuaSiraj/nnunet_updates Jun 29, 2026
6 of 26 checks passed
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.

nnunet-pipeline test set/partitioning

2 participants