def __init__(self, parent=None):
        ScriptedLoadableModuleWidget.__init__(self, parent)
        self.masterNode = None
        self.labelNode = None

        self.paint = None
        self.paintMode = False
        self.correct = None
        self.correctMode = False
        self.logic = ParenchymaLogic()
        self.editUtil = EditUtil()
示例#2
0
    def enter(self):
        """
    When entering the module, check that the lightbox modes are off
    and that we have the volumes loaded
    """
        self.turnOffLightboxes()
        self.installShortcutKeys()

        # get the master and merge nodes from the composite node associated
        # with the red slice, but only if showing volumes and we don't already
        # have an active set of volumes that we are using
        if self.showVolumesFrame:
            if not self.helper.master or not self.helper.merge:
                # get the slice composite node for the Red slice view (we'll assume it exists
                # since we are in the editor) to get the current background and label
                # - set the foreground layer as the active ID
                # in the selection node for later calls to PropagateVolumeSelection
                compositeNode = EditUtil.getCompositeNode()
                selectionNode = slicer.app.applicationLogic().GetSelectionNode(
                )
                selectionNode.SetSecondaryVolumeID(
                    compositeNode.GetForegroundVolumeID())
                bgID = lbID = ""
                if compositeNode.GetBackgroundVolumeID():
                    bgID = compositeNode.GetBackgroundVolumeID()
                if compositeNode.GetLabelVolumeID():
                    lbID = compositeNode.GetLabelVolumeID()
                masterNode = slicer.mrmlScene.GetNodeByID(bgID)
                mergeNode = slicer.mrmlScene.GetNodeByID(lbID)
                self.setMasterNode(masterNode)
                self.setMergeNode(mergeNode)
        # if not showing volumes, the caller is responsible for setting the master and
        # merge nodes, most likely according to a widget within the caller

        # Observe the parameter node in order to make changes to
        # button states as needed
        self.parameterNode = EditUtil.getParameterNode()
        self.addObserver(self.parameterNode, vtk.vtkCommand.ModifiedEvent,
                         self.updateGUIFromMRML)

        self.addObserver(slicer.mrmlScene, slicer.mrmlScene.StartCloseEvent,
                         self.resetInterface)

        if self.helper:
            self.helper.onEnter()

        if self.toolsColor:
            self.toolsColor.updateGUIFromMRML(self.parameterNode,
                                              vtk.vtkCommand.ModifiedEvent)
示例#3
0
  def enter(self):
    """
    When entering the module, check that the lightbox modes are off
    and that we have the volumes loaded
    """
    self.turnOffLightboxes()
    self.installShortcutKeys()

    # get the master and merge nodes from the composite node associated
    # with the red slice, but only if showing volumes and we don't already
    # have an active set of volumes that we are using
    if self.showVolumesFrame:
      if not self.helper.master or not self.helper.merge:
        # get the slice composite node for the Red slice view (we'll assume it exists
        # since we are in the editor) to get the current background and label
        # - set the foreground layer as the active ID
        # in the selection node for later calls to PropagateVolumeSelection
        compositeNode = EditUtil.getCompositeNode()
        selectionNode = slicer.app.applicationLogic().GetSelectionNode()
        selectionNode.SetReferenceSecondaryVolumeID( compositeNode.GetForegroundVolumeID() )
        bgID = lbID = ""
        if compositeNode.GetBackgroundVolumeID():
          bgID = compositeNode.GetBackgroundVolumeID()
        if compositeNode.GetLabelVolumeID():
          lbID = compositeNode.GetLabelVolumeID()
        masterNode = slicer.mrmlScene.GetNodeByID( bgID )
        mergeNode = slicer.mrmlScene.GetNodeByID( lbID )
        self.setMasterNode(masterNode)
        self.setMergeNode(mergeNode)
    # if not showing volumes, the caller is responsible for setting the master and
    # merge nodes, most likely according to a widget within the caller

    # Observe the parameter node in order to make changes to
    # button states as needed
    self.parameterNode = EditUtil.getParameterNode()
    self.parameterNodeTag = self.parameterNode.AddObserver(vtk.vtkCommand.ModifiedEvent, self.updateGUIFromMRML)

    self.mrmlSceneTag = slicer.mrmlScene.AddObserver(slicer.mrmlScene.StartCloseEvent, self.resetInterface)

    if self.helper:
      self.helper.onEnter()

    if self.toolsColor:
      self.toolsColor.updateGUIFromMRML(self.parameterNode, vtk.vtkCommand.ModifiedEvent)
示例#4
0
    def setDefaultParams(self):
        """Configure here all the required params for any LabelEffect (Paint, Draw, ect.)"""
        # self.editUtil = EditUtil()
        self.parameterNode = EditUtil.getParameterNode()

        self.parameterNode.SetParameter("LabelEffect,paintOver",
                                        "1")  # Enable paintOver
        self.parameterNode.SetParameter("LabelEffect,paintThreshold",
                                        "1")  # Enable Threshold checkbox
        self.parameterNode.SetParameter("PaintEffect,radius", "5")
示例#5
0
 def __init__(self, parent = None):
   ScriptedLoadableModuleWidget.__init__(self, parent)
   self.masterNode = None
   self.labelNode = None
   
   self.paint = None
   self.paintMode = False
   self.correct = None
   self.correctMode = False
   self.logic = ParenchymaLogic()
   self.editUtil = EditUtil()
示例#6
0
    def create(self):
        self.findEffects()

        self.mainFrame = qt.QFrame(self.parent)
        self.mainFrame.objectName = 'MainFrame'
        vbox = qt.QVBoxLayout()
        self.mainFrame.setLayout(vbox)
        self.parent.layout().addWidget(self.mainFrame)

        #
        # the buttons
        #
        self.rowFrames = []
        self.actions = {}
        self.buttons = {}
        self.icons = {}
        self.callbacks = {}

        # create all of the buttons (restricted version from the original)
        self.createButtonRow(self.activeTools)
        # # createButtonRow() ensures that only effects in self.effects are exposed,
        # self.createButtonRow( ("DefaultTool", "EraseLabel", "PaintEffect", "DrawEffect", "WandEffect", "LevelTracingEffect", "RectangleEffect", "IdentifyIslandsEffect", "ChangeIslandEffect", "RemoveIslandsEffect", "SaveIslandEffect") )
        # self.createButtonRow( ("ErodeEffect", "DilateEffect", "GrowCutEffect", "WatershedFromMarkerEffect", "ThresholdEffect", "ChangeLabelEffect", "MakeModelEffect", "FastMarchingEffect") )

        extensions = []
        for k in slicer.modules.editorExtensions:
            extensions.append(k)
        self.createButtonRow(extensions)

        # self.createButtonRow( ("PreviousCheckPoint", "NextCheckPoint"), rowLabel="Undo/Redo: " )

        #
        # the labels
        #
        self.toolsActiveToolFrame = qt.QFrame(self.parent)
        self.toolsActiveToolFrame.setLayout(qt.QHBoxLayout())
        self.parent.layout().addWidget(self.toolsActiveToolFrame)
        self.toolsActiveTool = qt.QLabel(self.toolsActiveToolFrame)
        self.toolsActiveTool.setText('Active Tool:')
        self.toolsActiveTool.setStyleSheet(
            "background-color: rgb(232,230,235)")
        self.toolsActiveToolFrame.layout().addWidget(self.toolsActiveTool)
        self.toolsActiveToolName = qt.QLabel(self.toolsActiveToolFrame)
        self.toolsActiveToolName.setText('')
        self.toolsActiveToolName.setStyleSheet(
            "background-color: rgb(232,230,235)")
        self.toolsActiveToolFrame.layout().addWidget(self.toolsActiveToolName)

        vbox.addStretch(1)

        self.setDefaultParams()

        self.updateUndoRedoButtons()
        self._onParameterNodeModified(EditUtil.getParameterNode())
示例#7
0
  def onMouseEvent(self, observer, eventid):
      ras = [0.0, 0.0, 0.0]
      ras = slicer.util.getNode('Crosshair').GetCrosshairRAS()

      compositeNode = EditUtil.getCompositeNode()
      bgID = compositeNode.GetBackgroundVolumeID()

      if bgID == None:
        self.reportInfo(ras)
        return
      else:
        volumeNode = slicer.mrmlScene.GetNodeByID(bgID)
	val = self.volumeInfo(volumeNode, ras)          
        self.reportInfo(ras, val)
示例#8
0
文件: Editor.py 项目: mehrtash/Slicer
  def __init__(self, parent=None, showVolumesFrame=True):
    self.observerTags = []
    self.shortcuts = []
    self.toolsBox = None

    # set attributes from ctor parameters
    self.showVolumesFrame = showVolumesFrame

    self.editUtil = EditUtil() # Kept for backward compatibility

    if not parent:
      self.parent = slicer.qMRMLWidget()
      self.parent.setLayout(qt.QVBoxLayout())
      self.parent.setMRMLScene(slicer.mrmlScene)
      self.layout = self.parent.layout()
      self.setup()
      self.parent.show()
    else:
      self.parent = parent
      self.layout = parent.layout()
示例#9
0
    def __init__(self, parent=None, showVolumesFrame=True):
        VTKObservationMixin.__init__(self)
        self.shortcuts = []
        self.toolsBox = None

        # set attributes from ctor parameters
        self.showVolumesFrame = showVolumesFrame

        self.editUtil = EditUtil()  # Kept for backward compatibility

        if not parent:
            self.parent = slicer.qMRMLWidget()
            self.parent.setLayout(qt.QVBoxLayout())
            self.parent.setMRMLScene(slicer.mrmlScene)
            self.layout = self.parent.layout()
        else:
            self.parent = parent
            self.layout = parent.layout()

        ScriptedLoadableModuleWidget.__init__(self, parent)
