How to understand the difference among (or when to use) getNode byName(), byRenferenceRole(), byID()?

Hi everyone,

I am trying to write my first extension module, however, really confused by the various methods to get a node:

self._parameterNode.GetNodeReference('InputVolume')
slicer.mrmlScene.GetNodeByID()
slicer.util.getNode('F')

I can understand that we try to avoid using slicer.util.getNode() because there could be variables with the same node name.

I am confused that when should I call self._parameterNode.SetNodeReferenceID() and when should I save the node ID, e.g., self.InputVolume_ID = node_InputVolume.GetID()?

Thank you so much in advance!

You need to use node references if you want to store connection between nodes persistently, in a scene file. This is because when a scene is loaded the application automatically modifies a loaded node’s ID if that ID is already used in the scene.

Thank you so much, Andras!

I kind of understand what is a node reference now. But still, I miss something:

When there is a scene change, if we can always do an update, is there a difference
between updating the ID: self.InputVolume_ID = node_InputVolume.GetID()
and updating the node reference: self._parameterNode.SetNodeReferenceID('InputVolume', node_InputVolume.GetID())
?

I would recommend to avoid node ID as a member variable as it would be too fragile. For example, if the user closes the scene and loads another scene then your module may find some completely unrelated node by that ID. You can make your module observe scene close and clear out the obsolete node ID, but there are several similar potential issues and node references take care of them.

Using node IDs are fine within method calls, as the user cannot close a scene or add/remove nodes while a method is running.

1 Like

Thank you so much, Andreas! I will try to void using nodeID.