Updating modules from Slicer-4.10 to Slicer-4.11

having spent some time working through our scripted modules, we failed to update slicer utility load functions to the most recent syntax. For instance, when calling slicer.util.loadMarkupsFiducialList the return is now a list but our script expects only the node.

You make a valid point, I will take the time to update our scripted modules to make it work with the latest stable.

You may find the migration guide useful and documentation may help, too:

>>> help(slicer.util.loadMarkupsFiducialList)
Help on function loadMarkupsFiducialList in module slicer.util:

loadMarkupsFiducialList(filename, returnNode=False)
    Deprecated. Use loadMarkups function instead.

>>> help(slicer.util.loadMarkups)
Help on function loadMarkups in module slicer.util:

loadMarkups(filename)
    Load node from file.
    
    :param filename: full path of the file to load.
    :return: loaded node (if multiple nodes are loaded then a list of nodes).

loadMarkups returns the loaded node or raises an exception.

fantastic resource. Thank you @lassoan for always being so responsive :+1:

a step in one of the modules is applying a MNI transform to the volumes and models in the scene. To do this I originally ran:

volumes = slicer.util.getNodesByClass('vtkMRMLScalarVolumeNode')
for ivol in volumes:
    ivol.SetAndObserveTransformNodeID(mniTransform.GetID())

models = slicer.util.getNodesByClass('vtkMRMLModelNode')
for imodel in models:
    imodel.SetAndObserveTransformNodeID(mniTransform.GetID())

however, now in the stable 4.11 release the 2D views look correct but the 3D view seems to display the volume incorrectly. Is this the correct way to apply the transform to volumes and models?

The code snippet looks good. Can you share a scene with us that reproduces this?

here is the .mrb file for the scene: https://drive.google.com/file/d/1Qmg8uSaWKLvbwnFhHZqlfTNYhmxP-EuR/view?usp=sharing

I realized that without my scripted module the scene may not look like the one I took a screenshot of. I can set up the .mrb file so it resembles the view I would like?

I think I know the problem, I have created a custom layout for the views. This is my code snippet for the views:

layout = (
			"<layout type=\"horizontal\">"
			" <item>"
			"  <settingsSidePanel></settingsSidePanel>"
			" </item>"
			" <item>"
			"  <layout type=\"vertical\">"
			"   <item>"
			"    <layout type=\"horizontal\">"
			"     <item>"
			"      <view class=\"vtkMRMLSliceNode\" singletontag=\"Red\">"
			"       <property name=\"orientation\" action=\"default\">Axial</property>"
			"       <property name=\"viewlabel\" action=\"default\">R</property>"
			"       <property name=\"viewcolor\" action=\"default\">#F34A33</property>"
			"      </view>"
			"     </item>"
			"     <item>"
			"      <view class=\"vtkMRMLViewNode\" singletontag=\"1\">"
			"       <property name=\"viewlabel\" action=\"default\">1</property>"
			"      </view>"
			"     </item>"
			"    </layout>"
			"   </item>"
			"   <item>"
			"    <layout type=\"horizontal\">"
			"     <item>"
			"      <view class=\"vtkMRMLSliceNode\" singletontag=\"Yellow\">"
			"       <property name=\"orientation\" action=\"default\">Sagittal</property>"
			"       <property name=\"viewlabel\" action=\"default\">Y</property>"
			"       <property name=\"viewcolor\" action=\"default\">#EDD54C</property>"
			"      </view>"
			"     </item>"
			"     <item>"
			"      <view class=\"vtkMRMLSliceNode\" singletontag=\"Green\">"
			"       <property name=\"orientation\" action=\"default\">Coronal</property>"
			"       <property name=\"viewlabel\" action=\"default\">G</property>"
			"       <property name=\"viewcolor\" action=\"default\">#6EB04B</property>"
			"      </view>"
			"     </item>"
			"    </layout>"
			"   </item>"
			"  </layout>"
			" </item>"
			"</layout>"
			)
		layoutNode = slicer.app.layoutManager().layoutLogic().GetLayoutNode()
		layoutNode.AddLayoutDescription(yourLayoutID, layout)

Based on what I see in the scene, it seems to be an LPS/RAS coordinate system mismatch: Slicer now assumes that surface meshes are stored on disk in LPS coordinate system if the file does not contain coordinate system information. See this section of the migration guide for details.

ah okay, that would explain it. What vtkMRMLModelNode method would I use to determine coordinate system?

In my custom layout, when defining the 3D view, am I missing any setting:

"     <item>"
"      <view class=\"vtkMRMLViewNode\" singletontag=\"1\">"
"       <property name=\"viewlabel\" action=\"default\">1</property>"
"      </view>"
"     </item>"

I think I found the solution from the documentation link you sent:

Option C: Write SPACE=RAS in the comment/description field in the mesh file…

[EDIT]

after further reading, it’s more clear how to obtain the coordinate system of a model (using Python syntax):

node=getNode('some_model.vtk')

# Will return either LPS or RAS
coordSys = node.GetStorageNode().GetCoordinateSystemTypeAsString(node.GetStorageNode().GetCoordinateSystem())

Then it’s a matter of setting the coordinate system you want the model to use:

# 0 for RAS and 1 for LPS
node.GetStorageNode().SetCoordinateSystem(0)
1 Like

I found the problem for why applying the transform to the models in the scene resulted in the spatial difference between 2D and 3D views. Using slicer.util.getNodesByClass('vtkMRMLModelNode') returns the models but also [‘Red Volume Slice’, ‘Green Volume Slice’, ‘Yellow Volume Slice’]. So the MNI transform was being applied to the 2D views as well as the models.

Good catch. You can determine if a node is a slice model node by calling slicer.vtkMRMLSliceLogic.IsSliceModelNode(modelNode). But of course it is much more cleaner and safer to apply transforms only to nodes that you load/create (you can never be sure what else is in the scene already).

1 Like