示例#10
0
class ParenchymaWidget(ScriptedLoadableModuleWidget):
  """Uses ScriptedLoadableModuleWidget base class, available at:
  https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py
  """
  
  def __init__(self, parent = None):
    ScriptedLoadableModuleWidget.__init__(self, parent)
    self.masterNode = None
    self.labelNode = None
    
    self.paint = None
    self.paintMode = False
    self.correct = None
    self.correctMode = False
    self.logic = ParenchymaLogic()
    self.editUtil = EditUtil()
    #self.editUtil = EditorLib.EditUtil.EditUtil()
    #self.localParEditorWidget = None
       
  def setup(self):
    
    ScriptedLoadableModuleWidget.setup(self)
    # Instantiate and connect widgets ...

    #
    # Parameters Area
    #
    parametersCollapsibleButton = ctk.ctkCollapsibleButton()
    parametersCollapsibleButton.text = "Parameters"
    self.layout.addWidget(parametersCollapsibleButton)

    # Layout within the dummy collapsible button
    parametersLayout = qt.QFormLayout(parametersCollapsibleButton)

    #
    # input volume selector
    #
    self.inputSelector = slicer.qMRMLNodeComboBox()
    self.inputSelector.nodeTypes = ( ("vtkMRMLScalarVolumeNode"), "" )
    self.inputSelector.addAttribute( "vtkMRMLScalarVolumeNode", "LabelMap", 0 )
    self.inputSelector.selectNodeUponCreation = True
    self.inputSelector.addEnabled = False
    self.inputSelector.removeEnabled = False
    self.inputSelector.noneEnabled = True
    self.inputSelector.showHidden = False
    self.inputSelector.showChildNodeTypes = False
    self.inputSelector.setMRMLScene( slicer.mrmlScene )
    self.inputSelector.setToolTip( "Pick the input to the algorithm." )
    parametersLayout.addRow("Input Volume: ", self.inputSelector)
    
    #self.activeVolume = self.inputSelector.currentNode()
    #self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)

    #self.labelSelector = slicer.qSlicerLabelMapVolumeDisplayWidget()
    #parametersLayout.addRow("Label Map: ", self.labelSelector)
    
    #
    # Select Button
    #
    self.selectButton = qt.QPushButton("Select")
    self.selectButton.toolTip = "Select the volume."
    self.selectButton.enabled = True
    parametersLayout.addRow(self.selectButton)

    #
    # Gradient Button
    #
    self.gradientButton = qt.QPushButton("Gradient - sergio reimplementation")
    self.gradientButton.toolTip = "re-implementation of sergio's gradient."
    self.gradientButton.enabled = True
    parametersLayout.addRow(self.gradientButton)

    #
    # Paint Button
    #
    self.paintButton = qt.QPushButton("Paint")
    self.paintButton.toolTip = "Turn on paint."
    self.paintButton.enabled = True
    self.paintButton.checkable = True
    parametersLayout.addRow(self.paintButton)
    
    #
    # Apply mask Button
    #
    self.applyButton = qt.QPushButton("Apply mask")
    self.applyButton.toolTip = "Find area of mask."
    self.applyButton.enabled = True
    parametersLayout.addRow(self.applyButton)

    #
    # Range for threshold
    #
    self.threshold = ctk.ctkRangeWidget()
    lo, hi = self.getLoHiImageValues()
    self.threshold.minimum, self.threshold.maximum = lo, hi
    self.threshold.singleStep = (hi - lo) / 1000.
    parametersLayout.addRow(self.threshold)
    
    #
    # Grow Button
    #
    self.growButton = qt.QPushButton("Grow with Threshold")
    self.growButton.toolTip = "Grow into 3D with connected threshold."
    self.growButton.enabled = True
    parametersLayout.addRow(self.growButton)

    #
    # Liver 2D Button
    #
    self.liver2DButton = qt.QPushButton("Liver 2D")
    self.liver2DButton.toolTip = "Grow from mask in 2D, but up down into next slices."
    self.liver2DButton.enabled = True
    parametersLayout.addRow(self.liver2DButton)

    #
    # Cross remove Button
    #
    self.crossButton = qt.QPushButton("Cross remove")
    self.crossButton.toolTip = "re-implementation of sergio's cross remove."
    self.crossButton.enabled = True
    parametersLayout.addRow(self.crossButton)

    #
    # Connectivity reduction Button
    #
    self.connectivityButton = qt.QPushButton("Connectivity reduction")
    self.connectivityButton.toolTip = "re-implementation of sergio's connectivity reduction."
    self.connectivityButton.enabled = True
    parametersLayout.addRow(self.connectivityButton)
    
    #
    # Paint Button (correction)
    #
    self.correctButton = qt.QPushButton("Correct")
    self.correctButton.toolTip = "Turn on paint for annotating corrections."
    self.correctButton.enabled = True
    self.correctButton.checkable = True
    parametersLayout.addRow(self.correctButton)

    #
    # Track centroid under mask
    #
    self.trackMaskButton = qt.QPushButton("Track correction")
    self.trackMaskButton.toolTip = "Try to use correction mask, and track the centroid in has inside it"
    self.trackMaskButton.enabled = True
    parametersLayout.addRow(self.trackMaskButton)

    #
    # Erase mask (including all under)
    #
    self.eraseMaskButton = qt.QPushButton("Erase correction")
    self.eraseMaskButton.toolTip = "Delete the correction mask to hopefully orphan other areas"
    self.eraseMaskButton.enabled = True
    parametersLayout.addRow(self.eraseMaskButton)
    
    #
    # Remove unconnected
    #
    self.removeIsolatedButton = qt.QPushButton("Remove unconnected")
    self.removeIsolatedButton.toolTip = "try to see just the main blob and remove stuff not connected."
    self.removeIsolatedButton.enabled = True
    parametersLayout.addRow(self.removeIsolatedButton)

    
    # connections
    #buttons
    self.selectButton.connect('clicked(bool)', self.onSelectButton)
    self.gradientButton.connect('clicked(bool)', self.onGradientButton)   
    self.paintButton.connect('clicked(bool)', self.onPaintButton)
    self.applyButton.connect('clicked(bool)', self.onApplyButton)
    self.growButton.connect('clicked(bool)', self.onGrowButton)
    self.liver2DButton.connect('clicked(bool)', self.onliver2DButton)
    self.crossButton.connect('clicked(bool)', self.onCrossButton)
    self.connectivityButton.connect('clicked(bool)', self.onConnectivityButton)
    # correction tools buttons
    self.correctButton.connect('clicked(bool)', self.onCorrectButton)
    self.trackMaskButton.connect('clicked(bool)', self.onTrackMaskButton)
    self.eraseMaskButton.connect('clicked(bool)', self.onEraseMaskButton)
    self.removeIsolatedButton.connect('clicked(bool)', self.onRemoveIsolatedButton)

    self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)

    self.threshold.connect('valuesChanged(double,double)', self.onThresholdValuesChanged)

    # Creates and adds the custom Editor Widget to the module
    #self.localParEditorWidget = ParEditorWidget(parent=self.parent, showVolumesFrame=False)
    #self.localParEditorWidget.setup()
    #self.localParEditorWidget.enter()

    # Add vertical spacer
    self.layout.addStretch(1)

    # sets the layout to Red Slice Only
    layoutManager = slicer.app.layoutManager()
    layoutManager.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutOneUpRedSliceView)


  '''-----------------------------------------------------------------------------'''
    
  def cleanup(self):
    pass

  def onSelect(self):
    self.applyButton.enabled = self.inputSelector.currentNode()
    self.masterNode = self.inputSelector.currentNode()

  def onSelectButton(self):
    self.masterNode = self.inputSelector.currentNode()
    lo, hi = self.getLoHiImageValues()
    self.threshold.minimum, self.threshold.maximum = lo, hi
    self.threshold.singleStep = (hi - lo) / 1000.
    #print(self.inputSelector.currentNode())

  def onLabelButton(self):
    self.labelNode = self.logic.createLabelMap(self.inputSelector.currentNode())

  def onProcessFilterButton(self):
    self.logic.processFilter(self.masterNode)

  def onPaintButton(self):
    if self.paintMode:
      self.paintMode = False
      print("deleting paint")
      self.painter.cleanup()
      self.painter = None
      #self.paint.removeObs()
    else:
      self.paintMode = True

      # just in case?
      selectionNode = slicer.app.applicationLogic().GetSelectionNode()
      selectionNode.SetReferenceActiveVolumeID( self.masterNode.GetID() )
      if self.labelNode == None:
        self.labelNode = self.logic.createLabelMap(self.inputSelector.currentNode())
      selectionNode.SetReferenceActiveLabelVolumeID( self.labelNode.GetID() )
      slicer.app.applicationLogic().PropagateVolumeSelection(0)

      self.editUtil.setLabel(1) # green
      
      print("create paint (editor paint effect tool)")
      lm = slicer.app.layoutManager()
      paintEffect = EditorLib.PaintEffectOptions()
      paintEffect.setMRMLDefaults()
      paintEffect.__del__()
      sliceWidget = lm.sliceWidget('Red')
      self.painter = EditorLib.PaintEffectTool(sliceWidget)

  def onApplyButton(self):
    self.logic.runMask(self.masterNode, self.labelNode)
    mean, std = self.logic.getMeanSD()
    max = mean + std
    min = mean - std
    hi = mean + 4*std
    lo = mean - 4*std
    self.threshold.minimum, self.threshold.maximum = lo, hi
    self.setThresholdValues(min, max)

  def onGrowButton(self):
    self.logic.runThreshold(self.masterNode, self.labelNode)

  def onGradientButton(self):
    self.logic.runGradient(self.masterNode)

  def onliver2DButton(self):    
    print("Liver button")
    #runFindLiver2D(self,masterNode,labelNode): 
    self.logic.runFindLiver2D(self.masterNode, self.labelNode)

  def onCrossButton(self):
    self.logic.runCrossRemove(self.masterNode, self.labelNode, 2) # need to pass in size of cross 

  def onConnectivityButton(self):
    self.logic.runConnectivity(self.masterNode, self.labelNode, 10) # need to pass in number of pixels around it that need to be 1

  def onCorrectButton(self):
    if self.correctMode:
      self.correctMode = False
      print("deleting correct")
      self.painter.cleanup()
      self.painter = None
      #self.paint.removeObs()
    else:
      self.correctMode = True

      # just in case?
      selectionNode = slicer.app.applicationLogic().GetSelectionNode()
      selectionNode.SetReferenceActiveVolumeID( self.masterNode.GetID() )
      if self.labelNode == None:
        self.labelNode = self.logic.createLabelMap(self.inputSelector.currentNode())
      selectionNode.SetReferenceActiveLabelVolumeID( self.labelNode.GetID() )
      slicer.app.applicationLogic().PropagateVolumeSelection(0)

      self.editUtil.setLabel(5) # red

      print("create correct (editor paint effect tool)")
      lm = slicer.app.layoutManager()
      paintEffect = EditorLib.PaintEffectOptions()
      paintEffect.setMRMLDefaults()
      paintEffect.__del__()
      sliceWidget = lm.sliceWidget('Red')
      self.painter = EditorLib.PaintEffectTool(sliceWidget)

  def onTrackMaskButton(self):
    self.logic.runTrackMask(self.masterNode, self.labelNode)

  def onEraseMaskButton(self):
    self.logic.runEraseMask(self.masterNode, self.labelNode)

  def onRemoveIsolatedButton(self):
    self.logic.runRemoveIsolated(self.masterNode, self.labelNode)
      
  def onEdgeButton(self):
    self.logic.runFindEdge(self.masterNode, self.labelNode)

  def getLoHiImageValues(self):
    backgroundImage = self.masterNode
    lo = 0
    hi = 100
    if backgroundImage:
      data = backgroundImage.GetImageData()
      lo, hi = data.GetScalarRange()
      print('Low: ', lo)
      print('High: ', hi)
    return lo, hi

  def onThresholdValuesChanged(self):
    print('value changed')
    min = self.threshold.minimumValue
    max = self.threshold.maximumValue
    print(min, max)

  def setThresholdValues(self, min, max):
    self.threshold.setMinimumValue( min )
    self.threshold.setMaximumValue( max )
    def run(self, enableScreenshots=0, screenshotScaleFactor=1):
        """
    Run the actual algorithm
    """
        self.delayDisplay(
            'Running test of the Neurosurgical Planning tutorial')

        self.enableScreenshots = enableScreenshots
        self.screenshotScaleFactor = screenshotScaleFactor

        # conventional layout
        lm = slicer.app.layoutManager()
        lm.setLayout(2)

        moduleSelector = slicer.util.mainWindow().moduleSelector()
        #
        # first load the data
        #
        if self.enableScreenshots == 1:
            # for the tutorial, do it through the welcome module
            moduleSelector.selectModule('Welcome')
            self.delayDisplay("Screenshot")
            self.takeScreenshot('NeurosurgicalPlanning-Welcome',
                                'Welcome module', -1)
        else:
            # otherwise show the sample data module
            moduleSelector.selectModule('SampleData')

        # use the sample data module logic to load data for the self test
        import SampleData
        sampleDataLogic = SampleData.SampleDataLogic()

        self.delayDisplay("Getting Baseline volume")
        baselineVolume = sampleDataLogic.downloadWhiteMatterExplorationBaselineVolume(
        )

        self.takeScreenshot('NeurosurgicalPlanning-Loaded', 'Data loaded', -1)

        #
        # link the viewers
        #

        if self.enableScreenshots == 1:
            # for the tutorial, pop up the linking control
            sliceController = slicer.app.layoutManager().sliceWidget(
                "Red").sliceController()
            popupWidget = sliceController.findChild("ctkPopupWidget")
            if popupWidget is not None:
                popupWidget.pinPopup(1)
                self.takeScreenshot('NeurosurgicalPlanning-Link',
                                    'Link slice viewers', -1)
                popupWidget.pinPopup(0)

        sliceLogic = slicer.app.layoutManager().sliceWidget('Red').sliceLogic()
        compositeNode = sliceLogic.GetSliceCompositeNode()
        compositeNode.SetLinkedControl(1)

        #
        # baseline in the background
        #
        sliceLogic.StartSliceCompositeNodeInteraction(1)
        compositeNode.SetBackgroundVolumeID(baselineVolume.GetID())
        sliceLogic.EndSliceCompositeNodeInteraction()

        self.takeScreenshot('NeurosurgicalPlanning-Baseline',
                            'Baseline in background', -1)

        #
        # adjust window level on baseline
        #
        moduleSelector.selectModule('Volumes')
        baselineDisplay = baselineVolume.GetDisplayNode()
        baselineDisplay.SetAutoWindowLevel(0)
        baselineDisplay.SetWindow(2600)
        baselineDisplay.SetLevel(1206)
        self.takeScreenshot('NeurosurgicalPlanning-WindowLevel',
                            'Set W/L on baseline', -1)

        #
        # switch to red slice only
        #
        lm.setLayout(6)
        self.takeScreenshot('NeurosurgicalPlanning-RedSliceOnly',
                            'Set layout to Red Slice only', -1)

        #
        # segmentation of tumour
        #

        #
        # create a label map and set it for editing
        #
        volumesLogic = slicer.modules.volumes.logic()
        baselineVolumeLabel = volumesLogic.CreateAndAddLabelVolume(
            slicer.mrmlScene, baselineVolume,
            baselineVolume.GetName() + '-label')
        baselineDisplayNode = baselineVolumeLabel.GetDisplayNode()
        baselineDisplayNode.SetAndObserveColorNodeID(
            'vtkMRMLColorTableNodeFileGenericAnatomyColors.txt')
        selectionNode = slicer.app.applicationLogic().GetSelectionNode()
        selectionNode.SetReferenceActiveVolumeID(baselineVolume.GetID())
        selectionNode.SetReferenceActiveLabelVolumeID(
            baselineVolumeLabel.GetID())
        slicer.app.applicationLogic().PropagateVolumeSelection(0)

        #
        # editor module
        #
        moduleSelector.selectModule('Editor')
        self.takeScreenshot('NeurosurgicalPlanning-Editor',
                            'Showing Editor Module', -1)

        # set the slice offset so drawing is right
        sliceNode = sliceLogic.GetSliceNode()
        sliceOffset = 58.7
        sliceNode.SetSliceOffset(sliceOffset)

        #
        # paint
        #
        parameterNode = EditUtil.getParameterNode()
        paintEffect = EditorLib.PaintEffectOptions()
        paintEffect.setMRMLDefaults()
        paintEffect.__del__()
        sliceWidget = lm.sliceWidget('Red')
        paintTool = EditorLib.PaintEffectTool(sliceWidget)
        self.takeScreenshot('NeurosurgicalPlanning-Paint',
                            'Paint tool in Editor Module', -1)

        #
        # paint in cystic part of tumor, using converstion from RAS coords to
        # avoid slice widget size differences
        #
        EditUtil.setLabel(293)
        displayCoords = self.rasToDisplay(-7.4, 71, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-11, 73, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-12, 85, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-13, 91, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-15, 78, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        paintTool.paintApply()
        self.takeScreenshot('NeurosurgicalPlanning-PaintCystic',
                            'Paint cystic part of tumor', -1)

        #
        # paint in solid part of tumor
        #
        EditUtil.setLabel(7)
        displayCoords = self.rasToDisplay(-0.5, 118.5, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-7.4, 116, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        paintTool.paintApply()
        self.takeScreenshot('NeurosurgicalPlanning-PaintSolid',
                            'Paint solid part of tumor', -1)

        #
        # paint around the tumor
        #
        EditUtil.setLabel(295)
        rMax = 25
        rMin = -50
        aMax = 145
        aMin = 50
        rasStep = 5

        # draw the top and bottom
        for r in range(rMin, rMax, rasStep):
            displayCoords = self.rasToDisplay(r, aMin, sliceOffset)
            paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
            displayCoords = self.rasToDisplay(r, aMax, sliceOffset)
            paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        # draw the left and right
        for a in range(aMin, aMax, rasStep):
            displayCoords = self.rasToDisplay(rMin, a, sliceOffset)
            paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
            displayCoords = self.rasToDisplay(rMax, a, sliceOffset)
            paintTool.paintAddPoint(displayCoords[0], displayCoords[1])

        paintTool.paintApply()

        self.takeScreenshot('NeurosurgicalPlanning-PaintAround',
                            'Paint around tumor', -1)
        #
        # clean up after painting
        #
        paintTool.cleanup()
        paintTool = None

        #
        # Grow cut
        #
        growCutLogic = EditorLib.GrowCutEffectLogic(sliceWidget.sliceLogic())
        growCutLogic.growCut()
        self.takeScreenshot('NeurosurgicalPlanning-Growcut', 'Growcut', -1)

        #
        # Merge split volume
        #
        slicer.util.selectModule('Editor')
        slicer.util.findChildren(text='Split Merge Volume')[0].clicked()
        self.takeScreenshot('NeurosurgicalPlanning-SplitMerge', 'SplitMerge',
                            -1)

        #
        # go to the data module
        #
        moduleSelector.selectModule('Data')
        self.takeScreenshot('NeurosurgicalPlanning-SplitMergeData',
                            'SplitMerge results in Data', -1)

        #
        # Ventricles Segmentation
        #

        moduleSelector.selectModule('Editor')
        #
        # select the label volume with the area around the tumor
        slicer.util.findChildren(
            name='PerStructureVolumesFrame')[0].collapsed = False
        treeView = slicer.util.findChildren(name='StructuresView')[0]
        selection = qt.QItemSelection()
        # selecting the last split volume in the third row
        row = 2
        rowStart = treeView.model().index(row, 0)
        rowEnd = treeView.model().index(row,
                                        treeView.model().columnCount() - 1)
        # rowSel = qt.QItemSelection(rowStart, rowEnd)
        selection.select(rowStart, rowEnd)
        # backup: select the label map in the slice logic too
        baselinelabel295 = slicer.mrmlScene.GetFirstNodeByName(
            "BaselineVolume-region 3-label")
        sliceLogic.StartSliceCompositeNodeInteraction(1)
        compositeNode.SetLabelVolumeID(baselinelabel295.GetID())
        sliceLogic.EndSliceCompositeNodeInteraction()
        self.takeScreenshot('NeurosurgicalPlanning-SelOutside',
                            'Select outside region', -1)

        #
        # Threshold tool
        #
        slicer.modules.EditorWidget.toolsBox.selectEffect('ThresholdEffect')
        parameterNode = EditUtil.getParameterNode()
        parameterNode.SetParameter('ThresholdEffect,min', str(1700))
        slicer.modules.EditorWidget.toolsBox.currentTools[0].apply()
        self.takeScreenshot('NeurosurgicalPlanning-Ventricles',
                            'Ventricles segmentation', -1)

        #
        # Save Islands
        #
        slicer.modules.EditorWidget.toolsBox.selectEffect('SaveIslandEffect')
        saveIslandLogic = EditorLib.SaveIslandEffectLogic(
            sliceWidget.sliceLogic())
        displayCoords = self.rasToDisplay(25.3, 5.8, sliceOffset)
        xy = (displayCoords[0], displayCoords[1])
        saveIslandLogic.saveIsland(xy)
        self.takeScreenshot('NeurosurgicalPlanning-SaveIsland',
                            'Ventricles save island', -1)

        #
        # Merge and build
        #
        slicer.util.findChildren(text='Merge And Build')[0].clicked()

        #
        # switch to conventional layout
        #
        lm.setLayout(2)
        self.takeScreenshot('NeurosurgicalPlanning-MergeAndBuild',
                            'Merged and built models', -1)

        #
        # select label volume with label 293, in the second row
        #
        row = 1
        rowStart = treeView.model().index(row, 0)
        rowEnd = treeView.model().index(row,
                                        treeView.model().columnCount() - 1)
        # rowSel = qt.QItemSelection(rowStart, rowEnd)
        selection.select(rowStart, rowEnd)
        # backup: select the label map in the slice logic too
        baselinelabel293 = slicer.mrmlScene.GetFirstNodeByName(
            "BaselineVolume-region 1-label")
        sliceLogic.StartSliceCompositeNodeInteraction(1)
        compositeNode.SetLabelVolumeID(baselinelabel293.GetID())
        sliceLogic.EndSliceCompositeNodeInteraction()
        self.takeScreenshot('NeurosurgicalPlanning-SelCystic',
                            'Select cystic region', -1)

        #
        # Dilate
        #
        slicer.modules.EditorWidget.toolsBox.selectEffect('DilateEffect')
        EditUtil.setLabel(293)
        self.takeScreenshot('NeurosurgicalPlanning-Dilate', 'Dilate tool', -1)
        # tutorial says to click apply three times
        for d in range(1, 3):
            print d
            # slicer.util.findChildren(name='DilateEffectOptionsApply')[0].clicked()
            # slicer.modules.EditorWidget.toolsBox.currentTools[0].apply()
            slicer.modules.EditorWidget.toolsBox.currentOption.onApply()
        self.takeScreenshot('NeurosurgicalPlanning-Dilated', 'Dilated tumor',
                            -1)

        return True
示例#12
0
    def test_ThresholdThreading(self):
        """
    Replicate the issue reported in bug 1822 where spliting
    a grow-cut produced volume causes a multi-threading related
    issue on mac release builds
    """

        #
        # first, get some sample data
        #
        self.delayDisplay("Get some data")
        import SampleData
        sampleDataLogic = SampleData.SampleDataLogic()
        head = sampleDataLogic.downloadMRHead()

        #
        # now, define an ROI in it
        #
        roi = slicer.vtkMRMLAnnotationROINode()
        slicer.mrmlScene.AddNode(roi)
        roi.SetXYZ(-2, 104, -80)
        roi.SetRadiusXYZ(30, 30, 30)

        #
        # apply the cropping to the head
        #
        cropLogic = slicer.modules.cropvolume.logic()
        cvpn = slicer.vtkMRMLCropVolumeParametersNode()
        cvpn.SetROINodeID(roi.GetID())
        cvpn.SetInputVolumeNodeID(head.GetID())
        cropLogic.Apply(cvpn)
        croppedHead = slicer.mrmlScene.GetNodeByID(
            cvpn.GetOutputVolumeNodeID())

        #
        # create a label map and set it for editing
        #
        volumesLogic = slicer.modules.volumes.logic()
        croppedHeadLabel = volumesLogic.CreateAndAddLabelVolume(
            slicer.mrmlScene, croppedHead,
            croppedHead.GetName() + '-label')
        selectionNode = slicer.app.applicationLogic().GetSelectionNode()
        selectionNode.SetActiveVolumeID(croppedHead.GetID())
        selectionNode.SetActiveLabelVolumeID(croppedHeadLabel.GetID())
        slicer.app.applicationLogic().PropagateVolumeSelection(0)

        #
        # got to the editor and do some drawing
        #
        self.delayDisplay("Paint some things")
        parameterNode = EditUtil.getParameterNode()
        lm = slicer.app.layoutManager()
        paintEffect = EditorLib.PaintEffectOptions()
        paintEffect.setMRMLDefaults()
        paintEffect.__del__()
        sliceWidget = lm.sliceWidget('Red')
        paintTool = EditorLib.PaintEffectTool(sliceWidget)
        EditUtil.setLabel(1)
        paintTool.paintAddPoint(100, 100)
        paintTool.paintApply()
        EditUtil.setLabel(2)
        paintTool.paintAddPoint(200, 200)
        paintTool.paintApply()
        paintTool.cleanup()
        paintTool = None

        self.delayDisplay("Now grow cut")

        #
        # now do GrowCut
        #
        growCutLogic = EditorLib.GrowCutEffectLogic(sliceWidget.sliceLogic())
        growCutLogic.growCut()

        #
        # now split the volume, merge it back, and see if it looks right
        #
        preArray = slicer.util.array(croppedHeadLabel.GetName())
        slicer.util.selectModule('Editor')
        slicer.util.findChildren(text='Split Merge Volume')[0].clicked()
        slicer.util.findChildren(text='Merge All')[0].clicked()
        postArray = slicer.util.array(croppedHeadLabel.GetName())

        if (postArray - preArray).max() != 0:
            print("!$!$!#!@#!@!@$%! Test Failed!!")
        else:
            print("Ahh... test passed.")

        self.assertEqual((postArray - preArray).max(), 0)

        self.delayDisplay("Test passed!")
  def run(self,enableScreenshots=0,screenshotScaleFactor=1):
    """
    Run the actual algorithm
    """
    self.delayDisplay('Running test of the Neurosurgical Planning tutorial')

    self.enableScreenshots = enableScreenshots
    self.screenshotScaleFactor = screenshotScaleFactor

    # conventional layout
    lm = slicer.app.layoutManager()
    lm.setLayout(2)

    moduleSelector = slicer.util.mainWindow().moduleSelector()
    #
    # first load the data
    #
    if self.enableScreenshots == 1:
      # for the tutorial, do it through the welcome module
      moduleSelector.selectModule('Welcome')
      self.delayDisplay("Screenshot")
      self.takeScreenshot('NeurosurgicalPlanning-Welcome','Welcome module',-1)
    else:
      # otherwise show the sample data module
      moduleSelector.selectModule('SampleData')

    # use the sample data module logic to load data for the self test
    import SampleData
    sampleDataLogic = SampleData.SampleDataLogic()

    self.delayDisplay("Getting Baseline volume")
    baselineVolume = sampleDataLogic.downloadWhiteMatterExplorationBaselineVolume()

    self.delayDisplay("Getting DTI volume")
    dtiVolume = sampleDataLogic.downloadWhiteMatterExplorationDTIVolume()

    self.takeScreenshot('NeurosurgicalPlanning-Loaded','Data loaded',-1)

    #
    # link the viewers
    #

    if self.enableScreenshots == 1:
      # for the tutorial, pop up the linking control
      sliceController = slicer.app.layoutManager().sliceWidget("Red").sliceController()
      popupWidget = sliceController.findChild("ctkPopupWidget")
      if popupWidget != None:
        popupWidget.pinPopup(1)
        self.takeScreenshot('NeurosurgicalPlanning-Link','Link slice viewers',-1)
        popupWidget.pinPopup(0)

    sliceLogic = slicer.app.layoutManager().sliceWidget('Red').sliceLogic()
    compositeNode = sliceLogic.GetSliceCompositeNode()
    compositeNode.SetLinkedControl(1)

    #
    # baseline in the background
    #
    sliceLogic.StartSliceCompositeNodeInteraction(1)
    compositeNode.SetBackgroundVolumeID(baselineVolume.GetID())
    sliceLogic.EndSliceCompositeNodeInteraction()

    self.takeScreenshot('NeurosurgicalPlanning-Baseline','Baseline in background',-1)

    #
    # adjust window level on baseline
    #
    moduleSelector.selectModule('Volumes')
    baselineDisplay = baselineVolume.GetDisplayNode()
    baselineDisplay.SetAutoWindowLevel(0)
    baselineDisplay.SetWindow(2600)
    baselineDisplay.SetLevel(1206)
    self.takeScreenshot('NeurosurgicalPlanning-WindowLevel','Set W/L on baseline',-1)

    #
    # switch to red slice only
    #
    lm.setLayout(6)
    self.takeScreenshot('NeurosurgicalPlanning-RedSliceOnly','Set layout to Red Slice only',-1)

    #
    # segmentation of tumour
    #

    #
    # create a label map and set it for editing
    #
    volumesLogic = slicer.modules.volumes.logic()
    baselineVolumeLabel =  volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, baselineVolume, baselineVolume.GetName() + '-label' )
    baselineDisplayNode = baselineVolumeLabel.GetDisplayNode()
    baselineDisplayNode.SetAndObserveColorNodeID('vtkMRMLColorTableNodeFileGenericAnatomyColors.txt')
    selectionNode = slicer.app.applicationLogic().GetSelectionNode()
    selectionNode.SetReferenceActiveVolumeID(baselineVolume.GetID())
    selectionNode.SetReferenceActiveLabelVolumeID(baselineVolumeLabel.GetID())
    slicer.app.applicationLogic().PropagateVolumeSelection(0)

    #
    # editor module
    #
    moduleSelector.selectModule('Editor')
    self.takeScreenshot('NeurosurgicalPlanning-Editor','Showing Editor Module',-1)

    # set the slice offset so drawing is right
    sliceNode = sliceLogic.GetSliceNode()
    sliceOffset = 58.7
    sliceNode.SetSliceOffset(sliceOffset)

    #
    # paint
    #
    parameterNode = EditUtil.getParameterNode()
    paintEffect = EditorLib.PaintEffectOptions()
    paintEffect.setMRMLDefaults()
    paintEffect.__del__()
    sliceWidget = lm.sliceWidget('Red')
    paintTool = EditorLib.PaintEffectTool(sliceWidget)
    self.takeScreenshot('NeurosurgicalPlanning-Paint','Paint tool in Editor Module',-1)

    #
    # paint in cystic part of tumor, using converstion from RAS coords to
    # avoid slice widget size differences
    #
    EditUtil.setLabel(293)
    displayCoords = self.rasToDisplay(-7.4, 71, sliceOffset)
    paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
    displayCoords = self.rasToDisplay(-11, 73, sliceOffset)
    paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
    displayCoords = self.rasToDisplay(-12, 85, sliceOffset)
    paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
    displayCoords = self.rasToDisplay(-13, 91, sliceOffset)
    paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
    displayCoords = self.rasToDisplay(-15, 78, sliceOffset)
    paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
    paintTool.paintApply()
    self.takeScreenshot('NeurosurgicalPlanning-PaintCystic','Paint cystic part of tumor',-1)

    #
    # paint in solid part of tumor
    #
    EditUtil.setLabel(7)
    displayCoords = self.rasToDisplay(-0.5 , 118.5, sliceOffset)
    paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
    displayCoords = self.rasToDisplay(-7.4 , 116, sliceOffset)
    paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
    paintTool.paintApply()
    self.takeScreenshot('NeurosurgicalPlanning-PaintSolid','Paint solid part of tumor',-1)

    #
    # paint around the tumor
    #
    EditUtil.setLabel(295)
    rMax = 25
    rMin = -50
    aMax = 145
    aMin = 50
    rasStep = 5

    # draw the top and bottom
    for r in range(rMin, rMax, rasStep):
      displayCoords = self.rasToDisplay(r, aMin, sliceOffset)
      paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
      displayCoords = self.rasToDisplay(r, aMax, sliceOffset)
      paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
    # draw the left and right
    for a in range(aMin, aMax, rasStep):
      displayCoords = self.rasToDisplay(rMin, a, sliceOffset)
      paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
      displayCoords = self.rasToDisplay(rMax, a, sliceOffset)
      paintTool.paintAddPoint(displayCoords[0], displayCoords[1])

    paintTool.paintApply()

    self.takeScreenshot('NeurosurgicalPlanning-PaintAround','Paint around tumor',-1)
    #
    # clean up after painting
    #
    paintTool.cleanup()
    paintTool = None

    #
    # Grow cut
    #
    growCutLogic = EditorLib.GrowCutEffectLogic(sliceWidget.sliceLogic())
    growCutLogic.growCut()
    self.takeScreenshot('NeurosurgicalPlanning-Growcut','Growcut',-1)

    #
    # Merge split volume
    #
    slicer.util.selectModule('Editor')
    slicer.util.findChildren(text='Split Merge Volume')[0].clicked()
    self.takeScreenshot('NeurosurgicalPlanning-SplitMerge','SplitMerge',-1)

    #
    # go to the data module
    #
    moduleSelector.selectModule('Data')
    self.takeScreenshot('NeurosurgicalPlanning-SplitMergeData','SplitMerge results in Data',-1)

    #
    # Ventricles Segmentation
    #

    moduleSelector.selectModule('Editor')
    #
    # select the label volume with the area around the tumor
    slicer.util.findChildren(name='PerStructureVolumesFrame')[0].collapsed = False
    treeView = slicer.util.findChildren(name='StructuresView')[0]
    selection = qt.QItemSelection()
    # selecting the last split volume in the third row
    row = 2
    rowStart = treeView.model().index(row,0)
    rowEnd = treeView.model().index(row,treeView.model().columnCount() - 1)
    # rowSel = qt.QItemSelection(rowStart, rowEnd)
    selection.select(rowStart, rowEnd)
    # backup: select the label map in the slice logic too
    baselinelabel295 = slicer.mrmlScene.GetFirstNodeByName("BaselineVolume-region 3-label")
    sliceLogic.StartSliceCompositeNodeInteraction(1)
    compositeNode.SetLabelVolumeID(baselinelabel295.GetID())
    sliceLogic.EndSliceCompositeNodeInteraction()
    self.takeScreenshot('NeurosurgicalPlanning-SelOutside','Select outside region',-1)

    #
    # Threshold tool
    #
    slicer.modules.EditorWidget.toolsBox.selectEffect('ThresholdEffect')
    parameterNode = EditUtil.getParameterNode()
    parameterNode.SetParameter('ThresholdEffect,min', str(1700))
    slicer.modules.EditorWidget.toolsBox.currentTools[0].apply()
    self.takeScreenshot('NeurosurgicalPlanning-Ventricles','Ventricles segmentation',-1)

    #
    # Save Islands
    #
    slicer.modules.EditorWidget.toolsBox.selectEffect('SaveIslandEffect')
    saveIslandLogic = EditorLib.SaveIslandEffectLogic(sliceWidget.sliceLogic())
    displayCoords = self.rasToDisplay(25.3, 5.8, sliceOffset)
    xy = (displayCoords[0], displayCoords[1])
    saveIslandLogic.saveIsland(xy)
    self.takeScreenshot('NeurosurgicalPlanning-SaveIsland','Ventricles save island',-1)

    #
    # Merge and build
    #
    slicer.util.findChildren(text='Merge And Build')[0].clicked()

    #
    # switch to conventional layout
    #
    lm.setLayout(2)
    self.takeScreenshot('NeurosurgicalPlanning-MergeAndBuild','Merged and built models',-1)

    #
    # Tractography label map seeding
    #

    #
    # select label volume with label 293, in the second row
    #
    row = 1
    rowStart = treeView.model().index(row,0)
    rowEnd = treeView.model().index(row,treeView.model().columnCount() - 1)
    # rowSel = qt.QItemSelection(rowStart, rowEnd)
    selection.select(rowStart, rowEnd)
    # backup: select the label map in the slice logic too
    baselinelabel293 = slicer.mrmlScene.GetFirstNodeByName("BaselineVolume-region 1-label")
    sliceLogic.StartSliceCompositeNodeInteraction(1)
    compositeNode.SetLabelVolumeID(baselinelabel293.GetID())
    sliceLogic.EndSliceCompositeNodeInteraction()
    self.takeScreenshot('NeurosurgicalPlanning-SelCystic','Select cystic region',-1)

    #
    # Dilate
    #
    slicer.modules.EditorWidget.toolsBox.selectEffect('DilateEffect')
    EditUtil.setLabel(293)
    self.takeScreenshot('NeurosurgicalPlanning-Dilate','Dilate tool',-1)
    # tutorial says to click apply three times
    for d in range (1,3):
      print d
      # slicer.util.findChildren(name='DilateEffectOptionsApply')[0].clicked()
      # slicer.modules.EditorWidget.toolsBox.currentTools[0].apply()
      slicer.modules.EditorWidget.toolsBox.currentOption.onApply()
    self.takeScreenshot('NeurosurgicalPlanning-Dilated','Dilated tumor',-1)

    #
    # Tractography Label Map Seeding module
    #
    moduleSelector.selectModule('TractographyLabelMapSeeding')
    self.takeScreenshot('NeurosurgicalPlanning-LabelMapSeedingModule','Showing Tractography Label Seeding Module',-1)
    tractographyLabelSeeding = slicer.modules.tractographylabelmapseeding
    parameters = {}
    parameters['InputVolume'] = dtiVolume.GetID()
    baselinelabel293 = slicer.mrmlScene.GetFirstNodeByName("BaselineVolume-region 1-label")
# VTK6 TODO - set 'InputROIPipelineInfo'
    parameters['InputROI'] = baselinelabel293.GetID()
    fibers = slicer.vtkMRMLFiberBundleNode()
    slicer.mrmlScene.AddNode(fibers)
    parameters['OutputFibers'] = fibers.GetID()
    parameters['UseIndexSpace'] = 1
    parameters['StoppingValue'] = 0.15
    parameters['ROIlabel'] = 293
    parameters['StoppingMode'] = 'FractionalAnisotropy'
    # defaults
    # parameters['ClTh'] = 0.3
    # parameters['MinimumLength'] = 20
    # parameters['MaximumLength'] = 800
    # parameters['StoppingCurvature'] = 0.7
    # parameters['IntegrationStepLength'] = 0.5
    # parameters['SeedSpacing'] = 2
    # and run it
    slicer.cli.run(tractographyLabelSeeding, None, parameters)
    self.takeScreenshot('NeurosurgicalPlanning-LabelMapSeeding','Showing Tractography Label Seeding Results',-1)

    #
    # tractography fiducial seeding
    #
    moduleSelector.selectModule('TractographyInteractiveSeeding')
    self.takeScreenshot('NeurosurgicalPlanning-TIS','Showing Tractography Interactive Seeding Module',-1)

    # DTI in background
    sliceLogic.StartSliceCompositeNodeInteraction(1)
    compositeNode.SetBackgroundVolumeID(dtiVolume.GetID())
    sliceLogic.EndSliceCompositeNodeInteraction()

    # DTI visible in 3D
    sliceNode = sliceLogic.GetSliceNode()
    sliceLogic.StartSliceNodeInteraction(128)
    sliceNode.SetSliceVisible(1)
    sliceLogic.EndSliceNodeInteraction()

    self.takeScreenshot('NeurosurgicalPlanning-TIS-DTI','DTI volume with Tractography Interactive Seeding Module',-1)

    # place a fiducial
    displayNode = slicer.vtkMRMLMarkupsDisplayNode()
    slicer.mrmlScene.AddNode(displayNode)
    fidNode = slicer.vtkMRMLMarkupsFiducialNode()
    fidNode.SetName('F')
    slicer.mrmlScene.AddNode(fidNode)
    fidNode.SetAndObserveDisplayNodeID(displayNode.GetID())
    r = 28.338526
    a = 34.064367
    s = sliceOffset
    fidNode.AddFiducial(r,a,s)

    # make it active
    selectionNode = slicer.mrmlScene.GetNodeByID("vtkMRMLSelectionNodeSingleton")
    if (selectionNode != None):
      selectionNode.SetReferenceActivePlaceNodeID(fidNode.GetID())

    self.takeScreenshot('NeurosurgicalPlanning-TIS-Fid1','Fiducial in Tractography Interactive Seeding Module',-1)


    # set up the arguments
    wr = slicer.modules.tractographyinteractiveseeding.widgetRepresentation()
    wr.setDiffusionTensorVolumeNode(dtiVolume)
    # create a fiber bundle
    fiducialFibers = slicer.vtkMRMLFiberBundleNode()
    slicer.mrmlScene.AddNode(fiducialFibers)
    wr.setFiberBundleNode(fiducialFibers)
    wr.setSeedingNode(fidNode)
    wr.setMinimumPath(10)
    wr.setStoppingValue(0.15)

    self.takeScreenshot('NeurosurgicalPlanning-TIS-Args','Tractography Interactive Seeding arguments',-1)

    self.delayDisplay("Moving the fiducial")
    for y in range(-20, 100, 5):
      msg = "Moving the fiducial to y = " + str(y)
      self.delayDisplay(msg,250)
      fidNode.SetNthFiducialPosition(0, r, y, s)

    self.takeScreenshot('NeurosurgicalPlanning-TIS-Moved','Moved fiducial and did Tractography Interactive Seeding',-1)

    return True
示例#14
0
 def onApply(self):
     logic = BinaryWatershedEffectLogic(EditUtil.getSliceLogic())
     logic.undoRedo = self.undoRedo
     logic.splitSize = float(self.splitSizeSpinBox.value)
     logic.doit()
 def onApply(self):
   logic = BinaryWatershedEffectLogic( EditUtil.getSliceLogic() )
   logic.undoRedo = self.undoRedo
   logic.splitSize = float( self.splitSizeSpinBox.value )
   logic.doit()
示例#16
0
  def test_SEGExporterSelfTest1(self):
    """ Test DICOM import, segmentation, export
    """
    self.messageDelay = 50

    import os
    self.delayDisplay("Starting the DICOM SEG Export test")

    #
    # first, get the data - a zip file of dicom data
    #
    filePath = self.logic.downloadSampleData()
    self.delayDisplay('Finished with download\n')

    self.delayDisplay("Unzipping")
    dicomFilesDirectory = self.logic.unzipSampleData(filePath)

    try:
      self.delayDisplay("Switching to temp database directory")
      tempDatabaseDirectory = slicer.app.temporaryPath + '/tempDICOMDatabase'
      import shutil
      try:
        shutil.rmtree(tempDatabaseDirectory)
      except OSError:
        pass
      qt.QDir().mkpath(tempDatabaseDirectory)
      if slicer.dicomDatabase:
        originalDatabaseDirectory = os.path.split(slicer.dicomDatabase.databaseFilename)[0]
      else:
        originalDatabaseDirectory = None
        settings = qt.QSettings()
        settings.setValue('DatabaseDirectory', tempDatabaseDirectory)
      dicomWidget = slicer.modules.dicom.widgetRepresentation().self()
      dicomWidget.onDatabaseDirectoryChanged(tempDatabaseDirectory)

      self.delayDisplay('Importing DICOM')
      mainWindow = slicer.util.mainWindow()
      mainWindow.moduleSelector().selectModule('DICOM')

      self.logic.importIntoDICOMDatabase(dicomFilesDirectory)

      dicomWidget.detailsPopup.open()

      # load the data by series UID
      mrHeadSeriesUID = "2.16.840.1.113662.4.4168496325.1025306170.548651188813145058"
      dicomWidget.detailsPopup.offerLoadables(mrHeadSeriesUID, 'Series')
      dicomWidget.detailsPopup.examineForLoading()
      self.delayDisplay('Loading Selection')
      dicomWidget.detailsPopup.loadCheckedLoadables()

      #
      # create a label map and set it for editing
      #
      masterNode = slicer.util.getNode('2: SAG*')
      volumesLogic = slicer.modules.volumes.logic()
      mergeNode = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, masterNode, masterNode.GetName() + '-label' )
      mergeNode.GetDisplayNode().SetAndObserveColorNodeID('vtkMRMLColorTableNodeFileGenericAnatomyColors.txt')
      selectionNode = slicer.app.applicationLogic().GetSelectionNode()
      selectionNode.SetReferenceActiveVolumeID( masterNode.GetID() )
      selectionNode.SetReferenceActiveLabelVolumeID( mergeNode.GetID() )
      slicer.app.applicationLogic().PropagateVolumeSelection(0)

      #
      # go to the editor and do some drawing
      #
      slicer.util.selectModule('Editor')

      import EditorLib
      from EditorLib.EditUtil import EditUtil
      parameterNode = EditUtil.getParameterNode()
      parameterNode.SetParameter("LabelEffect,paintThreshold", "1")
      parameterNode.SetParameter("LabelEffect,paintThresholdMin", "70.0")
      parameterNode.SetParameter("LabelEffect,paintThresholdMax", "279.75")
      parameterNode.SetParameter("PaintEffect,radius", "40")
      parameterNode.SetParameter("PaintEffect,sphere", "1")

      self.delayDisplay("Paint some things")
      parameterNode = EditUtil.getParameterNode()
      lm = slicer.app.layoutManager()
      paintEffect = EditorLib.PaintEffectOptions()
      paintEffect.setMRMLDefaults()
      paintEffect.__del__()
      sliceWidget = lm.sliceWidget('Red')
      paintTool = EditorLib.PaintEffectTool(sliceWidget)
      EditUtil.setLabel(1)
      paintTool.paintAddPoint(100,100)
      paintTool.paintApply()
      EditUtil.setLabel(2)
      paintTool.paintAddPoint(200,200)
      paintTool.paintApply()
      paintTool.cleanup()
      paintTool = None

      # save these to compare with the one we read back
      originalSegmentationArray = slicer.util.array(mergeNode.GetID())
      originalSegmentationNodeCopy = slicer.vtkMRMLLabelMapVolumeNode()
      originalSegmentationNodeCopy.CopyOrientation(mergeNode)

      # export the volumes into a SEG
      tempSEGDirectory = slicer.app.temporaryPath + '/tempDICOMSEG'
      qt.QDir().mkpath(tempSEGDirectory)
      segFilePath = os.path.join(tempSEGDirectory, "test.SEG.dcm")


      self.delayDisplay('spliting...', 200)
      EditUtil.splitPerStructureVolumes(masterNode, mergeNode)

      self.delayDisplay('exporting...', 200)
      EditUtil.exportAsDICOMSEG(masterNode)

      # close scene re-load the input data and SEG
      slicer.mrmlScene.Clear(0)
      indexer = ctk.ctkDICOMIndexer()
      indexer.addDirectory(slicer.dicomDatabase, tempSEGDirectory, None)
      indexer.waitForImportFinished()

      mrHeadStudyUID = "2.16.840.1.113662.4.4168496325.1025305873.7118351817185979330"
      dicomWidget.detailsPopup.offerLoadables(mrHeadStudyUID, 'Study')
      dicomWidget.detailsPopup.examineForLoading()
      self.delayDisplay('Loading Selection')
      dicomWidget.detailsPopup.loadCheckedLoadables()

      # confirm that segmentations are correctly reloaded
      headLabelName = '2: SAG/RF-FAST/VOL/FLIP 30-label'
      reloadedLabel = slicer.util.getNode(headLabelName)
      reloadedSegmentationArray = slicer.util.array(reloadedLabel.GetID())

      import numpy
      self.assertTrue(numpy.alltrue(originalSegmentationArray == reloadedSegmentationArray))
      geometryWarnings = volumesLogic.CompareVolumeGeometry(mergeNode, reloadedLabel)
      print(geometryWarnings)
      self.assertTrue(geometryWarnings == '')

      # re-export

      # close scene re-load the input data and SEG

      # confirm that segmentations are available again as per-structure volumes


      self.delayDisplay('Test passed!')
    except Exception, e:
      import traceback
      traceback.print_exc()
      self.delayDisplay('Test caused exception!\n' + str(e))
