Slicer crashes when setting master Sequence Node to SequenceBrowserNode

Operating system: Ubuntu Debian 18.04 (KDE neon 5.19)
Slicer version: 4.11.0-2020-06-05
Expected behavior:
Actual behavior:

Hi everyone,

I’m having some troubles managing sequences (create them and remove them completely) from python scripts for background nodes (ie ScalarVolumeNodes) and label nodes (ie LabelMapVolumeNodes). My problem is that I can create and delete everything once (sequence node for both background and label, sequence browser node, and both proxys). Buth when I attempt to create a sequence again after its removal, slicer crashes in this line:

SeqBrowNode.SetAndObserveMasterSequenceNodeID(SeqNode.GetID())

The way I manage a sequence creation is like this:

SeqBrowN = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSequenceBrowserNode')
SeqBrowN.SetName('SOME_SEQBROWN_NAME')

SeqN = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLSequenceNode')
SeqN.SetName('SOME_SEQN_NAME')

for frame_i in range(frames):
      NodeForSequence = slicer.mrmlScene.GetNodeByID('SOME_PREFIX' + str(frame_i))
      SeqN.SetDataNodeAtValue(NodeForSequence,str(frame_i))

SeqBrowN.SetAndObserveMasterSequenceNodeID(SeqN.GetID()) # Here I get the crash
sequencesModule.widgetRepresentation().setActiveBrowserNode(SeqBrowN)

The way I manage removal:

for seq_i in range(self.getNumberOfMySequences()):

    # Build background name
    name_i = str(seq_i + 1) + self.getBackgName()

    # Custom background SequenceNodes
    backgSeqNode = slicer.mrmlScene.GetNodesByClassByName('vtkMRMLSequenceNode',name_i).GetItemAsObject(0)
    while ( backgSeqNode != None ):
      backgSeqNode.RemoveAllObservers()
      slicer.mrmlScene.RemoveNode(backgSeqNode)
      backgSeqNode = slicer.mrmlScene.GetNodesByClassByName('vtkMRMLSequenceNode',name_i).GetItemAsObject(0)
    
    # Custom background ScalarVolumeNodes (proxys)
    backgProxyNode = slicer.mrmlScene.GetNodesByClassByName('vtkMRMLScalarVolumeNode',name_i).GetItemAsObject(0) 
    while ( backgProxyNode != None ):
      slicer.mrmlScene.RemoveNode(backgProxyNode)
      backgProxyNode = slicer.mrmlScene.GetNodesByClassByName('vtkMRMLScalarVolumeNode',name_i).GetItemAsObject(0)
    
  # Custom background SeqBrowNode
  name_SeqBrow = self.getBackgName()
  backgSeqBrowNode = slicer.mrmlScene.GetNodesByClassByName('vtkMRMLSequenceBrowserNode',name_SeqBrow).GetItemAsObject(0)
  while ( backgSeqBrowNode != None ):
    backgSeqBrowNode.RemoveAllObservers()  
    slicer.mrmlScene.RemoveNode(backgSeqBrowNode)
    backgSeqBrowNode = slicer.mrmlScene.GetNodesByClassByName('vtkMRMLSequenceBrowserNode',name_SeqBrow).GetItemAsObject(0)

I think I’m not removing correctly or maybe the synchronization is the problem. Any suggestion or similar code to look for and learn?

Thanks!!
Lucca

In the first example there does not seem to be anything wrong, so the issue is most likely the content of NodeForSequence. Can you send a code snippet that I can use as is to reproduce the crash? Or at least a link to your source code repository so that I can see the full context of the code.

To delete nodes, just call slicer.mrmlScene.RemoveNode(). No need for removing observers manually. Remove browser node first, then proxy nodes and sequence nodes.

Hi Andras,

First, thank you very much for your reply. I checked the NodeForSequence and they were correct (ScalarVolumeNodes). I could solved this by setting a ‘NodeAboutToBeRemoved’ callback on sequenceNodes and using RemoveSynchronizedSequenceNode’ s method of sequenceBrowserNode with its master SequenceNode that was about to be deleted. This stops slicer’s crashes and doesn’t give warnings. However, I don’t understand why it works.

I’m not sure how to encapsulate a snippet of code to reproduce as is, but I can try to make a reduced version. Meanwhile, here is the full code. Is relatively large, but functions mentioned are:

  • def createCardIAcSequence(self): (line 1466)
  • def deleteCardIAcSeqNodes(self,delete_only_shortSeq = False): (line 1549)

Thanks again