Access AnnotationROINode without knowing the ID

Hi :vulcan_salute:

I’m in python and when I create a volume rendering for a scalar volume node using UpdateDisplayNodeFromVolumeNode from modules.volumerendering.logic, the AnnotationROINode is created automatically.

I want to rename the default AnnotationROINode so that when I work with many volumes their ROI nodes are clearly identifiable in the Subject Hierarchy view.

I use this snippet from the docs to create the volume rendering:

volumeNode = myAwesomeVolumeNode

logic = slicer.modules.volumerendering.logic()

displayNode = logic.CreateVolumeRenderingDisplayNode()
displayNode.UnRegister(logic)
slicer.mrmlScene.AddNode(displayNode)
volumeNode.AddAndObserveDisplayNodeID(displayNode.GetID())

logic.UpdateDisplayNodeFromVolumeNode(displayNode, volumeNode)

freshlyCreatedDefaultAnnotationROINode = ...

I can see the connection to the AnnotationROI in the Data module if I select the Volume Node.
How do I see this link from python? Is there a way to access the AnnotationROINode without searching for it explicitly by id, name or classname?

image

Looks like you can create the ROI yourself and pass it in. You could create the volume property and ROI with logical names before calling the method.

https://apidocs.slicer.org/master/classvtkSlicerVolumeRenderingLogic.html#a0dd5b03b39e2f70a3edadd7b1c41cbf9

Thanks @pieper, I’ve tried calling the UpdateDisplayNodeFromVolumeNode but it appeared to me that it didn’t change anything in the scene and when I tried to turn on volume rendering from the UI the “AnnotationROI_3” still appeared.
As another similar workaround I’ve used for now is creating, naming and registering the node manually using the code like in the attached snippet. I probably miss attaching the roi to the volume because despite that the volume rendering works as expected I create these nodes manually I can’t see the “link” in the data module widget.

here’s the snippet

myVolume = pNode.GetNodeReference('myVolume')

ROINode = slicer.vtkMRMLAnnotationROINode()
ROINode.SetName('myVolumeAnnotationROI')
ROINode.Initialize(slicer.mrmlScene)
ROINode.SetRadiusXYZ(50, 50, 100)
ROINode.SetInteractiveMode(1)
ROINode.SetDisplayVisibility(1)

volumeRenderingDisplayNode = slicer.modules.volumerendering.logic().CreateDefaultVolumeRenderingNodes(myVolume)
propertyNode = volumeRenderingDisplayNode.GetVolumePropertyNode()

volumeRenderingDisplayNode.SetAndObserveROINodeID(ROINode.GetID())

volumeRenderingDisplayNode.SetCroppingEnabled(1)
volumeRenderingDisplayNode.VisibilityOn()

I’ve seen that the AnnotationROINode has a .GetVolumeNodeID method that should “Get/Set for the volume node ID associated with this ROI” but it’s empty by default. Do I need to use the setter here to link the ROI with the volume?

I’m not sure about that, I haven’t tried.

But do you ever add ROINode to the scene? If not probably ROINode.GetID() returns null.

You might switch to creating the node with slicer.mrmlScene.AddNewNodeByClass so you know it’s in the scene with a valid id.

Thanks, will try this.

Note that we are phasing out Annotations module. If you are building anything new then you may consider using markups ROI instead of annotations ROI. Markups ROI has a number of important advantages, such as you can rotate it without applying a transform.

Yes I remember that you mentioned thin in the call. What’s the timeline for such depreciation and are there isage examples in the script repository?

Probably we will remove annotations module in a year or so. You can find markups manipulation examples in the script repository and we can add more examples as questions are asked.

1 Like

Thanks, will look deeper into it.

By the way, will removal of annotations module break older extensions and custom apps that use it?

Yes, that’s why we remove annotations module slowly, in several phases. We have already stopped developing and fixing Annotations module and stated that the module is deprecated. Next step is to update all core modules and extensions to support markups as well, then change modules to create markups node instead by default, then hide Annotations module GUI, and finally remove the module completely. The last step will probably only happen in a few years when some Slicer changes would require too much work to keep Annotations module working. See current plan in the Roadmap.