def section_SimpleMarkupsWidget(self):
        self.delayDisplay("Test SimpleMarkupsWidget", self.delayMs)

        simpleMarkupsWidget = slicer.qSlicerSimpleMarkupsWidget()
        nodeSelector = slicer.util.findChildren(
            simpleMarkupsWidget, "MarkupsFiducialNodeComboBox")[0]

        simpleMarkupsWidget.setMRMLScene(slicer.mrmlScene)
        simpleMarkupsWidget.show()

        placeWidget = simpleMarkupsWidget.markupsPlaceWidget()
        self.assertIsNotNone(placeWidget)

        simpleMarkupsWidget.setCurrentNode(None)
        simpleMarkupsWidget.enterPlaceModeOnNodeChange = False
        placeWidget.placeModeEnabled = False
        nodeSelector.setCurrentNode(self.markupsNode1)
        self.assertFalse(placeWidget.placeModeEnabled)

        simpleMarkupsWidget.enterPlaceModeOnNodeChange = True
        nodeSelector.setCurrentNode(self.markupsNode2)
        self.assertTrue(placeWidget.placeModeEnabled)

        simpleMarkupsWidget.jumpToSliceEnabled = True
        self.assertTrue(simpleMarkupsWidget.jumpToSliceEnabled)
        simpleMarkupsWidget.jumpToSliceEnabled = False
        self.assertFalse(simpleMarkupsWidget.jumpToSliceEnabled)

        simpleMarkupsWidget.nodeSelectorVisible = False
        self.assertFalse(simpleMarkupsWidget.nodeSelectorVisible)
        simpleMarkupsWidget.nodeSelectorVisible = True
        self.assertTrue(simpleMarkupsWidget.nodeSelectorVisible)

        simpleMarkupsWidget.optionsVisible = False
        self.assertFalse(simpleMarkupsWidget.optionsVisible)
        simpleMarkupsWidget.optionsVisible = True
        self.assertTrue(simpleMarkupsWidget.optionsVisible)

        defaultColor = qt.QColor(0, 255, 0)
        simpleMarkupsWidget.defaultNodeColor = defaultColor
        self.assertEqual(simpleMarkupsWidget.defaultNodeColor, defaultColor)

        self.markupsNode3 = nodeSelector.addNode()
        displayNode3 = self.markupsNode3.GetDisplayNode()
        color3 = displayNode3.GetColor()
        self.assertEqual(color3[0] * 255, defaultColor.red())
        self.assertEqual(color3[1] * 255, defaultColor.green())
        self.assertEqual(color3[2] * 255, defaultColor.blue())

        numberOfFiducialsAdded = 5
        for i in range(numberOfFiducialsAdded):
            self.markupsLogic.AddFiducial()

        tableWidget = simpleMarkupsWidget.tableWidget()
        self.assertEqual(tableWidget.rowCount, numberOfFiducialsAdded)
  def section_SimpleMarkupsWidget(self):
    self.delayDisplay("Test SimpleMarkupsWidget",self.delayMs)

    simpleMarkupsWidget = slicer.qSlicerSimpleMarkupsWidget()
    nodeSelector = slicer.util.findChildren(simpleMarkupsWidget,"MarkupsFiducialNodeComboBox")[0]

    simpleMarkupsWidget.setMRMLScene(slicer.mrmlScene)
    simpleMarkupsWidget.show()

    placeWidget = simpleMarkupsWidget.markupsPlaceWidget()
    self.assertIsNotNone(placeWidget)

    simpleMarkupsWidget.setCurrentNode(None)
    simpleMarkupsWidget.enterPlaceModeOnNodeChange = False
    placeWidget.placeModeEnabled = False
    nodeSelector.setCurrentNode(self.markupsNode1)
    self.assertFalse(placeWidget.placeModeEnabled)

    simpleMarkupsWidget.enterPlaceModeOnNodeChange = True
    nodeSelector.setCurrentNode(self.markupsNode2)
    self.assertTrue(placeWidget.placeModeEnabled)

    simpleMarkupsWidget.jumpToSliceEnabled = True
    self.assertTrue(simpleMarkupsWidget.jumpToSliceEnabled)
    simpleMarkupsWidget.jumpToSliceEnabled = False
    self.assertFalse(simpleMarkupsWidget.jumpToSliceEnabled)

    simpleMarkupsWidget.nodeSelectorVisible = False
    self.assertFalse(simpleMarkupsWidget.nodeSelectorVisible)
    simpleMarkupsWidget.nodeSelectorVisible = True
    self.assertTrue(simpleMarkupsWidget.nodeSelectorVisible)

    simpleMarkupsWidget.optionsVisible = False
    self.assertFalse(simpleMarkupsWidget.optionsVisible)
    simpleMarkupsWidget.optionsVisible = True
    self.assertTrue(simpleMarkupsWidget.optionsVisible)

    defaultColor = qt.QColor(0,255,0)
    simpleMarkupsWidget.defaultNodeColor = defaultColor
    self.assertEqual(simpleMarkupsWidget.defaultNodeColor, defaultColor)

    self.markupsNode3 = nodeSelector.addNode()
    displayNode3 = self.markupsNode3.GetDisplayNode()
    color3 = displayNode3.GetColor()
    self.assertEqual(color3[0]*255, defaultColor.red())
    self.assertEqual(color3[1]*255, defaultColor.green())
    self.assertEqual(color3[2]*255, defaultColor.blue())

    numberOfFiducialsAdded = 5
    for i in range(numberOfFiducialsAdded):
      self.markupsLogic.AddFiducial()

    tableWidget = simpleMarkupsWidget.tableWidget()
    self.assertEqual(tableWidget.rowCount, numberOfFiducialsAdded)