class ParenchymaWidget(ScriptedLoadableModuleWidget):
    """Uses ScriptedLoadableModuleWidget base class, available at:
  https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py
  """
    def __init__(self, parent=None):
        ScriptedLoadableModuleWidget.__init__(self, parent)
        self.masterNode = None
        self.labelNode = None

        self.paint = None
        self.paintMode = False
        self.correct = None
        self.correctMode = False
        self.logic = ParenchymaLogic()
        self.editUtil = EditUtil()
        #self.editUtil = EditorLib.EditUtil.EditUtil()
        #self.localParEditorWidget = None

    def setup(self):

        ScriptedLoadableModuleWidget.setup(self)
        # Instantiate and connect widgets ...

        #
        # Parameters Area
        #
        parametersCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersCollapsibleButton.text = "Parameters"
        self.layout.addWidget(parametersCollapsibleButton)

        # Layout within the dummy collapsible button
        parametersLayout = qt.QFormLayout(parametersCollapsibleButton)

        #
        # input volume selector
        #
        self.inputSelector = slicer.qMRMLNodeComboBox()
        self.inputSelector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "")
        self.inputSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap",
                                        0)
        self.inputSelector.selectNodeUponCreation = True
        self.inputSelector.addEnabled = False
        self.inputSelector.removeEnabled = False
        self.inputSelector.noneEnabled = True
        self.inputSelector.showHidden = False
        self.inputSelector.showChildNodeTypes = False
        self.inputSelector.setMRMLScene(slicer.mrmlScene)
        self.inputSelector.setToolTip("Pick the input to the algorithm.")
        parametersLayout.addRow("Input Volume: ", self.inputSelector)

        #self.activeVolume = self.inputSelector.currentNode()
        #self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)

        #self.labelSelector = slicer.qSlicerLabelMapVolumeDisplayWidget()
        #parametersLayout.addRow("Label Map: ", self.labelSelector)

        #
        # Select Button
        #
        self.selectButton = qt.QPushButton("Select")
        self.selectButton.toolTip = "Select the volume."
        self.selectButton.enabled = True
        parametersLayout.addRow(self.selectButton)

        #
        # Gradient Button
        #
        self.gradientButton = qt.QPushButton(
            "Gradient - sergio reimplementation")
        self.gradientButton.toolTip = "re-implementation of sergio's gradient."
        self.gradientButton.enabled = True
        parametersLayout.addRow(self.gradientButton)

        #
        # Paint Button
        #
        self.paintButton = qt.QPushButton("Paint")
        self.paintButton.toolTip = "Turn on paint."
        self.paintButton.enabled = True
        self.paintButton.checkable = True
        parametersLayout.addRow(self.paintButton)

        #
        # Apply mask Button
        #
        self.applyButton = qt.QPushButton("Apply mask")
        self.applyButton.toolTip = "Find area of mask."
        self.applyButton.enabled = True
        parametersLayout.addRow(self.applyButton)

        #
        # Range for threshold
        #
        self.threshold = ctk.ctkRangeWidget()
        lo, hi = self.getLoHiImageValues()
        self.threshold.minimum, self.threshold.maximum = lo, hi
        self.threshold.singleStep = (hi - lo) / 1000.
        parametersLayout.addRow(self.threshold)

        #
        # Grow Button
        #
        self.growButton = qt.QPushButton("Grow with Threshold")
        self.growButton.toolTip = "Grow into 3D with connected threshold."
        self.growButton.enabled = True
        parametersLayout.addRow(self.growButton)

        #
        # Liver 2D Button
        #
        self.liver2DButton = qt.QPushButton("Liver 2D")
        self.liver2DButton.toolTip = "Grow from mask in 2D, but up down into next slices."
        self.liver2DButton.enabled = True
        parametersLayout.addRow(self.liver2DButton)

        #
        # Cross remove Button
        #
        self.crossButton = qt.QPushButton("Cross remove")
        self.crossButton.toolTip = "re-implementation of sergio's cross remove."
        self.crossButton.enabled = True
        parametersLayout.addRow(self.crossButton)

        #
        # Connectivity reduction Button
        #
        self.connectivityButton = qt.QPushButton("Connectivity reduction")
        self.connectivityButton.toolTip = "re-implementation of sergio's connectivity reduction."
        self.connectivityButton.enabled = True
        parametersLayout.addRow(self.connectivityButton)

        #
        # Paint Button (correction)
        #
        self.correctButton = qt.QPushButton("Correct")
        self.correctButton.toolTip = "Turn on paint for annotating corrections."
        self.correctButton.enabled = True
        self.correctButton.checkable = True
        parametersLayout.addRow(self.correctButton)

        #
        # Track centroid under mask
        #
        self.trackMaskButton = qt.QPushButton("Track correction")
        self.trackMaskButton.toolTip = "Try to use correction mask, and track the centroid in has inside it"
        self.trackMaskButton.enabled = True
        parametersLayout.addRow(self.trackMaskButton)

        #
        # Erase mask (including all under)
        #
        self.eraseMaskButton = qt.QPushButton("Erase correction")
        self.eraseMaskButton.toolTip = "Delete the correction mask to hopefully orphan other areas"
        self.eraseMaskButton.enabled = True
        parametersLayout.addRow(self.eraseMaskButton)

        #
        # Remove unconnected
        #
        self.removeIsolatedButton = qt.QPushButton("Remove unconnected")
        self.removeIsolatedButton.toolTip = "try to see just the main blob and remove stuff not connected."
        self.removeIsolatedButton.enabled = True
        parametersLayout.addRow(self.removeIsolatedButton)

        # connections
        #buttons
        self.selectButton.connect('clicked(bool)', self.onSelectButton)
        self.gradientButton.connect('clicked(bool)', self.onGradientButton)
        self.paintButton.connect('clicked(bool)', self.onPaintButton)
        self.applyButton.connect('clicked(bool)', self.onApplyButton)
        self.growButton.connect('clicked(bool)', self.onGrowButton)
        self.liver2DButton.connect('clicked(bool)', self.onliver2DButton)
        self.crossButton.connect('clicked(bool)', self.onCrossButton)
        self.connectivityButton.connect('clicked(bool)',
                                        self.onConnectivityButton)
        # correction tools buttons
        self.correctButton.connect('clicked(bool)', self.onCorrectButton)
        self.trackMaskButton.connect('clicked(bool)', self.onTrackMaskButton)
        self.eraseMaskButton.connect('clicked(bool)', self.onEraseMaskButton)
        self.removeIsolatedButton.connect('clicked(bool)',
                                          self.onRemoveIsolatedButton)

        self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.onSelect)

        self.threshold.connect('valuesChanged(double,double)',
                               self.onThresholdValuesChanged)

        # Creates and adds the custom Editor Widget to the module
        #self.localParEditorWidget = ParEditorWidget(parent=self.parent, showVolumesFrame=False)
        #self.localParEditorWidget.setup()
        #self.localParEditorWidget.enter()

        # Add vertical spacer
        self.layout.addStretch(1)

        # sets the layout to Red Slice Only
        layoutManager = slicer.app.layoutManager()
        layoutManager.setLayout(
            slicer.vtkMRMLLayoutNode.SlicerLayoutOneUpRedSliceView)

    '''-----------------------------------------------------------------------------'''

    def cleanup(self):
        pass

    def onSelect(self):
        self.applyButton.enabled = self.inputSelector.currentNode()
        self.masterNode = self.inputSelector.currentNode()

    def onSelectButton(self):
        self.masterNode = self.inputSelector.currentNode()
        lo, hi = self.getLoHiImageValues()
        self.threshold.minimum, self.threshold.maximum = lo, hi
        self.threshold.singleStep = (hi - lo) / 1000.
        #print(self.inputSelector.currentNode())

    def onLabelButton(self):
        self.labelNode = self.logic.createLabelMap(
            self.inputSelector.currentNode())

    def onProcessFilterButton(self):
        self.logic.processFilter(self.masterNode)

    def onPaintButton(self):
        if self.paintMode:
            self.paintMode = False
            print("deleting paint")
            self.painter.cleanup()
            self.painter = None
            #self.paint.removeObs()
        else:
            self.paintMode = True

            # just in case?
            selectionNode = slicer.app.applicationLogic().GetSelectionNode()
            selectionNode.SetReferenceActiveVolumeID(self.masterNode.GetID())
            if self.labelNode == None:
                self.labelNode = self.logic.createLabelMap(
                    self.inputSelector.currentNode())
            selectionNode.SetReferenceActiveLabelVolumeID(
                self.labelNode.GetID())
            slicer.app.applicationLogic().PropagateVolumeSelection(0)

            self.editUtil.setLabel(1)  # green

            print("create paint (editor paint effect tool)")
            lm = slicer.app.layoutManager()
            paintEffect = EditorLib.PaintEffectOptions()
            paintEffect.setMRMLDefaults()
            paintEffect.__del__()
            sliceWidget = lm.sliceWidget('Red')
            self.painter = EditorLib.PaintEffectTool(sliceWidget)

    def onApplyButton(self):
        self.logic.runMask(self.masterNode, self.labelNode)
        mean, std = self.logic.getMeanSD()
        max = mean + std
        min = mean - std
        hi = mean + 4 * std
        lo = mean - 4 * std
        self.threshold.minimum, self.threshold.maximum = lo, hi
        self.setThresholdValues(min, max)

    def onGrowButton(self):
        self.logic.runThreshold(self.masterNode, self.labelNode)

    def onGradientButton(self):
        self.logic.runGradient(self.masterNode)

    def onliver2DButton(self):
        print("Liver button")
        #runFindLiver2D(self,masterNode,labelNode):
        self.logic.runFindLiver2D(self.masterNode, self.labelNode)

    def onCrossButton(self):
        self.logic.runCrossRemove(self.masterNode, self.labelNode,
                                  2)  # need to pass in size of cross

    def onConnectivityButton(self):
        self.logic.runConnectivity(
            self.masterNode, self.labelNode,
            10)  # need to pass in number of pixels around it that need to be 1

    def onCorrectButton(self):
        if self.correctMode:
            self.correctMode = False
            print("deleting correct")
            self.painter.cleanup()
            self.painter = None
            #self.paint.removeObs()
        else:
            self.correctMode = True

            # just in case?
            selectionNode = slicer.app.applicationLogic().GetSelectionNode()
            selectionNode.SetReferenceActiveVolumeID(self.masterNode.GetID())
            if self.labelNode == None:
                self.labelNode = self.logic.createLabelMap(
                    self.inputSelector.currentNode())
            selectionNode.SetReferenceActiveLabelVolumeID(
                self.labelNode.GetID())
            slicer.app.applicationLogic().PropagateVolumeSelection(0)

            self.editUtil.setLabel(5)  # red

            print("create correct (editor paint effect tool)")
            lm = slicer.app.layoutManager()
            paintEffect = EditorLib.PaintEffectOptions()
            paintEffect.setMRMLDefaults()
            paintEffect.__del__()
            sliceWidget = lm.sliceWidget('Red')
            self.painter = EditorLib.PaintEffectTool(sliceWidget)

    def onTrackMaskButton(self):
        self.logic.runTrackMask(self.masterNode, self.labelNode)

    def onEraseMaskButton(self):
        self.logic.runEraseMask(self.masterNode, self.labelNode)

    def onRemoveIsolatedButton(self):
        self.logic.runRemoveIsolated(self.masterNode, self.labelNode)

    def onEdgeButton(self):
        self.logic.runFindEdge(self.masterNode, self.labelNode)

    def getLoHiImageValues(self):
        backgroundImage = self.masterNode
        lo = 0
        hi = 100
        if backgroundImage:
            data = backgroundImage.GetImageData()
            lo, hi = data.GetScalarRange()
            print('Low: ', lo)
            print('High: ', hi)
        return lo, hi

    def onThresholdValuesChanged(self):
        print('value changed')
        min = self.threshold.minimumValue
        max = self.threshold.maximumValue
        print(min, max)

    def setThresholdValues(self, min, max):
        self.threshold.setMinimumValue(min)
        self.threshold.setMaximumValue(max)
