Skip to content

Add missing channel_wise parameter to RandScaleIntensityFixedMean#8741

Open
engmohamedsalah wants to merge 9 commits intoProject-MONAI:devfrom
engmohamedsalah:fix/add-channel-wise-randscaleintensityfixedmean-8363
Open

Add missing channel_wise parameter to RandScaleIntensityFixedMean#8741
engmohamedsalah wants to merge 9 commits intoProject-MONAI:devfrom
engmohamedsalah:fix/add-channel-wise-randscaleintensityfixedmean-8363

Conversation

@engmohamedsalah
Copy link
Contributor

Summary

  • Adds the channel_wise parameter to RandScaleIntensityFixedMean and RandScaleIntensityFixedMeand, which was documented in docstrings but never implemented.
  • When channel_wise=True, a separate random scale factor is generated per channel, and preserve_range/fixed_mean are applied per channel — following the existing pattern from RandScaleIntensity.
  • Fixes docstring indentation for channel_wise in both array and dictionary transforms.

Fixes #8363

Changes

monai/transforms/intensity/array.py

  • Added channel_wise parameter to RandScaleIntensityFixedMean.__init__
  • Updated randomize() to generate per-channel factors when channel_wise=True
  • Updated __call__ to apply per-channel scaling with individual random factors

monai/transforms/intensity/dictionary.py

  • Added channel_wise parameter to RandScaleIntensityFixedMeand.__init__
  • Updated __call__ to pass image data to randomize() (needed for channel count), following the pattern from RandScaleIntensityd

Tests

  • Added test_channel_wise and test_channel_wise_preserve_range to test_rand_scale_intensity_fixed_mean.py
  • Added test_channel_wise to test_rand_scale_intensity_fixed_meand.py

Test plan

  • All existing tests pass (no regressions)
  • New channel_wise tests pass for both array and dictionary transforms
  • Verified per-channel mean preservation with fixed_mean=True
  • Verified preserve_range clipping works per channel

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 14, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between ae90682 and 3d83082.

📒 Files selected for processing (1)
  • monai/transforms/intensity/array.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • monai/transforms/intensity/array.py

📝 Walkthrough

Walkthrough

Adds channel-wise support to RandScaleIntensityFixedMean (array) and its dictionary wrapper. The array transform gains a new channel_wise: bool parameter, stores it, forwards it to the internal scaler, samples per-channel factors when enabled, and applies per-channel scaling by iterating channels and concatenating results while preserving dtype, fixed_mean, and preserve_range semantics. The dictionary transform propagates channel_wise into its internal scaler, changes randomization to self.scaler.randomize(d[first_key]) when keys share the same factor, and adds an early-return path that converts all values to tensors when first_key == (). Tests were added to validate per-channel scaling and preserve_range behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title directly describes the main change: adding a previously missing channel_wise parameter to RandScaleIntensityFixedMean.
Description check ✅ Passed Description covers all required sections: summary, changes, tests, and test plan. Fixes issue reference included.
Linked Issues check ✅ Passed PR implements all objectives from #8363: adds channel_wise parameter [#8363], generates per-channel factors [#8363], applies per-channel scaling [#8363], ensures fixed_mean and preserve_range work per-channel [#8363], follows RandScaleIntensity pattern [#8363].
Out of Scope Changes check ✅ Passed All changes align with #8363 scope: parameter implementation, per-channel logic, docstring corrections, and corresponding tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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 and usage tips.

@engmohamedsalah engmohamedsalah force-pushed the fix/add-channel-wise-randscaleintensityfixedmean-8363 branch from 738a3f9 to da88dbe Compare February 23, 2026 14:22
…oject-MONAI#8363)

The channel_wise parameter was documented in the docstring but not actually
accepted by RandScaleIntensityFixedMean or its dictionary variant. This adds
the parameter with per-channel random factor generation and scaling, matching
the existing pattern in RandScaleIntensity. Also fixes docstring indentation.

Signed-off-by: Mohamed Salah <eng.mohamed.tawab@gmail.com>
@engmohamedsalah engmohamedsalah force-pushed the fix/add-channel-wise-randscaleintensityfixedmean-8363 branch from da88dbe to f996a93 Compare February 23, 2026 15:43
Copy link
Member

@ericspod ericspod left a comment

Choose a reason for hiding this comment

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

Hi @engmohamedsalah I made a few comments below but it otherwise looks good to me with a few changes. Thanks!

… simplify loop

- Move channel_wise parameter to end of argument list in both array and
  dictionary variants to preserve positional argument compatibility
- Use R.uniform(size=) instead of list comprehension for per-channel factors
- Simplify channel-wise __call__ using float() cast, torch.cat, and removing
  redundant [0] index
- Reorder docstrings to match new argument order

Signed-off-by: Mohamed Salah <eng.mohamed.tawab@gmail.com>
…nd cat

- Add type: ignore[index] for self.factor[i] since mypy can't narrow the
  type in the channel_wise branch
- Add type: ignore[arg-type] for scale_trans output appended to list
- Type out list as list[torch.Tensor] to satisfy torch.cat signature
- Follows same pattern as existing RandScaleIntensity (line 738-740)

Signed-off-by: Mohamed Salah <eng.mohamed.tawab@gmail.com>
@engmohamedsalah
Copy link
Contributor Author

@ericspod please check again after apply all your comments

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.

channel_wise option missing in transforms.RandScaleIntensityFixedMean

2 participants