Tranformation of labelmap not working on script

Operating system: MacOS BigSur 11.6
Slicer version: 5.0.3
Expected behavior: Transform labelmap volume node
Actual behavior: Labelmap volume node is not transformed

Hello everyone,

I’m developing a script, that among other things, registers an MNI template onto the T1 brain scan of some patients for anatomical research purposes. For that, I just register the MNI template as the moving volume to the scan of each patient (fixed), which works wonderful. However, this MNI template also comes with a label map naming each region of the cortex, which I would like to transform too, so I could identify specific points in the brain. For that, I just apply the transformation matrix from the previous registration to the label map volume, like this:

labelmapVolumeNode = slicer.util.loadVolume(labelmapPath,properties={"name":"MNI_labels","labelmap":True,"center":True})
transform = slicer.util.getFirstNodeByName("Transform2MNI")
transformedLabels = slicer.mrmlScene.CopyNode(labelmapVolumeNode)

Where MNI_labels is the label map volume I would like to transform, and Transform2MNI is the transformation from the previous and successful registration. However, the code is not working. It creates the new “transformed_MNI_labels” Node but is just a replica of the original label map. What’s also interesting is that if I copy and paste the lines of code onto the python interactor, it works!

Finally, all the commands are in a simple function with no conditionals or structures of any kind that could prevent that part of the code from running. I’ve also checked that it was running adding logging info in between the lines. And as said, the label map is loaded and copied, the problem is that it is not transformed.

Am I missing something? Is there a better way to transform the label map?
Thanks in advance

Could it be that the transform is being applied, but the view is also being corrected so as to undo the effect visually? Sometimes I get thrown off by this. Like I’ll apply a transform to a volume and not see any effect, except the subtle effect that the slice views go from Axial/Sagittal/Coronal to “Reformat”.

(My comment applies to affine transforms only; not sure if that is what you have)

One way to see if that’s happening: you said that when you paste your snippet into the python interactor, it works. So after pasting it, try toggling the visibility of the successfully transformed label map. When it comes back into visibility do the slice views change to remove the visual effect of the transformation?

Alternatively: if you make the transformed labelmap visible at the same time that the transformed T1 image is visible, do they actually successfully line up?

Thank you so much for your response,

The slice view is kept as Axial/Sagittal/Coronal, it doesn’t change to Reformat.

Yes! It is an affine transform

No, the slice views are not changing after pasting the snippet in the python interactor either

They successfully line up only after running the snippet from the Python interactor. In the following image you can see the MNI template registered to the subject (ICBM152_registered) and the labelmap after transforming it with the script:

Captura de pantalla 2022-10-03 a las 10.38.57

where the transformed labelmap (transformed_MNI_labels) is clearly not transformed. However, the following figure shows in the same slice how the transformation is performed after running the snippet from the interactor:

Captura de pantalla 2022-10-03 a las 10.39.18

Any other ideas on what could be causing this script issue?

How are you running the script when it’s not by pasting into the python interactor?

I wonder if some of the objects (transform, transformedLabels, labelmapVolumeNode,…) are coming out as None and no error is being reported because the later funcitons do not complain when given None. Maybe you could print out those objects in the snippet to make sure they’re as expected

I’m running the script from a Scripted Module.

I already checked and that part of the script is running, the line that is apparently the issue is transformedLabels.ApplyTransformMatrix(transform.GetMatrixTransformToParent()) as it is not applying the transform. I’ve also tried with labelmapVolumeNode.ApplyTransform(transform.GetTransformToParent()) but it’s not working either.

All the objects are coming out as they are expected (labelmapVolumeNode and transform), with the exception of the transformedLabels, which is just the copy of labelmapVolumeNode, but it’s not None.

What if you apply the transform using SetAndObserveTransformNodeID as seen here, then does it work from the scripted module?

I’m not sure I understand the difference between the SetAndObserveTransformNodeID and the ApplyTransform approach, but if the difference is that ApplyTransform hardens the transform and this is something you want then you can call HardenTransform on the segmentation node afterwards.

I also have the same question, did you find the solution @justomont ?

Since the transformation was working from the Python Interactor, I just moved the section of the script that registered the label map to a different new function (called right after finishing the registration of the MNI template) and it worked. To be honest, I don’t really understand why it is working now, but it does.

CopyNode is a very low-level function. It makes a copy only of the data node, but still keeps referencing the same display, storage, etc. nodes. If you want to create an independent copy of a node then you can use clone feature of Subject Hierarchy.