Exemple #3
0
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        try:
            import vtkvmtkSegmentationPython as vtkvmtkSegmentation
        except ImportError:
            self.layout.addWidget(qt.QLabel("Failed to load VMTK libraries"))
            return

        #
        # 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."
        self.inputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
        self.inputVolumeNodeSelector.noneEnabled = False
        self.inputVolumeNodeSelector.addEnabled = False
        self.inputVolumeNodeSelector.removeEnabled = False
        ioFormLayout.addRow("Input Volume:", self.inputVolumeNodeSelector)
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.inputVolumeNodeSelector,
                            'setMRMLScene(vtkMRMLScene*)')

        # seed selector
        self.seedFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget()
        self.seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector'
        self.seedFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget()
        self.seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector'
        self.seedFiducialsNodeSelector.toolTip = "Select a point in the largest vessel. Preview will be shown around this point. This is point is also used for determining maximum vessel diameter if automatic filtering parameters computation is enabled."
        self.seedFiducialsNodeSelector.setNodeBaseName("DiameterSeed")
        self.seedFiducialsNodeSelector.tableWidget().hide()
        self.seedFiducialsNodeSelector.defaultNodeColor = qt.QColor(255, 0,
                                                                    0)  # red
        self.seedFiducialsNodeSelector.markupsSelectorComboBox(
        ).noneEnabled = False
        self.seedFiducialsNodeSelector.markupsPlaceWidget(
        ).placeMultipleMarkups = slicer.qSlicerMarkupsPlaceWidget.ForcePlaceSingleMarkup
        ioFormLayout.addRow("Seed point:", self.seedFiducialsNodeSelector)
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.seedFiducialsNodeSelector,
                            'setMRMLScene(vtkMRMLScene*)')

        # outputVolume selector
        self.outputVolumeNodeSelector = slicer.qMRMLNodeComboBox()
        self.outputVolumeNodeSelector.toolTip = "Select the output labelmap."
        self.outputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
        self.outputVolumeNodeSelector.baseName = "VesselnessFiltered"
        self.outputVolumeNodeSelector.noneEnabled = True
        self.outputVolumeNodeSelector.noneDisplay = "Create new volume"
        self.outputVolumeNodeSelector.addEnabled = True
        self.outputVolumeNodeSelector.selectNodeUponCreation = True
        self.outputVolumeNodeSelector.removeEnabled = True
        ioFormLayout.addRow("Output Volume:", self.outputVolumeNodeSelector)
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.outputVolumeNodeSelector,
                            'setMRMLScene(vtkMRMLScene*)')

        #
        # Advanced area
        #

        self.advancedCollapsibleButton = ctk.ctkCollapsibleButton()
        self.advancedCollapsibleButton.text = "Advanced"
        self.advancedCollapsibleButton.collapsed = True
        self.layout.addWidget(self.advancedCollapsibleButton)
        advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton)

        # previewVolume selector
        self.previewVolumeNodeSelector = slicer.qMRMLNodeComboBox()
        self.previewVolumeNodeSelector.toolTip = "Select the preview volume."
        self.previewVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
        self.previewVolumeNodeSelector.baseName = "VesselnessPreview"
        self.previewVolumeNodeSelector.noneEnabled = True
        self.previewVolumeNodeSelector.noneDisplay = "Create new volume"
        self.previewVolumeNodeSelector.addEnabled = True
        self.previewVolumeNodeSelector.selectNodeUponCreation = True
        self.previewVolumeNodeSelector.removeEnabled = True
        advancedFormLayout.addRow("Preview volume:",
                                  self.previewVolumeNodeSelector)
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.previewVolumeNodeSelector,
                            'setMRMLScene(vtkMRMLScene*)')

        self.displayThresholdSlider = ctk.ctkSliderWidget()
        self.displayThresholdSlider.decimals = 2
        self.displayThresholdSlider.minimum = 0
        self.displayThresholdSlider.maximum = 1.0
        self.displayThresholdSlider.singleStep = 0.01
        self.displayThresholdSlider.toolTip = "Voxels below this vesselness value will be hidden. It does not change the voxel values, only how the vesselness volume is displayed."
        advancedFormLayout.addRow("Display threshold:",
                                  self.displayThresholdSlider)
        self.displayThresholdSlider.connect('valueChanged(double)',
                                            self.onDisplayThresholdChanged)

        self.previewVolumeDiameterVoxelSlider = ctk.ctkSliderWidget()
        self.previewVolumeDiameterVoxelSlider.decimals = 0
        self.previewVolumeDiameterVoxelSlider.minimum = 10
        self.previewVolumeDiameterVoxelSlider.maximum = 200
        self.previewVolumeDiameterVoxelSlider.singleStep = 5
        self.previewVolumeDiameterVoxelSlider.suffix = " voxels"
        self.previewVolumeDiameterVoxelSlider.toolTip = "Diameter of the preview area in voxels."
        advancedFormLayout.addRow("Preview volume size:",
                                  self.previewVolumeDiameterVoxelSlider)

        # detect filterint parameters
        self.detectPushButton = qt.QPushButton()
        self.detectPushButton.text = "Compute vessel diameters and contrast from seed point"
        self.detectPushButton.checkable = True
        self.detectPushButton.checked = True
        advancedFormLayout.addRow(self.detectPushButton)
        self.detectPushButton.connect("clicked()", self.onNodeSelectionChanged)

        self.minimumDiameterSpinBox = qt.QSpinBox()
        self.minimumDiameterSpinBox.minimum = 1
        self.minimumDiameterSpinBox.maximum = 1000
        self.minimumDiameterSpinBox.singleStep = 1
        self.minimumDiameterSpinBox.suffix = " voxels"
        self.minimumDiameterSpinBox.enabled = False
        self.minimumDiameterSpinBox.toolTip = "Tubular structures that have minimum this diameter will be enhanced."
        advancedFormLayout.addRow("Minimum vessel diameter:",
                                  self.minimumDiameterSpinBox)
        self.detectPushButton.connect("toggled(bool)",
                                      self.minimumDiameterSpinBox.setDisabled)

        self.maximumDiameterSpinBox = qt.QSpinBox()
        self.maximumDiameterSpinBox.minimum = 0
        self.maximumDiameterSpinBox.maximum = 1000
        self.maximumDiameterSpinBox.singleStep = 1
        self.maximumDiameterSpinBox.suffix = " voxels"
        self.maximumDiameterSpinBox.enabled = False
        self.maximumDiameterSpinBox.toolTip = "Tubular structures that have maximum this diameter will be enhanced."
        advancedFormLayout.addRow("Maximum vessel diameter:",
                                  self.maximumDiameterSpinBox)
        self.detectPushButton.connect("toggled(bool)",
                                      self.maximumDiameterSpinBox.setDisabled)

        self.contrastSlider = ctk.ctkSliderWidget()
        self.contrastSlider.decimals = 0
        self.contrastSlider.minimum = 0
        self.contrastSlider.maximum = 500
        self.contrastSlider.singleStep = 10
        self.contrastSlider.enabled = False
        self.contrastSlider.toolTip = "If the intensity contrast in the input image between vessel and background is high, choose a high value else choose a low value."
        advancedFormLayout.addRow("Vessel contrast:", self.contrastSlider)
        self.detectPushButton.connect("toggled(bool)",
                                      self.contrastSlider.setDisabled)

        self.suppressPlatesSlider = ctk.ctkSliderWidget()
        self.suppressPlatesSlider.decimals = 0
        self.suppressPlatesSlider.minimum = 0
        self.suppressPlatesSlider.maximum = 100
        self.suppressPlatesSlider.singleStep = 1
        self.suppressPlatesSlider.suffix = " %"
        self.suppressPlatesSlider.toolTip = "A higher value filters out more plate-like structures."
        advancedFormLayout.addRow("Suppress plates:",
                                  self.suppressPlatesSlider)

        self.suppressBlobsSlider = ctk.ctkSliderWidget()
        self.suppressBlobsSlider.decimals = 0
        self.suppressBlobsSlider.minimum = 0
        self.suppressBlobsSlider.maximum = 100
        self.suppressBlobsSlider.singleStep = 1
        self.suppressBlobsSlider.suffix = " %"
        self.suppressBlobsSlider.toolTip = "A higher value filters out more blob-like structures."
        advancedFormLayout.addRow("Suppress blobs:", self.suppressBlobsSlider)

        #
        # 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.startButton = self.buttonBox.addButton(self.buttonBox.Apply)
        self.startButton.setIcon(qt.QIcon())
        self.startButton.text = "Start"
        self.startButton.enabled = False
        self.layout.addWidget(self.buttonBox)
        self.resetButton.connect("clicked()", self.restoreDefaults)
        self.previewButton.connect("clicked()", self.onPreviewButtonClicked)
        self.startButton.connect("clicked()", self.onStartButtonClicked)

        self.inputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene)
        self.seedFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene)
        self.outputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene)
        self.previewVolumeNodeSelector.setMRMLScene(slicer.mrmlScene)

        self.inputVolumeNodeSelector.connect(
            "currentNodeChanged(vtkMRMLNode*)", self.onNodeSelectionChanged)
        self.seedFiducialsNodeSelector.markupsSelectorComboBox().connect(
            "currentNodeChanged(vtkMRMLNode*)", self.onNodeSelectionChanged)
        self.seedFiducialsNodeSelector.connect("updateFinished()",
                                               self.onNodeSelectionChanged)

        # set default values
        self.restoreDefaults()

        self.onNodeSelectionChanged()

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

        # Instantiate and connect widgets ...

        #clear scene
        # slicer.mrmlScene.Clear(0)

        #Define Widgets layout
        lm = slicer.app.layoutManager()
        lm.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutThreeOverThreeView)
        lm.sliceWidget('Red').setSliceOrientation('Axial')
        lm.sliceWidget('Red+').setSliceOrientation('Axial')
        lm.sliceWidget('Yellow').setSliceOrientation('Axial')
        lm.sliceWidget('Yellow+').setSliceOrientation('Axial')
        lm.sliceWidget('Green').setSliceOrientation('Axial')
        lm.sliceWidget('Green+').setSliceOrientation('Axial')

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

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

        #
        # input volume selector
        #
        self.inputSelector = slicer.qMRMLNodeComboBox()
        self.inputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.inputSelector.selectNodeUponCreation = True
        self.inputSelector.addEnabled = False
        self.inputSelector.removeEnabled = False
        self.inputSelector.noneEnabled = False
        self.inputSelector.showHidden = False
        self.inputSelector.showChildNodeTypes = False
        self.inputSelector.setMRMLScene(slicer.mrmlScene)
        self.inputSelector.setToolTip("Pick the input to the algorithm.")
        #parametersFormLayout.addRow("Input Volume: ", self.inputSelector)  Por ahora no lo mostramos.

        #
        # output volume selector
        #
        self.outputSelector = slicer.qMRMLNodeComboBox()
        self.outputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.outputSelector.selectNodeUponCreation = True
        self.outputSelector.addEnabled = True
        self.outputSelector.removeEnabled = True
        self.outputSelector.noneEnabled = True
        self.outputSelector.showHidden = False
        self.outputSelector.showChildNodeTypes = False
        self.outputSelector.setMRMLScene(slicer.mrmlScene)
        self.outputSelector.setToolTip("Pick the output to the algorithm.")
        parametersFormLayout.addRow("Volume: ", self.outputSelector)

        #
        # Take Working Image Button
        #
        self.takeImageButton = qt.QPushButton("Take working image")
        self.takeImageButton.toolTip = "Take working image"
        self.takeImageButton.enabled = True
        parametersFormLayout.addRow(self.takeImageButton)

        #
        # Processing selector
        #
        self.processingSelector = qt.QComboBox()
        self.processingSelector.addItem("original")
        self.processingSelector.addItem("image smoothing")
        self.processingSelector.addItem("image segmentation")
        self.processingSelector.addItem("image segmentation + no holes")
        self.processingSelector.addItem("contouring")
        parametersFormLayout.addRow("Processing: ", self.processingSelector)

        #
        #  SpinBoxes : numerical inputs
        #
        self.segmentationGroupBox = qt.QGroupBox("Segmentation Data")
        self.segmentationVBoxLayout = qt.QVBoxLayout()

        self.tempGroupBox = qt.QGroupBox("Temperature")
        self.tempHBoxLayout = qt.QHBoxLayout()

        self.qlabelMin = QLabel('Min:')
        self.doubleMinTemp = ctk.ctkSliderWidget()
        self.doubleMinTemp.setSizePolicy(QSizePolicy.Ignored,
                                         QSizePolicy.Preferred)
        self.doubleMinTemp.setDecimals(2)
        self.doubleMinTemp.setValue(27.0)
        self.tempHBoxLayout.addWidget(self.qlabelMin)
        self.tempHBoxLayout.addWidget(self.doubleMinTemp)

        self.labelMax = qt.QLabel("Max:  ")
        self.doubleMaxTemp = ctk.ctkSliderWidget()
        self.doubleMaxTemp.setValue(35.0)
        self.tempHBoxLayout.addWidget(self.labelMax)
        self.tempHBoxLayout.addWidget(self.doubleMaxTemp)

        self.tempGroupBox.setLayout(self.tempHBoxLayout)
        self.segmentationVBoxLayout.addWidget(self.tempGroupBox)

        #
        # Button to get foot seed
        #
        self.seedBoxesGroup = qt.QGroupBox("Seed")

        frameControlHBox = qt.QVBoxLayout()

        self.seedCoords = {}

        # Seed Left selector
        self.seedLeftFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget(
        )
        self.seedLeftFiducialsNodeSelector.objectName = 'seedLeftFiducialsNodeSelector'
        self.seedLeftFiducialsNodeSelector.toolTip = "Select a fiducial to use as the origin of the left segments."
        self.seedLeftFiducialsNodeSelector.setNodeBaseName("Left")
        self.seedLeftFiducialsNodeSelector.defaultNodeColor = qt.QColor(
            0, 255, 0)
        self.seedLeftFiducialsNodeSelector.tableWidget().hide()
        self.seedLeftFiducialsNodeSelector.markupsSelectorComboBox(
        ).noneEnabled = False
        self.seedLeftFiducialsNodeSelector.markupsPlaceWidget(
        ).placeMultipleMarkups = slicer.qSlicerMarkupsPlaceWidget.ForcePlaceSingleMarkup
        self.seedLeftFiducialsNodeSelector.markupsPlaceWidget(
        ).buttonsVisible = False
        self.seedLeftFiducialsNodeSelector.markupsPlaceWidget().placeButton(
        ).show()
        self.seedLeftFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene)

        self.seedFiducialsBox = qt.QHBoxLayout()
        self.seedLabelWidget = qt.QLabel("Choose left seed node:")
        self.seedFiducialsBox.addWidget(self.seedLabelWidget)
        self.seedFiducialsBox.addWidget(self.seedLeftFiducialsNodeSelector)
        self.leftFiducial = qt.QGroupBox("Left: ")
        self.leftFiducial.setLayout(self.seedFiducialsBox)

        # Seed Right selector
        self.seedRightFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget(
        )
        self.seedRightFiducialsNodeSelector.objectName = 'seedRightFiducialsNodeSelector'
        self.seedRightFiducialsNodeSelector.toolTip = "Select a fiducial to use as the origin of the left segments."
        self.seedRightFiducialsNodeSelector.setNodeBaseName("Right")
        self.seedRightFiducialsNodeSelector.defaultNodeColor = qt.QColor(
            0, 255, 0)
        self.seedRightFiducialsNodeSelector.tableWidget().hide()
        self.seedRightFiducialsNodeSelector.markupsSelectorComboBox(
        ).noneEnabled = False
        self.seedRightFiducialsNodeSelector.markupsPlaceWidget(
        ).placeMultipleMarkups = slicer.qSlicerMarkupsPlaceWidget.ForcePlaceSingleMarkup
        self.seedRightFiducialsNodeSelector.markupsPlaceWidget(
        ).buttonsVisible = False
        self.seedRightFiducialsNodeSelector.markupsPlaceWidget().placeButton(
        ).show()
        self.seedRightFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene)
        seedRightFiducialsNodeSelector = self.seedRightFiducialsNodeSelector

        self.seedRightFiducialsBox = qt.QHBoxLayout()
        self.seedRightLabelWidget = qt.QLabel("Choose right seed node:")
        self.seedRightFiducialsBox.addWidget(self.seedRightLabelWidget)
        self.seedRightFiducialsBox.addWidget(
            self.seedRightFiducialsNodeSelector)
        self.rightFiducial = qt.QGroupBox("Right: ")
        self.rightFiducial.setLayout(self.seedRightFiducialsBox)

        frameControlHBox.addWidget(self.leftFiducial)
        frameControlHBox.addWidget(self.rightFiducial)

        self.seedBoxesGroup.setLayout(frameControlHBox)
        self.segmentationVBoxLayout.addWidget(self.seedBoxesGroup)

        # #Set Group
        self.segmentationGroupBox.setLayout(self.segmentationVBoxLayout)

        parametersFormLayout.addRow(self.segmentationGroupBox)

        #
        # Processing Button
        #
        self.extractButton = qt.QPushButton("Apply Segmentation")
        self.extractButton.toolTip = "Run the algorithm."
        # self.extractButton.enabled = False
        parametersFormLayout.addRow(self.extractButton)

        # connections
        self.extractButton.connect('clicked(bool)', self.onExtractButton)
        self.takeImageButton.connect('clicked(bool)', self.onTakeImageButton)
        self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                    self.onSelectWorkingImage)
        self.processingSelector.connect('currentIndexChanged(QString)',
                                        self.onProcessing)

        # self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', self.seedFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)')

        # Add vertical spacer
        self.layout.addStretch(1)
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        #
        # the I/O panel
        #

        inputsCollapsibleButton = ctk.ctkCollapsibleButton()
        inputsCollapsibleButton.text = "Inputs"
        self.layout.addWidget(inputsCollapsibleButton)
        inputsFormLayout = qt.QFormLayout(inputsCollapsibleButton)

        # 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
        inputsFormLayout.addRow("Input Volume:", self.inputVolumeNodeSelector)
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.inputVolumeNodeSelector,
                            'setMRMLScene(vtkMRMLScene*)')
        self.inputVolumeNodeSelector.connect(
            'currentNodeChanged(vtkMRMLNode*)', self.onInputVolumeChanged)

        # vesselnessVolume selector
        self.vesselnessVolumeNodeSelector = slicer.qMRMLNodeComboBox()
        self.vesselnessVolumeNodeSelector.objectName = 'vesselnessVolumeNodeSelector'
        self.vesselnessVolumeNodeSelector.toolTip = "Select the input vesselness volume."
        self.vesselnessVolumeNodeSelector.nodeTypes = [
            'vtkMRMLScalarVolumeNode'
        ]
        self.vesselnessVolumeNodeSelector.noneEnabled = True
        self.vesselnessVolumeNodeSelector.addEnabled = False
        self.vesselnessVolumeNodeSelector.removeEnabled = False
        inputsFormLayout.addRow("Vesselness Volume:",
                                self.vesselnessVolumeNodeSelector)
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.vesselnessVolumeNodeSelector,
                            'setMRMLScene(vtkMRMLScene*)')
        self.vesselnessVolumeNodeSelector.connect(
            'currentNodeChanged(vtkMRMLNode*)', self.onVesselnessVolumeChanged)
        self.vesselnessVolumeNodeSelector.setCurrentNode(None)

        # seed selector
        self.seedFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget()
        self.seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector'
        self.seedFiducialsNodeSelector.toolTip = "Select start and end point of the vessel branch. Only the first and last point in the list are used."
        self.seedFiducialsNodeSelector.defaultNodeColor = qt.QColor(
            0, 0, 255)  # blue
        self.seedFiducialsNodeSelector.jumpToSliceEnabled = True
        self.seedFiducialsNodeSelector.markupsPlaceWidget(
        ).placeMultipleMarkups = slicer.qSlicerMarkupsPlaceWidget.ForcePlaceMultipleMarkups
        self.seedFiducialsNodeSelector.setNodeBaseName("seeds")
        self.seedFiducialsNodeSelector.markupsSelectorComboBox(
        ).baseName = "Seeds"
        self.seedFiducialsNodeSelector.markupsSelectorComboBox(
        ).noneEnabled = False
        self.seedFiducialsNodeSelector.markupsSelectorComboBox(
        ).removeEnabled = True
        inputsFormLayout.addRow("Seeds:", self.seedFiducialsNodeSelector)
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.seedFiducialsNodeSelector,
                            'setMRMLScene(vtkMRMLScene*)')

        # stopper selector
        self.stopperFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget()
        self.stopperFiducialsNodeSelector.objectName = 'stopperFiducialsNodeSelector'
        self.stopperFiducialsNodeSelector.toolTip = "(Optional) Select a hierarchy containing the fiducials to use as Stoppers. Whenever one stopper is reached, the segmentation stops."
        self.stopperFiducialsNodeSelector.defaultNodeColor = qt.QColor(
            0, 0, 255)  # blue
        self.stopperFiducialsNodeSelector.setNodeBaseName("seeds")
        self.stopperFiducialsNodeSelector.tableWidget().hide()
        self.stopperFiducialsNodeSelector.markupsSelectorComboBox(
        ).baseName = "Stoppers"
        self.stopperFiducialsNodeSelector.markupsSelectorComboBox(
        ).noneEnabled = True
        self.stopperFiducialsNodeSelector.markupsSelectorComboBox(
        ).removeEnabled = True
        inputsFormLayout.addRow("Stoppers:", self.stopperFiducialsNodeSelector)
        self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                            self.stopperFiducialsNodeSelector,
                            'setMRMLScene(vtkMRMLScene*)')

        #
        # Outputs
        #

        outputsCollapsibleButton = ctk.ctkCollapsibleButton()
        outputsCollapsibleButton.text = "Outputs"
        self.layout.addWidget(outputsCollapsibleButton)
        outputsFormLayout = qt.QFormLayout(outputsCollapsibleButton)

        # outputVolume selector
        self.outputVolumeNodeSelector = slicer.qMRMLNodeComboBox()
        self.outputVolumeNodeSelector.toolTip = "Select the output labelmap."
        self.outputVolumeNodeSelector.nodeTypes = ['vtkMRMLLabelMapVolumeNode']
        self.outputVolumeNodeSelector.baseName = "LevelSetSegmentation"
        self.outputVolumeNodeSelector.noneEnabled = False
        self.outputVolumeNodeSelector.addEnabled = True
        self.outputVolumeNodeSelector.selectNodeUponCreation = True
        self.outputVolumeNodeSelector.removeEnabled = True
        outputsFormLayout.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.hideChildNodeTypes = [
            'vtkMRMLAnnotationNode'
        ]  # hide all annotation nodes
        self.outputModelNodeSelector.baseName = "LevelSetSegmentationModel"
        self.outputModelNodeSelector.noneEnabled = False
        self.outputModelNodeSelector.addEnabled = True
        self.outputModelNodeSelector.selectNodeUponCreation = True
        self.outputModelNodeSelector.removeEnabled = True
        outputsFormLayout.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" + (' ' * 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" + (' ' * 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" + (' ' * 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" + (
            ' ' * 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((' ' * 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.onPreviewButtonClicked)
        self.startButton.connect("clicked()", self.onStartButtonClicked)

        self.inputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene)
        self.seedFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene)
        self.vesselnessVolumeNodeSelector.setMRMLScene(slicer.mrmlScene)
        self.outputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene)
        self.outputModelNodeSelector.setMRMLScene(slicer.mrmlScene)
        self.stopperFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene)

        # set default values
        self.restoreDefaults()
        self.onInputVolumeChanged()

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

    #
    # Inputs
    #

    inputsCollapsibleButton = ctk.ctkCollapsibleButton()
    inputsCollapsibleButton.text = "Inputs"
    self.layout.addWidget(inputsCollapsibleButton)
    inputsFormLayout = qt.QFormLayout(inputsCollapsibleButton)

    # inputVolume selector
    self.inputModelNodeSelector = slicer.qMRMLNodeComboBox()
    self.inputModelNodeSelector.objectName = 'inputModelNodeSelector'
    self.inputModelNodeSelector.toolTip = "Select the input model."
    self.inputModelNodeSelector.nodeTypes = ['vtkMRMLModelNode']
    self.inputModelNodeSelector.hideChildNodeTypes = ['vtkMRMLAnnotationNode']  # hide all annotation nodes
    self.inputModelNodeSelector.noneEnabled = False
    self.inputModelNodeSelector.addEnabled = False
    self.inputModelNodeSelector.removeEnabled = False
    inputsFormLayout.addRow("Vessel tree model:", self.inputModelNodeSelector)
    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                        self.inputModelNodeSelector, 'setMRMLScene(vtkMRMLScene*)')

    # seed selector
    self.seedFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget()
    self.seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector'
    self.seedFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget()
    self.seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector'
    self.seedFiducialsNodeSelector.toolTip = "Select a fiducial to use as the origin of the Centerline."
    self.seedFiducialsNodeSelector.setNodeBaseName("OriginSeed")
    self.seedFiducialsNodeSelector.defaultNodeColor = qt.QColor(0,255,0)
    self.seedFiducialsNodeSelector.tableWidget().hide()
    self.seedFiducialsNodeSelector.markupsSelectorComboBox().noneEnabled = False
    self.seedFiducialsNodeSelector.markupsPlaceWidget().placeMultipleMarkups = slicer.qSlicerMarkupsPlaceWidget.ForcePlaceSingleMarkup
    inputsFormLayout.addRow("Start point:", self.seedFiducialsNodeSelector)
    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                        self.seedFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)')

    #
    # Outputs
    #

    outputsCollapsibleButton = ctk.ctkCollapsibleButton()
    outputsCollapsibleButton.text = "Outputs"
    self.layout.addWidget(outputsCollapsibleButton)
    outputsFormLayout = qt.QFormLayout(outputsCollapsibleButton)
                        
    # outputModel selector
    self.outputModelNodeSelector = slicer.qMRMLNodeComboBox()
    self.outputModelNodeSelector.objectName = 'outputModelNodeSelector'
    self.outputModelNodeSelector.toolTip = "Select the output model for the Centerlines."
    self.outputModelNodeSelector.nodeTypes = ['vtkMRMLModelNode']
    self.outputModelNodeSelector.baseName = "CenterlineComputationModel"
    self.outputModelNodeSelector.hideChildNodeTypes = ['vtkMRMLAnnotationNode']  # hide all annotation nodes
    self.outputModelNodeSelector.noneEnabled = True
    self.outputModelNodeSelector.noneDisplay = "Create new model"
    self.outputModelNodeSelector.addEnabled = True
    self.outputModelNodeSelector.selectNodeUponCreation = True
    self.outputModelNodeSelector.removeEnabled = True
    outputsFormLayout.addRow("Centerline model:", self.outputModelNodeSelector)
    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                        self.outputModelNodeSelector, 'setMRMLScene(vtkMRMLScene*)')

    self.outputEndPointsNodeSelector = slicer.qMRMLNodeComboBox()
    self.outputEndPointsNodeSelector.objectName = 'outputEndPointsNodeSelector'
    self.outputEndPointsNodeSelector.toolTip = "Select the output model for the Centerlines."
    self.outputEndPointsNodeSelector.nodeTypes = ['vtkMRMLMarkupsFiducialNode']
    self.outputEndPointsNodeSelector.baseName = "Centerline endpoints"
    self.outputEndPointsNodeSelector.noneEnabled = True
    self.outputEndPointsNodeSelector.noneDisplay = "Create new markups fiducial"
    self.outputEndPointsNodeSelector.addEnabled = True
    self.outputEndPointsNodeSelector.selectNodeUponCreation = True
    self.outputEndPointsNodeSelector.removeEnabled = True
    outputsFormLayout.addRow("Centerline endpoints:", self.outputEndPointsNodeSelector)
    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                        self.outputEndPointsNodeSelector, 'setMRMLScene(vtkMRMLScene*)')
                        
    # voronoiModel selector
    self.voronoiModelNodeSelector = slicer.qMRMLNodeComboBox()
    self.voronoiModelNodeSelector.objectName = 'voronoiModelNodeSelector'
    self.voronoiModelNodeSelector.toolTip = "Select the output model for the Voronoi Diagram."
    self.voronoiModelNodeSelector.nodeTypes = ['vtkMRMLModelNode']
    self.voronoiModelNodeSelector.baseName = "VoronoiModel"
    self.voronoiModelNodeSelector.hideChildNodeTypes = ['vtkMRMLAnnotationNode']  # hide all annotation nodes
    self.voronoiModelNodeSelector.noneEnabled = True
    self.voronoiModelNodeSelector.addEnabled = True
    self.voronoiModelNodeSelector.selectNodeUponCreation = True
    self.voronoiModelNodeSelector.removeEnabled = True
    outputsFormLayout.addRow("Voronoi Model:", self.voronoiModelNodeSelector)
    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                        self.voronoiModelNodeSelector, 'setMRMLScene(vtkMRMLScene*)')

    #
    # Reset, preview and apply buttons
    #

    self.buttonBox = qt.QDialogButtonBox()
    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.previewButton.connect("clicked()", self.onPreviewButtonClicked)
    self.startButton.connect("clicked()", self.onStartButtonClicked)

    self.inputModelNodeSelector.setMRMLScene(slicer.mrmlScene)
    self.seedFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene)
    self.outputModelNodeSelector.setMRMLScene(slicer.mrmlScene)
    self.outputEndPointsNodeSelector.setMRMLScene(slicer.mrmlScene)
    self.voronoiModelNodeSelector.setMRMLScene(slicer.mrmlScene)

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

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

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

        self.optionalInputSelector = slicer.qMRMLNodeComboBox()
        self.optionalInputSelector.nodeTypes = ["vtkMRMLModelNode"]
        self.optionalInputSelector.selectNodeUponCreation = True
        self.optionalInputSelector.addEnabled = False
        self.optionalInputSelector.removeEnabled = False
        self.optionalInputSelector.noneEnabled = True
        self.optionalInputSelector.showHidden = False
        self.optionalInputSelector.showChildNodeTypes = False
        self.optionalInputSelector.setMRMLScene(slicer.mrmlScene)
        self.optionalInputSelector.setToolTip("Pick the input to the algorithm.")
        parametersFormLayout.addRow("Input Initial (Optional): ", self.optionalInputSelector)

        #input model selector
        self.inputModelSelector = slicer.qMRMLNodeComboBox()
        self.inputModelSelector.nodeTypes = [ "vtkMRMLModelNode" ]
        self.inputModelSelector.selectNodeUponCreation = True
        self.inputModelSelector.addEnabled = False
        self.inputModelSelector.removeEnabled = False
        self.inputModelSelector.noneEnabled = False
        self.inputModelSelector.showHidden = False
        self.inputModelSelector.showChildNodeTypes = False
        self.inputModelSelector.setMRMLScene( slicer.mrmlScene )
        self.inputModelSelector.setToolTip( "Pick the input to the algorithm." )
        parametersFormLayout.addRow("Input Model: ", self.inputModelSelector)

        #input left Fiducal selector
        self.inputLFiducialSelector = slicer.qSlicerSimpleMarkupsWidget()
        self.inputLFiducialSelector.tableWidget().hide()
        self.inputLFiducialSelector.setMRMLScene(slicer.mrmlScene)
        self.inputLFiducialSelector.setToolTip("Pick the fiducials to define the left breast region of interest.")
        self.inputLFiducialSelector.setNodeBaseName ("LeftFiducials")

        parametersFormLayout.addRow("Left fiducials: ", self.inputLFiducialSelector)
        # Enable place multiple markups by default
        placeWidget = self.inputLFiducialSelector.markupsPlaceWidget()
        placeWidget.placeMultipleMarkups = slicer.qSlicerMarkupsPlaceWidget.ForcePlaceMultipleMarkups
        placeWidget.placeModeEnabled = False
        placeWidget.placeModeEnabled = True

        # input right  Fiducal selector
        self.inputRFiducialSelector = slicer.qSlicerSimpleMarkupsWidget()
        self.inputRFiducialSelector.tableWidget().hide()
        self.inputRFiducialSelector.setMRMLScene(slicer.mrmlScene)
        self.inputRFiducialSelector.setToolTip("Pick the fiducials to define the right breast region of interest.")
        self.inputRFiducialSelector.setNodeBaseName("RightFiducials")

        parametersFormLayout.addRow("Right fiducials: ", self.inputRFiducialSelector)

        placeWidget = self.inputRFiducialSelector.markupsPlaceWidget()
        placeWidget.placeMultipleMarkups = slicer.qSlicerMarkupsPlaceWidget.ForcePlaceMultipleMarkups
        placeWidget.placeModeEnabled = False
        placeWidget.placeModeEnabled = True

        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.enabled = False
        parametersFormLayout.addRow("Breast Volume Computations", self.applyButton)

        # Volume and distance Labels
        self.VolumeLabelLeft = qt.QLabel()
        self.VolumeLabelLeft.setText("Volume in cc")
        parametersFormLayout.addRow("Left Breast Volume: ", self.VolumeLabelLeft)

        self.VolumeLabelRight = qt.QLabel()
        self.VolumeLabelRight.setText("Volume in cc")
        parametersFormLayout.addRow("Right Breast Volume: ", self.VolumeLabelRight)

        self.VolumeLabelDifference = qt.QLabel()
        self.VolumeLabelDifference.setText("Volume Difference in cc")
        parametersFormLayout.addRow("Breast Volume Difference: ", self.VolumeLabelDifference)

        self.MeanDistanceLabel = qt.QLabel()
        self.MeanDistanceLabel.setText("Mean distance in mm")
        parametersFormLayout.addRow("Mean Distance After Registration: ", self.MeanDistanceLabel)

        # Checkboxes for different module input
        self.noBreastCheck = qt.QCheckBox("")
        self.noBreastCheck.setCheckState(False)
        parametersFormLayout.addRow("Check to create torso mesh (No breast): ", self.noBreastCheck)

        self.infoLabel = qt.QLabel()
        self.infoLabel.setText("")

        parametersFormLayout.addRow("Please see documentation for examples of the below check box use", self.infoLabel)

        self.reverseNormalCheckL = qt.QCheckBox("")
        self.reverseNormalCheckL.setCheckState(False)
        parametersFormLayout.addRow("Check to reverse normal of left breast: ", self.reverseNormalCheckL)

        self.reverseNormalCheckR = qt.QCheckBox("")
        self.reverseNormalCheckR.setCheckState(False)
        parametersFormLayout.addRow("Check to reverse normal of right breast: ", self.reverseNormalCheckR)

        self.setInSideOutCheckL = qt.QCheckBox("")
        self.setInSideOutCheckL.setCheckState(False)
        parametersFormLayout.addRow("Check to set clip function to inside out of left breast: ", self.setInSideOutCheckL)

        self.setInSideOutCheckR = qt.QCheckBox("")
        self.setInSideOutCheckR.setCheckState(False)
        parametersFormLayout.addRow("Check to set clip function to inside out of right breast: ", self.setInSideOutCheckR)

        #    connections
        self.optionalInputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)
        self.inputModelSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)
        self.inputLFiducialSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)
        self.inputRFiducialSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)
        self.applyButton.connect('clicked(bool)', self.onApplyButton)

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

        # Refresh Apply button state
        self.onSelect()
    def setup(self):

        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

        #
        # Parameters Area
        #

        # self.segVolumeTotalNode = slicer.vtkMRMLModelHierarchyNode()
        # self.segVolumeTotalNode.SetName('segVolumeTotalNode')
        # self.segVolumeTotalNode.SetSingletonTag('segVolumeTotalNode')
        # # self.segVolumeTotalNode.HideFromEditorsOn()
        # slicer.mrmlScene.AddNode(self.segVolumeTotalNode)

        self.segVolumeTotalNode = []
        self.segCombineVol = None

        inputCollapsibleButton = ctk.ctkCollapsibleButton()
        inputCollapsibleButton.text = "Input Volumes"
        self.layout.addWidget(inputCollapsibleButton)

        self.pathText = qt.QLineEdit()
        # self.__fixedShrinkFactor.setText("16, 16, 16")
        self.pathText.setToolTip('Specify output path')
        self.layout.addWidget(self.pathText)

        # Layout within the dummy collapsible button
        inputFormLayout = qt.QFormLayout(inputCollapsibleButton)

        loadSpineVolumeButton = qt.QPushButton('Load spine volume')
        loadSpineVolumeButton.connect('clicked()', self.loadVolume)
        inputFormLayout.addRow('Load spine volume', loadSpineVolumeButton)

        loadSegVolumeButton = qt.QPushButton('Load segmentation volume')
        loadSegVolumeButton.connect('clicked()', self.loadVolume)
        inputFormLayout.addRow('Load segmentation volume', loadSegVolumeButton)

        # input volume selector
        self.inputSelector = slicer.qMRMLNodeComboBox()
        self.inputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.inputSelector.selectNodeUponCreation = True
        self.inputSelector.addEnabled = False
        self.inputSelector.removeEnabled = False
        self.inputSelector.noneEnabled = False
        self.inputSelector.showHidden = False
        self.inputSelector.showChildNodeTypes = False
        self.inputSelector.setMRMLScene(slicer.mrmlScene)
        self.inputSelector.setToolTip("Select the CT spine volume.")
        inputFormLayout.addRow("Input Volume: ", self.inputSelector)

        #
        # output volume selector
        #
        self.segmentationSelector = slicer.qMRMLNodeComboBox()
        self.segmentationSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"]
        self.segmentationSelector.selectNodeUponCreation = True
        self.segmentationSelector.addEnabled = True
        self.segmentationSelector.removeEnabled = True
        self.segmentationSelector.noneEnabled = True
        self.segmentationSelector.showHidden = False
        self.segmentationSelector.showChildNodeTypes = False
        self.segmentationSelector.setMRMLScene(slicer.mrmlScene)
        self.segmentationSelector.setToolTip(
            "Select the ground truth segmentation "
            "(if any exists) to compare with prediction.")
        inputFormLayout.addRow("Segmentation Volume: ",
                               self.segmentationSelector)

        cropCollapsibleButton = ctk.ctkCollapsibleButton()
        cropCollapsibleButton.text = "Select Vertebrae"
        self.layout.addWidget(cropCollapsibleButton)
        # Layout within the dummy collapsible button
        cropFormLayout = qt.QFormLayout(cropCollapsibleButton)

        markerTable = slicer.qSlicerSimpleMarkupsWidget()
        self.markerTableSelector = markerTable.MarkupsFiducialNodeComboBox
        self.markerTableSelector.selectNodeUponCreation = False
        self.markerTableSelector.addEnabled = True
        self.markerTableSelector.removeEnabled = True
        self.markerTableSelector.noneEnabled = True
        self.markerTableSelector.renameEnabled = False
        markerTable.setMRMLScene(slicer.mrmlScene)
        markerTable.setCurrentNode(
            slicer.mrmlScene.GetNodeByID(
                slicer.modules.markups.logic().AddNewFiducialNode()))
        markerTable.show()
        cropFormLayout.addWidget(markerTable)

        font = qt.QFont()
        font.setBold(True)

        # Segment vertebrae button

        self.segmentationButton = qt.QPushButton('Segment Vertebrae')
        self.segmentationButton.setFont(font)
        self.segmentationButton.toolTip = 'Segment the selected vertebrae'
        self.segmentationButton.enabled = False

        # Segmentation button connections
        self.segmentationButton.connect('clicked(bool)', self.onSegmentButton)
        self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.onSelect)
        self.markerTableSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                         self.onSelect)

        self.layout.addWidget(self.segmentationButton)

        # Combine Segmentations
        combineCollapsibleButton = ctk.ctkCollapsibleButton()
        combineCollapsibleButton.text = "Combine Segmentations"
        self.layout.addWidget(combineCollapsibleButton)

        # Layout within the dummy collapsible button
        combineFormLayout = qt.QFormLayout(combineCollapsibleButton)

        # Section to assign labels to segmentations and combine segmentations to a single volume
        self.L5SegSelector = DefaultSegSelect()
        self.L5SegSelector.setToolTip("Select L5 Segmentation")
        combineFormLayout.addRow("L5: ", self.L5SegSelector)
        # self.L5SegSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.displayLabel(self.L5SegSelector.currentNode()))
        self.L5SegSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.displayLabel)

        self.L4SegSelector = DefaultSegSelect()
        self.L4SegSelector.setToolTip("Select L4 Segmentation")
        combineFormLayout.addRow("L4: ", self.L4SegSelector)
        self.L4SegSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.displayLabel)

        self.L3SegSelector = DefaultSegSelect()
        self.L3SegSelector.setToolTip("Select L3 Segmentation")
        combineFormLayout.addRow("L3: ", self.L3SegSelector)
        self.L3SegSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.displayLabel)

        self.L2SegSelector = DefaultSegSelect()
        self.L2SegSelector.setToolTip("Select L2 Segmentation")
        combineFormLayout.addRow("L2: ", self.L2SegSelector)
        self.L2SegSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.displayLabel)

        self.L1SegSelector = DefaultSegSelect()
        self.L1SegSelector.setToolTip("Select L1 Segmentation")
        combineFormLayout.addRow("L1: ", self.L1SegSelector)
        self.L1SegSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.displayLabel)

        self.T12SegSelector = DefaultSegSelect()
        self.T12SegSelector.setToolTip("Select T12 Segmentation")
        combineFormLayout.addRow("T12: ", self.T12SegSelector)
        self.T12SegSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                    self.displayLabel)

        self.T11SegSelector = DefaultSegSelect()
        self.T11SegSelector.setToolTip("Select T11 Segmentation")
        combineFormLayout.addRow("T11: ", self.T11SegSelector)
        self.T11SegSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                    self.displayLabel)

        self.T10SegSelector = DefaultSegSelect()
        self.T10SegSelector.setToolTip("Select T10 Segmentation")
        combineFormLayout.addRow("T10: ", self.T10SegSelector)
        self.T10SegSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                    self.displayLabel)

        self.T9SegSelector = DefaultSegSelect()
        self.T9SegSelector.setToolTip("Select T9 Segmentation")
        combineFormLayout.addRow("T9: ", self.T9SegSelector)
        self.T9SegSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.displayLabel)

        self.T8SegSelector = DefaultSegSelect()
        self.T8SegSelector.setToolTip("Select T8 Segmentation")
        combineFormLayout.addRow("T8: ", self.T8SegSelector)
        self.T8SegSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.displayLabel)

        self.T7SegSelector = DefaultSegSelect()
        self.T7SegSelector.setToolTip("Select T7 Segmentation")
        combineFormLayout.addRow("T7: ", self.T7SegSelector)
        self.T7SegSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.displayLabel)

        self.T6SegSelector = DefaultSegSelect()
        self.T6SegSelector.setToolTip("Select T6 Segmentation")
        combineFormLayout.addRow("T6: ", self.T6SegSelector)
        self.T6SegSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.displayLabel)

        self.SegSelectList = [
            self.L5SegSelector,
            self.L4SegSelector,
            self.L3SegSelector,
            self.L2SegSelector,
            self.L1SegSelector,
            self.T12SegSelector,
            self.T11SegSelector,
            self.T10SegSelector,
            self.T9SegSelector,
            self.T8SegSelector,
            self.T7SegSelector,
            self.T6SegSelector,
        ]

        # Segmentation button connections
        self.combineSegButton = qt.QPushButton('Combine Segmentations')
        self.combineSegButton.toolTip = 'Combine Segmented Vertebrae'
        self.combineSegButton.connect('clicked(bool)', self.onCombineSegButton)
        self.combineSegButton.setFont(font)
        combineFormLayout.addRow(self.combineSegButton)

        # Reset segmentations and fiducial markers
        self.resetSegButton = qt.QPushButton('Reset Segmentation and Markers')
        self.resetSegButton.toolTip = "Reset fiducial markers and individual vertebrae segmentations"
        self.resetSegButton.setFont(font)
        self.resetSegButton.connect('clicked(bool)', self.onResetSegButton)
        self.layout.addWidget(self.resetSegButton)

        # Save segmentation button
        self.saveButton = qt.QPushButton('Save')
        self.saveButton.toolTip = "Save segmentation"
        self.saveButton.setFont(font)
        self.saveButton.connect('clicked(bool)', self.onSaveButton)
        combineFormLayout.addRow(self.saveButton)

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

        # Refresh Apply button state
        self.onSelect()
  def setup(self):
    ScriptedLoadableModuleWidget.setup(self)

    #
    # the I/O panel
    #

    inputsCollapsibleButton = ctk.ctkCollapsibleButton()
    inputsCollapsibleButton.text = "Inputs"
    self.layout.addWidget(inputsCollapsibleButton)
    inputsFormLayout = qt.QFormLayout(inputsCollapsibleButton)

    # 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
    inputsFormLayout.addRow("Input Volume:", self.inputVolumeNodeSelector)
    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                        self.inputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)')
    self.inputVolumeNodeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onInputVolumeChanged)

    # vesselnessVolume selector
    self.vesselnessVolumeNodeSelector = slicer.qMRMLNodeComboBox()
    self.vesselnessVolumeNodeSelector.objectName = 'vesselnessVolumeNodeSelector'
    self.vesselnessVolumeNodeSelector.toolTip = "Select the input vesselness volume."
    self.vesselnessVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.vesselnessVolumeNodeSelector.noneEnabled = True
    self.vesselnessVolumeNodeSelector.addEnabled = False
    self.vesselnessVolumeNodeSelector.removeEnabled = False
    inputsFormLayout.addRow("Vesselness Volume:", self.vesselnessVolumeNodeSelector)
    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                        self.vesselnessVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)')
    self.vesselnessVolumeNodeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onVesselnessVolumeChanged)
    self.vesselnessVolumeNodeSelector.setCurrentNode(None)

    # seed selector
    self.seedFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget()
    self.seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector'
    self.seedFiducialsNodeSelector.toolTip = "Select start and end point of the vessel branch. Only the first and last point in the list are used."
    self.seedFiducialsNodeSelector.defaultNodeColor = qt.QColor(0,0,255) # blue
    self.seedFiducialsNodeSelector.jumpToSliceEnabled = True
    self.seedFiducialsNodeSelector.markupsPlaceWidget().placeMultipleMarkups = slicer.qSlicerMarkupsPlaceWidget.ForcePlaceMultipleMarkups
    self.seedFiducialsNodeSelector.setNodeBaseName("seeds")
    self.seedFiducialsNodeSelector.markupsSelectorComboBox().baseName = "Seeds"
    self.seedFiducialsNodeSelector.markupsSelectorComboBox().noneEnabled = False
    self.seedFiducialsNodeSelector.markupsSelectorComboBox().removeEnabled = True
    inputsFormLayout.addRow("Seeds:", self.seedFiducialsNodeSelector)
    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                        self.seedFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)')

    # stopper selector
    self.stopperFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget()
    self.stopperFiducialsNodeSelector.objectName = 'stopperFiducialsNodeSelector'
    self.stopperFiducialsNodeSelector.toolTip = "(Optional) Select a hierarchy containing the fiducials to use as Stoppers. Whenever one stopper is reached, the segmentation stops."
    self.stopperFiducialsNodeSelector.defaultNodeColor = qt.QColor(0,0,255) # blue
    self.stopperFiducialsNodeSelector.setNodeBaseName("seeds")
    self.stopperFiducialsNodeSelector.tableWidget().hide()
    self.stopperFiducialsNodeSelector.markupsSelectorComboBox().baseName = "Stoppers"
    self.stopperFiducialsNodeSelector.markupsSelectorComboBox().noneEnabled = True
    self.stopperFiducialsNodeSelector.markupsSelectorComboBox().removeEnabled = True
    inputsFormLayout.addRow("Stoppers:", self.stopperFiducialsNodeSelector)
    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                        self.stopperFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)')

    #
    # Outputs
    #

    outputsCollapsibleButton = ctk.ctkCollapsibleButton()
    outputsCollapsibleButton.text = "Outputs"
    self.layout.addWidget(outputsCollapsibleButton)
    outputsFormLayout = qt.QFormLayout(outputsCollapsibleButton)

    # outputVolume selector
    self.outputVolumeNodeSelector = slicer.qMRMLNodeComboBox()
    self.outputVolumeNodeSelector.toolTip = "Select the output labelmap."
    self.outputVolumeNodeSelector.nodeTypes = ['vtkMRMLLabelMapVolumeNode']
    self.outputVolumeNodeSelector.baseName = "LevelSetSegmentation"
    self.outputVolumeNodeSelector.noneEnabled = False
    self.outputVolumeNodeSelector.addEnabled = True
    self.outputVolumeNodeSelector.selectNodeUponCreation = True
    self.outputVolumeNodeSelector.removeEnabled = True
    outputsFormLayout.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.hideChildNodeTypes = ['vtkMRMLAnnotationNode']  # hide all annotation nodes
    self.outputModelNodeSelector.baseName = "LevelSetSegmentationModel"
    self.outputModelNodeSelector.noneEnabled = False
    self.outputModelNodeSelector.addEnabled = True
    self.outputModelNodeSelector.selectNodeUponCreation = True
    self.outputModelNodeSelector.removeEnabled = True
    outputsFormLayout.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" + (' '*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" + (' '*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" + (' '*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" + (' '*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((' '*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.onPreviewButtonClicked)
    self.startButton.connect("clicked()", self.onStartButtonClicked)

    self.inputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene)
    self.seedFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene)
    self.vesselnessVolumeNodeSelector.setMRMLScene(slicer.mrmlScene)
    self.outputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene)
    self.outputModelNodeSelector.setMRMLScene(slicer.mrmlScene)
    self.stopperFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene)

    # set default values
    self.restoreDefaults()
    self.onInputVolumeChanged()

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

        self.logic = ProstateReportingLogic()

        self.uiLoader = qt.QUiLoader()

        self.patientName = None

        self.lesionList = None
        self.lesionListTags = []

        # Instantiate and connect widgets ...

        # Load UI files
        self.scansWidget = self.loadUI('Scans')
        self.sectorMapWidget = self.loadUI('SectorMap')
        self.assessmentWidget = self.loadUI('Assessment')
        self.reportWidget = self.loadUI('Report')

        # Set up the sector relationships
        self.SectorMap = None
        self.initSectorMap()

        #
        # Volumes Area
        #
        scansCollapsibleButton = ctk.ctkCollapsibleButton()
        scansCollapsibleButton.text = "Patient Scans"
        self.layout.addWidget(scansCollapsibleButton)

        # Layout within the dummy collapsible button
        scansLayout = qt.QVBoxLayout(scansCollapsibleButton)

        # Patient name
        patientNameLayout = qt.QHBoxLayout()
        patientNameLayout.addWidget(qt.QLabel("Patient Name:"))
        self.patientNameLabel = qt.QLabel("")
        patientNameLayout.addWidget(self.patientNameLabel)

        scansLayout.addLayout(patientNameLayout)

        # Scans
        scansLayout.addWidget(self.scansWidget)

        self.t2VolumeSelector = self.logic.getChild(self.scansWidget,
                                                    't2VolumeSelector')
        self.t2VolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.t2ScanDateLabel = self.logic.getChild(self.scansWidget,
                                                   't2ScanDateLabel')

        self.t1VolumeSelector = self.logic.getChild(self.scansWidget,
                                                    't1VolumeSelector')
        self.t1VolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.t1ScanDateLabel = self.logic.getChild(self.scansWidget,
                                                   't1ScanDateLabel')

        self.dwiVolumeSelector = self.logic.getChild(self.scansWidget,
                                                     'dwiVolumeSelector')
        self.dwiVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.dwiScanDateLabel = self.logic.getChild(self.scansWidget,
                                                    'dwiScanDateLabel')

        self.adcVolumeSelector = self.logic.getChild(self.scansWidget,
                                                     'adcVolumeSelector')
        self.adcVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.adcScanDateLabel = self.logic.getChild(self.scansWidget,
                                                    'adcScanDateLabel')

        self.dceVolumeSelector = self.logic.getChild(self.scansWidget,
                                                     'dceVolumeSelector')
        self.dceVolumeSelector.setMRMLScene(slicer.mrmlScene)
        self.dceScanDateLabel = self.logic.getChild(self.scansWidget,
                                                    'dceScanDateLabel')

        #
        # Lesions Area
        #
        lesionsCollapsibleButton = ctk.ctkCollapsibleButton()
        lesionsCollapsibleButton.text = "Lesions"
        self.layout.addWidget(lesionsCollapsibleButton)

        # Layout within the dummy collapsible button
        lesionsLayout = qt.QVBoxLayout(lesionsCollapsibleButton)

        # Sector map
        sectorMapLabel = qt.QLabel()
        sectorMapLabel.setText("Prostate sector:")
        lesionsLayout.addWidget(sectorMapLabel)
        lesionsLayout.addWidget(self.sectorMapWidget)

        # Lesion target list
        if 0:
            self.targetListSelector = slicer.qMRMLNodeComboBox()
            self.targetListSelector.nodeTypes = ["vtkMRMLMarkupsFiducialNode"]
            self.targetListSelector.selectNodeUponCreation = True
            self.targetListSelector.addEnabled = True
            self.targetListSelector.removeEnabled = False
            self.targetListSelector.noneEnabled = False
            self.targetListSelector.showHidden = False
            self.targetListSelector.showChildNodeTypes = False
            self.targetListSelector.setMRMLScene(slicer.mrmlScene)
            self.targetListSelector.setToolTip(
                "Pick the list of target lesion fiducials.")
            lesionsLayout.addWidget(self.targetListSelector)

        # Add a lesion, will create a list if necessary. Will name it according
        # to sector selection
        self.addLesionButton = qt.QPushButton()
        self.addLesionButton.text = 'Add Lesion'
        lesionsLayout.addWidget(self.addLesionButton)

        # show the lesions in a table
        self.targetTableWidget = slicer.qSlicerSimpleMarkupsWidget()
        self.targetTableWidget.setMRMLScene(slicer.mrmlScene)
        lesionsLayout.addWidget(self.targetTableWidget)
        self.targetListSelector = self.logic.getChild(
            self.targetTableWidget, "MarkupsFiducialNodeComboBox")
        # hide the place button as want to rename fids when adding
        placeWidget = self.logic.getChild(self.targetTableWidget,
                                          "PlaceButton")
        placeWidget.hide()

        #
        # Assessment Area
        #
        assessmentCollapsibleButton = ctk.ctkCollapsibleButton()
        assessmentCollapsibleButton.text = "Assessment"
        self.layout.addWidget(assessmentCollapsibleButton)

        # Layout within the dummy collapsible button
        assessmentLayout = qt.QVBoxLayout(assessmentCollapsibleButton)

        assessmentLayout.addWidget(self.assessmentWidget)
        self.assessmentComboBox = self.logic.getChild(self.assessmentWidget,
                                                      "assessmentComboBox")

        #
        # Report Area
        #
        self.reportButton = qt.QPushButton()
        self.reportButton.setText("Report")
        self.layout.addWidget(self.reportButton)

        # get the report widgets need to fill in
        self.reportPatientName = self.logic.getChild(self.reportWidget,
                                                     "patientNameLabel")
        self.reportScans = self.logic.getChild(self.reportWidget,
                                               "patientScansTextEdit")
        self.reportLesions = self.logic.getChild(self.reportWidget,
                                                 "patientLesionsTextEdit")
        self.reportAssessment = self.logic.getChild(
            self.reportWidget, "patientAssessmentTextEdit")
        self.reportNotes = self.logic.getChild(self.reportWidget,
                                               "patientNotesTextEdit")
        self.reportSave = self.logic.getChild(self.reportWidget,
                                              "savePushButton")
        self.reportCancel = self.logic.getChild(self.reportWidget,
                                                "cancelPushButton")
        #
        # Set up Connections
        #
        # Volumes
        self.t2VolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                      self.onSelectT2)
        self.t1VolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                      self.onSelectT1)
        self.dwiVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                       self.onSelectDWI)
        self.adcVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                       self.onSelectADC)
        self.dceVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                       self.onSelectDCE)

        # Lesions
        self.targetListSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                        self.onSelectTargets)

        # Sector map
        self.LRComboBox.connect("currentIndexChanged(int)",
                                self.onSectorLRChanged)
        self.ZoneComboBox.connect("currentIndexChanged(int)",
                                  self.onSectorZoneChanged)
        self.GlandComboBox.connect("currentIndexChanged(int)",
                                   self.onSectorGlandChanged)
        self.APComboBox.connect("currentIndexChanged(int)",
                                self.onSectorAPChanged)

        self.addLesionButton.connect('clicked(bool)', self.onAddLesion)

        # Report
        self.reportButton.connect('clicked(bool)', self.onReportButton)
        self.reportSave.connect('clicked(bool)', self.onReportSave)
        self.reportCancel.connect('clicked(bool)', self.onReportCancel)

        # Add vertical spacer
        self.layout.addStretch(1)
  def setup(self):
    ScriptedLoadableModuleWidget.setup(self)

    try:
      import vtkvmtkSegmentationPython as vtkvmtkSegmentation
    except ImportError:
      self.layout.addWidget(qt.QLabel("Failed to load VMTK libraries"))
      return

    #
    # 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."
    self.inputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.inputVolumeNodeSelector.noneEnabled = False
    self.inputVolumeNodeSelector.addEnabled = False
    self.inputVolumeNodeSelector.removeEnabled = False
    ioFormLayout.addRow("Input Volume:", self.inputVolumeNodeSelector)
    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                        self.inputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)')

    # seed selector
    self.seedFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget()
    self.seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector'
    self.seedFiducialsNodeSelector = slicer.qSlicerSimpleMarkupsWidget()
    self.seedFiducialsNodeSelector.objectName = 'seedFiducialsNodeSelector'
    self.seedFiducialsNodeSelector.toolTip = "Select a point in the largest vessel. Preview will be shown around this point. This is point is also used for determining maximum vessel diameter if automatic filtering parameters computation is enabled."
    self.seedFiducialsNodeSelector.setNodeBaseName("DiameterSeed")
    self.seedFiducialsNodeSelector.tableWidget().hide()
    self.seedFiducialsNodeSelector.defaultNodeColor = qt.QColor(255,0,0) # red
    self.seedFiducialsNodeSelector.markupsSelectorComboBox().noneEnabled = False
    self.seedFiducialsNodeSelector.markupsPlaceWidget().placeMultipleMarkups = slicer.qSlicerMarkupsPlaceWidget.ForcePlaceSingleMarkup
    ioFormLayout.addRow("Seed point:", self.seedFiducialsNodeSelector)
    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                        self.seedFiducialsNodeSelector, 'setMRMLScene(vtkMRMLScene*)')

    # outputVolume selector
    self.outputVolumeNodeSelector = slicer.qMRMLNodeComboBox()
    self.outputVolumeNodeSelector.toolTip = "Select the output labelmap."
    self.outputVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.outputVolumeNodeSelector.baseName = "VesselnessFiltered"
    self.outputVolumeNodeSelector.noneEnabled = True
    self.outputVolumeNodeSelector.noneDisplay = "Create new volume"
    self.outputVolumeNodeSelector.addEnabled = True
    self.outputVolumeNodeSelector.selectNodeUponCreation = True
    self.outputVolumeNodeSelector.removeEnabled = True
    ioFormLayout.addRow("Output Volume:", self.outputVolumeNodeSelector)
    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                        self.outputVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)')

    #
    # Advanced area
    #

    self.advancedCollapsibleButton = ctk.ctkCollapsibleButton()
    self.advancedCollapsibleButton.text = "Advanced"
    self.advancedCollapsibleButton.collapsed = True
    self.layout.addWidget(self.advancedCollapsibleButton)
    advancedFormLayout = qt.QFormLayout(self.advancedCollapsibleButton)

    # previewVolume selector
    self.previewVolumeNodeSelector = slicer.qMRMLNodeComboBox()
    self.previewVolumeNodeSelector.toolTip = "Select the preview volume."
    self.previewVolumeNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
    self.previewVolumeNodeSelector.baseName = "VesselnessPreview"
    self.previewVolumeNodeSelector.noneEnabled = True
    self.previewVolumeNodeSelector.noneDisplay = "Create new volume"
    self.previewVolumeNodeSelector.addEnabled = True
    self.previewVolumeNodeSelector.selectNodeUponCreation = True
    self.previewVolumeNodeSelector.removeEnabled = True
    advancedFormLayout.addRow("Preview volume:", self.previewVolumeNodeSelector)
    self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)',
                        self.previewVolumeNodeSelector, 'setMRMLScene(vtkMRMLScene*)')

    self.displayThresholdSlider = ctk.ctkSliderWidget()
    self.displayThresholdSlider.decimals = 2
    self.displayThresholdSlider.minimum = 0
    self.displayThresholdSlider.maximum = 1.0
    self.displayThresholdSlider.singleStep = 0.01
    self.displayThresholdSlider.toolTip = "Voxels below this vesselness value will be hidden. It does not change the voxel values, only how the vesselness volume is displayed."
    advancedFormLayout.addRow("Display threshold:", self.displayThresholdSlider)
    self.displayThresholdSlider.connect('valueChanged(double)', self.onDisplayThresholdChanged)

    self.previewVolumeDiameterVoxelSlider = ctk.ctkSliderWidget()
    self.previewVolumeDiameterVoxelSlider.decimals = 0
    self.previewVolumeDiameterVoxelSlider.minimum = 10
    self.previewVolumeDiameterVoxelSlider.maximum = 200
    self.previewVolumeDiameterVoxelSlider.singleStep = 5
    self.previewVolumeDiameterVoxelSlider.suffix = " voxels"
    self.previewVolumeDiameterVoxelSlider.toolTip = "Diameter of the preview area in voxels."
    advancedFormLayout.addRow("Preview volume size:", self.previewVolumeDiameterVoxelSlider)

    # detect filterint parameters
    self.detectPushButton = qt.QPushButton()
    self.detectPushButton.text = "Compute vessel diameters and contrast from seed point"
    self.detectPushButton.checkable = True
    self.detectPushButton.checked = True
    advancedFormLayout.addRow(self.detectPushButton)
    self.detectPushButton.connect("clicked()", self.onNodeSelectionChanged)

    self.minimumDiameterSpinBox = qt.QSpinBox()
    self.minimumDiameterSpinBox.minimum = 1
    self.minimumDiameterSpinBox.maximum = 1000
    self.minimumDiameterSpinBox.singleStep = 1
    self.minimumDiameterSpinBox.suffix = " voxels"
    self.minimumDiameterSpinBox.enabled = False
    self.minimumDiameterSpinBox.toolTip = "Tubular structures that have minimum this diameter will be enhanced."
    advancedFormLayout.addRow("Minimum vessel diameter:", self.minimumDiameterSpinBox)
    self.detectPushButton.connect("toggled(bool)", self.minimumDiameterSpinBox.setDisabled)

    self.maximumDiameterSpinBox = qt.QSpinBox()
    self.maximumDiameterSpinBox.minimum = 0
    self.maximumDiameterSpinBox.maximum = 1000
    self.maximumDiameterSpinBox.singleStep = 1
    self.maximumDiameterSpinBox.suffix = " voxels"
    self.maximumDiameterSpinBox.enabled = False
    self.maximumDiameterSpinBox.toolTip = "Tubular structures that have maximum this diameter will be enhanced."
    advancedFormLayout.addRow("Maximum vessel diameter:", self.maximumDiameterSpinBox)
    self.detectPushButton.connect("toggled(bool)", self.maximumDiameterSpinBox.setDisabled)

    self.contrastSlider = ctk.ctkSliderWidget()
    self.contrastSlider.decimals = 0
    self.contrastSlider.minimum = 0
    self.contrastSlider.maximum = 500
    self.contrastSlider.singleStep = 10
    self.contrastSlider.enabled = False
    self.contrastSlider.toolTip = "If the intensity contrast in the input image between vessel and background is high, choose a high value else choose a low value."
    advancedFormLayout.addRow("Vessel contrast:", self.contrastSlider)
    self.detectPushButton.connect("toggled(bool)", self.contrastSlider.setDisabled)

    self.suppressPlatesSlider = ctk.ctkSliderWidget()
    self.suppressPlatesSlider.decimals = 0
    self.suppressPlatesSlider.minimum = 0
    self.suppressPlatesSlider.maximum = 100
    self.suppressPlatesSlider.singleStep = 1
    self.suppressPlatesSlider.suffix = " %"
    self.suppressPlatesSlider.toolTip = "A higher value filters out more plate-like structures."
    advancedFormLayout.addRow("Suppress plates:", self.suppressPlatesSlider)

    self.suppressBlobsSlider = ctk.ctkSliderWidget()
    self.suppressBlobsSlider.decimals = 0
    self.suppressBlobsSlider.minimum = 0
    self.suppressBlobsSlider.maximum = 100
    self.suppressBlobsSlider.singleStep = 1
    self.suppressBlobsSlider.suffix = " %"
    self.suppressBlobsSlider.toolTip = "A higher value filters out more blob-like structures."
    advancedFormLayout.addRow("Suppress blobs:", self.suppressBlobsSlider)

    #
    # 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.startButton = self.buttonBox.addButton(self.buttonBox.Apply)
    self.startButton.setIcon(qt.QIcon())
    self.startButton.text = "Start"
    self.startButton.enabled = False
    self.layout.addWidget(self.buttonBox)
    self.resetButton.connect("clicked()", self.restoreDefaults)
    self.previewButton.connect("clicked()", self.onPreviewButtonClicked)
    self.startButton.connect("clicked()", self.onStartButtonClicked)

    self.inputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene)
    self.seedFiducialsNodeSelector.setMRMLScene(slicer.mrmlScene)
    self.outputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene)
    self.previewVolumeNodeSelector.setMRMLScene(slicer.mrmlScene)

    self.inputVolumeNodeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onNodeSelectionChanged)
    self.seedFiducialsNodeSelector.markupsSelectorComboBox().connect("currentNodeChanged(vtkMRMLNode*)", self.onNodeSelectionChanged)
    self.seedFiducialsNodeSelector.connect("updateFinished()", self.onNodeSelectionChanged)

    # set default values
    self.restoreDefaults()

    self.onNodeSelectionChanged()

    # compress the layout
    self.layout.addStretch(1)