示例#18
0
    def test_SEGExporterSelfTest1(self):
        """ Test DICOM import, segmentation, export
    """
        self.messageDelay = 50

        import os
        self.delayDisplay("Starting the DICOM SEG Export test")

        #
        # first, get the data - a zip file of dicom data
        #
        import urllib
        downloads = ((
            'http://slicer.kitware.com/midas3/download/item/220834/PieperMRHead.zip',
            'PieperMRHead.zip'), )
        self.delayDisplay("Downloading")
        for url, name in downloads:
            filePath = slicer.app.temporaryPath + '/' + name
            if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
                self.delayDisplay('Requesting download %s from %s...\n' %
                                  (name, url))
                urllib.urlretrieve(url, filePath)
        self.delayDisplay('Finished with download\n')

        self.delayDisplay("Unzipping")
        dicomFilesDirectory = slicer.app.temporaryPath + '/dicomFiles'
        qt.QDir().mkpath(dicomFilesDirectory)
        slicer.app.applicationLogic().Unzip(filePath, dicomFilesDirectory)

        try:
            self.delayDisplay("Switching to temp database directory")
            tempDatabaseDirectory = slicer.app.temporaryPath + '/tempDICOMDatabase'
            import shutil
            shutil.rmtree(tempDatabaseDirectory)
            qt.QDir().mkpath(tempDatabaseDirectory)
            if slicer.dicomDatabase:
                originalDatabaseDirectory = os.path.split(
                    slicer.dicomDatabase.databaseFilename)[0]
            else:
                originalDatabaseDirectory = None
                settings = qt.QSettings()
                settings.setValue('DatabaseDirectory', tempDatabaseDirectory)
            dicomWidget = slicer.modules.dicom.widgetRepresentation().self()
            dicomWidget.onDatabaseDirectoryChanged(tempDatabaseDirectory)

            self.delayDisplay('Importing DICOM')
            mainWindow = slicer.util.mainWindow()
            mainWindow.moduleSelector().selectModule('DICOM')

            indexer = ctk.ctkDICOMIndexer()
            indexer.addDirectory(slicer.dicomDatabase, dicomFilesDirectory,
                                 None)
            indexer.waitForImportFinished()

            dicomWidget.detailsPopup.open()

            # load the data by series UID
            mrHeadSeriesUID = "2.16.840.1.113662.4.4168496325.1025306170.548651188813145058"
            dicomWidget.detailsPopup.offerLoadables(mrHeadSeriesUID, 'Series')
            dicomWidget.detailsPopup.examineForLoading()
            self.delayDisplay('Loading Selection')
            dicomWidget.detailsPopup.loadCheckedLoadables()

            #
            # create a label map and set it for editing
            #
            masterNode = slicer.util.getNode('2: SAG*')
            volumesLogic = slicer.modules.volumes.logic()
            mergeNode = volumesLogic.CreateAndAddLabelVolume(
                slicer.mrmlScene, masterNode,
                masterNode.GetName() + '-label')
            mergeNode.GetDisplayNode().SetAndObserveColorNodeID(
                'vtkMRMLColorTableNodeFileGenericAnatomyColors.txt')
            selectionNode = slicer.app.applicationLogic().GetSelectionNode()
            selectionNode.SetReferenceActiveVolumeID(masterNode.GetID())
            selectionNode.SetReferenceActiveLabelVolumeID(mergeNode.GetID())
            slicer.app.applicationLogic().PropagateVolumeSelection(0)

            #
            # go to the editor and do some drawing
            #
            slicer.util.selectModule('Editor')

            import EditorLib
            from EditorLib.EditUtil import EditUtil
            parameterNode = EditUtil.getParameterNode()
            parameterNode.SetParameter("LabelEffect,paintThreshold", "1")
            parameterNode.SetParameter("LabelEffect,paintThresholdMin", "70.0")
            parameterNode.SetParameter("LabelEffect,paintThresholdMax",
                                       "279.75")
            parameterNode.SetParameter("PaintEffect,radius", "40")
            parameterNode.SetParameter("PaintEffect,sphere", "1")

            self.delayDisplay("Paint some things")
            parameterNode = EditUtil.getParameterNode()
            lm = slicer.app.layoutManager()
            paintEffect = EditorLib.PaintEffectOptions()
            paintEffect.setMRMLDefaults()
            paintEffect.__del__()
            sliceWidget = lm.sliceWidget('Red')
            paintTool = EditorLib.PaintEffectTool(sliceWidget)
            EditUtil.setLabel(1)
            paintTool.paintAddPoint(100, 100)
            paintTool.paintApply()
            EditUtil.setLabel(2)
            paintTool.paintAddPoint(200, 200)
            paintTool.paintApply()
            paintTool.cleanup()
            paintTool = None

            # save these to compare with the one we read back
            originalSegmentationArray = slicer.util.array(mergeNode.GetID())
            originalSegmentationNodeCopy = slicer.vtkMRMLLabelMapVolumeNode()
            originalSegmentationNodeCopy.CopyOrientation(mergeNode)

            # export the volumes into a SEG
            tempSEGDirectory = slicer.app.temporaryPath + '/tempDICOMSEG'
            qt.QDir().mkpath(tempSEGDirectory)
            segFilePath = os.path.join(tempSEGDirectory, "test.SEG.dcm")

            self.delayDisplay('spliting...', 200)
            EditUtil.splitPerStructureVolumes(masterNode, mergeNode)

            self.delayDisplay('exporting...', 200)
            EditUtil.exportAsDICOMSEG(masterNode)

            # close scene re-load the input data and SEG
            slicer.mrmlScene.Clear(0)
            indexer.addDirectory(slicer.dicomDatabase, tempSEGDirectory, None)
            indexer.waitForImportFinished()

            mrHeadStudyUID = "2.16.840.1.113662.4.4168496325.1025305873.7118351817185979330"
            dicomWidget.detailsPopup.offerLoadables(mrHeadStudyUID, 'Study')
            dicomWidget.detailsPopup.examineForLoading()
            self.delayDisplay('Loading Selection')
            dicomWidget.detailsPopup.loadCheckedLoadables()

            # confirm that segmentations are correctly reloaded
            headLabelName = '2: SAG/RF-FAST/VOL/FLIP 30-label'
            reloadedLabel = slicer.util.getNode(headLabelName)
            reloadedSegmentationArray = slicer.util.array(
                reloadedLabel.GetID())

            import numpy
            self.assertTrue(
                numpy.alltrue(
                    originalSegmentationArray == reloadedSegmentationArray))
            geometryWarnings = volumesLogic.CompareVolumeGeometry(
                mergeNode, reloadedLabel)
            print(geometryWarnings)
            self.assertTrue(geometryWarnings == '')

            # re-export

            # close scene re-load the input data and SEG

            # confirm that segmentations are available again as per-structure volumes

            self.delayDisplay('Test passed!')
        except Exception, e:
            import traceback
            traceback.print_exc()
            self.delayDisplay('Test caused exception!\n' + str(e))
    def run(self, enableScreenshots=0, screenshotScaleFactor=1):
        """
    Run the actual algorithm
    """
        self.delayDisplay("Running test of the Neurosurgical Planning tutorial")

        self.enableScreenshots = enableScreenshots
        self.screenshotScaleFactor = screenshotScaleFactor

        # conventional layout
        lm = slicer.app.layoutManager()
        lm.setLayout(2)

        moduleSelector = slicer.util.mainWindow().moduleSelector()
        #
        # first load the data
        #
        if self.enableScreenshots == 1:
            # for the tutorial, do it through the welcome module
            moduleSelector.selectModule("Welcome")
            self.delayDisplay("Screenshot")
            self.takeScreenshot("NeurosurgicalPlanning-Welcome", "Welcome module", -1)
        else:
            # otherwise show the sample data module
            moduleSelector.selectModule("SampleData")

        # use the sample data module logic to load data for the self test
        import SampleData

        sampleDataLogic = SampleData.SampleDataLogic()

        self.delayDisplay("Getting Baseline volume")
        baselineVolume = sampleDataLogic.downloadWhiteMatterExplorationBaselineVolume()

        self.takeScreenshot("NeurosurgicalPlanning-Loaded", "Data loaded", -1)

        #
        # link the viewers
        #

        if self.enableScreenshots == 1:
            # for the tutorial, pop up the linking control
            sliceController = slicer.app.layoutManager().sliceWidget("Red").sliceController()
            popupWidget = sliceController.findChild("ctkPopupWidget")
            if popupWidget is not None:
                popupWidget.pinPopup(1)
                self.takeScreenshot("NeurosurgicalPlanning-Link", "Link slice viewers", -1)
                popupWidget.pinPopup(0)

        sliceLogic = slicer.app.layoutManager().sliceWidget("Red").sliceLogic()
        compositeNode = sliceLogic.GetSliceCompositeNode()
        compositeNode.SetLinkedControl(1)

        #
        # baseline in the background
        #
        sliceLogic.StartSliceCompositeNodeInteraction(1)
        compositeNode.SetBackgroundVolumeID(baselineVolume.GetID())
        sliceLogic.EndSliceCompositeNodeInteraction()

        self.takeScreenshot("NeurosurgicalPlanning-Baseline", "Baseline in background", -1)

        #
        # adjust window level on baseline
        #
        moduleSelector.selectModule("Volumes")
        baselineDisplay = baselineVolume.GetDisplayNode()
        baselineDisplay.SetAutoWindowLevel(0)
        baselineDisplay.SetWindow(2600)
        baselineDisplay.SetLevel(1206)
        self.takeScreenshot("NeurosurgicalPlanning-WindowLevel", "Set W/L on baseline", -1)

        #
        # switch to red slice only
        #
        lm.setLayout(6)
        self.takeScreenshot("NeurosurgicalPlanning-RedSliceOnly", "Set layout to Red Slice only", -1)

        #
        # segmentation of tumour
        #

        #
        # create a label map and set it for editing
        #
        volumesLogic = slicer.modules.volumes.logic()
        baselineVolumeLabel = volumesLogic.CreateAndAddLabelVolume(
            slicer.mrmlScene, baselineVolume, baselineVolume.GetName() + "-label"
        )
        baselineDisplayNode = baselineVolumeLabel.GetDisplayNode()
        baselineDisplayNode.SetAndObserveColorNodeID("vtkMRMLColorTableNodeFileGenericAnatomyColors.txt")
        selectionNode = slicer.app.applicationLogic().GetSelectionNode()
        selectionNode.SetReferenceActiveVolumeID(baselineVolume.GetID())
        selectionNode.SetReferenceActiveLabelVolumeID(baselineVolumeLabel.GetID())
        slicer.app.applicationLogic().PropagateVolumeSelection(0)

        #
        # editor module
        #
        moduleSelector.selectModule("Editor")
        self.takeScreenshot("NeurosurgicalPlanning-Editor", "Showing Editor Module", -1)

        # set the slice offset so drawing is right
        sliceNode = sliceLogic.GetSliceNode()
        sliceOffset = 58.7
        sliceNode.SetSliceOffset(sliceOffset)

        #
        # paint
        #
        parameterNode = EditUtil.getParameterNode()
        paintEffect = EditorLib.PaintEffectOptions()
        paintEffect.setMRMLDefaults()
        paintEffect.__del__()
        sliceWidget = lm.sliceWidget("Red")
        paintTool = EditorLib.PaintEffectTool(sliceWidget)
        self.takeScreenshot("NeurosurgicalPlanning-Paint", "Paint tool in Editor Module", -1)

        #
        # paint in cystic part of tumor, using converstion from RAS coords to
        # avoid slice widget size differences
        #
        EditUtil.setLabel(293)
        displayCoords = self.rasToDisplay(-7.4, 71, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-11, 73, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-12, 85, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-13, 91, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-15, 78, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        paintTool.paintApply()
        self.takeScreenshot("NeurosurgicalPlanning-PaintCystic", "Paint cystic part of tumor", -1)

        #
        # paint in solid part of tumor
        #
        EditUtil.setLabel(7)
        displayCoords = self.rasToDisplay(-0.5, 118.5, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-7.4, 116, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        paintTool.paintApply()
        self.takeScreenshot("NeurosurgicalPlanning-PaintSolid", "Paint solid part of tumor", -1)

        #
        # paint around the tumor
        #
        EditUtil.setLabel(295)
        rMax = 25
        rMin = -50
        aMax = 145
        aMin = 50
        rasStep = 5

        # draw the top and bottom
        for r in range(rMin, rMax, rasStep):
            displayCoords = self.rasToDisplay(r, aMin, sliceOffset)
            paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
            displayCoords = self.rasToDisplay(r, aMax, sliceOffset)
            paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        # draw the left and right
        for a in range(aMin, aMax, rasStep):
            displayCoords = self.rasToDisplay(rMin, a, sliceOffset)
            paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
            displayCoords = self.rasToDisplay(rMax, a, sliceOffset)
            paintTool.paintAddPoint(displayCoords[0], displayCoords[1])

        paintTool.paintApply()

        self.takeScreenshot("NeurosurgicalPlanning-PaintAround", "Paint around tumor", -1)
        #
        # clean up after painting
        #
        paintTool.cleanup()
        paintTool = None

        #
        # Grow cut
        #
        growCutLogic = EditorLib.GrowCutEffectLogic(sliceWidget.sliceLogic())
        growCutLogic.growCut()
        self.takeScreenshot("NeurosurgicalPlanning-Growcut", "Growcut", -1)

        #
        # Merge split volume
        #
        slicer.util.selectModule("Editor")
        slicer.util.findChildren(text="Split Merge Volume")[0].clicked()
        self.takeScreenshot("NeurosurgicalPlanning-SplitMerge", "SplitMerge", -1)

        #
        # go to the data module
        #
        moduleSelector.selectModule("Data")
        self.takeScreenshot("NeurosurgicalPlanning-SplitMergeData", "SplitMerge results in Data", -1)

        #
        # Ventricles Segmentation
        #

        moduleSelector.selectModule("Editor")
        #
        # select the label volume with the area around the tumor
        slicer.util.findChildren(name="PerStructureVolumesFrame")[0].collapsed = False
        treeView = slicer.util.findChildren(name="StructuresView")[0]
        selection = qt.QItemSelection()
        # selecting the last split volume in the third row
        row = 2
        rowStart = treeView.model().index(row, 0)
        rowEnd = treeView.model().index(row, treeView.model().columnCount() - 1)
        # rowSel = qt.QItemSelection(rowStart, rowEnd)
        selection.select(rowStart, rowEnd)
        # backup: select the label map in the slice logic too
        baselinelabel295 = slicer.mrmlScene.GetFirstNodeByName("BaselineVolume-region 3-label")
        sliceLogic.StartSliceCompositeNodeInteraction(1)
        compositeNode.SetLabelVolumeID(baselinelabel295.GetID())
        sliceLogic.EndSliceCompositeNodeInteraction()
        self.takeScreenshot("NeurosurgicalPlanning-SelOutside", "Select outside region", -1)

        #
        # Threshold tool
        #
        slicer.modules.EditorWidget.toolsBox.selectEffect("ThresholdEffect")
        parameterNode = EditUtil.getParameterNode()
        parameterNode.SetParameter("ThresholdEffect,min", str(1700))
        slicer.modules.EditorWidget.toolsBox.currentTools[0].apply()
        self.takeScreenshot("NeurosurgicalPlanning-Ventricles", "Ventricles segmentation", -1)

        #
        # Save Islands
        #
        slicer.modules.EditorWidget.toolsBox.selectEffect("SaveIslandEffect")
        saveIslandLogic = EditorLib.SaveIslandEffectLogic(sliceWidget.sliceLogic())
        displayCoords = self.rasToDisplay(25.3, 5.8, sliceOffset)
        xy = (displayCoords[0], displayCoords[1])
        saveIslandLogic.saveIsland(xy)
        self.takeScreenshot("NeurosurgicalPlanning-SaveIsland", "Ventricles save island", -1)

        #
        # Merge and build
        #
        slicer.util.findChildren(text="Merge And Build")[0].clicked()

        #
        # switch to conventional layout
        #
        lm.setLayout(2)
        self.takeScreenshot("NeurosurgicalPlanning-MergeAndBuild", "Merged and built models", -1)

        #
        # select label volume with label 293, in the second row
        #
        row = 1
        rowStart = treeView.model().index(row, 0)
        rowEnd = treeView.model().index(row, treeView.model().columnCount() - 1)
        # rowSel = qt.QItemSelection(rowStart, rowEnd)
        selection.select(rowStart, rowEnd)
        # backup: select the label map in the slice logic too
        baselinelabel293 = slicer.mrmlScene.GetFirstNodeByName("BaselineVolume-region 1-label")
        sliceLogic.StartSliceCompositeNodeInteraction(1)
        compositeNode.SetLabelVolumeID(baselinelabel293.GetID())
        sliceLogic.EndSliceCompositeNodeInteraction()
        self.takeScreenshot("NeurosurgicalPlanning-SelCystic", "Select cystic region", -1)

        #
        # Dilate
        #
        slicer.modules.EditorWidget.toolsBox.selectEffect("DilateEffect")
        EditUtil.setLabel(293)
        self.takeScreenshot("NeurosurgicalPlanning-Dilate", "Dilate tool", -1)
        # tutorial says to click apply three times
        for d in range(1, 3):
            print d
            # slicer.util.findChildren(name='DilateEffectOptionsApply')[0].clicked()
            # slicer.modules.EditorWidget.toolsBox.currentTools[0].apply()
            slicer.modules.EditorWidget.toolsBox.currentOption.onApply()
        self.takeScreenshot("NeurosurgicalPlanning-Dilated", "Dilated tumor", -1)

        return True
示例#20
0
  def test_ThresholdThreading(self):
    """
    Replicate the issue reported in bug 1822 where splitting
    a grow-cut produced volume causes a multi-threading related
    issue on mac release builds
    """

    #
    # first, get some sample data
    #
    self.delayDisplay("Get some data")
    import SampleData
    sampleDataLogic = SampleData.SampleDataLogic()
    head = sampleDataLogic.downloadMRHead()

    #
    # now, define an ROI in it
    #
    roi = slicer.vtkMRMLAnnotationROINode()
    slicer.mrmlScene.AddNode(roi)
    roi.SetXYZ(-2, 104, -80)
    roi.SetRadiusXYZ(30, 30, 30)

    #
    # apply the cropping to the head
    #
    cropLogic = slicer.modules.cropvolume.logic()
    cvpn = slicer.vtkMRMLCropVolumeParametersNode()
    cvpn.SetROINodeID( roi.GetID() )
    cvpn.SetInputVolumeNodeID( head.GetID() )
    cropLogic.Apply( cvpn )
    croppedHead = slicer.mrmlScene.GetNodeByID( cvpn.GetOutputVolumeNodeID() )

    #
    # create a label map and set it for editing
    #
    volumesLogic = slicer.modules.volumes.logic()
    croppedHeadLabel = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, croppedHead, croppedHead.GetName() + '-label' )
    selectionNode = slicer.app.applicationLogic().GetSelectionNode()
    selectionNode.SetActiveVolumeID( croppedHead.GetID() )
    selectionNode.SetActiveLabelVolumeID( croppedHeadLabel.GetID() )
    slicer.app.applicationLogic().PropagateVolumeSelection(0)


    #
    # got to the editor and do some drawing
    #
    self.delayDisplay("Paint some things")
    parameterNode = EditUtil.getParameterNode()
    lm = slicer.app.layoutManager()
    paintEffect = EditorLib.PaintEffectOptions()
    paintEffect.setMRMLDefaults()
    paintEffect.__del__()
    sliceWidget = lm.sliceWidget('Red')
    paintTool = EditorLib.PaintEffectTool(sliceWidget)
    EditUtil.setLabel(1)
    paintTool.paintAddPoint(100,100)
    paintTool.paintApply()
    EditUtil.setLabel(2)
    paintTool.paintAddPoint(200,200)
    paintTool.paintApply()
    paintTool.cleanup()
    paintTool = None

    self.delayDisplay("Now grow cut")

    #
    # now do GrowCut
    #
    growCutLogic = EditorLib.GrowCutEffectLogic(sliceWidget.sliceLogic())
    growCutLogic.growCut()

    #
    # now split the volume, merge it back, and see if it looks right
    #
    preArray = slicer.util.array(croppedHeadLabel.GetName())
    slicer.util.selectModule('Editor')
    slicer.util.findChildren(text='Split Merge Volume')[0].clicked()
    slicer.util.findChildren(text='Merge All')[0].clicked()
    postArray = slicer.util.array(croppedHeadLabel.GetName())

    if (postArray - preArray).max() != 0:
      print("!$!$!#!@#!@!@$%! Test Failed!!")
    else:
      print("Ahh... test passed.")

    self.assertEqual((postArray - preArray).max(), 0)

    self.delayDisplay("Test passed!")
    def run(self, enableScreenshots=0, screenshotScaleFactor=1):
        """
    Run the actual algorithm
    """
        self.delayDisplay(
            'Running test of the Neurosurgical Planning tutorial')

        self.enableScreenshots = enableScreenshots
        self.screenshotScaleFactor = screenshotScaleFactor

        # conventional layout
        lm = slicer.app.layoutManager()
        lm.setLayout(2)

        moduleSelector = slicer.util.mainWindow().moduleSelector()
        #
        # first load the data
        #
        if self.enableScreenshots == 1:
            # for the tutorial, do it through the welcome module
            moduleSelector.selectModule('Welcome')
            self.delayDisplay("Screenshot")
            self.takeScreenshot('NeurosurgicalPlanning-Welcome',
                                'Welcome module', -1)
        else:
            # otherwise show the sample data module
            moduleSelector.selectModule('SampleData')

        # use the sample data module logic to load data for the self test
        import SampleData
        sampleDataLogic = SampleData.SampleDataLogic()

        self.delayDisplay("Getting Baseline volume")
        baselineVolume = sampleDataLogic.downloadWhiteMatterExplorationBaselineVolume(
        )

        self.delayDisplay("Getting DTI volume")
        dtiVolume = sampleDataLogic.downloadWhiteMatterExplorationDTIVolume()

        self.takeScreenshot('NeurosurgicalPlanning-Loaded', 'Data loaded', -1)

        #
        # link the viewers
        #

        if self.enableScreenshots == 1:
            # for the tutorial, pop up the linking control
            sliceController = slicer.app.layoutManager().sliceWidget(
                "Red").sliceController()
            popupWidget = sliceController.findChild("ctkPopupWidget")
            if popupWidget != None:
                popupWidget.pinPopup(1)
                self.takeScreenshot('NeurosurgicalPlanning-Link',
                                    'Link slice viewers', -1)
                popupWidget.pinPopup(0)

        sliceLogic = slicer.app.layoutManager().sliceWidget('Red').sliceLogic()
        compositeNode = sliceLogic.GetSliceCompositeNode()
        compositeNode.SetLinkedControl(1)

        #
        # baseline in the background
        #
        sliceLogic.StartSliceCompositeNodeInteraction(1)
        compositeNode.SetBackgroundVolumeID(baselineVolume.GetID())
        sliceLogic.EndSliceCompositeNodeInteraction()

        self.takeScreenshot('NeurosurgicalPlanning-Baseline',
                            'Baseline in background', -1)

        #
        # adjust window level on baseline
        #
        moduleSelector.selectModule('Volumes')
        baselineDisplay = baselineVolume.GetDisplayNode()
        baselineDisplay.SetAutoWindowLevel(0)
        baselineDisplay.SetWindow(2600)
        baselineDisplay.SetLevel(1206)
        self.takeScreenshot('NeurosurgicalPlanning-WindowLevel',
                            'Set W/L on baseline', -1)

        #
        # switch to red slice only
        #
        lm.setLayout(6)
        self.takeScreenshot('NeurosurgicalPlanning-RedSliceOnly',
                            'Set layout to Red Slice only', -1)

        #
        # segmentation of tumour
        #

        #
        # create a label map and set it for editing
        #
        volumesLogic = slicer.modules.volumes.logic()
        baselineVolumeLabel = volumesLogic.CreateAndAddLabelVolume(
            slicer.mrmlScene, baselineVolume,
            baselineVolume.GetName() + '-label')
        baselineDisplayNode = baselineVolumeLabel.GetDisplayNode()
        baselineDisplayNode.SetAndObserveColorNodeID(
            'vtkMRMLColorTableNodeFileGenericAnatomyColors.txt')
        selectionNode = slicer.app.applicationLogic().GetSelectionNode()
        selectionNode.SetReferenceActiveVolumeID(baselineVolume.GetID())
        selectionNode.SetReferenceActiveLabelVolumeID(
            baselineVolumeLabel.GetID())
        slicer.app.applicationLogic().PropagateVolumeSelection(0)

        #
        # editor module
        #
        moduleSelector.selectModule('Editor')
        self.takeScreenshot('NeurosurgicalPlanning-Editor',
                            'Showing Editor Module', -1)

        # set the slice offset so drawing is right
        sliceNode = sliceLogic.GetSliceNode()
        sliceOffset = 58.7
        sliceNode.SetSliceOffset(sliceOffset)

        #
        # paint
        #
        parameterNode = EditUtil.getParameterNode()
        paintEffect = EditorLib.PaintEffectOptions()
        paintEffect.setMRMLDefaults()
        paintEffect.__del__()
        sliceWidget = lm.sliceWidget('Red')
        paintTool = EditorLib.PaintEffectTool(sliceWidget)
        self.takeScreenshot('NeurosurgicalPlanning-Paint',
                            'Paint tool in Editor Module', -1)

        #
        # paint in cystic part of tumor, using converstion from RAS coords to
        # avoid slice widget size differences
        #
        EditUtil.setLabel(293)
        displayCoords = self.rasToDisplay(-7.4, 71, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-11, 73, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-12, 85, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-13, 91, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-15, 78, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        paintTool.paintApply()
        self.takeScreenshot('NeurosurgicalPlanning-PaintCystic',
                            'Paint cystic part of tumor', -1)

        #
        # paint in solid part of tumor
        #
        EditUtil.setLabel(7)
        displayCoords = self.rasToDisplay(-0.5, 118.5, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        displayCoords = self.rasToDisplay(-7.4, 116, sliceOffset)
        paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        paintTool.paintApply()
        self.takeScreenshot('NeurosurgicalPlanning-PaintSolid',
                            'Paint solid part of tumor', -1)

        #
        # paint around the tumor
        #
        EditUtil.setLabel(295)
        rMax = 25
        rMin = -50
        aMax = 145
        aMin = 50
        rasStep = 5

        # draw the top and bottom
        for r in range(rMin, rMax, rasStep):
            displayCoords = self.rasToDisplay(r, aMin, sliceOffset)
            paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
            displayCoords = self.rasToDisplay(r, aMax, sliceOffset)
            paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
        # draw the left and right
        for a in range(aMin, aMax, rasStep):
            displayCoords = self.rasToDisplay(rMin, a, sliceOffset)
            paintTool.paintAddPoint(displayCoords[0], displayCoords[1])
            displayCoords = self.rasToDisplay(rMax, a, sliceOffset)
            paintTool.paintAddPoint(displayCoords[0], displayCoords[1])

        paintTool.paintApply()

        self.takeScreenshot('NeurosurgicalPlanning-PaintAround',
                            'Paint around tumor', -1)
        #
        # clean up after painting
        #
        paintTool.cleanup()
        paintTool = None

        #
        # Grow cut
        #
        growCutLogic = EditorLib.GrowCutEffectLogic(sliceWidget.sliceLogic())
        growCutLogic.growCut()
        self.takeScreenshot('NeurosurgicalPlanning-Growcut', 'Growcut', -1)

        #
        # Merge split volume
        #
        slicer.util.selectModule('Editor')
        slicer.util.findChildren(text='Split Merge Volume')[0].clicked()
        self.takeScreenshot('NeurosurgicalPlanning-SplitMerge', 'SplitMerge',
                            -1)

        #
        # go to the data module
        #
        moduleSelector.selectModule('Data')
        self.takeScreenshot('NeurosurgicalPlanning-SplitMergeData',
                            'SplitMerge results in Data', -1)

        #
        # Ventricles Segmentation
        #

        moduleSelector.selectModule('Editor')
        #
        # select the label volume with the area around the tumor
        slicer.util.findChildren(
            name='PerStructureVolumesFrame')[0].collapsed = False
        treeView = slicer.util.findChildren(name='StructuresView')[0]
        selection = qt.QItemSelection()
        # selecting the last split volume in the third row
        row = 2
        rowStart = treeView.model().index(row, 0)
        rowEnd = treeView.model().index(row,
                                        treeView.model().columnCount() - 1)
        # rowSel = qt.QItemSelection(rowStart, rowEnd)
        selection.select(rowStart, rowEnd)
        # backup: select the label map in the slice logic too
        baselinelabel295 = slicer.mrmlScene.GetFirstNodeByName(
            "BaselineVolume-region 3-label")
        sliceLogic.StartSliceCompositeNodeInteraction(1)
        compositeNode.SetLabelVolumeID(baselinelabel295.GetID())
        sliceLogic.EndSliceCompositeNodeInteraction()
        self.takeScreenshot('NeurosurgicalPlanning-SelOutside',
                            'Select outside region', -1)

        #
        # Threshold tool
        #
        slicer.modules.EditorWidget.toolsBox.selectEffect('ThresholdEffect')
        parameterNode = EditUtil.getParameterNode()
        parameterNode.SetParameter('ThresholdEffect,min', str(1700))
        slicer.modules.EditorWidget.toolsBox.currentTools[0].apply()
        self.takeScreenshot('NeurosurgicalPlanning-Ventricles',
                            'Ventricles segmentation', -1)

        #
        # Save Islands
        #
        slicer.modules.EditorWidget.toolsBox.selectEffect('SaveIslandEffect')
        saveIslandLogic = EditorLib.SaveIslandEffectLogic(
            sliceWidget.sliceLogic())
        displayCoords = self.rasToDisplay(25.3, 5.8, sliceOffset)
        xy = (displayCoords[0], displayCoords[1])
        saveIslandLogic.saveIsland(xy)
        self.takeScreenshot('NeurosurgicalPlanning-SaveIsland',
                            'Ventricles save island', -1)

        #
        # Merge and build
        #
        slicer.util.findChildren(text='Merge And Build')[0].clicked()

        #
        # switch to conventional layout
        #
        lm.setLayout(2)
        self.takeScreenshot('NeurosurgicalPlanning-MergeAndBuild',
                            'Merged and built models', -1)

        #
        # Tractography label map seeding
        #

        #
        # select label volume with label 293, in the second row
        #
        row = 1
        rowStart = treeView.model().index(row, 0)
        rowEnd = treeView.model().index(row,
                                        treeView.model().columnCount() - 1)
        # rowSel = qt.QItemSelection(rowStart, rowEnd)
        selection.select(rowStart, rowEnd)
        # backup: select the label map in the slice logic too
        baselinelabel293 = slicer.mrmlScene.GetFirstNodeByName(
            "BaselineVolume-region 1-label")
        sliceLogic.StartSliceCompositeNodeInteraction(1)
        compositeNode.SetLabelVolumeID(baselinelabel293.GetID())
        sliceLogic.EndSliceCompositeNodeInteraction()
        self.takeScreenshot('NeurosurgicalPlanning-SelCystic',
                            'Select cystic region', -1)

        #
        # Dilate
        #
        slicer.modules.EditorWidget.toolsBox.selectEffect('DilateEffect')
        EditUtil.setLabel(293)
        self.takeScreenshot('NeurosurgicalPlanning-Dilate', 'Dilate tool', -1)
        # tutorial says to click apply three times
        for d in range(1, 3):
            print d
            # slicer.util.findChildren(name='DilateEffectOptionsApply')[0].clicked()
            # slicer.modules.EditorWidget.toolsBox.currentTools[0].apply()
            slicer.modules.EditorWidget.toolsBox.currentOption.onApply()
        self.takeScreenshot('NeurosurgicalPlanning-Dilated', 'Dilated tumor',
                            -1)

        #
        # Tractography Label Map Seeding module
        #
        moduleSelector.selectModule('TractographyLabelMapSeeding')
        self.takeScreenshot('NeurosurgicalPlanning-LabelMapSeedingModule',
                            'Showing Tractography Label Seeding Module', -1)
        tractographyLabelSeeding = slicer.modules.tractographylabelmapseeding
        parameters = {}
        parameters['InputVolume'] = dtiVolume.GetID()
        baselinelabel293 = slicer.mrmlScene.GetFirstNodeByName(
            "BaselineVolume-region 1-label")
        # VTK6 TODO - set 'InputROIPipelineInfo'
        parameters['InputROI'] = baselinelabel293.GetID()
        fibers = slicer.vtkMRMLFiberBundleNode()
        slicer.mrmlScene.AddNode(fibers)
        parameters['OutputFibers'] = fibers.GetID()
        parameters['UseIndexSpace'] = 1
        parameters['StoppingValue'] = 0.15
        parameters['ROIlabel'] = 293
        parameters['StoppingMode'] = 'FractionalAnisotropy'
        # defaults
        # parameters['ClTh'] = 0.3
        # parameters['MinimumLength'] = 20
        # parameters['MaximumLength'] = 800
        # parameters['StoppingCurvature'] = 0.7
        # parameters['IntegrationStepLength'] = 0.5
        # parameters['SeedSpacing'] = 2
        # and run it
        slicer.cli.run(tractographyLabelSeeding, None, parameters)
        self.takeScreenshot('NeurosurgicalPlanning-LabelMapSeeding',
                            'Showing Tractography Label Seeding Results', -1)

        #
        # tractography fiducial seeding
        #
        moduleSelector.selectModule('TractographyInteractiveSeeding')
        self.takeScreenshot('NeurosurgicalPlanning-TIS',
                            'Showing Tractography Interactive Seeding Module',
                            -1)

        # DTI in background
        sliceLogic.StartSliceCompositeNodeInteraction(1)
        compositeNode.SetBackgroundVolumeID(dtiVolume.GetID())
        sliceLogic.EndSliceCompositeNodeInteraction()

        # DTI visible in 3D
        sliceNode = sliceLogic.GetSliceNode()
        sliceLogic.StartSliceNodeInteraction(128)
        sliceNode.SetSliceVisible(1)
        sliceLogic.EndSliceNodeInteraction()

        self.takeScreenshot(
            'NeurosurgicalPlanning-TIS-DTI',
            'DTI volume with Tractography Interactive Seeding Module', -1)

        # place a fiducial
        displayNode = slicer.vtkMRMLMarkupsDisplayNode()
        slicer.mrmlScene.AddNode(displayNode)
        fidNode = slicer.vtkMRMLMarkupsFiducialNode()
        fidNode.SetName('F')
        slicer.mrmlScene.AddNode(fidNode)
        fidNode.SetAndObserveDisplayNodeID(displayNode.GetID())
        r = 28.338526
        a = 34.064367
        s = sliceOffset
        fidNode.AddFiducial(r, a, s)

        # make it active
        selectionNode = slicer.mrmlScene.GetNodeByID(
            "vtkMRMLSelectionNodeSingleton")
        if (selectionNode != None):
            selectionNode.SetReferenceActivePlaceNodeID(fidNode.GetID())

        self.takeScreenshot(
            'NeurosurgicalPlanning-TIS-Fid1',
            'Fiducial in Tractography Interactive Seeding Module', -1)

        # set up the arguments
        wr = slicer.modules.tractographyinteractiveseeding.widgetRepresentation(
        )
        wr.setDiffusionTensorVolumeNode(dtiVolume)
        # create a fiber bundle
        fiducialFibers = slicer.vtkMRMLFiberBundleNode()
        slicer.mrmlScene.AddNode(fiducialFibers)
        wr.setFiberBundleNode(fiducialFibers)
        wr.setSeedingNode(fidNode)
        wr.setMinimumPath(10)
        wr.setStoppingValue(0.15)

        self.takeScreenshot('NeurosurgicalPlanning-TIS-Args',
                            'Tractography Interactive Seeding arguments', -1)

        self.delayDisplay("Moving the fiducial")
        for y in range(-20, 100, 5):
            msg = "Moving the fiducial to y = " + str(y)
            self.delayDisplay(msg, 250)
            fidNode.SetNthFiducialPosition(0, r, y, s)

        self.takeScreenshot(
            'NeurosurgicalPlanning-TIS-Moved',
            'Moved fiducial and did Tractography Interactive Seeding', -1)

        return True