# Odd behavior after adding a moving mask in the ANTs extension

**URL:** <https://discourse.slicer.org/t/odd-behavior-after-adding-a-moving-mask-in-the-ants-extension/46117>\
**Category:** Support\
**Tags:** registration, masking, ants\
**Created:** [February 10, 2026, 8:05pm UTC](https://discourse.slicer.org/t/odd-behavior-after-adding-a-moving-mask-in-the-ants-extension/46117 "2026-02-10T20:05:44Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![sulli419](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulli419/32/78859_2.png) [@sulli419](https://discourse.slicer.org/u/sulli419)\
**Post date:** [February 10, 2026, 8:05pm UTC](https://discourse.slicer.org/t/odd-behavior-after-adding-a-moving-mask-in-the-ants-extension/46117/1 "2026-02-10T20:05:44Z")

</div>

I’ve been using the ANTs extension for registering two single-label volumes to eachother with good results. In an attempt to improve registration robustness, I started incorporating fixed and moving masks (FM, MM), but this is yielding some unexpected results. To simplify the issue I’m just focusing on a single stage affine transform. The affine transform with the fixed mask alone looks very reasonable; but if I add a moving mask to this same affine configuration (along with the fixed) the registration is much poorer. For now, the moving mask is essentially just a bounding box with zeros at the edges.

When working properly, the largest components of the final affine transform are a Z translation (shift) and a Z scaling (expansion). Something about showing the MM (in addition to FM) loses this info. As a test, I ran a “good” FM only registration but also included a 2nd dummy affine stage (following the correct/complete one), where there are zero convergence steps, but now both the FM and MM are shown. This somehow changes the 3-3 matrix value (Z scaling factor) from 1.2 (ideal) to ~1. If this dummy step only has the FM, the “affine erasure” doesn’t happen.

Trouble shooting I created a MM that is “all 1s”, expecting that it should work the same as a having no moving mask but this wasn’t the case, the all 1s MM worsened the quality.

Any chance this is a bug? Might the image origin of the moving mask be getting read improperly? Perhaps I’m just ignorant of how masks interact by design in ANTs.

If it’s any help I’m including an image  
Red: Fixed volume (my tissue); Yellow: Moving volume (atlas); Green: fixed mask; Purple: moving mask

\*\*Note, this doesn’t show the dimensions of the zero values. For example, how large the virtual space of the fixed volume is.

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/d/1/d1093bf97e79e1fa29dfd43eacd1441c8fa6fab0.jpeg)

---

<div class="post-metadata">

**Author:** ![sulli419](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulli419/32/78859_2.png) [@sulli419](https://discourse.slicer.org/u/sulli419)\
**Post date:** [February 20, 2026, 12:00am UTC](https://discourse.slicer.org/t/odd-behavior-after-adding-a-moving-mask-in-the-ants-extension/46117/2 "2026-02-20T00:00:42Z")

</div>

I’ve been troubleshooting this issue for days. I’m not sure if something changed in my ANTs, but now I am convinced that even the “fixed mask” (for hiding parts of the fixed volume) is not working.

To make things easier I started playing with the demo MR data here. I am finding that the registration is identical, irrespective of if I add the fixed mask in ANTs. However, if I add the fixed mask in the Elastix extension, it changes the registration, as expected.

Can anyone confirm that the fixed or moving masks are working for them in the ANTs extension? Wonder it is a version issue, or maybe something was corrupted as I was tinkering with parameters, etc.

I should add, if anyone has some simple positive controls to test for masking I’d gladly run them and share the results here.

Thanks!

> **[GitHub - stnava/BasicBrainMapping: A simple and "fast" brain registration example](https://github.com/stnava/BasicBrainMapping)**
>
> A simple and "fast" brain registration example

---

<div class="post-metadata">

**Author:** ![sulli419](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulli419/32/78859_2.png) [@sulli419](https://discourse.slicer.org/u/sulli419)\
**Post date:** [February 20, 2026, 1:50am UTC](https://discourse.slicer.org/t/odd-behavior-after-adding-a-moving-mask-in-the-ants-extension/46117/3 "2026-02-20T01:50:02Z")

</div>

On the off chance this is a clue, I noticed that the masks have to be in the labelmap format to be seen in the “moving mask” dropdown menu. Does this sound correct or point to the issue? If recall correctly, I think Elastix can also use scalar volumes.

---

<div class="post-metadata">

**Author:** ![drnoorfatima](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/drnoorfatima/32/81980_2.png) [@drnoorfatima](https://discourse.slicer.org/u/drnoorfatima)\
**Post date:** [February 20, 2026, 10:37am UTC](https://discourse.slicer.org/t/odd-behavior-after-adding-a-moving-mask-in-the-ants-extension/46117/4 "2026-02-20T10:37:01Z")

</div>

Hi!

I’ve been looking at this and I think the issue is actually in how the ANTs extension GUI passes mask parameters internally which explains why the same mask behaves differently depending on the stage configuration.

The “all 1s” mask behaving differently than no mask is a strong clue that the problem is in the extension layer, not ANTs itself.

There’s a way to bypass this entirely and get proper mask control, but it involves a different approach than using the extension GUI directly.

Happy to help if you want to discuss further!

---

<div class="post-metadata">

**Author:** ![sulli419](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulli419/32/78859_2.png) [@sulli419](https://discourse.slicer.org/u/sulli419)\
**Post date:** [February 20, 2026, 5:44pm UTC](https://discourse.slicer.org/t/odd-behavior-after-adding-a-moving-mask-in-the-ants-extension/46117/5 "2026-02-20T17:44:13Z")

</div>

Thanks for your message. Interesting, so you are also unable to read the hide masks with the ANTs extension? Since the extension has been around so long, I wonder if the conflict arose in a newerer version of Slicer?

To my more recent post, I might have been getting distracted by the odd behavior of the moving mask. I now wonder if because it isn’t reading the fixed mask the moving mask was also getting misread. Somewhere in the ANTs documentation I vaguely recall reading that if you have a moving mask a fixed mask is obligatory.

Maybe we could keep the Slicer specific details here, and I will DM about alternative approaches. However, the GUI has been so useful for tracking my workflow and quality control. If everyone has this bug I hope it can be fixed. I’ll put in a request if you can confirm you also get the error. I’m in the process of testing it on a different machine with a fresh install.

Appreciate the help

---

<div class="post-metadata">

**Author:** ![drnoorfatima](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/drnoorfatima/32/81980_2.png) [@drnoorfatima](https://discourse.slicer.org/u/drnoorfatima)\
**Post date:** [February 22, 2026, 11:01am UTC](https://discourse.slicer.org/t/odd-behavior-after-adding-a-moving-mask-in-the-ants-extension/46117/6 "2026-02-22T11:01:28Z")

</div>

Happy to discuss alternative approaches over DM!

---

<div class="post-metadata">

**Author:** ![sulli419](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulli419/32/78859_2.png) [@sulli419](https://discourse.slicer.org/u/sulli419)\
**Post date:** [February 28, 2026, 2:06am UTC](https://discourse.slicer.org/t/odd-behavior-after-adding-a-moving-mask-in-the-ants-extension/46117/7 "2026-02-28T02:06:16Z")

</div>

A solution. Thanks to those who helped fix and update ATNs @mhalle @lassoan @pieper @simonoxen

Ok, I pitched this problem in a forum where people were discussing using large documentation and code data bases for priming AI for working in slicer, which includes debugging! Claude spotted the bug and fixed it. Interestingly, in my hands GPT 5.2 was suggesting a similar fix with zero documentation priming, but I didn’t completely trust it.

It appears that what was happening is that if the user selected only one mask (either fixed or moving) it didn’t load it and ran with no warning.

A new slicer ants released a couple of days ago with this fixed (see link). You can either replace the suspect .py file in your existing ANTs or install the absolute latest Slicer and then find the new extension from within the GUI

@mikebind is an expert user, so he might add some comments about how well it’s working. The masks seem to change the registration in fairly sensible ways, but I haven’t probed it rigorously.

Things I plan to check:  
1.) can different masks be mixed at matched at different stages (confirm at least in the CLI)?

2.) Why was I getting a funny result in the old version when adding a fixed AND moving mask (since this shouldn’t trigger this bug)? Test if this is still happening, i.e., not a separate bug to address.

> [@New slicer-skill ai tool](https://discourse.slicer.org/t/new-slicer-skill-ai-tool/46243/4):
>
> This sounds very useful. Could it be used to fixed bugs in extensions? As an example task, I am finding the ANTs extension can no longer apply fixed masks (for hiding parts of the volume). It would be interesting to see if Claude could nail the problem and provide a fix for the next version.

> <https://github.com/netstim/SlicerANTs/pull/15>
>
> \## Summary
> 
> \- \*\*Fixed\*\*: \`getMasksCommand()\` required both fixed AND moving mask…s to generate the \`--masks\` flag. Providing only a fixed mask (the common use case for hiding parts of the volume during registration) silently dropped the mask entirely — no \`--masks\` flag was emitted and no warning was shown.
> \- \*\*Fix\*\*: When only one mask is provided, \`NULL\` is passed as the ANTs placeholder for the missing mask, allowing either mask to be used independently.
> 
> \### Before (broken)
> \`\`\`
> \# User selects only a fixed mask → no --masks flag generated at all
> \`\`\`
> 
> \### After (fixed)
> \`\`\`
> \# Fixed only: --masks \[$fixedMask,NULL\]
> \# Moving only: --masks \[NULL,$movingMask\]
> \# Both: --masks \[$fixedMask,$movingMask\]
> \# Neither: no flag (unchanged)
> \`\`\`
> 
> \## Test plan
> 
> \- \[\] Load two volumes and a label map mask in Slicer
> \- \[\] In ANTs Registration, select only a fixed mask (leave moving mask as None)
> \- \[\] Run registration and verify the \`--masks\` flag appears in the generated command with \`NULL\` for the moving mask
> \- \[\] Repeat with only a moving mask selected
> \- \[\] Verify both masks together still works as before
> \- \[\] Verify no masks selected still omits the \`--masks\` flag
> 
> 🤖 Generated with \[Claude Code\](https://claude.com/claude-code)

---

<div class="post-metadata">

**Author:** ![sulli419](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulli419/32/78859_2.png) [@sulli419](https://discourse.slicer.org/u/sulli419)\
**Post date:** [March 1, 2026, 6:53pm UTC](https://discourse.slicer.org/t/odd-behavior-after-adding-a-moving-mask-in-the-ants-extension/46117/8 "2026-03-01T18:53:54Z")

</div>

Reposting because I might have accidentally deleted

> <https://github.com/netstim/SlicerANTs/pull/15>
>
> \## Summary
> 
> \- \*\*Fixed\*\*: \`getMasksCommand()\` required both fixed AND moving mask…s to generate the \`--masks\` flag. Providing only a fixed mask (the common use case for hiding parts of the volume during registration) silently dropped the mask entirely — no \`--masks\` flag was emitted and no warning was shown.
> \- \*\*Fix\*\*: When only one mask is provided, \`NULL\` is passed as the ANTs placeholder for the missing mask, allowing either mask to be used independently.
> 
> \### Before (broken)
> \`\`\`
> \# User selects only a fixed mask → no --masks flag generated at all
> \`\`\`
> 
> \### After (fixed)
> \`\`\`
> \# Fixed only: --masks \[$fixedMask,NULL\]
> \# Moving only: --masks \[NULL,$movingMask\]
> \# Both: --masks \[$fixedMask,$movingMask\]
> \# Neither: no flag (unchanged)
> \`\`\`
> 
> \## Test plan
> 
> \- \[\] Load two volumes and a label map mask in Slicer
> \- \[\] In ANTs Registration, select only a fixed mask (leave moving mask as None)
> \- \[\] Run registration and verify the \`--masks\` flag appears in the generated command with \`NULL\` for the moving mask
> \- \[\] Repeat with only a moving mask selected
> \- \[\] Verify both masks together still works as before
> \- \[\] Verify no masks selected still omits the \`--masks\` flag
> 
> 🤖 Generated with \[Claude Code\](https://claude.com/claude-code)

> [@sulli419](#):
>
> A solution. Thanks to those who helped fix and update ANTs @mhalle @lassoan @pieper @simonoxen
> 
> Ok, I pitched this problem in a forum where people were discussing using large documentation and code data bases for priming AI for working in slicer, which includes debugging! Claude spotted the bug and fixed it. Interestingly, in my hands GPT 5.2 was suggesting a similar fix with zero documentation priming, but I didn’t completely trust it.
> 
> It appears that what was happening is that if the user selected only one mask (either fixed or moving) it didn’t load it and ran with no warning.
> 
> A new slicer ants released a couple of days ago with this fixed (see link). You can either replace the suspect .py file in your existing ANTs or install the absolute latest Slicer and then find the new extension from within the GUI
> 
> @mikebind is an expert user, so he might add some comments about how well it’s working. The masks seem to change the registration in fairly sensible ways, but I haven’t probed it rigorously.
> 
> Things I plan to check:  
> 1.) can different masks be mixed at matched at different stages (confirm at least in the CLI)?
> 
> 2.) Why was I getting a funny result in the old version when adding a fixed AND moving mask (since this shouldn’t trigger this bug)? Test if this is still happening, i.e., not a separate bug to address.

---

<div class="post-metadata">

**Author:** ![sulli419](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulli419/32/78859_2.png) [@sulli419](https://discourse.slicer.org/u/sulli419)\
**Post date:** [March 2, 2026, 7:12pm UTC](https://discourse.slicer.org/t/odd-behavior-after-adding-a-moving-mask-in-the-ants-extension/46117/9 "2026-03-02T19:12:47Z")

</div>

Sharing more of my notes on this post after running some quality tests in slicer. I think everything is in order.

I took some dummy T1 MRI data of the head and registered two volumes to eachother with quick syn (rigid, affine, SyN). I created masks for the brain and everything but the brain (~skull) for each volume. This allowed me to hide various parts and see if the reg worked as predicted.

With “link across stages” selected for the masks, I am now able to select just one mask (either fixed or moving) and it works predictably, e.g., if I mask/hide everything but the skull with _either_ a fixed or moving mask, the skull reg looks great but the brain is poorer. Same from brain but not skull.

**The CLI that shows up under the double arrow of the ANTs GUI shows this, as expected**  
_All\_Command\_lines\_OK  
Using single precision for computations.  
Reading mask(s).  
Registration stage 0  
No fixed mask  
Moving mask = C:/Users/sulliste/AppData/Local/Temp/1/Slicer/BBJFC\_vtkMRMLLabelMapVolumeNodeE.nrrd  
Registration stage 1  
No fixed mask  
Moving mask = C:/Users/sulliste/AppData/Local/Temp/1/Slicer/BBJFC\_vtkMRMLLabelMapVolumeNodeE.nrrd  
Registration stage 2  
No fixed mask  
Moving mask = C:/Users/sulliste/AppData/Local/Temp/1/Slicer/BBJFC\_vtkMRMLLabelMapVolumeNodeE.nrrd_

Next I tested if single masks can be applied at certain stages but not others, for example, just a fixed mask at the affine stage (2nd). Now the the same CLI readout looks wrong, only applying at stage 0 (rigid) (?).

_Reading mask(s).  
Registration stage 0  
Fixed mask = C:/Users/APOM/AppData/Local/Temp/Slicer/FJEE\_vtkMRMLLabelMapVolumeNodeC.nrrd  
No moving mask_

I thought maybe this is just a readout error so dug deeper…  
Each time the ANTs extension runs it creates a report in the slicer data module. To see it, click the tab “all nodes” in the main data module, then at the bottom tick “show hidden nodes” and it will look something like the image I shared. I expanded my last run “…CLI\_13” by right clicking then “edit properties”. Under the command dropdown it shows this info. Note in bold that the mask is only applied to affine, as I intended:  
\*–dimensionality 3 --use-histogram-matching 0 --winsorize-image-intensities [0.005,0.995] --float $useFloat --verbose 1 --interpolation Linear --output [$outputBase,$outputVolume] --write-composite-transform 1 --collapse-output-transforms 1 --transform Rigid[0.1] --metric MI[$inputVolume01,$inputVolume02,1,32,Regular,0.25] --convergence [1000x500x250x0,1e-6,10] --smoothing-sigmas 4x3x2x1vox --shrink-factors 12x8x4x2 **–transform Affine[0.1] --metric MI[$inputVolume01,$inputVolume02,1,32,Regular,0.25] --convergence [1000x500x250x0,1e-6,10] --smoothing-sigmas 4x3x2x1vox --shrink-factors 12x8x4x2 \*\*–masks [$inputVolume03,NULL] –**\*_transform SyN[0.1,3,0] --metric MI[$inputVolume01,$inputVolume02,1,32,Regular,0.25] --convergence [100x100x70x50x0,1e-6,10] --smoothing-sigmas 5x3x2x1x0vox --shrink-factors 10x6x4x2x1_

Yet to confirm single stage reg is perfectly predictable, but **long story short, it seems to be applying correctly.**

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/2/0/20a846c253df42c0798c32b76b60ca138f226f77.png)

---

<div class="post-metadata">

**Author:** ![sulli419](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sulli419/32/78859_2.png) [@sulli419](https://discourse.slicer.org/u/sulli419)\
**Post date:** [March 4, 2026, 5:52pm UTC](https://discourse.slicer.org/t/odd-behavior-after-adding-a-moving-mask-in-the-ants-extension/46117/10 "2026-03-04T17:52:15Z")

</div>

I take it back! The new version indeed fixes the single masking bug if you link them across all stages. BUT probing to see if I can apply various masks in any (many) permutations, i.e., differently at each stage, show it isn’t working. So my previous concern (below) was justified! I have a new .py script that seems to have fixed this issue. Testing it more and plan to place another git pull request.

”Next I tested if single masks can be applied at certain stages but not others, for example, just a fixed mask at the affine stage (2nd). Now the the same CLI readout looks wrong, only applying at stage 0 (rigid) (?).

_Reading mask(s).  
Registration stage 0  
Fixed mask = C:/Users/APOM/AppData/Local/Temp/Slicer/FJEE\_vtkMRMLLabelMapVolumeNodeC.nrrd  
No moving mask”_