Exemple #12
0
  def setup(self):
    ScriptedLoadableModuleWidget.setup(self)

    self.logic = LineProfileLogic()

    # Instantiate and connect widgets ...

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

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

    #
    # input volume selector
    #
    self.inputVolumeSelector = slicer.qMRMLNodeComboBox()
    self.inputVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
    self.inputVolumeSelector.selectNodeUponCreation = True
    self.inputVolumeSelector.addEnabled = False
    self.inputVolumeSelector.removeEnabled = False
    self.inputVolumeSelector.noneEnabled = False
    self.inputVolumeSelector.showHidden = False
    self.inputVolumeSelector.setMRMLScene(slicer.mrmlScene)
    self.inputVolumeSelector.setToolTip("Pick the input to the algorithm which will be sampled along the line.")
    parametersFormLayout.addRow("Input Volume: ", self.inputVolumeSelector)

    #
    # input line selector
    #
    self.inputLineWidget = slicer.qSlicerSimpleMarkupsWidget()
    self.inputLineSelector = self.inputLineWidget.markupsSelectorComboBox()
    self.inputLineSelector.nodeTypes = ["vtkMRMLMarkupsLineNode", "vtkMRMLMarkupsCurveNode"]
    self.inputLineSelector.selectNodeUponCreation = True
    self.inputLineSelector.addEnabled = True
    self.inputLineSelector.removeEnabled = True
    self.inputLineSelector.noneEnabled = False
    self.inputLineSelector.showHidden = False
    self.inputLineWidget.tableWidget().setVisible(False)
    self.inputLineWidget.setDefaultNodeColor(qt.QColor().fromRgbF(1,1,0))
    self.inputLineWidget.setMRMLScene( slicer.mrmlScene )
    self.inputLineWidget.setToolTip("Pick line or curve to take image samples along.")
    parametersFormLayout.addRow("Input line: ", self.inputLineWidget)

    #
    # output table selector
    #
    self.outputTableSelector = slicer.qMRMLNodeComboBox()
    self.outputTableSelector.nodeTypes = ["vtkMRMLTableNode"]
    self.outputTableSelector.addEnabled = True
    self.outputTableSelector.renameEnabled = True
    self.outputTableSelector.removeEnabled = True
    self.outputTableSelector.noneEnabled = True
    self.outputTableSelector.showHidden = False
    self.outputTableSelector.setMRMLScene( slicer.mrmlScene )
    self.outputTableSelector.setToolTip( "Pick the output table to the algorithm." )
    parametersFormLayout.addRow("Output table: ", self.outputTableSelector)

    #
    # output plot selector
    #
    self.outputPlotSeriesSelector = slicer.qMRMLNodeComboBox()
    self.outputPlotSeriesSelector.nodeTypes = ["vtkMRMLPlotSeriesNode"]
    self.outputPlotSeriesSelector.addEnabled = True
    self.outputPlotSeriesSelector.renameEnabled = True
    self.outputPlotSeriesSelector.removeEnabled = True
    self.outputPlotSeriesSelector.noneEnabled = True
    self.outputPlotSeriesSelector.showHidden = False
    self.outputPlotSeriesSelector.setMRMLScene( slicer.mrmlScene )
    self.outputPlotSeriesSelector.setToolTip( "Pick the output plot series to the algorithm." )
    parametersFormLayout.addRow("Output plot series: ", self.outputPlotSeriesSelector)

    #
    # line resolution
    #
    self.lineResolutionSliderWidget = ctk.ctkSliderWidget()
    self.lineResolutionSliderWidget.singleStep = 1
    self.lineResolutionSliderWidget.minimum = 2
    self.lineResolutionSliderWidget.maximum = 1000
    self.lineResolutionSliderWidget.value = 100
    self.lineResolutionSliderWidget.decimals = 0
    self.lineResolutionSliderWidget.setToolTip("Number of points to sample along the line.")
    parametersFormLayout.addRow("Line resolution", self.lineResolutionSliderWidget)

    #
    # Proportional percent distance from start
    #
    self.plotProportionalDistanceCheckBox = qt.QCheckBox(" ")
    self.plotProportionalDistanceCheckBox.checked = False
    self.plotProportionalDistanceCheckBox.setToolTip("If checked, distance along the line in plot is not absolute, but the percent distance from the start of the line.")
    parametersFormLayout.addRow("Proportional distance (%):", self.plotProportionalDistanceCheckBox)

    #
    # Apply Button
    #
    self.applyButton = ctk.ctkCheckablePushButton()
    self.applyButton.text = "Compute intensity profile"
    self.applyButton.toolTip = "Run the algorithm."
    self.applyButton.enabled = False
    self.applyButton.checkable = False
    self.applyButton.checkBoxControlsButtonToggleState = True
    parametersFormLayout.addRow(self.applyButton)

    # connections
    self.applyButton.connect('clicked(bool)', self.onApplyButton)
    self.applyButton.connect('checkBoxToggled(bool)', self.onApplyButtonToggled)
    self.inputVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelectNode)
    self.inputLineSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelectNode)
    self.outputPlotSeriesSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelectNode)
    self.outputTableSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelectNode)
    self.lineResolutionSliderWidget.connect("valueChanged(double)", self.onSetLineResolution)
    self.plotProportionalDistanceCheckBox.connect("clicked()", self.onProportionalDistance)

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

    # Refresh Apply button state
    self.onSelectNode()
    def setup(self):

        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

        #
        # Parameters Area
        #
        inputCollapsibleButton = ctk.ctkCollapsibleButton()
        inputCollapsibleButton.text = "Input Volumes"
        self.layout.addWidget(inputCollapsibleButton)

        # Layout within the dummy collapsible button
        inputFormLayout = qt.QFormLayout(inputCollapsibleButton)

        loadSpineVolumeButton = qt.QPushButton('Load spine volume')
        loadSpineVolumeButton.connect('clicked()', self.loadVolume)
        inputFormLayout.addRow('Load spine volume', loadSpineVolumeButton)

        loadSegVolumeButton = qt.QPushButton('Load segmentation volume')
        loadSegVolumeButton.connect('clicked()', self.loadVolume)
        inputFormLayout.addRow('Load segmentation volume', loadSegVolumeButton)

        # TODO Add functionality so that if the segmentation is NOT imported as a label map, it is converted to one immediately

        #
        # input volume selector
        #
        self.inputSelector = slicer.qMRMLNodeComboBox()
        self.inputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"]
        self.inputSelector.selectNodeUponCreation = True
        self.inputSelector.addEnabled = False
        self.inputSelector.removeEnabled = False
        self.inputSelector.noneEnabled = False
        self.inputSelector.showHidden = False
        self.inputSelector.showChildNodeTypes = False
        self.inputSelector.setMRMLScene(slicer.mrmlScene)
        self.inputSelector.setToolTip("Select the CT spine volume.")
        inputFormLayout.addRow("Input Volume: ", self.inputSelector)

        #
        # output volume selector
        #
        self.segmentationSelector = slicer.qMRMLNodeComboBox()
        self.segmentationSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"]
        self.segmentationSelector.selectNodeUponCreation = True
        self.segmentationSelector.addEnabled = True
        self.segmentationSelector.removeEnabled = True
        self.segmentationSelector.noneEnabled = True
        self.segmentationSelector.showHidden = False
        self.segmentationSelector.showChildNodeTypes = False
        self.segmentationSelector.setMRMLScene(slicer.mrmlScene)
        self.segmentationSelector.setToolTip(
            "Select the ground truth segmentation "
            "(if any exists) to compare with prediction.")
        inputFormLayout.addRow("Segmentation Volume: ",
                               self.segmentationSelector)

        # TODO Add a save resampled volume

        cropCollapsibleButton = ctk.ctkCollapsibleButton()
        cropCollapsibleButton.text = "Select Vertebrae"
        self.layout.addWidget(cropCollapsibleButton)

        # Layout within the dummy collapsible button
        cropFormLayout = qt.QFormLayout(cropCollapsibleButton)

        markerTable = slicer.qSlicerSimpleMarkupsWidget()
        self.markerTableSelector = markerTable.MarkupsFiducialNodeComboBox
        self.markerTableSelector.selectNodeUponCreation = False
        self.markerTableSelector.addEnabled = True
        self.markerTableSelector.removeEnabled = True
        self.markerTableSelector.noneEnabled = False
        self.markerTableSelector.renameEnabled = True
        markerTable.setMRMLScene(slicer.mrmlScene)
        markerTable.setCurrentNode(
            slicer.mrmlScene.GetNodeByID(
                slicer.modules.markups.logic().AddNewFiducialNode()))
        markerTable.show()
        cropFormLayout.addWidget(markerTable)

        # # crop output volume selector
        # self.cropOutputSelector = slicer.qMRMLNodeComboBox()
        # self.cropOutputSelector.nodeTypes = ['vtkMRMLScalarVolumeNode']
        # self.cropOutputSelector.toolTip = "Crop volumes for vertebrae levels"
        # self.cropOutputSelector.setMRMLScene(slicer.mrmlScene)
        # self.cropOutputSelector.renameEnabled = True
        # self.cropOutputSelector.addEnabled = True
        # self.cropOutputSelector.noneEnabled = True
        # self.cropOutputSelector.selectNodeUponCreation = True
        # self.cropOutputSelector.noneDisplay = 'Define name for cropped volume'
        # self.cropOutputSelector.removeEnabled = True
        # self.cropOutputSelector.showHidden = True
        #
        #
        # cropFormLayout.addRow("Output Crop Volume: ", self.cropOutputSelector)
        #
        #
        # # crop button
        # cropButton = qt.QPushButton("Crop Vertebrae")
        # cropButton.connect("clicked(bool)", self.onCropButton)
        # cropFormLayout.addRow("Crop Vertebrae", cropButton)

        # Segment vertebrae button
        self.segmentationButton = qt.QPushButton('Segment Vertebrae')
        self.segmentationButton.toolTip = 'Segment the selected vertebrae'
        self.segmentationButton.enabled = False

        # Segmentation button connections
        self.segmentationButton.connect('clicked(bool)', self.onSegmentButton)
        self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.onSelect)
        self.markerTableSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                         self.onSelect)

        self.layout.addWidget(self.segmentationButton)

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

        # Refresh Apply button state
        self.onSelect()