Esempio n. 1
0
    def createUserInterface(self):
        """ This step is mostly empty. A volume rendering threshold is added to be useful.
		"""

        self.__layout = self.__parent.createUserInterface()

        self.__threshRange = slicer.qMRMLRangeWidget()
        self.__threshRange.decimals = 0
        self.__threshRange.singleStep = 1
        self.__threshRange.connect('valuesChanged(double,double)',
                                   self.onThresholdChanged)
        qt.QTimer.singleShot(0, self.killButton)

        ThreshGroupBox = qt.QGroupBox()
        ThreshGroupBox.setTitle('3D Visualization Intensity Threshold')
        ThreshGroupBoxLayout = qt.QFormLayout(ThreshGroupBox)
        ThreshGroupBoxLayout.addRow(self.__threshRange)
        self.__layout.addRow(ThreshGroupBox)

        editorWidgetParent = slicer.qMRMLWidget()
        editorWidgetParent.setLayout(qt.QVBoxLayout())
        editorWidgetParent.setMRMLScene(slicer.mrmlScene)
        self.__editorWidget = EditorWidget(parent=editorWidgetParent)
        self.__editorWidget.setup()
        self.__layout.addRow(editorWidgetParent)
        self.hideUnwantedEditorUIElements()

        RestartGroupBox = qt.QGroupBox()
        RestartGroupBox.setTitle('Restart')
        RestartGroupBoxLayout = qt.QFormLayout(RestartGroupBox)

        self.__RestartButton = qt.QPushButton('Return to Step 1')
        RestartGroupBoxLayout.addRow(self.__RestartButton)

        self.__RemoveCroppedSubtractionMap = qt.QCheckBox()
        self.__RemoveCroppedSubtractionMap.checked = True
        self.__RemoveCroppedSubtractionMap.setToolTip(
            "Delete the cropped version of your subtaction map.")
        RestartGroupBoxLayout.addRow("Delete cropped subtraction map: ",
                                     self.__RemoveCroppedSubtractionMap)

        self.__RemoveFullSubtracitonMap = qt.QCheckBox()
        self.__RemoveFullSubtracitonMap.checked = True
        self.__RemoveFullSubtracitonMap.setToolTip(
            "Delete the full version of your subtaction map.")
        RestartGroupBoxLayout.addRow("Delete full subtraction map: ",
                                     self.__RemoveFullSubtracitonMap)

        self.__RemoveROI = qt.QCheckBox()
        self.__RemoveROI.checked = False
        self.__RemoveROI.setToolTip(
            "Delete the ROI resulting from your subtaction map.")
        RestartGroupBoxLayout.addRow("Delete ROI: ", self.__RemoveROI)

        # self.__RestartButton.setEnabled(0)

        self.__RestartButton.connect('clicked()', self.Restart)
        self.__RestartActivated = True

        self.__layout.addRow(RestartGroupBox)
    def createUserInterface(self):
        """ This UI takes advantage of a pre-built slicer thresholding widget.
		"""

        self.__layout = self.__parent.createUserInterface()

        step_label = qt.QLabel(
            """Use the slider bar below to set an intensity threshold. Any pixels within your ROI and within the intensity threshold will be selected."""
        )
        step_label.setWordWrap(True)
        self.__primaryGroupBox = qt.QGroupBox()
        self.__primaryGroupBox.setTitle('Information')
        self.__primaryGroupBoxLayout = qt.QFormLayout(self.__primaryGroupBox)
        self.__primaryGroupBoxLayout.addRow(step_label)
        self.__layout.addRow(self.__primaryGroupBox)

        self.__thresholdGroupBox = qt.QGroupBox()
        self.__thresholdGroupBox.setTitle('Threshold Range')
        self.__thresholdGroupBoxLayout = qt.QFormLayout(
            self.__thresholdGroupBox)
        threshLabel = qt.QLabel('Select Intensity Range:')
        threshLabel.alignment = 4

        self.__threshRange = slicer.qMRMLRangeWidget()
        self.__threshRange.decimals = 0
        self.__threshRange.singleStep = 1

        self.__thresholdGroupBoxLayout.addRow(threshLabel)
        self.__thresholdGroupBoxLayout.addRow(self.__threshRange)
        self.__layout.addRow(self.__thresholdGroupBox)

        self.__threshRange.connect('valuesChanged(double,double)',
                                   self.onThresholdChanged)
        qt.QTimer.singleShot(0, self.killButton)
  def createUserInterface( self ):
    '''
    '''
    self.skip = 0
    self.__layout = self.__parent.createUserInterface()

    self.__basicFrame = ctk.ctkCollapsibleButton()
    self.__basicFrame.text = "Basic settings"
    self.__basicFrame.collapsed = 0
    basicFrameLayout = qt.QFormLayout(self.__basicFrame)
    self.__layout.addRow(self.__basicFrame)

    self.__advancedFrame = ctk.ctkCollapsibleButton()
    self.__advancedFrame.text = "Advanced settings"
    self.__advancedFrame.collapsed = 1
    advFrameLayout = qt.QFormLayout(self.__advancedFrame)
    self.__layout.addRow(self.__advancedFrame)

    threshLabel = qt.QLabel('1/ Make the holes visible:')
    self.__threshRange = slicer.qMRMLRangeWidget()
    self.__threshRange.decimals = 0
    self.__threshRange.singleStep = 1

    self.__useThresholdsCheck = qt.QCheckBox()
    self.__useThresholdsCheck.setEnabled(0)
    threshCheckLabel = qt.QLabel('Use thresholds for segmentation')

    roiLabel = qt.QLabel( 'Select segmentation:' )
    self.__roiLabelSelector = slicer.qMRMLNodeComboBox()
    self.__roiLabelSelector.nodeTypes = ( 'vtkMRMLScalarVolumeNode', '' )
    self.__roiLabelSelector.addAttribute('vtkMRMLScalarVolumeNode','LabelMap','1')
    self.__roiLabelSelector.toolTip = "Choose the ROI segmentation"
    self.__roiLabelSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.__roiLabelSelector.addEnabled = 0
    self.__roiLabelSelector.setMRMLScene(slicer.mrmlScene)

    self.__applyButton = qt.QPushButton('2/ Make a 3D Model')
    self.__applyButton.connect('clicked()', self.applyModelMaker)
    
    basicFrameLayout.addRow(threshLabel, self.__threshRange)
    basicFrameLayout.addRow(self.__applyButton)
    advFrameLayout.addRow(threshCheckLabel, self.__useThresholdsCheck)
    advFrameLayout.addRow( roiLabel, self.__roiLabelSelector )

    self.__threshRange.connect('valuesChanged(double,double)', self.onThresholdChanged)
    self.__useThresholdsCheck.connect('stateChanged(int)', self.onThresholdsCheckChanged)
    
    self.__secondReg = qt.QPushButton('3/ ICP Registration')
    self.__secondReg.connect('clicked()', self.ICPRegistration)
    self.__secondReg.setEnabled(0)
    self.__layout.addRow(self.__secondReg)
    
    self.fiducialButton = qt.QPushButton('Manual Registration')
    self.fiducialButton.checkable = True
    self.__layout.addRow(self.fiducialButton)
    self.fiducialButton.connect('toggled(bool)', self.onRunButtonToggled)
	def createUserInterface( self ):

		""" This UI takes advantage of a pre-built slicer thresholding widget.
		"""

		self.__layout = self.__parent.createUserInterface()

		threshLabel = qt.QLabel('Choose threshold:')
		self.__threshRange = slicer.qMRMLRangeWidget()
		self.__threshRange.decimals = 0
		self.__threshRange.singleStep = 1

		self.__layout.addRow(threshLabel, self.__threshRange)
		self.__threshRange.connect('valuesChanged(double,double)', self.onThresholdChanged)
		qt.QTimer.singleShot(0, self.killButton)
	def createUserInterface( self ):

		""" This UI takes advantage of a pre-built slicer thresholding widget.
		"""

		self.__layout = self.__parent.createUserInterface()

		threshLabel = qt.QLabel('Choose threshold:')
		self.__threshRange = slicer.qMRMLRangeWidget()
		self.__threshRange.decimals = 0
		self.__threshRange.singleStep = 1

		self.__layout.addRow(threshLabel, self.__threshRange)
		self.__threshRange.connect('valuesChanged(double,double)', self.onThresholdChanged)
		qt.QTimer.singleShot(0, self.killButton)
	def createUserInterface( self ):

		""" This step is mostly empty. A volume rendering threshold is added to be useful.
		"""

		self.__layout = self.__parent.createUserInterface()

		threshLabel = qt.QLabel('Choose Volume Rendering Threshold:')
		self.__threshRange = slicer.qMRMLRangeWidget()
		self.__threshRange.decimals = 0
		self.__threshRange.singleStep = 1

		self.__layout.addRow(threshLabel, self.__threshRange)
		self.__threshRange.connect('valuesChanged(double,double)', self.onThresholdChanged)
		qt.QTimer.singleShot(0, self.killButton)
