Skip to content

Fix per_component Dice silently ignoring ignore_index - #9171

Open
SID-6921 wants to merge 2 commits into
Project-MONAI:devfrom
SID-6921:fix-per-component-dice-ignore-index
Open

SID-6921 wants to merge 2 commits into
Project-MONAI:devfrom
SID-6921:fix-per-component-dice-ignore-index

Conversation

@SID-6921

@SID-6921 SID-6921 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Description

DiceHelper/DiceMetric's per_component=True path never received the spatial mask create_ignore_mask builds from ignore_index — compute_cc_dice has no mask parameter at all, so combining per_component=True with ignore_index silently computed TP/FP/FN over the "ignored" voxels as if nothing were ignored. The regular per-channel path already applies this mask correctly; only the per-component path was missing it.

Fix threads the mask into compute_cc_dice: ignored voxels are forced to agree as background in both y and y_pred before the connected-component assignment and histogram, so they never contribute to any component's score — consistent with how the non-per_component path already handles masking.

Reachable via the public API: DiceMetric(per_component=True, ignore_index=N)(y_pred, y). No existing test exercised this combination (checked tests/metrics/test_compute_meandice.py — separate per_component and ignore_index cases, never together).

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • New tests added to cover the changes
  • Integration tests passed locally by running ./runtests.sh -f -u --net --coverage
  • Quick tests passed locally by running ./runtests.sh --quick --unittests --disttests (ran the targeted test file directly via pytest instead: pytest tests/metrics/test_compute_meandice.py, 22/22 passed; did not run the full repo test runner)
  • In-line docstrings updated
  • Documentation updated

DiceHelper/DiceMetric's per_component=True path (per-connected-
component Dice via compute_cc_dice) never received the spatial mask
that create_ignore_mask builds from ignore_index, while the regular
per-channel path already applies it. compute_cc_dice has no mask
parameter at all, so combining per_component=True with ignore_index
silently computed TP/FP/FN over the "ignored" voxels as if nothing
were ignored, with no validation or warning.

Threads the mask into compute_cc_dice: ignored voxels are forced to
agree as background in both y and y_pred before the connected-
component assignment and histogram, so they never contribute to a
component's score, consistent with how masking works in the
non-per_component path.

Reachable via the public API: DiceMetric(per_component=True,
ignore_index=N)(y_pred, y). No existing test exercised this
combination.

Signed-off-by: Siddhardha Nanda <99672439+SID-6921@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 13, 2026 23:16

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.

@coderabbitai

coderabbitai Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: Project-MONAI/MONAI/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: da07dcad-96b0-4e61-8e53-861e81272b19
📥 Commits

Reviewing files that changed from the base of the PR and between cb35d45 and bcb96a9.

📒 Files selected for processing: 2
  • monai/metrics/meandice.py
  • tests/metrics/test_compute_meandice.py

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to bcb96

The change correctly excludes ignored voxels from per-component scores, and its focused regression test covers the reported case. No actionable merge-blocking risk remains.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Title check Passed The title clearly identifies the main change: fixing the interaction between per-component Dice and ignore_index.
Description check Passed The description explains the bug, implementation, public API impact, test coverage, and test command results. The issue reference and full repository test-runner checks are not provided, but the descr…
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

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.

This branch has not been deployed

No deployments
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