Esempio n. 7
0
  def createUserInterface( self ):

    self.__layout = qt.QFormLayout( self )
    self.__layout.setVerticalSpacing( 5 )

    # Add empty rows
    self.__layout.addRow( "", qt.QWidget() )
    self.__layout.addRow( "", qt.QWidget() )

    #label for ROI selector
    vertLabel = qt.QLabel( 'Vertebrae Labels:' )
    font = vertLabel.font
    font.setBold(True)
    vertLabel.setFont(font)

    labelText = qt.QLabel("Add Labels:  ")
    self.identify = qt.QPushButton("Click to Identify")
    self.identify.connect('clicked(bool)', self.addFiducials)
    self.identify.setMaximumWidth(170)

    blank = qt.QLabel("  ")
    blank.setMaximumWidth(30)

    self.vertebraeGridBox = qt.QFormLayout()
    self.vertebraeGridBox.addRow(vertLabel)
    self.vertebraeGridBox.addRow(labelText,self.identify)

    self.__layout.addRow(self.vertebraeGridBox)

    # Hide Threshold Details
    threshCollapsibleButton = ctk.ctkCollapsibleButton()
    #roiCollapsibleButton.setMaximumWidth(320)
    threshCollapsibleButton.text = "Bone Threshold Details"
    self.__layout.addWidget(threshCollapsibleButton)
    threshCollapsibleButton.collapsed = False

    # Layout
    threshLayout = qt.QFormLayout(threshCollapsibleButton)

    self.__loadThreshButton = qt.QPushButton("Show Threshold Label")
    threshLayout.addRow(self.__loadThreshButton)
    self.__loadThreshButton.connect('clicked(bool)', self.showThreshold)

    self.__corticalRange = slicer.qMRMLRangeWidget()
    self.__corticalRange.decimals = 0
    self.__corticalRange.singleStep = 1

    cortLabel = qt.QLabel('Choose Cortical Bone Threshold:')
    self.__corticalRange.connect('valuesChanged(double,double)', self.onCorticalChanged)
    threshLayout.addRow(cortLabel)
    threshLayout.addRow(self.__corticalRange)


    # Hide ROI Details
    roiCollapsibleButton = ctk.ctkCollapsibleButton()
    roiCollapsibleButton.text = "Advanced Options"
    self.__layout.addWidget(roiCollapsibleButton)
    roiCollapsibleButton.collapsed = True
    roiCollapsibleButton.visible = False

    # Layout
    roiLayout = qt.QFormLayout(roiCollapsibleButton)

    self.__loadLandmarksButton = qt.QPushButton("Show Crop Landmarks")
    roiLayout.addRow(self.__loadLandmarksButton)
    self.__loadLandmarksButton.connect('clicked(bool)', self.showLandmarks)

    #label for ROI selector
    roiLabel = qt.QLabel( 'Select ROI:' )
    font = roiLabel.font
    font.setBold(True)
    roiLabel.setFont(font)

    #creates combobox and populates it with all vtkMRMLAnnotationROINodes in the scene
    self.__roiSelector = slicer.qMRMLNodeComboBox()
    self.__roiSelector.nodeTypes = ['vtkMRMLAnnotationROINode']
    self.__roiSelector.toolTip = "ROI defining the structure of interest"
    self.__roiSelector.setMRMLScene(slicer.mrmlScene)
    self.__roiSelector.addEnabled = 1

    #add label + combobox
    roiLayout.addRow( roiLabel, self.__roiSelector )

    self.__roiSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onROIChanged)

    # the ROI parameters
    # GroupBox to hold ROI Widget
    voiGroupBox = qt.QGroupBox()
    voiGroupBox.setTitle( 'Define VOI' )
    roiLayout.addRow( voiGroupBox )

    # create form layout for GroupBox
    voiGroupBoxLayout = qt.QFormLayout( voiGroupBox )

    # create ROI Widget and add it to the form layout of the GroupBox
    self.__roiWidget = PythonQt.qSlicerAnnotationsModuleWidgets.qMRMLAnnotationROIWidget()
    voiGroupBoxLayout.addRow( self.__roiWidget )

    # Hide VR Details
    vrCollapsibleButton = ctk.ctkCollapsibleButton()
    #roiCollapsibleButton.setMaximumWidth(320)
    vrCollapsibleButton.text = "Rendering Details"
    self.__layout.addWidget(vrCollapsibleButton)
    vrCollapsibleButton.collapsed = True
    vrCollapsibleButton.visible = False

    # Layout
    vrLayout = qt.QFormLayout(vrCollapsibleButton)

    # the ROI parameters
    # GroupBox to hold ROI Widget
    vrGroupBox = qt.QGroupBox()
    vrGroupBox.setTitle( 'Define Rendering' )
    vrLayout.addRow( vrGroupBox )

    # create form layout for GroupBox
    vrGroupBoxLayout = qt.QFormLayout( vrGroupBox )

    # create ROI Widget and add it to the form layout of the GroupBox
    self.__vrWidget = PythonQt.qSlicerVolumeRenderingModuleWidgets.qSlicerPresetComboBox()
    #self.__vrWidget = PythonQt.qSlicerVolumeRenderingModuleWidgets.qMRMLVolumePropertyNodeWidget()
    vrGroupBoxLayout.addRow( self.__vrWidget )

    # initialize VR
    self.__vrLogic = slicer.modules.volumerendering.logic()

    lm = slicer.app.layoutManager()
    redWidget = lm.sliceWidget('Red')
    self.__redController = redWidget.sliceController()
    self.__redLogic = redWidget.sliceLogic()

    yellowWidget = lm.sliceWidget('Yellow')
    self.__yellowController = yellowWidget.sliceController()
    self.__yellowLogic = yellowWidget.sliceLogic()

    greenWidget = lm.sliceWidget('Green')
    self.__greenController = greenWidget.sliceController()
    self.__greenLogic = greenWidget.sliceLogic()

    qt.QTimer.singleShot(0, self.killButton)
  def createUserInterface( self ):
    '''
    '''
    self.__layout = self.__parent.createUserInterface()

    self.__registrationStatus = qt.QLabel('Register Template and Scan')
    self.__layout.addRow(self.__registrationStatus)
    self.automaticRegistrationButton = qt.QPushButton('Auto Register Template')
    self.automaticRegistrationButton.connect('clicked()', self.automaticRegistration)
    self.__layout.addRow(self.automaticRegistrationButton)
    
    typeOfRegLabel = qt.QLabel('Or Manually Register the Template')
    self.__layout.addRow(typeOfRegLabel)

    self.fiducialButton = qt.QPushButton('1. Choose Fiducial Points')
    self.fiducialButton.checkable = True
    self.__layout.addRow(self.fiducialButton)
    self.fiducialButton.connect('toggled(bool)', self.onRunButtonToggled)
  
    self.firstRegButton = qt.QPushButton('2. Run Initial Registration')
    self.firstRegButton.checkable = False
    self.__layout.addRow(self.firstRegButton)
    self.firstRegButton.connect('clicked()', self.firstRegistration)

    self.resetRegistration = qt.QPushButton('Reset Registration')
    self.resetRegistration.checkable = False
    self.__layout.addRow(self.resetRegistration)
    self.resetRegistration.connect('clicked()', self.backToInitialRegistration)

    # # define cropping area
    # self.drawRectlangelButton = qt.QPushButton('Outline Area Containing Fiducial Points')
    # self.drawRectlangelButton.checkable = True
    # self.__layout.addRow(self.drawRectlangelButton)
    # self.drawRectlangelButton.connect('toggled(bool)',self.onDrawRectangleButtonToggled)


    # Hough parameters - Cropping box: used to limit the volume where to find the circles
    self.__houghFrame = ctk.ctkCollapsibleButton()
    self.__houghFrame.text = "Registration Parameters"
    self.__houghFrame.collapsed = 1
    houghFrame = qt.QFormLayout(self.__houghFrame)
    
    # option for horizontal template
    self.horizontalTemplate=qt.QCheckBox('Horizontal Template')
    houghFrame.addRow(self.horizontalTemplate)

    # Use Hough Transform?
    self.withHT = qt.QCheckBox('Use Hough Transform to Detect Circles (needs separate CLI Module)')
    self.withHT.checked = False
    houghFrame.addRow(self.withHT)

    # Auto-value option
    self.autoLimit = qt.QCheckBox('Limit fiducial search computation volume')
    self.autoLimit.checked = True
    houghFrame.addRow(self.autoLimit)

    # Auto-value option
    # self.autoValue = qt.QCheckBox('Automatic values?')
    # self.autoValue.checked = False
    # houghFrame.addRow(self.autoValue)

    # Ratio height
    self.ratioHeightCroppedVolume = qt.QSpinBox()
    self.ratioHeightCroppedVolume.setMinimum(1)
    self.ratioHeightCroppedVolume.setMaximum(15)
    self.ratioHeightCroppedVolume.setValue(2)
    ratioHeightCroppedVolumeLabel = qt.QLabel("Divide the height by: ")
    houghFrame.addRow(ratioHeightCroppedVolumeLabel, self.ratioHeightCroppedVolume)
    # Ratio width
    # self.ratioWidthCroppedVolume = qt.QSpinBox()
    # self.ratioWidthCroppedVolume.setMinimum(1)
    # self.ratioWidthCroppedVolume.setMaximum(15)
    # self.ratioWidthCroppedVolume.setValue(4)
    # ratioWidthCroppedVolumeLabel = qt.QLabel("Divide the width by: ")
    # houghFrame.addRow(ratioWidthCroppedVolumeLabel, self.ratioWidthCroppedVolume)
    # # Ratio length
    # self.ratioLengthCroppedVolume = qt.QSpinBox()
    # self.ratioLengthCroppedVolume.setMinimum(1)
    # self.ratioLengthCroppedVolume.setMaximum(15)
    # self.ratioLengthCroppedVolume.setValue(4)
    # ratioLengthCroppedVolumeLabel = qt.QLabel("Divide the length by: ")
    # houghFrame.addRow(ratioLengthCroppedVolumeLabel, self.ratioLengthCroppedVolume)

    # Get Maximum Threshold Value
    red_logic = slicer.app.layoutManager().sliceWidget("Red").sliceLogic()
    imageData = red_logic.GetImageData()
    minMax = imageData.GetScalarRange()
    maxThresh = minMax[1]

    # Threshold slider for template segmentation
    threshLabel = qt.QLabel('Threshold for CHT:')
    self.__threshRange = slicer.qMRMLRangeWidget()
    self.__threshRange.decimals = 0
    self.__threshRange.singleStep = 1
    self.__threshRange.minimum = 150
    self.__threshRange.minimumValue = 150
    self.__threshRange.maximum = maxThresh
    self.__threshRange.maximumValue = maxThresh
    houghFrame.addRow(threshLabel,self.__threshRange)
    self.__layout.addRow(self.__houghFrame)

    # Threshold slider for template segmentation
    thresholdSliderLabel = qt.QLabel('Speed of registration (increases inaccuracy) 1-10')
    self.thresholdSlider=qt.QSlider(0x1)
    self.thresholdSlider.toolTip = "Select Threshold."
    self.thresholdSlider.enabled = True
    self.thresholdSlider.setMinimum(1)
    self.thresholdSlider.setMaximum(10)
    self.thresholdSlider.setValue(2)
    houghFrame.addRow(thresholdSliderLabel,self.thresholdSlider)
    self.__layout.addRow(self.__houghFrame)
    # reset module button 
    # resetButton = qt.QPushButton( 'Reset Module' )
    # resetButton.connect( 'clicked()', self.onResetButton )
    # self.__layout.addWidget( resetButton )
    qt.QTimer.singleShot(0, self.killButton)
  def setup( self ):

    # check if the SlicerVmtk module is installed properly
    # self.__vmtkInstalled = SlicerVmtkCommonLib.Helper.CheckIfVmtkIsInstalled()
    # Helper.Debug("VMTK found: " + self.__vmtkInstalled)

    #
    # the I/O panel
    #

    ioCollapsibleButton = ctk.ctkCollapsibleButton()
    ioCollapsibleButton.text = "Input/Output"
    self.layout.addWidget( ioCollapsibleButton )

    ioFormLayout = qt.QFormLayout( ioCollapsibleButton )

    # inputVolume selector
    self.__inputVolumeNodeSelector = slicer.qMRMLNodeComboBox()
    self.__inputVolumeNodeSelector.objectName = 'inputVolumeNodeSelector'
    self.__inputVolumeNodeSelector.toolTip = "Select the input volume. This should always be the original image and not a vesselness image, if possible."
    self.__inputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.__inputVolumeNodeSelector.noneEnabled = False
    self.__inputVolumeNodeSelector.addEnabled = False
    self.__inputVolumeNodeSelector.removeEnabled = False
    self.__inputVolumeNodeSelector.addAttribute( "vtkMRMLScalarVolumeNode", "LabelMap", "0" )
    ioFormLayout.addRow( "Input Volume:", self.__inputVolumeNodeSelector )
    self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)',
                        self.__inputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)' )
    self.__inputVolumeNodeSelector.connect( 'currentNodeChanged(vtkMRMLNode*)', self.onInputVolumeChanged )
    self.__inputVolumeNodeSelector.connect( 'nodeActivated(vtkMRMLNode*)', self.onInputVolumeChanged )

    # seed selector
    self.__seedFiducialsNodeSelector = slicer.qMRMLNodeComboBox()
    self.__seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector'
    self.__seedFiducialsNodeSelector.toolTip = "Select a hierarchy containing the fiducials to use as Seeds."
    self.__seedFiducialsNodeSelector.nodeTypes = ['vtkMRMLAnnotationHierarchyNode']
    self.__seedFiducialsNodeSelector.baseName = "Seeds"
    self.__seedFiducialsNodeSelector.noneEnabled = False
    self.__seedFiducialsNodeSelector.addEnabled = False
    self.__seedFiducialsNodeSelector.removeEnabled = False
    ioFormLayout.addRow( "Seeds:", self.__seedFiducialsNodeSelector )
    self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)',
                        self.__seedFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)' )

    self.__ioAdvancedToggle = qt.QCheckBox( "Show Advanced I/O Properties" )
    self.__ioAdvancedToggle.setChecked( False )
    ioFormLayout.addRow( self.__ioAdvancedToggle )

    #
    # I/O advanced panel
    #

    self.__ioAdvancedPanel = qt.QFrame( ioCollapsibleButton )
    self.__ioAdvancedPanel.hide()
    self.__ioAdvancedPanel.setFrameStyle( 6 )
    ioFormLayout.addRow( self.__ioAdvancedPanel )
    self.__ioAdvancedToggle.connect( "clicked()", self.onIOAdvancedToggle )

    ioAdvancedFormLayout = qt.QFormLayout( self.__ioAdvancedPanel )

    # inputVolume selector
    self.__vesselnessVolumeNodeSelector = slicer.qMRMLNodeComboBox()
    self.__vesselnessVolumeNodeSelector.objectName = 'vesselnessVolumeNodeSelector'
    self.__vesselnessVolumeNodeSelector.toolTip = "Select the input vesselness volume. This is optional input."
    self.__vesselnessVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.__vesselnessVolumeNodeSelector.noneEnabled = True
    self.__vesselnessVolumeNodeSelector.addEnabled = False
    self.__vesselnessVolumeNodeSelector.removeEnabled = False
    self.__vesselnessVolumeNodeSelector.addAttribute( "vtkMRMLScalarVolumeNode", "LabelMap", "0" )
    ioAdvancedFormLayout.addRow( "Vesselness Volume:", self.__vesselnessVolumeNodeSelector )
    self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)',
                        self.__vesselnessVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)' )
    self.__vesselnessVolumeNodeSelector.setCurrentNode( None )

    # stopper selector
    self.__stopperFiducialsNodeSelector = slicer.qMRMLNodeComboBox()
    self.__stopperFiducialsNodeSelector.objectName = 'stopperFiducialsNodeSelector'
    self.__stopperFiducialsNodeSelector.toolTip = "Select a hierarchy containing the fiducials to use as Stoppers. Whenever one stopper is reached, the segmentation stops."
    self.__stopperFiducialsNodeSelector.nodeTypes = ['vtkMRMLAnnotationHierarchyNode']
    self.__stopperFiducialsNodeSelector.baseName = "Stoppers"
    self.__stopperFiducialsNodeSelector.noneEnabled = False
    self.__stopperFiducialsNodeSelector.addEnabled = True
    self.__stopperFiducialsNodeSelector.removeEnabled = False
    ioAdvancedFormLayout.addRow( "Stoppers:", self.__stopperFiducialsNodeSelector )
    self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)',
                        self.__stopperFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)' )

    # outputVolume selector
    self.__outputVolumeNodeSelector = slicer.qMRMLNodeComboBox()
    self.__outputVolumeNodeSelector.toolTip = "Select the output labelmap."
    self.__outputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.__outputVolumeNodeSelector.baseName = "LevelSetSegmentation"
    self.__outputVolumeNodeSelector.noneEnabled = False
    self.__outputVolumeNodeSelector.addEnabled = True
    self.__outputVolumeNodeSelector.selectNodeUponCreation = True
    self.__outputVolumeNodeSelector.addAttribute( "vtkMRMLScalarVolumeNode", "LabelMap", "1" )
    self.__outputVolumeNodeSelector.removeEnabled = True
    ioAdvancedFormLayout.addRow( "Output Labelmap:", self.__outputVolumeNodeSelector )
    self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)',
                        self.__outputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)' )

    # outputModel selector
    self.__outputModelNodeSelector = slicer.qMRMLNodeComboBox()
    self.__outputModelNodeSelector.objectName = 'outputModelNodeSelector'
    self.__outputModelNodeSelector.toolTip = "Select the output model."
    self.__outputModelNodeSelector.nodeTypes = ['vtkMRMLModelNode']
    self.__outputModelNodeSelector.baseName = "LevelSetSegmentationModel"
    self.__outputModelNodeSelector.hideChildNodeTypes = ['vtkMRMLAnnotationNode']  # hide all annotation nodes
    self.__outputModelNodeSelector.noneEnabled = False
    self.__outputModelNodeSelector.addEnabled = True
    self.__outputModelNodeSelector.selectNodeUponCreation = True
    self.__outputModelNodeSelector.removeEnabled = True
    ioAdvancedFormLayout.addRow( "Output Model:", self.__outputModelNodeSelector )
    self.parent.connect( 'mrmlSceneChanged(vtkMRMLScene*)',
                        self.__outputModelNodeSelector, 'setMRMLScene(vtkMRMLScene*)' )


    #
    # the segmentation panel
    #

    segmentationCollapsibleButton = ctk.ctkCollapsibleButton()
    segmentationCollapsibleButton.text = "Segmentation"
    self.layout.addWidget( segmentationCollapsibleButton )

    segmentationFormLayout = qt.QFormLayout( segmentationCollapsibleButton )

    # Threshold slider
    thresholdLabel = qt.QLabel()
    thresholdLabel.text = "Thresholding" + SlicerVmtkCommonLib.Helper.CreateSpace( 7 )
    thresholdLabel.toolTip = "Choose the intensity range to segment."
    thresholdLabel.setAlignment( 4 )
    segmentationFormLayout.addRow( thresholdLabel )

    self.__thresholdSlider = slicer.qMRMLRangeWidget()
    segmentationFormLayout.addRow( self.__thresholdSlider )
    self.__thresholdSlider.connect( 'valuesChanged(double,double)', self.onThresholdSliderChanged )

    self.__segmentationAdvancedToggle = qt.QCheckBox( "Show Advanced Segmentation Properties" )
    self.__segmentationAdvancedToggle.setChecked( False )
    segmentationFormLayout.addRow( self.__segmentationAdvancedToggle )

    #
    # segmentation advanced panel
    #

    self.__segmentationAdvancedPanel = qt.QFrame( segmentationCollapsibleButton )
    self.__segmentationAdvancedPanel.hide()
    self.__segmentationAdvancedPanel.setFrameStyle( 6 )
    segmentationFormLayout.addRow( self.__segmentationAdvancedPanel )
    self.__segmentationAdvancedToggle.connect( "clicked()", self.onSegmentationAdvancedToggle )

    segmentationAdvancedFormLayout = qt.QFormLayout( self.__segmentationAdvancedPanel )

    # inflation slider
    inflationLabel = qt.QLabel()
    inflationLabel.text = "less inflation <-> more inflation" + SlicerVmtkCommonLib.Helper.CreateSpace( 14 )
    inflationLabel.setAlignment( 4 )
    inflationLabel.toolTip = "Define how fast the segmentation expands."
    segmentationAdvancedFormLayout.addRow( inflationLabel )

    self.__inflationSlider = ctk.ctkSliderWidget()
    self.__inflationSlider.decimals = 0
    self.__inflationSlider.minimum = -100
    self.__inflationSlider.maximum = 100
    self.__inflationSlider.singleStep = 10
    self.__inflationSlider.toolTip = inflationLabel.toolTip
    segmentationAdvancedFormLayout.addRow( self.__inflationSlider )

    # curvature slider
    curvatureLabel = qt.QLabel()
    curvatureLabel.text = "less curvature <-> more curvature" + SlicerVmtkCommonLib.Helper.CreateSpace( 14 )
    curvatureLabel.setAlignment( 4 )
    curvatureLabel.toolTip = "Choose a high curvature to generate a smooth segmentation."
    segmentationAdvancedFormLayout.addRow( curvatureLabel )

    self.__curvatureSlider = ctk.ctkSliderWidget()
    self.__curvatureSlider.decimals = 0
    self.__curvatureSlider.minimum = -100
    self.__curvatureSlider.maximum = 100
    self.__curvatureSlider.singleStep = 10
    self.__curvatureSlider.toolTip = curvatureLabel.toolTip
    segmentationAdvancedFormLayout.addRow( self.__curvatureSlider )

    # attraction slider
    attractionLabel = qt.QLabel()
    attractionLabel.text = "less attraction to gradient <-> more attraction to gradient" + SlicerVmtkCommonLib.Helper.CreateSpace( 14 )
    attractionLabel.setAlignment( 4 )
    attractionLabel.toolTip = "Configure how the segmentation travels towards gradient ridges (vessel lumen wall)."
    segmentationAdvancedFormLayout.addRow( attractionLabel )

    self.__attractionSlider = ctk.ctkSliderWidget()
    self.__attractionSlider.decimals = 0
    self.__attractionSlider.minimum = -100
    self.__attractionSlider.maximum = 100
    self.__attractionSlider.singleStep = 10
    self.__attractionSlider.toolTip = attractionLabel.toolTip
    segmentationAdvancedFormLayout.addRow( self.__attractionSlider )

    # iteration spinbox
    self.__iterationSpinBox = qt.QSpinBox()
    self.__iterationSpinBox.minimum = 0
    self.__iterationSpinBox.maximum = 5000
    self.__iterationSpinBox.singleStep = 10
    self.__iterationSpinBox.toolTip = "Choose the number of evolution iterations."
    segmentationAdvancedFormLayout.addRow( SlicerVmtkCommonLib.Helper.CreateSpace( 100 ) + "Iterations:", self.__iterationSpinBox )

    #
    # Reset, preview and apply buttons
    #

    self.__buttonBox = qt.QDialogButtonBox()
    self.__resetButton = self.__buttonBox.addButton( self.__buttonBox.RestoreDefaults )
    self.__resetButton.toolTip = "Click to reset all input elements to default."
    self.__previewButton = self.__buttonBox.addButton( self.__buttonBox.Discard )
    self.__previewButton.setIcon( qt.QIcon() )
    self.__previewButton.text = "Preview.."
    self.__previewButton.toolTip = "Click to refresh the preview."
    self.__startButton = self.__buttonBox.addButton( self.__buttonBox.Apply )
    self.__startButton.setIcon( qt.QIcon() )
    self.__startButton.text = "Start!"
    self.__startButton.enabled = False
    self.__startButton.toolTip = "Click to start the filtering."
    self.layout.addWidget( self.__buttonBox )
    self.__resetButton.connect( "clicked()", self.restoreDefaults )
    self.__previewButton.connect( "clicked()", self.onRefreshButtonClicked )
    self.__startButton.connect( "clicked()", self.onStartButtonClicked )

    # be ready for events
    self.__updating = 0

    # set default values
    self.restoreDefaults()

    # compress the layout
    self.layout.addStretch( 1 )
    def setup(self):

        # check if the SlicerVmtk module is installed properly
        # self.__vmtkInstalled = SlicerVmtkCommonLib.Helper.CheckIfVmtkIsInstalled()
        # Helper.Debug("VMTK found: " + self.__vmtkInstalled)

        #
        # the I/O panel
        #

        ioCollapsibleButton = ctk.ctkCollapsibleButton()
        ioCollapsibleButton.text = "Input/Output"
        self.layout.addWidget(ioCollapsibleButton)

        ioFormLayout = qt.QFormLayout(ioCollapsibleButton)

        # inputVolume selector
        self.__inputVolumeNodeSelector = slicer.qMRMLNodeComboBox()
        self.__inputVolumeNodeSelector.objectName = 'inputVolumeNodeSelector'
        self.__inputVolumeNodeSelector.toolTip = "Select the input volume. This should always be the original image and not a vesselness image, if possible."
        self.__inputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
        self.__inputVolumeNodeSelector.noneEnabled = False
        self.__inputVolumeNodeSelector.addEnabled = False
        self.__inputVolumeNodeSelector.removeEnabled = False
        self.__inputVolumeNodeSelector.addAttribute("vtkMRMLScalarVolumeNode",
                                                    "LabelMap", "0")
        ioFormLayout.addRow("Input Volume:", self.__inputVolumeNodeSelector)
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.__inputVolumeNodeSelector,
                            'setMRMLScene(vtkMRMLScene*)')
        self.__inputVolumeNodeSelector.connect(
            'currentNodeChanged(vtkMRMLNode*)', self.onInputVolumeChanged)
        self.__inputVolumeNodeSelector.connect('nodeActivated(vtkMRMLNode*)',
                                               self.onInputVolumeChanged)

        # seed selector
        self.__seedFiducialsNodeSelector = slicer.qMRMLNodeComboBox()
        self.__seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector'
        self.__seedFiducialsNodeSelector.toolTip = "Select a hierarchy containing the fiducials to use as Seeds."
        self.__seedFiducialsNodeSelector.nodeTypes = [
            'vtkMRMLAnnotationHierarchyNode'
        ]
        self.__seedFiducialsNodeSelector.baseName = "Seeds"
        self.__seedFiducialsNodeSelector.noneEnabled = False
        self.__seedFiducialsNodeSelector.addEnabled = False
        self.__seedFiducialsNodeSelector.removeEnabled = False
        ioFormLayout.addRow("Seeds:", self.__seedFiducialsNodeSelector)
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.__seedFiducialsNodeSelector,
                            'setMRMLScene(vtkMRMLScene*)')

        self.__ioAdvancedToggle = qt.QCheckBox("Show Advanced I/O Properties")
        self.__ioAdvancedToggle.setChecked(False)
        ioFormLayout.addRow(self.__ioAdvancedToggle)

        #
        # I/O advanced panel
        #

        self.__ioAdvancedPanel = qt.QFrame(ioCollapsibleButton)
        self.__ioAdvancedPanel.hide()
        self.__ioAdvancedPanel.setFrameStyle(6)
        ioFormLayout.addRow(self.__ioAdvancedPanel)
        self.__ioAdvancedToggle.connect("clicked()", self.onIOAdvancedToggle)

        ioAdvancedFormLayout = qt.QFormLayout(self.__ioAdvancedPanel)

        # inputVolume selector
        self.__vesselnessVolumeNodeSelector = slicer.qMRMLNodeComboBox()
        self.__vesselnessVolumeNodeSelector.objectName = 'vesselnessVolumeNodeSelector'
        self.__vesselnessVolumeNodeSelector.toolTip = "Select the input vesselness volume. This is optional input."
        self.__vesselnessVolumeNodeSelector.nodeTypes = [
            'vtkMRMLScalarVolumeNode'
        ]
        self.__vesselnessVolumeNodeSelector.noneEnabled = True
        self.__vesselnessVolumeNodeSelector.addEnabled = False
        self.__vesselnessVolumeNodeSelector.removeEnabled = False
        self.__vesselnessVolumeNodeSelector.addAttribute(
            "vtkMRMLScalarVolumeNode", "LabelMap", "0")
        ioAdvancedFormLayout.addRow("Vesselness Volume:",
                                    self.__vesselnessVolumeNodeSelector)
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.__vesselnessVolumeNodeSelector,
                            'setMRMLScene(vtkMRMLScene*)')
        self.__vesselnessVolumeNodeSelector.setCurrentNode(None)

        # stopper selector
        self.__stopperFiducialsNodeSelector = slicer.qMRMLNodeComboBox()
        self.__stopperFiducialsNodeSelector.objectName = 'stopperFiducialsNodeSelector'
        self.__stopperFiducialsNodeSelector.toolTip = "Select a hierarchy containing the fiducials to use as Stoppers. Whenever one stopper is reached, the segmentation stops."
        self.__stopperFiducialsNodeSelector.nodeTypes = [
            'vtkMRMLAnnotationHierarchyNode'
        ]
        self.__stopperFiducialsNodeSelector.baseName = "Stoppers"
        self.__stopperFiducialsNodeSelector.noneEnabled = False
        self.__stopperFiducialsNodeSelector.addEnabled = True
        self.__stopperFiducialsNodeSelector.removeEnabled = False
        ioAdvancedFormLayout.addRow("Stoppers:",
                                    self.__stopperFiducialsNodeSelector)
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.__stopperFiducialsNodeSelector,
                            'setMRMLScene(vtkMRMLScene*)')

        # outputVolume selector
        self.__outputVolumeNodeSelector = slicer.qMRMLNodeComboBox()
        self.__outputVolumeNodeSelector.toolTip = "Select the output labelmap."
        self.__outputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
        self.__outputVolumeNodeSelector.baseName = "LevelSetSegmentation"
        self.__outputVolumeNodeSelector.noneEnabled = False
        self.__outputVolumeNodeSelector.addEnabled = True
        self.__outputVolumeNodeSelector.selectNodeUponCreation = True
        self.__outputVolumeNodeSelector.addAttribute("vtkMRMLScalarVolumeNode",
                                                     "LabelMap", "1")
        self.__outputVolumeNodeSelector.removeEnabled = True
        ioAdvancedFormLayout.addRow("Output Labelmap:",
                                    self.__outputVolumeNodeSelector)
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.__outputVolumeNodeSelector,
                            'setMRMLScene(vtkMRMLScene*)')

        # outputModel selector
        self.__outputModelNodeSelector = slicer.qMRMLNodeComboBox()
        self.__outputModelNodeSelector.objectName = 'outputModelNodeSelector'
        self.__outputModelNodeSelector.toolTip = "Select the output model."
        self.__outputModelNodeSelector.nodeTypes = ['vtkMRMLModelNode']
        self.__outputModelNodeSelector.baseName = "LevelSetSegmentationModel"
        self.__outputModelNodeSelector.hideChildNodeTypes = [
            'vtkMRMLAnnotationNode'
        ]  # hide all annotation nodes
        self.__outputModelNodeSelector.noneEnabled = False
        self.__outputModelNodeSelector.addEnabled = True
        self.__outputModelNodeSelector.selectNodeUponCreation = True
        self.__outputModelNodeSelector.removeEnabled = True
        ioAdvancedFormLayout.addRow("Output Model:",
                                    self.__outputModelNodeSelector)
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.__outputModelNodeSelector,
                            'setMRMLScene(vtkMRMLScene*)')

        #
        # the segmentation panel
        #

        segmentationCollapsibleButton = ctk.ctkCollapsibleButton()
        segmentationCollapsibleButton.text = "Segmentation"
        self.layout.addWidget(segmentationCollapsibleButton)

        segmentationFormLayout = qt.QFormLayout(segmentationCollapsibleButton)

        # Threshold slider
        thresholdLabel = qt.QLabel()
        thresholdLabel.text = "Thresholding" + SlicerVmtkCommonLib.Helper.CreateSpace(
            7)
        thresholdLabel.toolTip = "Choose the intensity range to segment."
        thresholdLabel.setAlignment(4)
        segmentationFormLayout.addRow(thresholdLabel)

        self.__thresholdSlider = slicer.qMRMLRangeWidget()
        segmentationFormLayout.addRow(self.__thresholdSlider)
        self.__thresholdSlider.connect('valuesChanged(double,double)',
                                       self.onThresholdSliderChanged)

        self.__segmentationAdvancedToggle = qt.QCheckBox(
            "Show Advanced Segmentation Properties")
        self.__segmentationAdvancedToggle.setChecked(False)
        segmentationFormLayout.addRow(self.__segmentationAdvancedToggle)

        #
        # segmentation advanced panel
        #

        self.__segmentationAdvancedPanel = qt.QFrame(
            segmentationCollapsibleButton)
        self.__segmentationAdvancedPanel.hide()
        self.__segmentationAdvancedPanel.setFrameStyle(6)
        segmentationFormLayout.addRow(self.__segmentationAdvancedPanel)
        self.__segmentationAdvancedToggle.connect(
            "clicked()", self.onSegmentationAdvancedToggle)

        segmentationAdvancedFormLayout = qt.QFormLayout(
            self.__segmentationAdvancedPanel)

        # inflation slider
        inflationLabel = qt.QLabel()
        inflationLabel.text = "less inflation <-> more inflation" + SlicerVmtkCommonLib.Helper.CreateSpace(
            14)
        inflationLabel.setAlignment(4)
        inflationLabel.toolTip = "Define how fast the segmentation expands."
        segmentationAdvancedFormLayout.addRow(inflationLabel)

        self.__inflationSlider = ctk.ctkSliderWidget()
        self.__inflationSlider.decimals = 0
        self.__inflationSlider.minimum = -100
        self.__inflationSlider.maximum = 100
        self.__inflationSlider.singleStep = 10
        self.__inflationSlider.toolTip = inflationLabel.toolTip
        segmentationAdvancedFormLayout.addRow(self.__inflationSlider)

        # curvature slider
        curvatureLabel = qt.QLabel()
        curvatureLabel.text = "less curvature <-> more curvature" + SlicerVmtkCommonLib.Helper.CreateSpace(
            14)
        curvatureLabel.setAlignment(4)
        curvatureLabel.toolTip = "Choose a high curvature to generate a smooth segmentation."
        segmentationAdvancedFormLayout.addRow(curvatureLabel)

        self.__curvatureSlider = ctk.ctkSliderWidget()
        self.__curvatureSlider.decimals = 0
        self.__curvatureSlider.minimum = -100
        self.__curvatureSlider.maximum = 100
        self.__curvatureSlider.singleStep = 10
        self.__curvatureSlider.toolTip = curvatureLabel.toolTip
        segmentationAdvancedFormLayout.addRow(self.__curvatureSlider)

        # attraction slider
        attractionLabel = qt.QLabel()
        attractionLabel.text = "less attraction to gradient <-> more attraction to gradient" + SlicerVmtkCommonLib.Helper.CreateSpace(
            14)
        attractionLabel.setAlignment(4)
        attractionLabel.toolTip = "Configure how the segmentation travels towards gradient ridges (vessel lumen wall)."
        segmentationAdvancedFormLayout.addRow(attractionLabel)

        self.__attractionSlider = ctk.ctkSliderWidget()
        self.__attractionSlider.decimals = 0
        self.__attractionSlider.minimum = -100
        self.__attractionSlider.maximum = 100
        self.__attractionSlider.singleStep = 10
        self.__attractionSlider.toolTip = attractionLabel.toolTip
        segmentationAdvancedFormLayout.addRow(self.__attractionSlider)

        # iteration spinbox
        self.__iterationSpinBox = qt.QSpinBox()
        self.__iterationSpinBox.minimum = 0
        self.__iterationSpinBox.maximum = 5000
        self.__iterationSpinBox.singleStep = 10
        self.__iterationSpinBox.toolTip = "Choose the number of evolution iterations."
        segmentationAdvancedFormLayout.addRow(
            SlicerVmtkCommonLib.Helper.CreateSpace(100) + "Iterations:",
            self.__iterationSpinBox)

        #
        # Reset, preview and apply buttons
        #

        self.__buttonBox = qt.QDialogButtonBox()
        self.__resetButton = self.__buttonBox.addButton(
            self.__buttonBox.RestoreDefaults)
        self.__resetButton.toolTip = "Click to reset all input elements to default."
        self.__previewButton = self.__buttonBox.addButton(
            self.__buttonBox.Discard)
        self.__previewButton.setIcon(qt.QIcon())
        self.__previewButton.text = "Preview.."
        self.__previewButton.toolTip = "Click to refresh the preview."
        self.__startButton = self.__buttonBox.addButton(self.__buttonBox.Apply)
        self.__startButton.setIcon(qt.QIcon())
        self.__startButton.text = "Start!"
        self.__startButton.enabled = False
        self.__startButton.toolTip = "Click to start the filtering."
        self.layout.addWidget(self.__buttonBox)
        self.__resetButton.connect("clicked()", self.restoreDefaults)
        self.__previewButton.connect("clicked()", self.onRefreshButtonClicked)
        self.__startButton.connect("clicked()", self.onStartButtonClicked)

        # be ready for events
        self.__updating = 0

        # set default values
        self.restoreDefaults()

        # compress the layout
        self.layout.addStretch(1)