Beispiel #1
0
    def create(self):
        super(PETTumorSegmentationEffectOptions, self).create()

        #Save space in the GUI
        self.frame.layout().setSpacing(0)
        self.frame.layout().setMargin(0)

        # refinementBoxesFrame contains the options for how clicks are handled
        self.refinementBoxesFrame = qt.QFrame(self.frame)
        self.refinementBoxesFrame.setLayout(qt.QHBoxLayout())
        self.refinementBoxesFrame.layout().setSpacing(0)
        self.refinementBoxesFrame.layout().setMargin(0)
        self.frame.layout().addWidget(self.refinementBoxesFrame)

        #default is global refinement (threshold refinement)
        self.noRefinementRadioButton = qt.QRadioButton(
            "Create new", self.refinementBoxesFrame)
        self.noRefinementRadioButton.setToolTip(
            "On click, always segment a new object.")
        self.globalRefinementRadioButton = qt.QRadioButton(
            "Global refinement", self.refinementBoxesFrame)
        self.globalRefinementRadioButton.setToolTip(
            "On click, refine globally (adjusting then entire boundary) if no center point for the label, otherwise segment a new object."
        )
        self.localRefinementRadioButton = qt.QRadioButton(
            "Local refinement", self.refinementBoxesFrame)
        self.localRefinementRadioButton.setToolTip(
            "On click, refine locally (adjusting part of the boundary) if no center point for the label, otherwise segment a new object."
        )
        self.globalRefinementRadioButton.setChecked(True)

        #radio button so only one can be applied
        self.refinementBoxesFrame.layout().addWidget(
            qt.QLabel("Interaction style: ", self.refinementBoxesFrame))
        self.refinementBoxesFrame.layout().addWidget(
            self.noRefinementRadioButton)
        self.refinementBoxesFrame.layout().addWidget(
            self.globalRefinementRadioButton)
        self.refinementBoxesFrame.layout().addWidget(
            self.localRefinementRadioButton)
        self.refinementBoxesFrame.layout().addStretch(1)
        self.widgets.append(self.noRefinementRadioButton)
        self.widgets.append(self.globalRefinementRadioButton)
        self.widgets.append(self.localRefinementRadioButton)
        self.noRefinementRadioButton.connect('clicked()',
                                             self.onRefinementTypeChanged)
        self.localRefinementRadioButton.connect('clicked()',
                                                self.onRefinementTypeChanged)
        self.globalRefinementRadioButton.connect('clicked()',
                                                 self.onRefinementTypeChanged)

        #options are hidden (collapsed) until requested
        self.optFrame = ctk.ctkCollapsibleButton(self.frame)
        self.optFrame.setText("Options")
        self.optFrame.setLayout(qt.QVBoxLayout())
        self.optFrame.layout().setSpacing(0)
        self.optFrame.layout().setMargin(0)
        self.optFrame.visible = True
        self.optFrame.collapsed = True
        self.optFrame.collapsedHeight = 0
        self.optFrame.setToolTip("Displays algorithm options.")

        #most useful options are kept on top: Splitting, Sealing, Assist Centering, Allow
        # Overwriting
        #to save vertical space, put 2 ina  row, so subframes here with horizontal layout are used

        #first row
        self.commonCheckBoxesFrame1 = qt.QFrame(self.optFrame)
        self.commonCheckBoxesFrame1.setLayout(qt.QHBoxLayout())
        self.commonCheckBoxesFrame1.layout().setSpacing(0)
        self.commonCheckBoxesFrame1.layout().setMargin(0)
        self.optFrame.layout().addWidget(self.commonCheckBoxesFrame1)

        #top left
        self.splittingCheckBox = qt.QCheckBox("Splitting",
                                              self.commonCheckBoxesFrame1)
        self.splittingCheckBox.setToolTip(
            "Cut off adjacent objects to the target via watershed or local minimum.  Useful for lymph node chains."
        )
        self.splittingCheckBox.checked = False
        self.commonCheckBoxesFrame1.layout().addWidget(self.splittingCheckBox)
        self.widgets.append(self.splittingCheckBox)

        #top right
        self.sealingCheckBox = qt.QCheckBox("Sealing",
                                            self.commonCheckBoxesFrame1)
        self.sealingCheckBox.setToolTip(
            "Close single-voxel gaps in the object or between the object and other objects, if above the threshold.  Useful for lymph node chains."
        )
        self.sealingCheckBox.checked = False
        self.commonCheckBoxesFrame1.layout().addWidget(self.sealingCheckBox)
        self.widgets.append(self.sealingCheckBox)

        #second row
        self.commonCheckBoxesFrame2 = qt.QFrame(self.optFrame)
        self.commonCheckBoxesFrame2.setLayout(qt.QHBoxLayout())
        self.commonCheckBoxesFrame2.layout().setSpacing(0)
        self.commonCheckBoxesFrame2.layout().setMargin(0)
        self.optFrame.layout().addWidget(self.commonCheckBoxesFrame2)

        #bottom left
        self.assistCenteringCheckBox = qt.QCheckBox(
            "Assist Centering", self.commonCheckBoxesFrame2)
        self.assistCenteringCheckBox.setToolTip(
            "Move the center to the highest voxel within 7 physical units, without being on or next to other object labels.  Improves consistency."
        )
        self.assistCenteringCheckBox.checked = True
        self.commonCheckBoxesFrame2.layout().addWidget(
            self.assistCenteringCheckBox)
        self.widgets.append(self.assistCenteringCheckBox)

        #bottom right
        self.allowOverwritingCheckBox = qt.QCheckBox(
            "Allow Overwriting", self.commonCheckBoxesFrame2)
        self.allowOverwritingCheckBox.setToolTip("Ignore other object labels.")
        self.allowOverwritingCheckBox.checked = False
        self.commonCheckBoxesFrame2.layout().addWidget(
            self.allowOverwritingCheckBox)
        self.widgets.append(self.allowOverwritingCheckBox)

        #advanced options, for abnormal cases such as massive necrotic objects or
        #low-transition scans like phantoms
        #infrequently used, just keep vertical
        self.advFrame = ctk.ctkCollapsibleButton(self.optFrame)
        self.advFrame.setText("Advanced")
        self.advFrame.setLayout(qt.QVBoxLayout())
        self.advFrame.layout().setSpacing(0)
        self.advFrame.layout().setMargin(0)
        self.advFrame.visible = True
        self.advFrame.collapsed = True
        self.advFrame.collapsedHeight = 0
        self.advFrame.setToolTip(
            "Displays more advanced algorithm options.  Do not use if you don't know what they mean."
        )

        #top
        self.necroticRegionCheckBox = qt.QCheckBox("Necrotic Region",
                                                   self.advFrame)
        self.necroticRegionCheckBox.setToolTip(
            "Prevents cutoff from low uptake.  Use if placing a center inside a necrotic region."
        )
        self.necroticRegionCheckBox.checked = False
        self.advFrame.layout().addWidget(self.necroticRegionCheckBox)
        self.widgets.append(self.necroticRegionCheckBox)

        #middle
        self.denoiseThresholdCheckBox = qt.QCheckBox("Denoise Threshold",
                                                     self.advFrame)
        self.denoiseThresholdCheckBox.setToolTip(
            "Calculates threshold based on median-filtered image.  Use only if scan is very noisey."
        )
        self.denoiseThresholdCheckBox.checked = False
        self.advFrame.layout().addWidget(self.denoiseThresholdCheckBox)
        self.widgets.append(self.denoiseThresholdCheckBox)

        #bottom
        self.linearCostCheckBox = qt.QCheckBox("Linear Cost", self.advFrame)
        self.linearCostCheckBox.setToolTip(
            "Cost function below threshold is linear rather than based on region.  Use only if little/no transition region in uptake."
        )
        self.linearCostCheckBox.checked = False
        self.advFrame.layout().addWidget(self.linearCostCheckBox)
        self.widgets.append(self.linearCostCheckBox)

        self.optFrame.layout().addWidget(self.advFrame)

        #apply button kept at bottom of all options
        self.applyButton = qt.QPushButton("Apply", self.optFrame)
        self.optFrame.layout().addWidget(self.applyButton)
        self.applyButton.connect('clicked()', self.onApply)
        self.widgets.append(self.applyButton)
        self.applyButton.setToolTip(
            "Redo last segmentation with the same center and refinement points with any changes in options."
        )

        #When changing settings, update the MRML with it
        self.assistCenteringCheckBox.connect('toggled(bool)',
                                             self.updateMRMLFromGUI)
        self.allowOverwritingCheckBox.connect('toggled(bool)',
                                              self.updateMRMLFromGUI)
        self.splittingCheckBox.connect('toggled(bool)', self.updateMRMLFromGUI)
        self.sealingCheckBox.connect('toggled(bool)', self.updateMRMLFromGUI)
        self.necroticRegionCheckBox.connect('toggled(bool)',
                                            self.updateMRMLFromGUI)
        self.denoiseThresholdCheckBox.connect('toggled(bool)',
                                              self.updateMRMLFromGUI)
        self.linearCostCheckBox.connect('toggled(bool)',
                                        self.updateMRMLFromGUI)

        self.frame.layout().addWidget(self.optFrame)

        HelpButton(
            self.frame,
            "Click on a lesion in a PET scan to segment it. Depending on refinement settings, click again to refine globally and/or locally. Options may help deal with cases such as segmenting individual lesions in a chain. For more information: http://www.slicer.org/slicerWiki/index.php/Documentation/4.4/Modules/PETTumorSegmentationEffect"
        )

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

        # Clear any existing data and undo/redo queue; working directly with other tools is
        # beyond the scope of this
        self.logic.reset()

        self.updateGUIFromMRML(self, 0)
Beispiel #2
0
    def createUserInterface(self):

        self.__layout = self.__parent.createUserInterface()

        step_label = qt.QLabel(
            """Review your segmentation. Use the 3D Visualization slider to see your segmentation in context with your image. Use the Editor panel to apply spot edits to your segmentation. If you would like to start over, see the Restart box below"""
        )
        step_label.setWordWrap(True)
        self.__primaryGroupBox = qt.QGroupBox()
        self.__primaryGroupBox.setTitle('Information')
        self.__primaryGroupBoxLayout = qt.QFormLayout(self.__primaryGroupBox)
        self.__primaryGroupBoxLayout.addRow(step_label)
        self.__layout.addRow(self.__primaryGroupBox)

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

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

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

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

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

        self.__RemoveRegisteredImage = qt.QCheckBox()
        self.__RemoveRegisteredImage.checked = True
        self.__RemoveRegisteredImage.setToolTip(
            "Delete your registered images.")
        RestartGroupBoxLayout.addRow("Delete Registered images: ",
                                     self.__RemoveRegisteredImage)

        self.__RemoveNormalizedImages = qt.QCheckBox()
        self.__RemoveNormalizedImages.checked = True
        self.__RemoveNormalizedImages.setToolTip(
            "Delete your normalized images.")
        RestartGroupBoxLayout.addRow("Delete Normalized images: ",
                                     self.__RemoveNormalizedImages)

        self.__RemoveSubtractionMap = qt.QCheckBox()
        self.__RemoveSubtractionMap.checked = True
        self.__RemoveSubtractionMap.setToolTip("Delete your subtraction map.")
        RestartGroupBoxLayout.addRow("Delete Subtraction map: ",
                                     self.__RemoveSubtractionMap)

        self.__RemoveCroppedMap = qt.QCheckBox()
        self.__RemoveCroppedMap.checked = True
        self.__RemoveCroppedMap.setToolTip(
            "Delete the cropped version of your input volume.")
        RestartGroupBoxLayout.addRow("Delete Cropped Volume: ",
                                     self.__RemoveCroppedMap)

        self.__RemoveROI = qt.QCheckBox()
        self.__RemoveROI.checked = False
        self.__RemoveROI.setToolTip(
            "Delete the ROI you made with your markup points.")
        RestartGroupBoxLayout.addRow("Delete Full ROI: ", self.__RemoveROI)

        self.__RemoveThresholdedROI = qt.QCheckBox()
        self.__RemoveThresholdedROI.checked = False
        self.__RemoveThresholdedROI.setToolTip(
            "Delete the intensity-thresholded version of your ROI.")
        RestartGroupBoxLayout.addRow("Delete Thresholded ROI: ",
                                     self.__RemoveThresholdedROI)

        self.__RemoveMarkups = qt.QCheckBox()
        self.__RemoveMarkups.checked = True
        self.__RemoveMarkups.setToolTip(
            "Delete the markup points you used to create your 3D ROI.")
        RestartGroupBoxLayout.addRow("Delete Markup Points: ",
                                     self.__RemoveMarkups)

        self.__RemoveModels = qt.QCheckBox()
        self.__RemoveModels.checked = True
        self.__RemoveModels.setToolTip(
            "Delete the 3D model you created from your markup points.")
        RestartGroupBoxLayout.addRow("Delete 3D Model: ", self.__RemoveModels)

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

        self.__layout.addRow(RestartGroupBox)
Beispiel #3
0
    def setup(self):

        #
        # servers
        #

        # testing server - not exposed (used for development)
        self.localFrame = ctk.ctkCollapsibleButton(self.parent)
        self.localFrame.setLayout(qt.QVBoxLayout())
        self.localFrame.setText("Servers")
        self.layout.addWidget(self.localFrame)
        self.localFrame.collapsed = False

        self.toggleServer = qt.QPushButton("Start Testing Server")
        self.localFrame.layout().addWidget(self.toggleServer)
        self.toggleServer.connect('clicked()', self.onToggleServer)

        self.verboseServer = qt.QCheckBox("Verbose")
        self.localFrame.layout().addWidget(self.verboseServer)

        # advanced options - not exposed to end users
        # developers can uncomment these lines to access testing server
        self.toggleServer.hide()
        self.verboseServer.hide()

        # Listener

        settings = qt.QSettings()
        self.toggleListener = qt.QPushButton()
        if hasattr(slicer, 'dicomListener'):
            self.toggleListener.text = "Stop Listener"
            slicer.dicomListener.process.connect('stateChanged(int)',
                                                 self.onListenerStateChanged)
        else:
            self.toggleListener.text = "Start Listener"
        self.localFrame.layout().addWidget(self.toggleListener)
        self.toggleListener.connect('clicked()', self.onToggleListener)

        self.runListenerAtStart = qt.QCheckBox(
            "Start Listener when Slicer Starts")
        self.localFrame.layout().addWidget(self.runListenerAtStart)
        if settings.contains('DICOM/RunListenerAtStart'):
            self.runListenerAtStart.checked = bool(
                settings.value('DICOM/RunListenerAtStart'))
        self.runListenerAtStart.connect('clicked()', self.onRunListenerAtStart)

        # the Database frame (home of the ctkDICOM widget)
        self.dicomFrame = ctk.ctkCollapsibleButton(self.parent)
        self.dicomFrame.setLayout(qt.QVBoxLayout())
        self.dicomFrame.setText("DICOM Database and Networking")
        self.layout.addWidget(self.dicomFrame)

        # initialize the dicomDatabase
        # - don't let the user escape without
        #   picking a valid database directory
        while not slicer.dicomDatabase:
            self.promptForDatabaseDirectory()

        #
        # create and configure the app widget - this involves
        # reaching inside and manipulating the widget hierarchy
        # - TODO: this configurability should be exposed more natively
        #   in the CTK code to avoid the findChildren calls
        #
        self.dicomApp = ctk.ctkDICOMAppWidget()
        if self.hideSearch:
            # hide the search options - doesn't work yet and doesn't fit
            # well into the frame
            slicer.util.findChildren(self.dicomApp, 'SearchOption')[0].hide()

        self.detailsPopup = DICOMLib.DICOMDetailsPopup(
            self.dicomApp, setBrowserPersistence=self.setBrowserPersistence)

        self.tree = self.detailsPopup.tree

        self.showBrowser = qt.QPushButton('Show DICOM Browser')
        self.dicomFrame.layout().addWidget(self.showBrowser)
        self.showBrowser.connect('clicked()', self.detailsPopup.open)

        # make the tree view a bit bigger
        self.tree.setMinimumHeight(250)

        if hasattr(slicer, 'dicomListener'):
            slicer.dicomListener.fileToBeAddedCallback = self.onListenerToAddFile
            slicer.dicomListener.fileAddedCallback = self.onListenerAddedFile

        self.contextMenu = qt.QMenu(self.tree)
        self.exportAction = qt.QAction("Export to Study", self.contextMenu)
        self.contextMenu.addAction(self.exportAction)
        self.exportAction.enabled = False
        self.deleteAction = qt.QAction("Delete", self.contextMenu)
        self.contextMenu.addAction(self.deleteAction)
        self.contextMenu.connect('triggered(QAction*)',
                                 self.onContextMenuTriggered)

        slicer.dicomDatabase.connect('databaseChanged()',
                                     self.onDatabaseChanged)
        self.dicomApp.connect('databaseDirectoryChanged(QString)',
                              self.onDatabaseDirectoryChanged)
        selectionModel = self.tree.selectionModel()
        # TODO: can't use this because QList<QModelIndex> is not visible in PythonQt
        #selectionModel.connect('selectionChanged(QItemSelection, QItemSelection)', self.onTreeSelectionChanged)
        self.tree.connect('clicked(QModelIndex)', self.onTreeClicked)
        self.tree.setContextMenuPolicy(3)
        self.tree.connect('customContextMenuRequested(QPoint)',
                          self.onTreeContextMenuRequested)

        # enable to the Send button of the app widget and take it over
        # for our purposes - TODO: fix this to enable it at the ctkDICOM level
        self.sendButton = slicer.util.findChildren(self.dicomApp,
                                                   text='Send')[0]
        self.sendButton.enabled = False
        self.sendButton.connect('clicked()', self.onSendClicked)

        # the recent activity frame
        self.activityFrame = ctk.ctkCollapsibleButton(self.parent)
        self.activityFrame.setLayout(qt.QVBoxLayout())
        self.activityFrame.setText("Recent DICOM Activity")
        self.layout.addWidget(self.activityFrame)

        self.recentActivity = DICOMLib.DICOMRecentActivityWidget(
            self.activityFrame, detailsPopup=self.detailsPopup)
        self.activityFrame.layout().addWidget(self.recentActivity.widget)
        self.requestUpdateRecentActivity()

        # Add spacer to layout
        self.layout.addStretch(1)
Beispiel #4
0
    def create(self):
        super(PaintEffectOptions, self).create()

        labelVolume = self.editUtil.getLabelVolume()
        if labelVolume and labelVolume.GetImageData():
            spacing = labelVolume.GetSpacing()
            dimensions = labelVolume.GetImageData().GetDimensions()
            self.minimumRadius = 0.5 * min(spacing)
            bounds = [a * b for a, b in zip(spacing, dimensions)]
            self.maximumRadius = 0.5 * max(bounds)
        else:
            self.minimumRadius = 0.01
            self.maximumRadius = 100

        self.radiusFrame = qt.QFrame(self.frame)
        self.radiusFrame.setLayout(qt.QHBoxLayout())
        self.frame.layout().addWidget(self.radiusFrame)
        self.widgets.append(self.radiusFrame)
        self.radiusLabel = qt.QLabel("Radius:", self.radiusFrame)
        self.radiusLabel.setToolTip(
            "Set the radius of the paint brush in millimeters")
        self.radiusFrame.layout().addWidget(self.radiusLabel)
        self.widgets.append(self.radiusLabel)
        self.radiusSpinBox = slicer.qMRMLSpinBox(self.radiusFrame)
        self.radiusSpinBox.setToolTip(
            "Set the radius of the paint brush in millimeters")
        self.radiusSpinBox.quantity = "length"
        # QFlags not wrapped in python. Equivalent to Prefix | Suffix
        # See qMRMLSpinBox for more details.
        self.radiusSpinBox.unitAwareProperties = 0x01 | 0x02
        self.radiusSpinBox.minimum = self.minimumRadius
        self.radiusSpinBox.maximum = self.maximumRadius
        self.radiusSpinBox.setMRMLScene(slicer.mrmlScene)
        from math import log, floor
        decimals = floor(log(self.minimumRadius, 10))
        if decimals < 0:
            self.radiusSpinBox.decimals = -decimals + 2
        self.radiusFrame.layout().addWidget(self.radiusSpinBox)
        self.widgets.append(self.radiusSpinBox)
        self.radiusUnitsToggle = qt.QPushButton("px:")
        self.radiusUnitsToggle.setToolTip(
            "Toggle radius quick set buttons between mm and label volume pixel size units"
        )
        self.radiusUnitsToggle.setFixedWidth(35)
        self.radiusFrame.layout().addWidget(self.radiusUnitsToggle)
        self.radiusUnitsToggle.connect('clicked()', self.onRadiusUnitsToggle)
        self.radiusQuickies = {}
        quickies = ((2, self.onQuickie2Clicked), (3, self.onQuickie3Clicked),
                    (4, self.onQuickie4Clicked), (5, self.onQuickie5Clicked),
                    (10, self.onQuickie10Clicked), (20,
                                                    self.onQuickie20Clicked))
        for rad, callback in quickies:
            self.radiusQuickies[rad] = qt.QPushButton(str(rad))
            self.radiusFrame.layout().addWidget(self.radiusQuickies[rad])
            self.radiusQuickies[rad].setFixedWidth(25)
            self.radiusQuickies[rad].connect('clicked()', callback)
            self.radiusQuickies[rad].setToolTip(
                "Set radius based on mm or label voxel size units depending on toggle value"
            )

        self.radius = ctk.ctkDoubleSlider(self.frame)
        self.radius.minimum = self.minimumRadius
        self.radius.maximum = self.maximumRadius
        self.radius.orientation = 1
        self.radius.singleStep = self.minimumRadius
        self.frame.layout().addWidget(self.radius)
        self.widgets.append(self.radius)

        self.sphere = qt.QCheckBox("Sphere", self.frame)
        self.sphere.setToolTip(
            "Use a 3D spherical brush rather than a 2D circular brush.")
        self.frame.layout().addWidget(self.sphere)
        self.widgets.append(self.sphere)

        self.smudge = qt.QCheckBox("Smudge", self.frame)
        self.smudge.setToolTip(
            "Set the label number automatically by sampling the pixel location where the brush stroke starts."
        )
        self.frame.layout().addWidget(self.smudge)
        self.widgets.append(self.smudge)

        self.pixelMode = qt.QCheckBox("Pixel Mode", self.frame)
        self.pixelMode.setToolTip(
            "Paint exactly the pixel under the cursor, ignoring the radius, threshold, and paint over."
        )
        self.frame.layout().addWidget(self.pixelMode)
        self.widgets.append(self.pixelMode)

        EditorLib.HelpButton(
            self.frame,
            "Use this tool to paint with a round brush of the selected radius")

        self.connections.append(
            (self.sphere, 'clicked()', self.updateMRMLFromGUI))
        self.connections.append(
            (self.smudge, 'clicked()', self.updateMRMLFromGUI))
        self.connections.append(
            (self.pixelMode, 'clicked()', self.updateMRMLFromGUI))
        self.connections.append(
            (self.radius, 'valueChanged(double)', self.onRadiusValueChanged))
        self.connections.append((self.radiusSpinBox, 'valueChanged(double)',
                                 self.onRadiusSpinBoxChanged))

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

        # set the node parameters that are dependent on the input data
        self.parameterNode.SetParameter("PaintEffect,radius",
                                        str(self.minimumRadius * 10))
Beispiel #5
0
    def setup(self):

        self.FilteringFrame = qt.QFrame()
        self.FilteringFrame.setLayout(qt.QVBoxLayout())
        self.FilteringFrame.enabled = False
        self.FilteringFrame.setObjectName('FilteringFrame')
        self.FilteringFrame.setStyleSheet(
            '#FilteringFrame {border: 1px solid lightGray; color: black; }')
        self.layout.addWidget(self.FilteringFrame)

        filterLabel = qt.QLabel()
        filterLabel.setText('Filtering')
        self.FilteringFrame.layout().addWidget(filterLabel)

        radioButtonsGroup = qt.QGroupBox()
        radioButtonsGroup.setLayout(qt.QHBoxLayout())
        radioButtonsGroup.setFixedWidth(120)
        radioButtonsGroup.setObjectName('radioButtonsGroup')
        radioButtonsGroup.setStyleSheet(
            '#radioButtonsGroup {border: 1px solid white; color: black; }')

        self.filterOnRadioButton = qt.QRadioButton()
        self.filterOnRadioButton.setText('On')
        self.filterOnRadioButton.setChecked(0)
        radioButtonsGroup.layout().addWidget(self.filterOnRadioButton)

        self.filterOffRadioButton = qt.QRadioButton()
        self.filterOffRadioButton.setText('Off')
        self.filterOffRadioButton.setChecked(1)
        radioButtonsGroup.layout().addWidget(self.filterOffRadioButton)

        self.FilteringFrame.layout().addWidget(radioButtonsGroup)

        self.filterOptionsFrame = qt.QFrame()
        self.filterOptionsFrame.setLayout(qt.QVBoxLayout())
        self.filterOptionsFrame.setObjectName('filterOptionsFrame')
        self.filterOptionsFrame.setStyleSheet(
            '#filterOptionsFrame {border: 0.5px solid lightGray; color: black; }'
        )
        self.filterOptionsFrame.hide()

        self.FilteringFrame.layout().addWidget(self.filterOptionsFrame)

        self.filterApplication = qt.QCheckBox()
        self.filterApplication.setText('Filter for Phenotype Analysis')
        self.filterApplication.setChecked(0)
        self.filterOptionsFrame.layout().addWidget(self.filterApplication)

        filterOptionsGroup = qt.QGroupBox()
        filterOptionsGroup.setLayout(qt.QHBoxLayout())
        filterOptionsGroup.setFixedWidth(220)
        filterOptionsGroup.setObjectName('filterOptionsGroup')
        filterOptionsGroup.setStyleSheet(
            '#filterOptionsGroup {border: 1px solid white; color: black; }')

        self.NLMFilterRadioButton = qt.QRadioButton()
        self.NLMFilterRadioButton.setText('NLM')
        self.NLMFilterRadioButton.setChecked(1)
        filterOptionsGroup.layout().addWidget(self.NLMFilterRadioButton)

        self.MedianFilterRadioButton = qt.QRadioButton()
        self.MedianFilterRadioButton.setText('Median')
        self.MedianFilterRadioButton.setChecked(0)
        filterOptionsGroup.layout().addWidget(self.MedianFilterRadioButton)

        self.GaussianFilterRadioButton = qt.QRadioButton()
        self.GaussianFilterRadioButton.setText('Gaussian')
        self.GaussianFilterRadioButton.setChecked(0)
        filterOptionsGroup.layout().addWidget(self.GaussianFilterRadioButton)

        self.filterOptionsFrame.layout().addWidget(filterOptionsGroup)

        # Filter Params
        FilterParams = qt.QFrame()
        FilterParams.setLayout(qt.QVBoxLayout())
        self.filterOptionsFrame.layout().addWidget(FilterParams)

        DimGroupBox = qt.QGroupBox()
        DimGroupBox.setLayout(qt.QHBoxLayout())
        DimGroupBox.setFixedWidth(180)
        DimGroupBox.setObjectName('DimGroupBox')
        DimGroupBox.setStyleSheet(
            '#DimGroupBox {border: 1px solid white; color: black; }')
        FilterParams.layout().addWidget(DimGroupBox)

        FilterDimensionLabel = qt.QLabel()
        FilterDimensionLabel.setText('Dimensions: ')
        FilterDimensionLabel.setToolTip(
            'Choose if the filter has to operate in 2D or 3D.')
        DimGroupBox.layout().addWidget(FilterDimensionLabel)

        self.Filt2DOption = qt.QPushButton()
        self.Filt2DOption.setText('2D')
        self.Filt2DOption.setCheckable(1)
        self.Filt2DOption.setChecked(1)
        self.Filt2DOption.setAutoExclusive(1)
        self.Filt2DOption.setFixedWidth(45)
        DimGroupBox.layout().addWidget(self.Filt2DOption)

        self.Filt3DOption = qt.QPushButton()
        self.Filt3DOption.setText('3D')
        self.Filt3DOption.setCheckable(1)
        self.Filt3DOption.setChecked(0)
        self.Filt3DOption.setFixedWidth(45)
        self.Filt3DOption.setAutoExclusive(1)
        DimGroupBox.layout().addWidget(self.Filt3DOption)

        StrengthGroupBox = qt.QGroupBox()
        StrengthGroupBox.setLayout(qt.QHBoxLayout())
        StrengthGroupBox.setFixedWidth(270)
        StrengthGroupBox.setObjectName('StrengthGroupBox')
        StrengthGroupBox.setStyleSheet(
            '#StrengthGroupBox {border: 1px solid white; color: black; }')
        FilterParams.layout().addWidget(StrengthGroupBox)

        FilterStrengthLabel = qt.QLabel()
        FilterStrengthLabel.setText('Strength: ')
        FilterStrengthLabel.setToolTip(
            'Choose strength of the filtering process.')
        StrengthGroupBox.layout().addWidget(FilterStrengthLabel)

        self.SmoothOption = qt.QPushButton()
        self.SmoothOption.setText('Smooth')
        self.SmoothOption.setCheckable(1)
        self.SmoothOption.setChecked(1)
        self.SmoothOption.setAutoExclusive(1)
        self.SmoothOption.setFixedWidth(60)
        StrengthGroupBox.layout().addWidget(self.SmoothOption)

        self.MediumOption = qt.QPushButton()
        self.MediumOption.setText('Medium')
        self.MediumOption.setCheckable(1)
        self.MediumOption.setChecked(0)
        self.MediumOption.setFixedWidth(60)
        self.MediumOption.setAutoExclusive(1)
        StrengthGroupBox.layout().addWidget(self.MediumOption)

        self.HeavyOption = qt.QPushButton()
        self.HeavyOption.setText('Heavy')
        self.HeavyOption.setCheckable(1)
        self.HeavyOption.setChecked(0)
        self.HeavyOption.setFixedWidth(60)
        self.HeavyOption.setAutoExclusive(1)
        StrengthGroupBox.layout().addWidget(self.HeavyOption)

        # Downsampling option for label map creation
        self.LMCreationFrame = qt.QFrame()
        self.LMCreationFrame.setLayout(qt.QVBoxLayout())
        self.LMCreationFrame.enabled = False
        self.LMCreationFrame.setObjectName('LMCreationFrame')
        self.LMCreationFrame.setStyleSheet(
            '#LMCreationFrame {border: 1px solid lightGray; color: black; }')
        self.parent.layout().addWidget(self.LMCreationFrame)

        LMCreationLabel = qt.QLabel()
        LMCreationLabel.setText('Label Map Creation:')
        self.LMCreationFrame.layout().addWidget(LMCreationLabel)

        self.DownSamplingGroupBox = qt.QGroupBox()
        self.DownSamplingGroupBox.setLayout(qt.QHBoxLayout())
        self.DownSamplingGroupBox.setFixedWidth(130)
        self.DownSamplingGroupBox.setObjectName('DownSamplingGroupBox')
        self.DownSamplingGroupBox.setStyleSheet(
            '#DownSamplingGroupBox {border: 1px solid white; color: black; }')
        self.DownSamplingGroupBox.setToolTip(
            'Choose between fast and slow label map creation.')
        self.LMCreationFrame.layout().addWidget(self.DownSamplingGroupBox)

        self.FastOption = qt.QRadioButton()
        self.FastOption.setText('Fast')
        self.FastOption.setCheckable(1)
        self.FastOption.setChecked(0)
        self.DownSamplingGroupBox.layout().addWidget(self.FastOption)

        self.SlowOption = qt.QRadioButton()
        self.SlowOption.setText('Slow')
        self.SlowOption.setCheckable(1)
        self.SlowOption.setChecked(1)
        self.DownSamplingGroupBox.layout().addWidget(self.SlowOption)

        self.filterOnRadioButton.connect('toggled(bool)',
                                         self.showFilterParams)
        self.filterOffRadioButton.connect('toggled(bool)',
                                          self.hideFilterParams)
Beispiel #6
0
    def setup(self):

        if self.developerMode:
            self.reloadButton = qt.QPushButton("Reload")
            self.reloadButton.toolTip = "Reload this module."
            self.reloadButton.name = "SurfaceToolbox Reload"
            self.layout.addWidget(self.reloadButton)
            self.reloadButton.connect('clicked()', self.onReload)

            self.reloadAndTestButton = qt.QPushButton("Reload and Test")
            self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests."
            self.layout.addWidget(self.reloadAndTestButton)
            self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest)

        inputModelSelectorFrame = qt.QFrame(self.parent)
        inputModelSelectorFrame.setLayout(qt.QHBoxLayout())
        self.parent.layout().addWidget(inputModelSelectorFrame)

        inputModelSelectorLabel = qt.QLabel("Input Model: ",
                                            inputModelSelectorFrame)
        inputModelSelectorLabel.setToolTip("Select the input model")
        inputModelSelectorFrame.layout().addWidget(inputModelSelectorLabel)

        inputModelSelector = slicer.qMRMLNodeComboBox(inputModelSelectorFrame)
        inputModelSelector.nodeTypes = (("vtkMRMLModelNode"), "")
        inputModelSelector.selectNodeUponCreation = False
        inputModelSelector.addEnabled = False
        inputModelSelector.removeEnabled = False
        inputModelSelector.noneEnabled = True
        inputModelSelector.showHidden = False
        inputModelSelector.showChildNodeTypes = False
        inputModelSelector.setMRMLScene(slicer.mrmlScene)
        inputModelSelectorFrame.layout().addWidget(inputModelSelector)

        outputModelSelectorFrame = qt.QFrame(self.parent)
        outputModelSelectorFrame.setLayout(qt.QHBoxLayout())
        self.parent.layout().addWidget(outputModelSelectorFrame)

        outputModelSelectorLabel = qt.QLabel("Output Model: ",
                                             outputModelSelectorFrame)
        outputModelSelectorLabel.setToolTip("Select the output model")
        outputModelSelectorFrame.layout().addWidget(outputModelSelectorLabel)

        outputModelSelector = slicer.qMRMLNodeComboBox(
            outputModelSelectorFrame)
        outputModelSelector.nodeTypes = (("vtkMRMLModelNode"), "")
        outputModelSelector.selectNodeUponCreation = False
        outputModelSelector.addEnabled = True
        outputModelSelector.renameEnabled = True
        outputModelSelector.removeEnabled = True
        outputModelSelector.noneEnabled = True
        outputModelSelector.showHidden = False
        outputModelSelector.showChildNodeTypes = False
        outputModelSelector.baseName = "Model"
        outputModelSelector.selectNodeUponCreation = True
        outputModelSelector.setMRMLScene(slicer.mrmlScene)
        outputModelSelectorFrame.layout().addWidget(outputModelSelector)

        decimationButton = qt.QPushButton("Decimation")
        decimationButton.checkable = True
        self.layout.addWidget(decimationButton)
        decimationFrame = qt.QFrame(self.parent)
        self.layout.addWidget(decimationFrame)
        decimationFormLayout = qt.QFormLayout(decimationFrame)

        reductionFrame, reductionSlider, reductionSpinBox = numericInputFrame(
            self.parent, "Reduction:", "Tooltip", 0.0, 1.0, 0.1, 1)
        decimationFormLayout.addWidget(reductionFrame)

        boundaryDeletionCheckBox = qt.QCheckBox("Boundary deletion")
        decimationFormLayout.addWidget(boundaryDeletionCheckBox)

        smoothingButton = qt.QPushButton("Smoothing")
        smoothingButton.checkable = True
        self.layout.addWidget(smoothingButton)
        smoothingFrame = qt.QFrame(self.parent)
        self.layout.addWidget(smoothingFrame)
        smoothingFormLayout = qt.QFormLayout(smoothingFrame)

        smoothingMethodCombo = qt.QComboBox(smoothingFrame)
        smoothingMethodCombo.addItem("Laplace")
        smoothingMethodCombo.addItem("Taubin")
        smoothingFormLayout.addWidget(smoothingMethodCombo)

        laplaceMethodFrame = qt.QFrame(self.parent)
        smoothingFormLayout.addWidget(laplaceMethodFrame)
        laplaceMethodFormLayout = qt.QFormLayout(laplaceMethodFrame)

        laplaceIterationsFrame, laplaceIterationsSlider, laplaceIterationsSpinBox = numericInputFrame(
            self.parent, "Iterations:", "Tooltip", 0.0, 500.0, 1.0, 0)
        laplaceMethodFormLayout.addWidget(laplaceIterationsFrame)

        laplaceRelaxationFrame, laplaceRelaxationSlider, laplaceRelaxationSpinBox = numericInputFrame(
            self.parent, "Relaxation:", "Tooltip", 0.0, 1.0, 0.1, 1)
        laplaceMethodFormLayout.addWidget(laplaceRelaxationFrame)

        taubinMethodFrame = qt.QFrame(self.parent)
        smoothingFormLayout.addWidget(taubinMethodFrame)
        taubinMethodFormLayout = qt.QFormLayout(taubinMethodFrame)

        taubinIterationsFrame, taubinIterationsSlider, taubinIterationsSpinBox = numericInputFrame(
            self.parent, "Iterations:", "Tooltip", 0.0, 100.0, 1.0, 0)
        taubinMethodFormLayout.addWidget(taubinIterationsFrame)

        taubinPassBandFrame, taubinPassBandSlider, taubinPassBandSpinBox = numericInputFrame(
            self.parent, "Pass Band:", "Tooltip", 0.0, 1.0, 0.01, 2)
        taubinMethodFormLayout.addWidget(taubinPassBandFrame)

        boundarySmoothingCheckBox = qt.QCheckBox("Boundary Smoothing")
        smoothingFormLayout.addWidget(boundarySmoothingCheckBox)

        normalsButton = qt.QPushButton("Normals")
        normalsButton.checkable = True
        self.layout.addWidget(normalsButton)
        normalsFrame = qt.QFrame(self.parent)
        self.layout.addWidget(normalsFrame)
        normalsFormLayout = qt.QFormLayout(normalsFrame)

        flipNormalsCheckBox = qt.QCheckBox("Flip Normals")
        normalsFormLayout.addWidget(flipNormalsCheckBox)

        splittingCheckBox = qt.QCheckBox("Splitting")
        normalsFormLayout.addWidget(splittingCheckBox)

        featureAngleFrame, featureAngleSlider, featureAngleSpinBox = numericInputFrame(
            self.parent, "Feature Angle:", "Tooltip", 0.0, 180.0, 1.0, 0)
        normalsFormLayout.addWidget(featureAngleFrame)

        cleanerButton = qt.QPushButton("Cleaner")
        cleanerButton.checkable = True
        self.layout.addWidget(cleanerButton)

        connectivityButton = qt.QPushButton("Connectivity")
        connectivityButton.checkable = True
        self.layout.addWidget(connectivityButton)
        #connectivityFrame = qt.QFrame(self.parent)
        #self.layout.addWidget(connectivityFrame)
        #connectivityFormLayout = qt.QFormLayout(connectivityFrame)

        # TODO: connectivity could be
        # - largest connected
        # - threshold connected (discard below point count)
        # - pick a region interactively
        # - turn a multiple connected surface into a model hierarchy

        buttonFrame = qt.QFrame(self.parent)
        buttonFrame.setLayout(qt.QHBoxLayout())
        self.layout.addWidget(buttonFrame)

        toggleModelsButton = qt.QPushButton("Toggle Models")
        toggleModelsButton.toolTip = "Show original model."
        buttonFrame.layout().addWidget(toggleModelsButton)

        applyButton = qt.QPushButton("Apply")
        applyButton.toolTip = "Filter surface."
        buttonFrame.layout().addWidget(applyButton)

        self.layout.addStretch(1)

        class state(object):
            inputModelNode = None
            outputModelNode = None
            decimation = False
            reduction = 0.8
            boundaryDeletion = False
            smoothing = False
            smoothingMethod = "Laplace"
            laplaceIterations = 100.0
            laplaceRelaxation = 0.5
            taubinIterations = 30.0
            taubinPassBand = 0.1
            boundarySmoothing = True
            normals = False
            flipNormals = False
            splitting = False
            featureAngle = 30.0
            cleaner = False
            connectivity = False

        scope_locals = locals()

        def connect(obj, evt, cmd):
            def callback(*args):
                current_locals = scope_locals.copy()
                current_locals.update({'args': args})
                exec cmd in globals(), current_locals
                updateGUI()

            obj.connect(evt, callback)

        def updateGUI():
            def button_stylesheet(active):
                if active:
                    return "background-color: green"
                else:
                    return ""

            decimationButton.checked = state.decimation
            #decimationButton.setStyleSheet(button_stylesheet(state.decimation))
            decimationFrame.visible = state.decimation
            boundaryDeletionCheckBox.checked = state.boundaryDeletion
            reductionSlider.value = state.reduction
            reductionSpinBox.value = state.reduction

            smoothingButton.checked = state.smoothing
            smoothingFrame.visible = state.smoothing
            laplaceMethodFrame.visible = state.smoothingMethod == "Laplace"
            laplaceIterationsSlider.value = state.laplaceIterations
            laplaceIterationsSpinBox.value = state.laplaceIterations
            laplaceRelaxationSlider.value = state.laplaceRelaxation
            laplaceRelaxationSpinBox.value = state.laplaceRelaxation
            taubinMethodFrame.visible = state.smoothingMethod == "Taubin"
            taubinIterationsSlider.value = state.taubinIterations
            taubinIterationsSpinBox.value = state.taubinIterations
            taubinPassBandSlider.value = state.taubinPassBand
            taubinPassBandSpinBox.value = state.taubinPassBand
            boundarySmoothingCheckBox.checked = state.boundarySmoothing

            normalsButton.checked = state.normals
            normalsFrame.visible = state.normals
            flipNormalsCheckBox.checked = state.flipNormals
            splittingCheckBox.checked = state.splitting
            featureAngleFrame.visible = state.splitting
            featureAngleSlider.value = state.featureAngle
            featureAngleSpinBox.value = state.featureAngle

            cleanerButton.checked = state.cleaner

            connectivityButton.checked = state.connectivity

            toggleModelsButton.enabled = state.inputModelNode != None and state.outputModelNode != None
            applyButton.enabled = state.inputModelNode != None and state.outputModelNode != None

        connect(inputModelSelector, 'currentNodeChanged(vtkMRMLNode*)',
                'state.inputModelNode = args[0]')
        connect(outputModelSelector, 'currentNodeChanged(vtkMRMLNode*)',
                'state.outputModelNode = args[0]')

        def initializeModelNode(node):
            displayNode = slicer.vtkMRMLModelDisplayNode()
            storageNode = slicer.vtkMRMLModelStorageNode()
            displayNode.SetScene(slicer.mrmlScene)
            storageNode.SetScene(slicer.mrmlScene)
            slicer.mrmlScene.AddNode(displayNode)
            slicer.mrmlScene.AddNode(storageNode)
            node.SetAndObserveDisplayNodeID(displayNode.GetID())
            node.SetAndObserveStorageNodeID(storageNode.GetID())

        outputModelSelector.connect('nodeAddedByUser(vtkMRMLNode*)',
                                    initializeModelNode)

        connect(decimationButton, 'clicked(bool)',
                'state.decimation = args[0]')
        connect(reductionSlider, 'valueChanged(double)',
                'state.reduction = args[0]')
        connect(reductionSpinBox, 'valueChanged(double)',
                'state.reduction = args[0]')
        connect(boundaryDeletionCheckBox, 'stateChanged(int)',
                'state.boundaryDeletion = bool(args[0])')

        connect(smoothingButton, 'clicked(bool)', 'state.smoothing = args[0]')
        connect(smoothingMethodCombo, 'currentIndexChanged(QString)',
                'state.smoothingMethod = args[0]')

        connect(laplaceIterationsSlider, 'valueChanged(double)',
                'state.laplaceIterations = int(args[0])')
        connect(laplaceIterationsSpinBox, 'valueChanged(double)',
                'state.laplaceIterations = int(args[0])')
        connect(laplaceRelaxationSlider, 'valueChanged(double)',
                'state.laplaceRelaxation = args[0]')
        connect(laplaceRelaxationSpinBox, 'valueChanged(double)',
                'state.laplaceRelaxation = args[0]')

        connect(taubinIterationsSlider, 'valueChanged(double)',
                'state.taubinIterations = int(args[0])')
        connect(taubinIterationsSpinBox, 'valueChanged(double)',
                'state.taubinIterations = int(args[0])')
        connect(taubinPassBandSlider, 'valueChanged(double)',
                'state.taubinPassBand = args[0]')
        connect(taubinPassBandSpinBox, 'valueChanged(double)',
                'state.taubinPassBand = args[0]')

        connect(boundarySmoothingCheckBox, 'stateChanged(int)',
                'state.boundarySmoothing = bool(args[0])')

        connect(normalsButton, 'clicked(bool)', 'state.normals = args[0]')

        connect(flipNormalsCheckBox, 'stateChanged(int)',
                'state.flipNormals = bool(args[0])')
        connect(splittingCheckBox, 'stateChanged(int)',
                'state.splitting = bool(args[0])')
        connect(featureAngleSlider, 'valueChanged(double)',
                'state.featureAngle = args[0]')
        connect(featureAngleSpinBox, 'valueChanged(double)',
                'state.featureAngle = args[0]')

        connect(cleanerButton, 'clicked(bool)', 'state.cleaner = args[0]')
        connect(connectivityButton, 'clicked(bool)',
                'state.connectivity = args[0]')

        def onApply():
            updateGUI()
            applyButton.text = "Working..."
            applyButton.repaint()
            slicer.app.processEvents()
            logic = SurfaceToolboxLogic()
            result = logic.applyFilters(state)
            if result:
                state.inputModelNode.GetModelDisplayNode().VisibilityOff()
                state.outputModelNode.GetModelDisplayNode().VisibilityOn()
            else:
                state.inputModelNode.GetModelDisplayNode().VisibilityOn()
                state.outputModelNode.GetModelDisplayNode().VisibilityOff()
            applyButton.text = "Apply"

        applyButton.connect('clicked()', onApply)

        def onToggleModels():
            updateGUI()
            if state.inputModelNode.GetModelDisplayNode().GetVisibility():
                state.inputModelNode.GetModelDisplayNode().VisibilityOff()
                state.outputModelNode.GetModelDisplayNode().VisibilityOn()
                toggleModelsButton.text = "Toggle Models (Output)"
            else:
                state.inputModelNode.GetModelDisplayNode().VisibilityOn()
                state.outputModelNode.GetModelDisplayNode().VisibilityOff()
                toggleModelsButton.text = "Toggle Models (Input)"

        toggleModelsButton.connect('clicked()', onToggleModels)

        updateGUI()

        self.updateGUI = updateGUI
Beispiel #7
0
  def setup(self):

    #
    # servers
    #

    # testing server - not exposed (used for development)
    self.localFrame = ctk.ctkCollapsibleButton(self.parent)
    self.localFrame.setLayout(qt.QVBoxLayout())
    self.localFrame.setText("Servers")
    self.layout.addWidget(self.localFrame)
    self.localFrame.collapsed = False

    self.toggleServer = qt.QPushButton("Start Testing Server")
    self.localFrame.layout().addWidget(self.toggleServer)
    self.toggleServer.connect('clicked()', self.onToggleServer)

    self.verboseServer = qt.QCheckBox("Verbose")
    self.localFrame.layout().addWidget(self.verboseServer)

    # advanced options - not exposed to end users
    # developers can uncomment these lines to access testing server
    self.toggleServer.hide()
    self.verboseServer.hide()

    # Listener

    settings = qt.QSettings()
    self.toggleListener = qt.QPushButton()
    self.toggleListener.checkable = True
    if hasattr(slicer, 'dicomListener'):
      self.toggleListener.text = "Stop Listener"
      slicer.dicomListener.process.connect('stateChanged(int)',self.onListenerStateChanged)
    else:
      self.toggleListener.text = "Start Listener"
    self.localFrame.layout().addWidget(self.toggleListener)
    self.toggleListener.connect('clicked()', self.onToggleListener)

    self.runListenerAtStart = qt.QCheckBox("Start Listener when Slicer Starts")
    self.localFrame.layout().addWidget(self.runListenerAtStart)
    if settings.contains('DICOM/RunListenerAtStart'):
      self.runListenerAtStart.checked = bool(settings.value('DICOM/RunListenerAtStart') == 'true')
    self.runListenerAtStart.connect('clicked()', self.onRunListenerAtStart)

    # the Database frame (home of the ctkDICOM widget)
    self.dicomFrame = ctk.ctkCollapsibleButton(self.parent)
    self.dicomFrame.setLayout(qt.QVBoxLayout())
    self.dicomFrame.setText("DICOM Database and Networking")
    self.layout.addWidget(self.dicomFrame)

    # initialize the dicomDatabase
    #   - pick a default and let the user know
    if not slicer.dicomDatabase:
      self.promptForDatabaseDirectory()

    #
    # create and configure the app widget - this involves
    # reaching inside and manipulating the widget hierarchy
    # - TODO: this configurability should be exposed more natively
    #   in the CTK code to avoid the findChildren calls
    #
    self.dicomBrowser = ctk.ctkDICOMBrowser()
    DICOM.setDatabasePrecacheTags(self.dicomBrowser)

    self.detailsPopup = DICOMLib.DICOMDetailsPopup(self.dicomBrowser)

    self.tables = self.detailsPopup.tables

    self.showBrowser = qt.QPushButton('Show DICOM Browser')
    self.dicomFrame.layout().addWidget(self.showBrowser)
    self.showBrowser.connect('clicked()', self.detailsPopup.open)

    # connect to the main window's dicom button
    mw = slicer.util.mainWindow()
    try:
      action = slicer.util.findChildren(mw,name='LoadDICOMAction')[0]
      action.connect('triggered()',self.detailsPopup.open)
    except IndexError:
      print('Could not connect to the main window DICOM button')

    # connect to our menu file entry so it raises the browser
    fileMenu = slicer.util.lookupTopLevelWidget('FileMenu')
    if fileMenu:
      for action in fileMenu.actions():
        if action.text == 'DICOM':
          action.connect('triggered()',self.detailsPopup.open)

    # make the tables view a bit bigger
    self.tables.setMinimumHeight(250)

    if hasattr(slicer, 'dicomListener'):
      slicer.dicomListener.fileToBeAddedCallback = self.onListenerToAddFile
      slicer.dicomListener.fileAddedCallback = self.onListenerAddedFile

    # TODO: populate context menu
    self.contextMenu = qt.QMenu(self.tables)
    self.deleteAction = qt.QAction("Delete", self.contextMenu)
    self.contextMenu.addAction(self.deleteAction)
    self.deleteAction.enabled = False
    self.contextMenu.connect('triggered(QAction*)', self.onContextMenuTriggered)

    slicer.dicomDatabase.connect('databaseChanged()', self.onDatabaseChanged)
    self.dicomBrowser.connect('databaseDirectoryChanged(QString)', self.onDatabaseDirectoryChanged)
    self.tables.connect('seriesSelectionChanged(QStringList)', self.onSeriesSelected)
    self.tables.setContextMenuPolicy(3)
    self.tables.connect('customContextMenuRequested(QPoint)', self.onTreeContextMenuRequested)

    # enable to the Send button of the app widget and take it over
    # for our purposes - TODO: fix this to enable it at the ctkDICOM level
    self.sendButton = slicer.util.findChildren(self.dicomBrowser, text='Send')[0]
    self.sendButton.enabled = False
    self.sendButton.connect('triggered()', self.onSendClicked)

    # the recent activity frame
    self.activityFrame = ctk.ctkCollapsibleButton(self.parent)
    self.activityFrame.setLayout(qt.QVBoxLayout())
    self.activityFrame.setText("Recent DICOM Activity")
    self.layout.addWidget(self.activityFrame)

    self.recentActivity = DICOMLib.DICOMRecentActivityWidget(self.activityFrame,detailsPopup=self.detailsPopup)
    self.activityFrame.layout().addWidget(self.recentActivity.widget)
    self.requestUpdateRecentActivity()


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

        # Instantiate and connect widgets ...

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

        # Layout within the dummy collapsible button
        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)

        #
        # 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("Output Volume: ", self.outputSelector)

        #
        # threshold value
        #
        self.imageThresholdSliderWidget = ctk.ctkSliderWidget()
        self.imageThresholdSliderWidget.singleStep = 0.1
        self.imageThresholdSliderWidget.minimum = -100
        self.imageThresholdSliderWidget.maximum = 100
        self.imageThresholdSliderWidget.value = 0.5
        self.imageThresholdSliderWidget.setToolTip(
            "Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero."
        )
        parametersFormLayout.addRow("Image threshold",
                                    self.imageThresholdSliderWidget)

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.enableScreenshotsFlagCheckBox = qt.QCheckBox()
        self.enableScreenshotsFlagCheckBox.checked = 0
        self.enableScreenshotsFlagCheckBox.setToolTip(
            "If checked, take screen shots for tutorials. Use Save Data to write them to disk."
        )
        parametersFormLayout.addRow("Enable Screenshots",
                                    self.enableScreenshotsFlagCheckBox)

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

        # connections
        self.applyButton.connect('clicked(bool)', self.onApplyButton)
        self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.onSelect)
        self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                    self.onSelect)

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

        # Refresh Apply button state
        self.onSelect()
Beispiel #9
0
  def setup(self):
    # Instantiate and connect widgets ...

    if self.developerMode:
      #
      # Reload and Test area
      #
      reloadCollapsibleButton = ctk.ctkCollapsibleButton()
      reloadCollapsibleButton.text = "Reload && Test"
      self.layout.addWidget(reloadCollapsibleButton)
      reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton)

      # reload button
      # (use this during development, but remove it when delivering
      #  your module to users)
      self.reloadButton = qt.QPushButton("Reload")
      self.reloadButton.toolTip = "Reload this module."
      self.reloadButton.name = "VolumeProbe Reload"
      reloadFormLayout.addWidget(self.reloadButton)
      self.reloadButton.connect('clicked()', self.onReload)

      # reload and test button
      # (use this during development, but remove it when delivering
      #  your module to users)
      self.reloadAndTestButton = qt.QPushButton("Reload and Test All")
      self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests."
      reloadFormLayout.addWidget(self.reloadAndTestButton)
      self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest)

      # reload and run specific tests
      scenarios = ("Three Volume", "View Watcher", "ROIManager",)
      for scenario in scenarios:
        button = qt.QPushButton("Reload and Test %s" % scenario)
        self.reloadAndTestButton.toolTip = "Reload this module and then run the %s self test." % scenario
        reloadFormLayout.addWidget(button)
        button.connect('clicked()', lambda s=scenario: self.onReloadAndTest(scenario=s))

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

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

    """
    #
    # target volume selector
    #
    self.inputSelector = slicer.qMRMLNodeComboBox()
    self.inputSelector.nodeTypes = ( ("vtkMRMLVolumeNode"), "" )
    self.inputSelector.selectNodeUponCreation = True
    self.inputSelector.addEnabled = False
    self.inputSelector.removeEnabled = False
    self.inputSelector.noneEnabled = False
    self.inputSelector.showHidden = False
    self.inputSelector.showChildNodeTypes = True
    self.inputSelector.setMRMLScene( slicer.mrmlScene )
    self.inputSelector.setToolTip( "Pick the input to the algorithm." )
    parametersFormLayout.addRow("Target Volume: ", self.inputSelector)
    """

    #
    # Add ROI
    #
    self.drawROICheck = qt.QCheckBox()
    parametersFormLayout.addRow("Draw ROI", self.drawROICheck)
    self.drawROICheck.connect("toggled(bool)", self.onDrawROIToggled)

    self.ROIRadiusSlider = ctk.ctkSliderWidget()
    #self.ROIRadiusSlider.setMinimum(1)
    #self.ROIRadiusSlider.setMaximum(100)
    self.ROIRadiusSlider.setValue(self.ROIRadius)
    parametersFormLayout.addRow("ROI Radius", self.ROIRadiusSlider)
    self.ROIRadiusSlider.connect("valueChanged(double)", self.onROIRadiusChanged)

    #
    # Add Histogram
    self.numBins = qt.QSpinBox()
    self.numBins.setRange(0, 200)
    self.numBins.setEnabled(1)
    self.numBins.setValue(20)
    parametersFormLayout.addRow("Number of Bins", self.numBins)

    self.histogramArray = vtk.vtkDoubleArray()
    self.histogramArray.SetNumberOfComponents(1)
    self.histogramArray.SetNumberOfTuples(0)

    self.histogram = ctk.ctkVTKHistogram()
    self.histogram.setDataArray(self.histogramArray)
    self.histogram.numberOfBins = self.numBins.value

    self.histogramView = ctk.ctkTransferFunctionView()
    self.histogramItem = ctk.ctkTransferFunctionBarsItem(self.histogram)
    self.histogramItem.barWidth = 0.7

    self.histogramView.scene().addItem(self.histogramItem)
    parametersFormLayout.addRow("Histogram", self.histogramView)
    self.histogramView.show()


    self.minField = qt.QSpinBox()
    self.minField.setRange(-100000, 100000)
    self.minField.setEnabled(0)
    parametersFormLayout.addRow("Min Value", self.minField)

    self.maxField = qt.QSpinBox()
    self.maxField.setRange(-100000, 100000)
    self.maxField.setEnabled(0)
    parametersFormLayout.addRow("Max Value", self.maxField)

    self.meanField = qt.QSpinBox()
    self.meanField.setRange(-100000, 100000)
    self.meanField.setEnabled(0)
    parametersFormLayout.addRow("Mean Value", self.meanField)
    
    self.medianField = qt.QSpinBox()
    self.medianField.setRange(-100000, 100000)
    self.medianField.setEnabled(0)
    parametersFormLayout.addRow("Median Value", self.medianField)
  
    self.stdField = qt.QSpinBox()
    self.stdField.setRange(-100000, 100000)
    self.stdField.setEnabled(0)
    parametersFormLayout.addRow("STD Value", self.stdField)
    
    # Add vertical spacer
    self.layout.addStretch(1)
  def createUserInterface( self ):
    '''
    '''
#    self.buttonBoxHints = self.ButtonBoxHidden

    self.__layout = self.__parent.createUserInterface()

    # find all metrics in the plugins directory. The assumption is that all
    # metrics are named as ChangeTracker*Metric
    allModules = dir(slicer.moduleNames)
    changeTrackerMetrics = []
    for m in allModules:
      if m.endswith('Metric'):
        changeTrackerMetrics.append(m)

    print 'Metrics discovered: ', changeTrackerMetrics

    # if len(changeTrackerMetrics) == 0:
    #   report error -- should this be done in __init__ ? 
    
    self.__metricCheckboxList = {}

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

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

    self.__metricsFrame = ctk.ctkCollapsibleButton()
    self.__metricsFrame.text = "Change Detection Metrics"
    self.__metricsFrame.collapsed = 0
    metricsFrameLayout = qt.QVBoxLayout(self.__metricsFrame)
    boxLayout.addWidget(self.__metricsFrame)

    self.__registrationFrame = ctk.ctkCollapsibleButton()
    self.__registrationFrame.text = "Registration"
    self.__registrationFrame.collapsed = 0
    registrationFrameLayout = qt.QFormLayout(self.__registrationFrame)
    boxLayout.addWidget(self.__registrationFrame)

    self.__metricsTabs = qt.QTabWidget()
    metricsFrameLayout.addWidget(self.__metricsTabs)

    # TODO: error checking!
    for m in changeTrackerMetrics:
      pluginName = m
      moduleManager = slicer.app.moduleManager()
      plugin = moduleManager.module(pluginName)
      label = qt.QLabel(plugin.title)
      checkbox = qt.QCheckBox()
      self.__metricCheckboxList[checkbox] = pluginName

      # initialize basic frame
      basicFrameLayout.addRow(label, checkbox)

      # initialize advanced frame
      metricGui = slicer.util.getModuleGui(pluginName)
      parametersWidget = Helper.findChildren(metricGui, text='Parameters')[0]

      if parametersWidget != None:
        metricWidget = qt.QWidget()
        metricLayout = qt.QFormLayout(metricWidget)
        metricLayout.addRow(parametersWidget)
        self.__metricsTabs.addTab(metricWidget, pluginName)
      
    self.__transformSelector = slicer.qMRMLNodeComboBox()
    self.__transformSelector.toolTip = "Transform aligning the follow-up scan with the baseline"
    self.__transformSelector.nodeTypes = ['vtkMRMLLinearTransformNode']
    self.__transformSelector.noneEnabled = 1
    self.__transformSelector.setMRMLScene(slicer.mrmlScene)

    transformSelectorLabel = qt.QLabel('Transform: ')
    registrationFrameLayout.addRow(transformSelectorLabel, self.__transformSelector)
    def setup(self):

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

        #
        # the I/O panel
        #

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

        ioFormLayout = qt.QFormLayout(ioCollapsibleButton)

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

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

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

        #
        # I/O advanced panel
        #

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

        ioAdvancedFormLayout = qt.QFormLayout(self.__ioAdvancedPanel)

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

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

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

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

        #
        # the segmentation panel
        #

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

        segmentationFormLayout = qt.QFormLayout(segmentationCollapsibleButton)

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

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

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

        #
        # segmentation advanced panel
        #

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

        segmentationAdvancedFormLayout = qt.QFormLayout(
            self.__segmentationAdvancedPanel)

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

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

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

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

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

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

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

        #
        # Reset, preview and apply buttons
        #

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

        # be ready for events
        self.__updating = 0

        # set default values
        self.restoreDefaults()

        # compress the layout
        self.layout.addStretch(1)
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)
        print("-------Mesh Statistic Widget Setup-------")
        # -------------------------------------------------------------------------------------
        self.modelList = list()
        self.fieldList = list()
        self.ROIList = list()
        self.ROIDict = dict()  # Key = Name of ROI
                               # Value = Dictionary of Fields (key = Name of Field
                               #                               Value = dictionary of shapes
                               #                                             key = name of shapes
                               #                                             value = Statistics store()

        self.logic = MeshStatisticsLogic(self)

        # ---------------------------------------------------------------- #
        # ---------------- Definition of the UI interface ---------------- #
        # ---------------------------------------------------------------- #

        # ------------ Loading of the .ui file ---------- #

        modulePath = os.path.dirname(slicer.util.modulePath(self.moduleName))
        path = os.path.join(modulePath, 'Resources', 'UI', '%s.ui' % self.moduleName)

        self.layout = self.parent.layout()
        self.widget = slicer.util.loadUI(path)
        self.layout.addWidget(self.widget)

        # ------------------------------------------------------------------------------------
        #                                    SHAPES INPUT
        # ------------------------------------------------------------------------------------
        self.inputComboBox = self.logic.get("inputComboBox")
        self.inputComboBox.setMRMLScene(slicer.mrmlScene)
        self.inputComboBox.connect('checkedNodesChanged()', self.onInputComboBoxCheckedNodesChanged)
        # ------------------------------------------------------------------------------------
        #                                  ROI TABLE
        # ------------------------------------------------------------------------------------
        self.ROIComboBox = self.logic.get("ROIComboBox")
        self.ROICheckBox = self.logic.get("ROICheckBox")
        self.ROICheckBox.connect('stateChanged(int)', self.onROICheckBoxStateChanged)
        # ------------------------------------------------------------------------------------
        #                                  FIELD TABLE
        # ------------------------------------------------------------------------------------
        self.tableField = self.logic.get("tableField")
        self.tableField.setColumnCount(2)
        self.tableField.setMinimumHeight(250)
        self.tableField.setHorizontalHeaderLabels([' ', ' Field Name '])
        self.tableField.setColumnWidth(0, 20)
        self.tableField.setColumnWidth(1, 260)
        self.tableField.setSizePolicy(qt.QSizePolicy().Expanding, qt.QSizePolicy().Expanding)
        # ------------------------------------------------------------------------------------
        #                                    RUN
        # ------------------------------------------------------------------------------------
        self.runButton = self.logic.get("runButton")
        self.runButton.connect('clicked()', self.onRunButton)

        # ------------------------------------------------------------------------------------
        #                          Statistics Table - Export
        # ------------------------------------------------------------------------------------
        self.mainLayout = self.logic.get("mainLayout")
        self.tabROI = qt.QTabWidget()
        self.tabROI.setTabPosition(0)
        self.tabROI.adjustSize()
        # ---------------------------- Directory - Export Button -----------------------------
        self.directoryExport = ctk.ctkDirectoryButton()
        self.exportCheckBox = qt.QCheckBox('Separate Files')
        self.exportCheckBox.setChecked(True)
        self.exportButton = qt.QPushButton(' Export ')
        self.exportButton.enabled = True
        self.exportPointValueCheckBox = qt.QCheckBox('Export Value on Each Point')
        
        self.exportLayout = qt.QVBoxLayout()
        self.directoryAndExportLayout = qt.QHBoxLayout()
        self.directoryAndExportLayout.addWidget(self.directoryExport)
        self.directoryAndExportLayout.addWidget(self.exportCheckBox)
        self.directoryAndExportLayout.addWidget(self.exportPointValueCheckBox)
        self.exportButtonsLayout = qt.QHBoxLayout()
        self.exportButtonsLayout.addWidget(self.exportButton)
        

        self.exportLayout.addLayout(self.directoryAndExportLayout)
        self.exportLayout.addLayout(self.exportButtonsLayout)
        
        self.layout.addStretch(1)
        self.logic.updateInterface(self.tableField, self.ROIComboBox, self.ROIList, self.modelList, self.mainLayout)

        # ------------------------------------------------------------------------------------
        #                                   OBSERVERS
        # ------------------------------------------------------------------------------------

        slicer.mrmlScene.AddObserver(slicer.mrmlScene.EndCloseEvent, self.onCloseScene)
    def updateInterface(self, tableField, ROIComboBox, ROIList, modelList, layout):
        tableField.clearContents()
        tableField.setRowCount(0)
        
        ROIComboBox.clear()
        ROIComboBox.addItem('Entire Model')
        del ROIList[:]
        ROIList.append('Entire Model')
        tableFieldNumRows = 0
        expression = '_ROI'
        
        if tableField.rowCount == 0:
            tableField.setRowCount(1)
            tableField.setSpan(0,0,1,2)
            label = qt.QLabel(' Please select at least a model! ')
            label.setStyleSheet(' QLabel{ qproperty-alignment: AlignCenter; }')
            tableField.setCellWidget(tableFieldNumRows, 0, label)

        if modelList:
            tableField.setSpan(0,0,1,1)
            numberOfArrayList = list()
            for model in modelList:
                numberOfArrayList.append(model.GetPolyData().GetPointData().GetNumberOfArrays())
            # set the model with the higher number of fields as reference
            modelOfReference = modelList[numberOfArrayList.index(max(numberOfArrayList))]
            PointDataOfReference = modelOfReference.GetPolyData().GetPointData()
            numOfArrayOfReference = PointDataOfReference.GetNumberOfArrays()

            fieldInCommon = list()
            fieldNotInCommon = []
            fieldNameOfRefList = list()
            fieldModel = list()

            del fieldNameOfRefList[:]
            for i in range(0, numOfArrayOfReference):
                if PointDataOfReference.GetArray(i).GetNumberOfComponents() == 1:
                    fieldNameOfRefList.append(PointDataOfReference.GetArray(i).GetName())
                    fieldInCommon.append(PointDataOfReference.GetArray(i).GetName())

            if modelList.__len__() > 1:
                for model in modelList:
                    del fieldModel[:]
                    if model.GetID() != modelOfReference.GetID():
                        numOfArray = model.GetPolyData().GetPointData().GetNumberOfArrays()
                        for i in range(0, numOfArray):
                            if model.GetPolyData().GetPointData().GetArray(i).GetNumberOfComponents() == 1:
                                fieldModel.append(model.GetPolyData().GetPointData().GetArray(i).GetName())
                        fieldInCommon, tempFieldNotInCommon = self.compareList(fieldInCommon, fieldModel)
                        fieldNotInCommon = fieldNotInCommon + tempFieldNotInCommon

            for arrayName in set(fieldInCommon):
                if not re.search(expression, arrayName):
                    tableFieldNumRows += 1
                    tableField.setMinimumHeight(tableFieldNumRows*35)
                    tableField.setRowCount(tableFieldNumRows)
                    tableField.setCellWidget(tableFieldNumRows - 1, 0, qt.QCheckBox())
                    label = qt.QLabel(arrayName)
                    label.setStyleSheet(' QLabel{qproperty-alignment: AlignVCenter | AlignLeft; }')
                    tableField.setCellWidget(tableFieldNumRows - 1, 1, label)
                else:
                    ROIComboBox.addItem(arrayName)
                    ROIList.append(arrayName)

            for arrayName in set(fieldNotInCommon):
                if not re.search(expression, arrayName):
                    tableFieldNumRows += 1
                    tableField.setMinimumHeight(tableFieldNumRows*35)
                    tableField.setRowCount(tableFieldNumRows)
                    label = qt.QLabel(arrayName)
                    label.setStyleSheet(' QLabel{ font-style:oblique; text-decoration:line-through;  }')
                    tableField.setCellWidget(tableFieldNumRows - 1, 1, label )

        layout.addStretch(1)
    def setup(self):
        ScriptedLoadableModuleWidget.setup(self)

        # Instantiate and connect widgets ...

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

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

        self.inputDirSelector = ctk.ctkPathLineEdit()
        self.inputDirSelector.filters = ctk.ctkPathLineEdit.Dirs
        self.inputDirSelector.settingKey = 'Philips4dUsDicomPatcherInputDir'
        parametersFormLayout.addRow("Input DICOM directory:",
                                    self.inputDirSelector)

        self.outputDirSelector = ctk.ctkPathLineEdit()
        self.outputDirSelector.filters = ctk.ctkPathLineEdit.Dirs
        self.outputDirSelector.settingKey = 'Philips4dUsDicomPatcherOutputDir'
        parametersFormLayout.addRow("Output DICOM directory:",
                                    self.outputDirSelector)

        self.enableDicomOutputCheckBox = qt.QCheckBox()
        self.enableDicomOutputCheckBox.checked = True
        self.enableDicomOutputCheckBox.setToolTip(
            "If checked, patched 4D US DICOM files will be saved as DICOM files"
        )
        parametersFormLayout.addRow("Export to DICOM files",
                                    self.enableDicomOutputCheckBox)

        self.anonymizeDicomCheckBox = qt.QCheckBox()
        self.anonymizeDicomCheckBox.checked = False
        self.anonymizeDicomCheckBox.setToolTip(
            "If checked, then patient identifiable information will be removed from the patched DICOM files"
        )
        parametersFormLayout.addRow("     Anonymize DICOM files",
                                    self.anonymizeDicomCheckBox)

        self.enableNrrdOutputCheckBox = qt.QCheckBox()
        self.enableNrrdOutputCheckBox.checked = False
        self.enableNrrdOutputCheckBox.setToolTip(
            "If checked, 4D US DICOM files will be saved as NRRD files")
        parametersFormLayout.addRow("Export to NRRD files",
                                    self.enableNrrdOutputCheckBox)

        #
        # Patch Button
        #
        self.patchButton = qt.QPushButton("Patch")
        self.patchButton.toolTip = "Fix and optionally anonymize DICOM files"
        parametersFormLayout.addRow(self.patchButton)

        # connections
        self.patchButton.connect('clicked(bool)', self.onPatchButton)

        self.statusLabel = qt.QPlainTextEdit()
        self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse)
        parametersFormLayout.addRow(self.statusLabel)

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

        self.logic = Philips4dUsDicomPatcherLogic()
        self.logic.logCallback = self.addLog
    def setup(self):
        # Instantiate and connect widgets ...

        #
        # Reload and Test area
        #
        reloadCollapsibleButton = ctk.ctkCollapsibleButton()
        reloadCollapsibleButton.text = "Reload && Test"
        self.layout.addWidget(reloadCollapsibleButton)
        reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton)

        # reload button
        # (use this during development, but remove it when delivering
        #  your module to users)
        self.reloadButton = qt.QPushButton("Reload")
        self.reloadButton.toolTip = "Reload this module."
        self.reloadButton.name = "ScriptedLoadableModuleTemplate Reload"
        reloadFormLayout.addWidget(self.reloadButton)
        self.reloadButton.connect('clicked()', self.onReload)

        # reload and test button
        # (use this during development, but remove it when delivering
        #  your module to users)
        self.reloadAndTestButton = qt.QPushButton("Reload and Test")
        self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests."
        reloadFormLayout.addWidget(self.reloadAndTestButton)
        self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest)

        #
        # 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.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap",
                                        0)
        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)

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

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.enableScreenshotsFlagCheckBox = qt.QCheckBox()
        self.enableScreenshotsFlagCheckBox.checked = 0
        self.enableScreenshotsFlagCheckBox.setToolTip(
            "If checked, take screen shots for tutorials. Use Save Data to write them to disk."
        )
        parametersFormLayout.addRow("Enable Screenshots",
                                    self.enableScreenshotsFlagCheckBox)

        #
        # scale factor for screen shots
        #
        self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget()
        self.screenshotScaleFactorSliderWidget.singleStep = 1.0
        self.screenshotScaleFactorSliderWidget.minimum = 1.0
        self.screenshotScaleFactorSliderWidget.maximum = 50.0
        self.screenshotScaleFactorSliderWidget.value = 1.0
        self.screenshotScaleFactorSliderWidget.setToolTip(
            "Set scale factor for the screen shots.")
        parametersFormLayout.addRow("Screenshot scale factor",
                                    self.screenshotScaleFactorSliderWidget)

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

        # connections
        self.applyButton.connect('clicked(bool)', self.onApplyButton)
        self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                   self.onSelect)
        self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                    self.onSelect)

        # Add vertical spacer
        self.layout.addStretch(1)
    def create(self, json):
        if not self.parent:
            raise "no parent"

        parametersFormLayout = self.parent.layout()

        # You can't use exec in a function that has a subfunction, unless you specify a context.
        exec('self.filter = sitk.{0}()'.format(
            json["name"])) in globals(), locals()

        self.prerun_callbacks = []
        self.inputs = []
        self.outputLabelMap = False

        #
        # input volume selectors
        #
        if "inputs" in json:

            # have named inputs
            n = 0
            for input in json["inputs"]:

                w = self.createInputWidget(n,
                                           noneEnabled=("optional" in input
                                                        and input["optional"]))

                name = "Input Volume: "
                if "name" in input:
                    name = "Input {0}: ".format(input["name"])
                name = name.replace("Image", "Volume")

                print "adding {1}: {0}".format(name, n)
                inputSelectorLabel = qt.QLabel(name)
                self.widgets.append(inputSelectorLabel)

                # add to layout after connection
                parametersFormLayout.addRow(inputSelectorLabel, w)

                self.inputs.append(w.currentNode())

                n += 1

                if "number_of_inputs" in json and json["number_of_inputs"] != 0:
                    import sys
                    sys.stderr.write(
                        "Expected \"number_of_inputs\" to be 0 not {0}!".
                        format(json["number_of_inputs"]))

        else:

            for n in range(json["number_of_inputs"]):

                w = self.createInputWidget(n)

                inputSelectorLabel = qt.QLabel("Input Volume: ")
                self.widgets.append(inputSelectorLabel)

                # add to layout after connection
                parametersFormLayout.addRow(inputSelectorLabel, w)

                self.inputs.append(w.currentNode())

            #end for each input

        if json["template_code_filename"] == "KernelImageFilter":
            w = self.createVectorWidget("KernelRadius",
                                        "std::vector<uint32_t>")
            self.widgets.append(w)
            self.addWidgetWithToolTipAndLabel(
                w, {
                    "briefdescriptionSet": "Radius of structuring element",
                    "name": "KernelRadius"
                })

            labels = ["Annulus", "Box", "Ball", "Cross"]
            values = [
                "sitk.sitkAnnulus", "sitk.sitkBox", "sitk.sitkBall",
                "sitk.sitkCross"
            ]
            w = self.createEnumWidget("KernelType", labels, values)
            self.addWidgetWithToolTipAndLabel(
                w, {
                    "briefdescriptionSet": "Structuring element",
                    "name": "Kernel Type"
                })

        elif json["template_code_filename"] == "RegionGrowingImageFilter"\
              or json["template_code_filename"] == "FastMarchingImageFilter":

            name = "SeedList"
            if (json["template_code_filename"] == "FastMarchingImageFilter"):
                name = "TrialPoints"

            fiducialSelector = slicer.qMRMLNodeComboBox()
            self.widgets.append(fiducialSelector)
            fiducialSelector.nodeTypes = ("vtkMRMLMarkupsFiducialNode",
                                          "vtkMRMLAnnotationHierarchyNode")
            fiducialSelector.addAttribute("vtkMRMLAnnotationHierarchyNode",
                                          "MainChildType",
                                          "vtkMRMLAnnotationFiducialNode")
            fiducialSelector.selectNodeUponCreation = True
            fiducialSelector.addEnabled = True
            fiducialSelector.removeEnabled = False
            fiducialSelector.renameEnabled = True
            fiducialSelector.noneEnabled = False
            fiducialSelector.showHidden = False
            fiducialSelector.showChildNodeTypes = True
            fiducialSelector.setMRMLScene(slicer.mrmlScene)
            fiducialSelector.setToolTip(
                "Pick the Markups node for the seed list.")

            fiducialSelector.connect(
                "nodeActivated(vtkMRMLNode*)",
                lambda node, name=name: self.onFiducialListNode(name, node))
            self.prerun_callbacks.append(
                lambda w=fiducialSelector, name=name: self.onFiducialListNode(
                    name, w.currentNode()))

            fiducialSelectorLabel = qt.QLabel("{0}: ".format(name))
            self.widgets.append(fiducialSelectorLabel)

            #todo set tool tip
            # add to layout after connection
            parametersFormLayout.addRow(fiducialSelectorLabel,
                                        fiducialSelector)

        #
        # Iterate over the members in the JSON to generate a GUI
        #
        for member in json["members"]:
            w = None
            if "type" in member:
                t = member["type"]

            if "dim_vec" in member and int(member["dim_vec"]):
                if member["itk_type"].endswith("IndexType") or member[
                        "itk_type"].endswith("PointType"):
                    isPoint = member["itk_type"].endswith("PointType")

                    fiducialSelector = slicer.qMRMLNodeComboBox()
                    self.widgets.append(fiducialSelector)
                    fiducialSelector.nodeTypes = (
                        "vtkMRMLMarkupsFiducialNode",
                        "vtkMRMLAnnotationFiducialNode")
                    fiducialSelector.selectNodeUponCreation = True
                    fiducialSelector.addEnabled = False
                    fiducialSelector.removeEnabled = False
                    fiducialSelector.renameEnabled = True
                    fiducialSelector.noneEnabled = False
                    fiducialSelector.showHidden = False
                    fiducialSelector.showChildNodeTypes = True
                    fiducialSelector.setMRMLScene(slicer.mrmlScene)
                    fiducialSelector.setToolTip(
                        "Pick the Fiducial for the Point or Index")

                    fiducialSelector.connect(
                        "nodeActivated(vtkMRMLNode*)",
                        lambda node, w=fiducialSelector, name=member["name"],
                        isPt=isPoint: self.onFiducialNode(name, w, isPt))
                    self.prerun_callbacks.append(
                        lambda w=fiducialSelector, name=member["name"], isPt=
                        isPoint: self.onFiducialNode(name, w, isPt))

                    w1 = fiducialSelector

                    fiducialSelectorLabel = qt.QLabel("{0}: ".format(
                        member["name"]))
                    self.widgets.append(fiducialSelectorLabel)

                    icon = qt.QIcon(SimpleFilters.ICON_DIR + "Fiducials.png")

                    toggle = qt.QPushButton(icon, "")
                    toggle.setCheckable(True)
                    toggle.toolTip = "Toggle Fiducial Selection"
                    self.widgets.append(toggle)

                    w2 = self.createVectorWidget(member["name"], t)

                    hlayout = qt.QHBoxLayout()
                    hlayout.addWidget(fiducialSelector)
                    hlayout.setStretchFactor(fiducialSelector, 1)
                    hlayout.addWidget(w2)
                    hlayout.setStretchFactor(w2, 1)
                    hlayout.addWidget(toggle)
                    hlayout.setStretchFactor(toggle, 0)
                    w1.hide()

                    self.widgets.append(hlayout)

                    toggle.connect("clicked(bool)",
                                   lambda checked, ptW=w2, fidW=w1: self.
                                   onToggledPointSelector(checked, ptW, fidW))

                    parametersFormLayout.addRow(fiducialSelectorLabel, hlayout)

                else:
                    w = self.createVectorWidget(member["name"], t)

            elif "point_vec" in member:

                fiducialSelector = slicer.qMRMLNodeComboBox()
                self.widgets.append(fiducialSelector)
                fiducialSelector.nodeTypes = ("vtkMRMLMarkupsFiducialNode",
                                              "vtkMRMLAnnotationHierarchyNode")
                fiducialSelector.addAttribute("vtkMRMLAnnotationHierarchyNode",
                                              "MainChildType",
                                              "vtkMRMLAnnotationFiducialNode")
                fiducialSelector.selectNodeUponCreation = True
                fiducialSelector.addEnabled = True
                fiducialSelector.removeEnabled = False
                fiducialSelector.renameEnabled = True
                fiducialSelector.noneEnabled = False
                fiducialSelector.showHidden = False
                fiducialSelector.showChildNodeTypes = True
                fiducialSelector.setMRMLScene(slicer.mrmlScene)
                fiducialSelector.setToolTip(
                    "Pick the Markups node for the point list.")

                fiducialSelector.connect("nodeActivated(vtkMRMLNode*)",
                                         lambda node, name=member["name"]: self
                                         .onFiducialListNode(name, node))
                self.prerun_callbacks.append(
                    lambda w=fiducialSelector, name=member["name"], : self.
                    onFiducialListNode(name, w.currentNode()))

                w = fiducialSelector

            elif "enum" in member:
                w = self.createEnumWidget(member["name"], member["enum"])
            elif member["name"].endswith("Direction") and "std::vector" in t:
                # This member name is use for direction cosine matrix for image sources.
                # We are going to ignore it
                pass
            elif t == "InterpolatorEnum":
                labels = [
                    "Nearest Neighbor", "Linear", "BSpline", "Gaussian",
                    "Label Gaussian", "Hamming Windowed Sinc",
                    "Cosine Windowed Sinc", "Welch Windowed Sinc",
                    "Lanczos Windowed Sinc", "Blackman Windowed Sinc"
                ]
                values = [
                    "sitk.sitkNearestNeighbor", "sitk.sitkLinear",
                    "sitk.sitkBSpline", "sitk.sitkGaussian",
                    "sitk.sitkLabelGaussian", "sitk.sitkHammingWindowedSinc",
                    "sitk.sitkCosineWindowedSinc",
                    "sitk.sitkWelchWindowedSinc",
                    "sitk.sitkLanczosWindowedSinc",
                    "sitk.sitkBlackmanWindowedSinc"
                ]

                w = self.createEnumWidget(member["name"], labels, values)
                pass
            elif t == "PixelIDValueEnum":
                labels = [
                    "int8_t", "uint8_t", "int16_t", "uint16_t", "uint32_t",
                    "int32_t", "float", "double"
                ]
                values = [
                    "sitk.sitkInt8", "sitk.sitkUInt8", "sitk.sitkInt16",
                    "sitk.sitkUInt16", "sitk.sitkInt32", "sitk.sitkUInt32",
                    "sitk.sitkFloat32", "sitk.sitkFloat64"
                ]
                w = self.createEnumWidget(member["name"], labels, values)
            elif t in ["double", "float"]:
                w = self.createDoubleWidget(member["name"])
            elif t == "bool":
                w = self.createBoolWidget(member["name"])
            elif t in [
                    "uint8_t", "int8_t", "uint16_t", "int16_t", "uint32_t",
                    "int32_t", "uint64_t", "int64_t", "unsigned int", "int"
            ]:
                w = self.createIntWidget(member["name"], t)
            else:
                import sys
                sys.stderr.write(
                    "Unknown member \"{0}\" of type \"{1}\"\n".format(
                        member["name"], member["type"]))

            if w:
                self.addWidgetWithToolTipAndLabel(w, member)

        # end for each member

        #
        # output volume selector
        #
        outputSelectorLabel = qt.QLabel("Output Volume: ")
        self.widgets.append(outputSelectorLabel)

        self.outputSelector = slicer.qMRMLNodeComboBox()
        self.widgets.append(self.outputSelector)
        self.outputSelector.nodeTypes = [
            "vtkMRMLScalarVolumeNode", "vtkMRMLLabelMapVolumeNode"
        ]
        self.outputSelector.selectNodeUponCreation = True
        self.outputSelector.addEnabled = True
        self.outputSelector.removeEnabled = False
        self.outputSelector.renameEnabled = True
        self.outputSelector.noneEnabled = False
        self.outputSelector.showHidden = False
        self.outputSelector.showChildNodeTypes = False
        self.outputSelector.baseName = json["name"] + " Output"
        self.outputSelector.setMRMLScene(slicer.mrmlScene)
        self.outputSelector.setToolTip("Pick the output to the algorithm.")

        self.outputSelector.connect("nodeActivated(vtkMRMLNode*)",
                                    lambda node: self.onOutputSelect(node))

        # add to layout after connection
        parametersFormLayout.addRow(outputSelectorLabel, self.outputSelector)

        self.output = self.outputSelector.currentNode()

        #
        # LabelMap toggle
        #
        outputLabelMapLabel = qt.QLabel("LabelMap: ")
        self.widgets.append(outputLabelMapLabel)

        self.outputLabelMapBox = qt.QCheckBox()
        self.widgets.append(self.outputLabelMapBox)
        self.outputLabelMapBox.setToolTip("Output Volume is set as a labelmap")
        self.outputLabelMapBox.setChecked(self.outputLabelMap)
        self.outputLabelMapBox.setDisabled(True)

        self.outputLabelMapBox.connect(
            "stateChanged(int)",
            lambda val: self.onOutputLabelMapChanged(bool(val)))
        # add to layout after connection
        parametersFormLayout.addRow(outputLabelMapLabel,
                                    self.outputLabelMapBox)
  def setup(self):
    ScriptedLoadableModuleWidget.setup(self)
    # Instantiate and connect widgets ...

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

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

    #
    # input fiducial list selector
    #
    fiducialWarningLabel = qt.QLabel( "Note: Parent transforms of fiducials are not used. Fiducials should be defined in the coordinate system that is being registered." )
    fiducialWarningLabel.setWordWrap( True )
    parametersFormLayout.addRow(fiducialWarningLabel)

    self.inputFiducialSelector = slicer.qMRMLNodeComboBox()
    self.inputFiducialSelector.nodeTypes = ( ("vtkMRMLMarkupsFiducialNode"), "" )
    self.inputFiducialSelector.selectNodeUponCreation = True
    self.inputFiducialSelector.addEnabled = False
    self.inputFiducialSelector.removeEnabled = False
    self.inputFiducialSelector.noneEnabled = False
    self.inputFiducialSelector.showHidden = False
    self.inputFiducialSelector.showChildNodeTypes = False
    self.inputFiducialSelector.setMRMLScene( slicer.mrmlScene )
    self.inputFiducialSelector.setToolTip( "Pick the input fiducial list for the algorithm." )
    parametersFormLayout.addRow("Input fiducials: ", self.inputFiducialSelector)

    #
    # 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 model for the algorithm." )
    parametersFormLayout.addRow("Input model: ", self.inputModelSelector)

    #
    # output transform selector
    #
    self.outputSelector = slicer.qMRMLNodeComboBox()
    self.outputSelector.nodeTypes = ( ("vtkMRMLLinearTransformNode"), "" )
    self.outputSelector.selectNodeUponCreation = True
    self.outputSelector.addEnabled = True
    self.outputSelector.removeEnabled = True
    self.outputSelector.noneEnabled = False
    self.outputSelector.showHidden = False
    self.outputSelector.showChildNodeTypes = False
    self.outputSelector.renameEnabled = True
    self.outputSelector.setMRMLScene( slicer.mrmlScene )
    self.outputSelector.setToolTip( "Pick the output to the algorithm." )
    parametersFormLayout.addRow("Output transform: ", self.outputSelector)

    #
    # check box to trigger taking screen shots for later use in tutorials
    #
    self.enableScreenshotsFlagCheckBox = qt.QCheckBox()
    self.enableScreenshotsFlagCheckBox.checked = 0
    self.enableScreenshotsFlagCheckBox.setToolTip("If checked, take screen shots for tutorials. Use Save Data to write them to disk.")
    # parametersFormLayout.addRow("Enable Screenshots", self.enableScreenshotsFlagCheckBox)

    #
    # scale factor for screen shots
    #
    self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget()
    self.screenshotScaleFactorSliderWidget.singleStep = 1.0
    self.screenshotScaleFactorSliderWidget.minimum = 1.0
    self.screenshotScaleFactorSliderWidget.maximum = 50.0
    self.screenshotScaleFactorSliderWidget.value = 1.0
    self.screenshotScaleFactorSliderWidget.setToolTip("Set scale factor for the screen shots.")

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

    #
    # Output panel
    #
    outputCollapsibleButton = ctk.ctkCollapsibleButton()
    outputCollapsibleButton.text = "Output"
    self.layout.addWidget( outputCollapsibleButton )
    outputFormLayout = qt.QFormLayout( outputCollapsibleButton )

    self.outputLine = qt.QLineEdit()
    self.outputLine.setReadOnly( True )
    outputFormLayout.addRow( "Mean distance after registration:", self.outputLine )

    #
    # Advanced parameters
    #
    advancedCollapsibleButton = ctk.ctkCollapsibleButton()
    advancedCollapsibleButton.text = "Advanced"
    self.layout.addWidget(advancedCollapsibleButton)

    # Layout
    advancedCollapsibleButton.collapsed = True
    advancedFormLayout = qt.QFormLayout(advancedCollapsibleButton)

    #
    # Transform type selector
    #
    self.typeSelector = qt.QComboBox()
    self.typeSelector.insertItem( 0, "Rigid" )
    self.typeSelector.insertItem( 1, "Similarity" )
    self.typeSelector.insertItem( 2, "Affine" )
    advancedFormLayout.addRow("Transform type: ", self.typeSelector)

    #
    # Iteration selector
    #
    self.iterationSpin = qt.QSpinBox()
    self.iterationSpin.setMaximum( 1000 )
    self.iterationSpin.setValue( 100 )
    advancedFormLayout.addRow("Number of iterations:", self.iterationSpin)

    # connections
    self.applyButton.connect('clicked(bool)', self.onApplyButton)
    self.inputModelSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)
    self.inputFiducialSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)
    self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect)

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

        #
        # Reload and Test area
        #
        reloadCollapsibleButton = ctk.ctkCollapsibleButton()
        reloadCollapsibleButton.text = "Reload && Test"
        self.layout.addWidget(reloadCollapsibleButton)
        reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton)

        # reload button
        # (use this during development, but remove it when delivering
        #  your module to users)
        self.reloadButton = qt.QPushButton("Reload")
        self.reloadButton.toolTip = "Reload this module."
        self.reloadButton.name = "Radiomics Reload"
        reloadFormLayout.addWidget(self.reloadButton)
        self.reloadButton.connect('clicked()', self.onReload)

        # reload and test button
        # (use this during development, but remove it when delivering
        #  your module to users)
        self.reloadAndTestButton = qt.QPushButton("Reload and Test")
        self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests."
        reloadFormLayout.addWidget(self.reloadAndTestButton)
        # self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest)
        reloadCollapsibleButton.collapsed = True
        #---------------------------------------------------------

        #
        # Compute Radiomics area
        #
        self.computeRadiomicsCollapsibleButton = ctk.ctkCollapsibleButton()
        self.computeRadiomicsCollapsibleButton.text = "Slicer Radiomics Platform"
        self.layout.addWidget(self.computeRadiomicsCollapsibleButton)
        self.computeRadiomicsFormLayout = qt.QFormLayout(
            self.computeRadiomicsCollapsibleButton)

        #
        # Universal Advanced Settings Collapsible Button
        #

        self.AdvancedSettingsCollapsibleButton = ctk.ctkCollapsibleButton()
        self.AdvancedSettingsCollapsibleButton.text = "Advanced Settings"
        self.AdvancedSettingsCollapsibleButtonLayout = qt.QHBoxLayout()
        self.AdvancedSettingsCollapsibleButton.setLayout(qt.QHBoxLayout())
        self.computeRadiomicsFormLayout.addWidget(
            self.AdvancedSettingsCollapsibleButton)
        self.AdvancedSettingsCollapsibleButton.collapsed = True

        self.AdvancedSettingsFrame = qt.QFrame(
            self.AdvancedSettingsCollapsibleButton)
        self.AdvancedSettingsFrameLayout = qt.QFormLayout()
        self.AdvancedSettingsFrame.setLayout(self.AdvancedSettingsFrameLayout)
        self.AdvancedSettingsCollapsibleButton.layout().addWidget(
            self.AdvancedSettingsFrame)

        # Label Values
        self.inputLabelValues = qt.QLabel("Label Values:",
                                          self.AdvancedSettingsFrame)
        self.inputLabelValuesField = qt.QLineEdit("1",
                                                  self.AdvancedSettingsFrame)
        self.AdvancedSettingsFrameLayout.addRow(self.inputLabelValues,
                                                self.inputLabelValuesField)

        # Interpolation Settings
        self.settingsRadioButtonFrame = qt.QFrame(self.AdvancedSettingsFrame)
        self.settingsRadioButtonFrame.setLayout(qt.QHBoxLayout())
        self.interpolationsGroup = qt.QButtonGroup(
            self.settingsRadioButtonFrame)
        self.ipRawButton = qt.QRadioButton("Raw")
        self.ip1x1x1Button = qt.QRadioButton("(1,1,1)")
        self.ip2x2x2Button = qt.QRadioButton("(2,2,2)")
        self.ip3x3x3Button = qt.QRadioButton("(3,3,3)")
        self.ipRawButton.checked = True
        self.interpolationsGroup.addButton(self.ipRawButton)
        self.interpolationsGroup.addButton(self.ip1x1x1Button)
        self.interpolationsGroup.addButton(self.ip2x2x2Button)
        self.interpolationsGroup.addButton(self.ip3x3x3Button)
        self.settingsRadioButtonFrame.layout().addWidget(self.ipRawButton)
        self.settingsRadioButtonFrame.layout().addWidget(self.ip1x1x1Button)
        self.settingsRadioButtonFrame.layout().addWidget(self.ip2x2x2Button)
        self.settingsRadioButtonFrame.layout().addWidget(self.ip3x3x3Button)
        self.interpHeader = qt.QLabel("Interpolation:")
        self.AdvancedSettingsFrameLayout.addRow(self.interpHeader,
                                                self.settingsRadioButtonFrame)

        # Bin Width
        self.inputBinWidth = qt.QLabel("Bin Width:",
                                       self.AdvancedSettingsFrame)
        self.inputBinWidthField = qt.QLineEdit("25",
                                               self.AdvancedSettingsFrame)
        self.AdvancedSettingsFrameLayout.addRow(self.inputBinWidth,
                                                self.inputBinWidthField)

        # Modality Radio Buttons Frame
        self.ModalityRadioButtonFrame = qt.QFrame(self.AdvancedSettingsFrame)
        self.ModalityRadioButtonFrame.setLayout(qt.QHBoxLayout())
        self.ModalityFileFormatGroup = qt.QButtonGroup(
            self.ModalityRadioButtonFrame)
        self.CTButton = qt.QRadioButton("CT")
        self.CTButton.checked = True
        self.MRIButton = qt.QRadioButton("MRI")
        self.PETButton = qt.QRadioButton("PET")
        self.ModalityFileFormatGroup.addButton(self.CTButton)
        self.ModalityFileFormatGroup.addButton(self.MRIButton)
        self.ModalityFileFormatGroup.addButton(self.PETButton)
        self.ModalityRadioButtonFrame.layout().addWidget(self.CTButton)
        self.ModalityRadioButtonFrame.layout().addWidget(self.MRIButton)
        self.ModalityRadioButtonFrame.layout().addWidget(self.PETButton)
        self.ModalityInputLabel = qt.QLabel("Image Modality:",
                                            self.AdvancedSettingsFrame)
        self.AdvancedSettingsFrameLayout.addRow(self.ModalityInputLabel,
                                                self.ModalityRadioButtonFrame)
        #
        # End Universal Advanced Settings Collapsible Button
        #

        # Parent Tab Widget
        self.computeRadiomicsTabWidget = qt.QTabWidget()
        self.computeRadiomicsFormLayout.addWidget(
            self.computeRadiomicsTabWidget)

        #  Radiomics Current Mode
        self.tabComputeRadiomicsCurr = qt.QWidget()
        self.singleCaseInputFormLayout = qt.QFormLayout()
        self.tabComputeRadiomicsCurr.setLayout(self.singleCaseInputFormLayout)
        self.tabComputeRadiomicsCurrName = "Single Case Mode"
        self.computeRadiomicsTabWidget.addTab(self.tabComputeRadiomicsCurr,
                                              self.tabComputeRadiomicsCurrName)

        # Input 1: Input Image
        self.input1Frame = qt.QFrame(self.tabComputeRadiomicsCurr)
        self.input1Frame.setLayout(qt.QHBoxLayout())
        self.singleCaseInputFormLayout.addWidget(self.input1Frame)
        self.input1Selector = qt.QLabel("Input Image: ", self.input1Frame)
        self.input1Frame.layout().addWidget(self.input1Selector)
        self.input1Selector = slicer.qMRMLNodeComboBox(self.input1Frame)
        self.input1Selector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "")
        self.input1Selector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap",
                                         0)
        self.input1Selector.addEnabled = False
        self.input1Selector.removeEnabled = False
        self.input1Selector.setMRMLScene(slicer.mrmlScene)
        self.input1Frame.layout().addWidget(self.input1Selector)

        # Input 2: Input Segmentation
        self.input2Frame = qt.QFrame(self.tabComputeRadiomicsCurr)
        self.input2Frame.setLayout(qt.QHBoxLayout())
        self.singleCaseInputFormLayout.addWidget(self.input2Frame)
        self.input2Selector = qt.QLabel("Input Label:  ", self.input2Frame)
        self.input2Frame.layout().addWidget(self.input2Selector)
        self.input2Selector = slicer.qMRMLNodeComboBox(self.input2Frame)
        self.input2Selector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "")
        self.input2Selector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap",
                                         1)
        self.input2Selector.addEnabled = False
        self.input2Selector.removeEnabled = False
        self.input2Selector.setMRMLScene(slicer.mrmlScene)
        self.input2Frame.layout().addWidget(self.input2Selector)

        # Settings Collapsible Button
        self.SettingsCollapsibleButtonCurr = ctk.ctkCollapsibleButton()
        self.SettingsCollapsibleButtonCurr.text = "Settings"
        self.SettingsCollapsibleButtonCurrLayout = qt.QHBoxLayout()
        self.SettingsCollapsibleButtonCurr.setLayout(
            self.SettingsCollapsibleButtonCurrLayout)
        self.singleCaseInputFormLayout.addWidget(
            self.SettingsCollapsibleButtonCurr)
        self.SettingsCollapsibleButtonCurr.collapsed = False
        self.SettingsFrameCurr = qt.QFrame(self.SettingsCollapsibleButtonCurr)
        self.SettingsFrameCurr.setLayout(qt.QFormLayout())
        self.SettingsCollapsibleButtonCurrLayout.addWidget(
            self.SettingsFrameCurr)

        # Settings
        self.para2curr = qt.QCheckBox("Use MatlabBridge",
                                      self.tabComputeRadiomicsCurr)
        self.para2curr.toolTip = "When checked: Matlab features extracted"
        self.para2curr.checked = False
        self.SettingsFrameCurr.layout().addRow(self.para2curr)

        # Apply Radiomics button
        self.RadiomicCurrButtonsFrame = qt.QFrame(self.tabComputeRadiomicsCurr)
        self.RadiomicCurrButtonsFrame.setLayout(qt.QHBoxLayout())
        self.singleCaseInputFormLayout.addWidget(self.RadiomicCurrButtonsFrame)

        self.radiomicsCurrButton = qt.QPushButton(
            "Compute Radiomics Features (Single Case)",
            self.RadiomicCurrButtonsFrame)
        self.radiomicsCurrButton.enabled = True
        self.radiomicsCurrButton.toolTip = "Run the feature extraction for a single case."
        self.RadiomicCurrButtonsFrame.layout().addWidget(
            self.radiomicsCurrButton)

        # Chart
        self.RadiomicsTableFrame = qt.QFrame(self.tabComputeRadiomicsCurr)
        self.RadiomicsTableFrameLayout = qt.QHBoxLayout()
        self.RadiomicsTableFrame.setLayout(self.RadiomicsTableFrameLayout)
        self.singleCaseInputFormLayout.addWidget(self.RadiomicsTableFrame)

        self.RadiomicsTableView = qt.QTableView(self.RadiomicsTableFrame)
        self.RadiomicsTableView.sortingEnabled = True
        self.RadiomicsTableView.minimumHeight = 175
        self.RadiomicsTableView.verticalHeader().visible = False
        self.RadiomicsTableView.setColumnWidth(0, 30)
        self.RadiomicsTableFrameLayout.addWidget(self.RadiomicsTableView)
        self.RadiomicsTableModel = qt.QStandardItemModel()

        # Save Table Button
        self.saveButton = qt.QPushButton("Save Table to CSV File",
                                         self.RadiomicCurrButtonsFrame)
        self.saveButton.toolTip = "Save Radiomics Feature from table to CSV file"
        self.saveButton.enabled = False
        self.singleCaseInputFormLayout.layout().addWidget(self.saveButton)
        """
    #
    # The interface we use for batch mode (not part of this module)
    #
    
    #---------------------------------------------------------
    # Radiomics Batch
    self.tabComputeRadiomicsBatch = qt.QWidget()
    self.RadiomicsFormLayout = qt.QFormLayout()
    self.tabComputeRadiomicsBatch.setLayout(self.RadiomicsFormLayout)
    self.tabComputeRadiomicsBatchName = "Batch Mode"
    self.computeRadiomicsTabWidget.addTab(self.tabComputeRadiomicsBatch, self.tabComputeRadiomicsBatchName)
    
    # Input 3: Database selection
    self.input3Frame = qt.QFrame(self.tabComputeRadiomicsBatch)
    self.input3Frame.setLayout(qt.QHBoxLayout())
    self.RadiomicsFormLayout.addWidget(self.input3Frame)
    self.DatabaseButton = qt.QPushButton("Set Root Patient Directory")
    self.DatabaseButton.toolTip = "Set the main Patient Data location"
    self.DatabaseButton.enabled = True
    self.input3Frame.layout().addWidget(self.DatabaseButton)
    self.PatientSelector = qt.QComboBox()
    self.PatientSelector.enabled = False
    self.input3Frame.layout().addWidget(self.PatientSelector)
    
    # Settings Collapsible Button
    self.SettingsCollapsibleButton = ctk.ctkCollapsibleButton()
    self.SettingsCollapsibleButton.text = "Settings"
    self.SettingsCollapsibleButtonLayout = qt.QHBoxLayout()
    self.SettingsCollapsibleButton.setLayout(self.SettingsCollapsibleButtonLayout)    
    self.RadiomicsFormLayout.addWidget(self.SettingsCollapsibleButton)
    self.SettingsCollapsibleButton.collapsed = False
    self.SettingsFrame = qt.QFrame(self.SettingsCollapsibleButton)
    self.SettingsFrame.setLayout(qt.QFormLayout())
    self.SettingsCollapsibleButtonLayout.addWidget(self.SettingsFrame)
    
    # Settings 
    self.para2 = qt.QCheckBox("Use MatlabBridge", self.SettingsFrame)
    self.para2.toolTip = "When checked: Matlab features extracted"
    self.para2.checked = True
    self.SettingsFrame.layout().addRow(self.para2)

    self.para3 = qt.QCheckBox("Clear Database", self.SettingsFrame)
    self.para3.toolTip = "When checked: old database is cleared"
    self.para3.checked = True
    self.SettingsFrame.layout().addRow(self.para3)

    # Keywords Collapsible Button
    self.KeywordsCollapsibleButton = ctk.ctkCollapsibleButton()
    self.KeywordsCollapsibleButton.text = "Keyword Matching"
    self.KeywordsCollapsibleButtonLayout = qt.QHBoxLayout()
    self.KeywordsCollapsibleButton.setLayout(self.KeywordsCollapsibleButtonLayout)    
    self.SettingsFrame.layout().addRow(self.KeywordsCollapsibleButton)
    self.KeywordsCollapsibleButton.collapsed = True
    
    self.keywordsFrame = qt.QFrame(self.KeywordsCollapsibleButton)
    self.keywordsFrame.setLayout(qt.QFormLayout())
    self.KeywordsCollapsibleButtonLayout.addWidget(self.keywordsFrame)
    self.keywordsHeader = qt.QLabel("Keyword Matching:", self.keywordsFrame)
    self.keywordsFrame.layout().addRow(self.keywordsHeader)
    
    # File Type Radio Buttons Frame
    self.radioButtonFrame = qt.QFrame(self.keywordsFrame)
    self.radioButtonFrame.setLayout(qt.QFormLayout())
    self.fileFormatGroup = qt.QButtonGroup(self.radioButtonFrame)
    self.nrrdButton = qt.QRadioButton("NRRD")
    self.nrrdButton.checked = True
    self.niftiButton = qt.QRadioButton("NIFTI")
    self.fileFormatGroup.addButton(self.nrrdButton)
    self.fileFormatGroup.addButton(self.niftiButton)
    self.radioButtonFrame.layout().addRow(self.nrrdButton, self.niftiButton)
    self.inputMaskHeader = qt.QLabel("Input Image File Type:", self.keywordsFrame)
    self.keywordsFrame.layout().addRow(self.inputMaskHeader, self.radioButtonFrame)
    
    # Keywords Frame
    self.inputImageKeywords = qt.QLabel("Input Image Keywords:", self.keywordsFrame)
    self.inputImageKeywordsField = qt.QLineEdit("",self.keywordsFrame)
    self.keywordsFrame.layout().addRow(self.inputImageKeywords, self.inputImageKeywordsField )
    
    self.inputImageExclusionKeywords = qt.QLabel("Input Image Exclusion Keywords:", self.keywordsFrame)
    self.inputImageExclusionKeywordsField = qt.QLineEdit("",self.keywordsFrame)
    self.keywordsFrame.layout().addRow(self.inputImageExclusionKeywords, self.inputImageExclusionKeywordsField )
    
    self.inputLabelKeywords = qt.QLabel("Input Label Keywords:", self.keywordsFrame)
    self.inputLabelKeywordsField = qt.QLineEdit("",self.keywordsFrame)
    self.keywordsFrame.layout().addRow(self.inputLabelKeywords, self.inputLabelKeywordsField )
    
    self.inputLabelExclusionKeywords = qt.QLabel("Input Label Exclusion Keywords:", self.keywordsFrame)
    self.inputLabelExclusionKeywordsField = qt.QLineEdit("",self.keywordsFrame)
    self.keywordsFrame.layout().addRow(self.inputLabelExclusionKeywords, self.inputLabelExclusionKeywordsField )
    
    # Radiomic Mode Buttons
    self.RadiomicButtonsFrame = qt.QFrame(self.tabComputeRadiomicsBatch)
    self.RadiomicButtonsFrame.setLayout(qt.QHBoxLayout())
    self.RadiomicsFormLayout.addWidget(self.RadiomicButtonsFrame)
    self.radiomicsBatchButton = qt.QPushButton("Compute Radiomics Features (Batch Mode)")
    self.radiomicsBatchButton.toolTip = "Run the feature extraction for database batch."
    self.radiomicsBatchButton.enabled = True
    self.RadiomicButtonsFrame.layout().addWidget(self.radiomicsBatchButton)
    self.RadiomicButtonsFrame.enabled = True
    """

        #---------------------------------------------------------
        # Connections
        #self.DatabaseButton.connect('clicked(bool)', self.onDatabaseButton)
        self.radiomicsCurrButton.connect('clicked(bool)', self.onRadiomicsCurr)
        #self.radiomicsBatchButton.connect('clicked(bool)', self.onRadiomicsBatch)
        self.saveButton.connect('clicked()', self.onSave)

        self.layout.addStretch(1)  # Add vertical spacer
Beispiel #19
0
    def setup(self):
        # Instantiate and connect widgets ...

        if self.developerMode:
            #
            # Reload and Test area
            #
            reloadCollapsibleButton = ctk.ctkCollapsibleButton()
            reloadCollapsibleButton.text = "Reload && Test"
            self.layout.addWidget(reloadCollapsibleButton)
            reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton)

            # reload button
            # (use this during development, but remove it when delivering
            #  your module to users)
            self.reloadButton = qt.QPushButton("Reload")
            self.reloadButton.toolTip = "Reload this module."
            self.reloadButton.name = "CompareVolumes Reload"
            reloadFormLayout.addWidget(self.reloadButton)
            self.reloadButton.connect('clicked()', self.onReload)

            # reload and test button
            # (use this during development, but remove it when delivering
            #  your module to users)
            self.reloadAndTestButton = qt.QPushButton("Reload and Test All")
            self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests."
            reloadFormLayout.addWidget(self.reloadAndTestButton)
            self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest)

            # reload and run specific tests
            scenarios = (
                "Three Volume",
                "View Watcher",
                "LayerReveal",
            )
            for scenario in scenarios:
                button = qt.QPushButton("Reload and Test %s" % scenario)
                self.reloadAndTestButton.toolTip = "Reload this module and then run the %s self test." % scenario
                reloadFormLayout.addWidget(button)
                button.connect(
                    'clicked()',
                    lambda s=scenario: self.onReloadAndTest(scenario=s))

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

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

        #
        # orientation
        #
        self.orientationBox = qt.QGroupBox("Orientation")
        self.orientationBox.setLayout(qt.QFormLayout())
        self.orientationButtons = {}
        self.orientations = ("Axial", "Sagittal", "Coronal")
        for orientation in self.orientations:
            self.orientationButtons[orientation] = qt.QRadioButton()
            self.orientationButtons[orientation].text = orientation
            self.orientationButtons[orientation].connect(
                "clicked()", lambda o=orientation: self.setOrientation(o))
            self.orientationBox.layout().addWidget(
                self.orientationButtons[orientation])
        parametersFormLayout.addWidget(self.orientationBox)
        self.setOrientation(self.orientations[0])

        #
        # target volume selector
        #
        self.inputSelector = slicer.qMRMLNodeComboBox()
        self.inputSelector.nodeTypes = (("vtkMRMLVolumeNode"), "")
        self.inputSelector.selectNodeUponCreation = True
        self.inputSelector.addEnabled = False
        self.inputSelector.removeEnabled = False
        self.inputSelector.noneEnabled = False
        self.inputSelector.showHidden = False
        self.inputSelector.showChildNodeTypes = True
        self.inputSelector.setMRMLScene(slicer.mrmlScene)
        self.inputSelector.setToolTip("Pick the input to the algorithm.")
        parametersFormLayout.addRow("Target Volume: ", self.inputSelector)

        #
        # lightbox
        #
        self.lightboxVolumeButton = qt.QPushButton("Lightbox Target Volume")
        self.lightboxVolumeButton.setToolTip(
            "Make a set of slice views that span the extent of this study at equally spaced locations in the selected orientation."
        )
        parametersFormLayout.addRow(self.lightboxVolumeButton)
        self.lightboxVolumeButton.connect("clicked()", self.onLightboxVolume)

        #
        # background volume selector
        #
        self.backgroundSelector = slicer.qMRMLNodeComboBox()
        self.backgroundSelector.nodeTypes = (("vtkMRMLVolumeNode"), "")
        self.backgroundSelector.selectNodeUponCreation = True
        self.backgroundSelector.addEnabled = False
        self.backgroundSelector.removeEnabled = False
        self.backgroundSelector.noneEnabled = True
        self.backgroundSelector.showHidden = False
        self.backgroundSelector.showChildNodeTypes = True
        self.backgroundSelector.setMRMLScene(slicer.mrmlScene)
        self.backgroundSelector.setToolTip(
            "Common background - all lightbox panes will have this background and a different volume in each foreground."
        )
        parametersFormLayout.addRow("Common Background Volume: ",
                                    self.backgroundSelector)

        #
        # label volume selector
        #
        self.labelSelector = slicer.qMRMLNodeComboBox()
        self.labelSelector.nodeTypes = (("vtkMRMLLabelMapVolumeNode"), "")
        self.labelSelector.selectNodeUponCreation = True
        self.labelSelector.addEnabled = False
        self.labelSelector.removeEnabled = False
        self.labelSelector.noneEnabled = True
        self.labelSelector.showHidden = False
        self.labelSelector.showChildNodeTypes = True
        self.labelSelector.setMRMLScene(slicer.mrmlScene)
        self.labelSelector.setToolTip(
            "Common label - all lightbox panes will have this label on top.")
        parametersFormLayout.addRow("Common Label Volume: ",
                                    self.labelSelector)

        self.lightboxVolumesButton = qt.QPushButton("Lightbox All Volumes")
        self.lightboxVolumesButton.setToolTip(
            "Make a set of slice views that show each of the currently loaded volumes, with optional companion volumes, in the selected orientation."
        )
        parametersFormLayout.addRow(self.lightboxVolumesButton)
        self.lightboxVolumesButton.connect("clicked()", self.onLightboxVolumes)

        #
        # Add layer reveal area
        #
        layerRevealCollapsibleButton = ctk.ctkCollapsibleButton()
        layerRevealCollapsibleButton.text = "Layer Reveal Cursor"
        self.layout.addWidget(layerRevealCollapsibleButton)
        layerRevealFormLayout = qt.QFormLayout(layerRevealCollapsibleButton)

        self.layerRevealCheck = qt.QCheckBox()
        layerRevealFormLayout.addRow("Layer Reveal Cursor",
                                     self.layerRevealCheck)
        self.layerRevealCheck.connect("toggled(bool)",
                                      self.onLayerRevealToggled)

        # Add vertical spacer
        self.layout.addStretch(1)
Beispiel #20
0
    def setup(self):
        # Instantiate and connect widgets ...

        # reload button
        # (use this during development, but remove it when delivering
        #  your module to users)
        self.reloadButton = qt.QPushButton("Reload")
        self.reloadButton.toolTip = "Reload this module."
        self.reloadButton.name = "RSNAQuantTutorial Reload"
        self.layout.addWidget(self.reloadButton)
        self.reloadButton.connect('clicked()', self.onReload)

        # reload and test button
        # (use this during development, but remove it when delivering
        #  your module to users)
        self.reloadAndTestButton = qt.QPushButton("Reload and Test")
        self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests."
        self.layout.addWidget(self.reloadAndTestButton)
        self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest)

        # Collapsible button
        testsCollapsibleButton = ctk.ctkCollapsibleButton()
        testsCollapsibleButton.text = "Tests"
        self.layout.addWidget(testsCollapsibleButton)

        # Layout within the collapsible button
        formLayout = qt.QFormLayout(testsCollapsibleButton)

        # test buttons
        tests = (("Part 1 : Ruler", self.onPart1Ruler),
                 ("Part 2: ChangeTracker", self.onPart2ChangeTracker),
                 ("Part 3 : PETCT", self.onPart3PETCT))
        for text, slot in tests:
            testButton = qt.QPushButton(text)
            testButton.toolTip = "Run the test."
            formLayout.addWidget(testButton)
            testButton.connect('clicked(bool)', slot)

        # A collapsible button to hide screen shot options
        screenShotsCollapsibleButton = ctk.ctkCollapsibleButton()
        screenShotsCollapsibleButton.text = "Screen shot options"
        self.layout.addWidget(screenShotsCollapsibleButton)

        # layout within the collapsible button
        screenShotsFormLayout = qt.QFormLayout(screenShotsCollapsibleButton)

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.enableScreenshotsFlagCheckBox = qt.QCheckBox()
        self.enableScreenshotsFlagCheckBox.checked = 0
        self.enableScreenshotsFlagCheckBox.setToolTip(
            "If checked, take screen shots for tutorials. Use Save Data to write them to disk."
        )
        screenShotsFormLayout.addRow("Enable Screenshots",
                                     self.enableScreenshotsFlagCheckBox)

        #
        # scale factor for screen shots
        #
        self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget()
        self.screenshotScaleFactorSliderWidget.singleStep = 1.0
        self.screenshotScaleFactorSliderWidget.minimum = 1.0
        self.screenshotScaleFactorSliderWidget.maximum = 50.0
        self.screenshotScaleFactorSliderWidget.value = 1.0
        self.screenshotScaleFactorSliderWidget.setToolTip(
            "Set scale factor for the screen shots.")
        screenShotsFormLayout.addRow("Screenshot scale factor",
                                     self.screenshotScaleFactorSliderWidget)

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

    # Instantiate and connect widgets ...


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

    # ground truth transform selector
    self.groundTruthTransformSelectorLabel = qt.QLabel()
    self.groundTruthTransformSelectorLabel.setText( "Ground truth transform: " )
    self.groundTruthTransformSelector = slicer.qMRMLNodeComboBox()
    self.groundTruthTransformSelector.nodeTypes = ( ["vtkMRMLTransformNode"] )
    self.groundTruthTransformSelector.noneEnabled = False
    self.groundTruthTransformSelector.addEnabled = True
    self.groundTruthTransformSelector.removeEnabled = True
    self.groundTruthTransformSelector.setMRMLScene( slicer.mrmlScene )
    self.groundTruthTransformSelector.setToolTip( "Pick the input ground truth transform (e.g., optical tracker)" )
    parametersFormLayout.addRow(self.groundTruthTransformSelectorLabel, self.groundTruthTransformSelector)

    # mapped transform selector
    self.mappedTransformSelectorLabel = qt.QLabel("Mapped transform: ")
    self.mappedTransformSelector = slicer.qMRMLNodeComboBox()
    self.mappedTransformSelector.nodeTypes = ( ["vtkMRMLTransformNode"] )
    self.mappedTransformSelector.noneEnabled = False
    self.mappedTransformSelector.addEnabled = True
    self.mappedTransformSelector.removeEnabled = True
    self.mappedTransformSelector.setMRMLScene( slicer.mrmlScene )
    self.mappedTransformSelector.setToolTip( "Pick the input transform to be mapped compared to the ground truth (e.g., electromagnetic tracker)" )
    parametersFormLayout.addRow(self.mappedTransformSelectorLabel, self.mappedTransformSelector)

    # output volume selector
    self.outputVisitedPointsModelSelectorLabel = qt.QLabel("Output visited points model: ")
    self.outputVisitedPointsModelSelector = slicer.qMRMLNodeComboBox()
    self.outputVisitedPointsModelSelector.nodeTypes = ( ["vtkMRMLModelNode"] )
    self.outputVisitedPointsModelSelector.noneEnabled = True
    self.outputVisitedPointsModelSelector.addEnabled = True
    self.outputVisitedPointsModelSelector.removeEnabled = True
    self.outputVisitedPointsModelSelector.baseName = "VisitedPoints"
    self.outputVisitedPointsModelSelector.setMRMLScene( slicer.mrmlScene )
    self.outputVisitedPointsModelSelector.setToolTip( "A glyph is added to the model at each measurement point. Optional." )
    parametersFormLayout.addRow(self.outputVisitedPointsModelSelectorLabel, self.outputVisitedPointsModelSelector)

    # Position error vector
    self.positionErrorTransformSelectorLabel = qt.QLabel("Position error transform: ")
    self.positionErrorTransformSelector = slicer.qMRMLNodeComboBox()
    self.positionErrorTransformSelector.nodeTypes = ( ["vtkMRMLTransformNode"] )
    self.positionErrorTransformSelector.noneEnabled = True
    self.positionErrorTransformSelector.addEnabled = True
    self.positionErrorTransformSelector.removeEnabled = True
    self.positionErrorTransformSelector.baseName = "PositionErrorTransform"
    self.positionErrorTransformSelector.setMRMLScene( slicer.mrmlScene )
    self.positionErrorTransformSelector.setToolTip( "The transform node will store and interpolate the measurement points to generate a vector field of the position error of the mapped transform compared to the ground truth transform. Optional." )
    parametersFormLayout.addRow(self.positionErrorTransformSelectorLabel, self.positionErrorTransformSelector)

    # Orientation error magnitude
    self.orientationErrorTransformSelectorLabel = qt.QLabel("Orientation error transform:")
    self.orientationErrorTransformSelector = slicer.qMRMLNodeComboBox()
    self.orientationErrorTransformSelector.nodeTypes = ( ["vtkMRMLTransformNode"] )
    self.orientationErrorTransformSelector.noneEnabled = True
    self.orientationErrorTransformSelector.addEnabled = True
    self.orientationErrorTransformSelector.removeEnabled = True
    self.orientationErrorTransformSelector.baseName = "OrientationErrorTransform"
    self.orientationErrorTransformSelector.setMRMLScene( slicer.mrmlScene )
    self.orientationErrorTransformSelector.setToolTip( "The transform node will store and interpolate the measurement points to generate a vector field of the orientation error of the mapped transform compared to the ground truth transform. Only the x component is used. Optional." )
    parametersFormLayout.addRow(self.orientationErrorTransformSelectorLabel, self.orientationErrorTransformSelector)

    # Select defaults (to make debugging easier)
    emPointerToEmTrackerNode = slicer.util.getNode('EmPointerToEmTracker')
    if emPointerToEmTrackerNode:
        self.mappedTransformSelector.setCurrentNode(emPointerToEmTrackerNode)
    emPointerGtruthToOpPointerNode = slicer.util.getNode('EmPointerGtruthToOpPointer')
    if emPointerGtruthToOpPointerNode:
        self.groundTruthTransformSelector.setCurrentNode(emPointerGtruthToOpPointerNode)
    visitedPointsModelNode = slicer.util.getNode('VisitedPoints')
    if visitedPointsModelNode:
        self.outputVisitedPointsModelSelector.setCurrentNode(visitedPointsModelNode)
    positionErrorTransformNode = slicer.util.getNode('PositionErrorTransform')
    if positionErrorTransformNode:
        self.positionErrorTransformSelector.setCurrentNode(positionErrorTransformNode)
    orientationErrorTransformNode = slicer.util.getNode('OrientationErrorTransform')
    if orientationErrorTransformNode:
        self.orientationErrorTransformSelector.setCurrentNode(orientationErrorTransformNode)

    #
    # Check box to enable creating output transforms automatically.
    # The function is useful for testing and initial creation of the transforms but not recommended when the
    # transforms are already in the scene.
    #
    self.enableTransformMappingCheckBox = qt.QCheckBox()
    self.enableTransformMappingCheckBox.checked = 0
    self.enableTransformMappingCheckBox.setToolTip("If checked, then the mapped transform difference compared to the ground truth is written into the volume.")
    parametersFormLayout.addRow("Enable mapping", self.enableTransformMappingCheckBox)
    self.enableTransformMappingCheckBox.connect('stateChanged(int)', self.setEnableTransformMapping)

    #
    # View current error area
    #

    errorCollapsibleButton = ctk.ctkCollapsibleButton()
    errorCollapsibleButton.text = "Current Error"
    self.layout.addWidget(errorCollapsibleButton)
    errorFormLayout = qt.QFormLayout(errorCollapsibleButton)

    self.errorPositionLabel = qt.QLabel("Position error (mm): ")
    self.errorPositionValueLabel = qt.QLabel()

    self.errorOrientationLabel = qt.QLabel("Orientation error (deg): ")
    self.errorOrientationValueLabel = qt.QLabel()

    self.errorXLabel = qt.QLabel("Error in X-value (mm): ")
    self.errorXValueLabel = qt.QLabel()

    self.errorYLabel = qt.QLabel("Error in Y-value (mm): ")
    self.errorYValueLabel = qt.QLabel()

    self.errorZLabel = qt.QLabel("Error in Z-value (mm): ")
    self.errorZValueLabel = qt.QLabel()

    errorFormLayout.addRow(self.errorPositionLabel, self.errorPositionValueLabel)
    errorFormLayout.addRow(self.errorOrientationLabel, self.errorOrientationValueLabel)
    errorFormLayout.addRow(self.errorXLabel, self.errorXValueLabel)
    errorFormLayout.addRow(self.errorYLabel, self.errorYValueLabel)
    errorFormLayout.addRow(self.errorZLabel, self.errorZValueLabel)

    #
    # Export Area
    #
    exportCollapsibleButton = ctk.ctkCollapsibleButton()
    exportCollapsibleButton.text = "Export"
    self.layout.addWidget(exportCollapsibleButton)
    exportFormLayout = qt.QFormLayout(exportCollapsibleButton)

    # ROI selector
    self.exportRoiSelectorLabel = qt.QLabel()
    self.exportRoiSelectorLabel.setText( "Region of interest: " )
    self.exportRoiSelector = slicer.qMRMLNodeComboBox()
    self.exportRoiSelector.nodeTypes = ( "vtkMRMLAnnotationROINode", "" )
    self.exportRoiSelector.noneEnabled = False
    self.exportRoiSelector.addEnabled = False
    self.exportRoiSelector.removeEnabled = True
    self.exportRoiSelector.setMRMLScene( slicer.mrmlScene )
    self.exportRoiSelector.setToolTip( "Pick the input region of interest for export" )
    exportFormLayout.addRow(self.exportRoiSelectorLabel, self.exportRoiSelector)

    # Export button
    self.exportButton = qt.QPushButton("Export")
    self.exportButton.toolTip = "Export the transform in the selected region of interest to a vector volume"
    self.exportButton.enabled = True
    exportFormLayout.addRow(self.exportButton)
    self.exportButton.connect('clicked(bool)', self.onExport)

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

        # Instantiate and connect widgets ...

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

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

        self.inputDirSelector = ctk.ctkPathLineEdit()
        self.inputDirSelector.filters = ctk.ctkPathLineEdit.Dirs
        self.inputDirSelector.settingKey = 'DICOMPatcherInputDir'
        parametersFormLayout.addRow("Input DICOM directory:",
                                    self.inputDirSelector)

        self.outputDirSelector = ctk.ctkPathLineEdit()
        self.outputDirSelector.filters = ctk.ctkPathLineEdit.Dirs
        self.outputDirSelector.settingKey = 'DICOMPatcherOutputDir'
        parametersFormLayout.addRow("Output DICOM directory:",
                                    self.outputDirSelector)

        self.normalizeFileNamesCheckBox = qt.QCheckBox()
        self.normalizeFileNamesCheckBox.checked = True
        self.normalizeFileNamesCheckBox.setToolTip(
            "Replace file and folder names with automatically generated names."
            " Fixes errors caused by file path containins special characters or being too long."
        )
        parametersFormLayout.addRow("Normalize file names",
                                    self.normalizeFileNamesCheckBox)

        self.forceSamePatientNameIdInEachDirectoryCheckBox = qt.QCheckBox()
        self.forceSamePatientNameIdInEachDirectoryCheckBox.checked = False
        self.forceSamePatientNameIdInEachDirectoryCheckBox.setToolTip(
            "Generate patient name and ID from the first file in a directory"
            " and force all other files in the same directory to have the same patient name and ID."
            " Enable this option if a separate patient directory is created for each patched file."
        )
        parametersFormLayout.addRow(
            "Force same patient name and ID in each directory",
            self.forceSamePatientNameIdInEachDirectoryCheckBox)

        self.generateMissingIdsCheckBox = qt.QCheckBox()
        self.generateMissingIdsCheckBox.checked = True
        self.generateMissingIdsCheckBox.setToolTip(
            "Generate missing patient, study, series IDs. It is assumed that"
            " all files in a directory belong to the same series. Fixes error caused by too aggressive anonymization"
            " or incorrect DICOM image converters.")
        parametersFormLayout.addRow(
            "Generate missing patient/study/series IDs",
            self.generateMissingIdsCheckBox)

        self.generateImagePositionFromSliceThicknessCheckBox = qt.QCheckBox()
        self.generateImagePositionFromSliceThicknessCheckBox.checked = True
        self.generateImagePositionFromSliceThicknessCheckBox.setToolTip(
            "Generate 'image position sequence' for"
            " multi-frame files that only have 'SliceThickness' field. Fixes error in Dolphin 3D CBCT scanners."
        )
        parametersFormLayout.addRow(
            "Generate slice position for multi-frame volumes",
            self.generateImagePositionFromSliceThicknessCheckBox)

        self.anonymizeDicomCheckBox = qt.QCheckBox()
        self.anonymizeDicomCheckBox.checked = False
        self.anonymizeDicomCheckBox.setToolTip(
            "If checked, then some patient identifiable information will be removed"
            " from the patched DICOM files. There are many fields that can identify a patient, this function does not remove all of them."
        )
        parametersFormLayout.addRow("Partially anonymize",
                                    self.anonymizeDicomCheckBox)

        #
        # Patch Button
        #
        self.patchButton = qt.QPushButton("Patch")
        self.patchButton.toolTip = "Fix DICOM files in input directory and write them to output directory"
        parametersFormLayout.addRow(self.patchButton)

        #
        # Import Button
        #
        self.importButton = qt.QPushButton("Import")
        self.importButton.toolTip = "Import DICOM files in output directory into Slicer DICOM database"
        parametersFormLayout.addRow(self.importButton)

        #
        # Switch to DICOM module Button
        #
        self.switchToDICOMModuleButton = qt.QPushButton("Go to DICOM module")
        self.switchToDICOMModuleButton.toolTip = "Open DICOM module where imported data can be loaded into the scene"
        parametersFormLayout.addRow(self.switchToDICOMModuleButton)

        # connections
        self.patchButton.connect('clicked(bool)', self.onPatchButton)
        self.importButton.connect('clicked(bool)', self.onImportButton)
        self.switchToDICOMModuleButton.connect(
            'clicked(bool)', self.onSwitchToDICOMModuleButton)

        self.statusLabel = qt.QPlainTextEdit()
        self.statusLabel.setTextInteractionFlags(qt.Qt.TextSelectableByMouse)
        parametersFormLayout.addRow(self.statusLabel)

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

        self.logic = DICOMPatcherLogic()
        self.logic.logCallback = self.addLog
Beispiel #23
0
    def create(self):
        """create the segmentation helper box"""

        #
        # Master Frame
        #
        self.masterFrame = qt.QFrame(self.parent)
        self.masterFrame.setLayout(qt.QVBoxLayout())
        self.parent.layout().addWidget(self.masterFrame)

        #
        # the master volume selector
        #
        self.masterSelectorFrame = qt.QFrame(self.parent)
        self.masterSelectorFrame.objectName = 'MasterVolumeFrame'
        self.masterSelectorFrame.setLayout(qt.QHBoxLayout())
        self.masterFrame.layout().addWidget(self.masterSelectorFrame)

        self.masterSelectorLabel = qt.QLabel("Master Volume: ",
                                             self.masterSelectorFrame)
        self.masterSelectorLabel.setToolTip(
            "Select the master volume (background grayscale scalar volume node)"
        )
        self.masterSelectorFrame.layout().addWidget(self.masterSelectorLabel)

        self.masterSelector = slicer.qMRMLNodeComboBox(
            self.masterSelectorFrame)
        self.masterSelector.objectName = 'MasterVolumeNodeSelector'
        # TODO
        self.masterSelector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "")
        self.masterSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap",
                                         0)
        self.masterSelector.selectNodeUponCreation = False
        self.masterSelector.addEnabled = False
        self.masterSelector.removeEnabled = False
        self.masterSelector.noneEnabled = True
        self.masterSelector.showHidden = False
        self.masterSelector.showChildNodeTypes = False
        self.masterSelector.setMRMLScene(slicer.mrmlScene)
        # TODO: need to add a QLabel
        # self.masterSelector.SetLabelText( "Master Volume:" )
        self.masterSelector.setToolTip(
            "Pick the master structural volume to define the segmentation.  A label volume with the with \"-label\" appended to the name will be created if it doesn't already exist."
        )
        self.masterSelectorFrame.layout().addWidget(self.masterSelector)

        #
        # merge label name and set button
        #
        self.mergeFrame = qt.QFrame(self.masterFrame)
        self.mergeFrame.objectName = 'MergeVolumeFrame'
        self.mergeFrame.setLayout(qt.QHBoxLayout())
        self.masterFrame.layout().addWidget(self.mergeFrame)

        mergeNameToolTip = "Composite label map containing the merged structures (be aware that merge operations will overwrite any edits applied to this volume)"
        self.mergeNameLabel = qt.QLabel("Merge Volume: ", self.mergeFrame)
        self.mergeNameLabel.setToolTip(mergeNameToolTip)
        self.mergeFrame.layout().addWidget(self.mergeNameLabel)

        self.mergeName = qt.QLabel("", self.mergeFrame)
        self.mergeName.setToolTip(mergeNameToolTip)
        self.mergeFrame.layout().addWidget(self.mergeName)

        self.setMergeButton = qt.QPushButton("Set...", self.mergeFrame)
        self.setMergeButton.objectName = 'MergeVolumeButton'
        self.setMergeButton.setToolTip(
            "Set the merge volume to use with this master.")
        self.mergeFrame.layout().addWidget(self.setMergeButton)

        #
        # Structures Frame
        #

        self.structuresFrame = ctk.ctkCollapsibleGroupBox(self.masterFrame)
        self.structuresFrame.objectName = 'PerStructureVolumesFrame'
        self.structuresFrame.title = "Per-Structure Volumes"
        self.structuresFrame.collapsed = True
        self.structuresFrame.setLayout(qt.QVBoxLayout())
        self.masterFrame.layout().addWidget(self.structuresFrame)

        # buttons frame

        self.structureButtonsFrame = qt.QFrame(self.structuresFrame)
        self.structureButtonsFrame.objectName = 'ButtonsFrame'
        self.structureButtonsFrame.setLayout(qt.QHBoxLayout())
        self.structuresFrame.layout().addWidget(self.structureButtonsFrame)

        # add button

        self.addStructureButton = qt.QPushButton("Add Structure",
                                                 self.structureButtonsFrame)
        self.addStructureButton.objectName = 'AddStructureButton'
        self.addStructureButton.setToolTip(
            "Add a label volume for a structure to edit")
        self.structureButtonsFrame.layout().addWidget(self.addStructureButton)

        # split button

        self.splitButton = qt.QPushButton("Split Merge Volume",
                                          self.structuresFrame)
        self.splitButton.objectName = 'SplitStructureButton'
        self.splitButton.setToolTip(
            "Split distinct labels from merge volume into new volumes")
        self.structureButtonsFrame.layout().addWidget(self.splitButton)

        # structures view

        self.structuresView = qt.QTreeView()
        self.structuresView.objectName = 'StructuresView'
        self.structuresView.sortingEnabled = True
        self.structuresFrame.layout().addWidget(self.structuresView)

        # all buttons frame

        self.allButtonsFrame = qt.QFrame(self.structuresFrame)
        self.allButtonsFrame.objectName = 'AllButtonsFrameButton'
        self.allButtonsFrame.setLayout(qt.QHBoxLayout())
        self.structuresFrame.layout().addWidget(self.allButtonsFrame)

        # delete structures button

        self.deleteStructuresButton = qt.QPushButton("Delete Structures",
                                                     self.allButtonsFrame)
        self.deleteStructuresButton.objectName = 'DeleteStructureButton'
        self.deleteStructuresButton.setToolTip(
            "Delete all the structure volumes from the scene.\n\nNote: to delete individual structure volumes, use the Data Module."
        )
        self.allButtonsFrame.layout().addWidget(self.deleteStructuresButton)

        # merge button

        self.mergeButton = qt.QPushButton("Merge All", self.allButtonsFrame)
        self.mergeButton.objectName = 'MergeAllStructuresButton'
        self.mergeButton.setToolTip("Merge all structures into Merge Volume")
        self.allButtonsFrame.layout().addWidget(self.mergeButton)

        # merge and build button

        self.mergeAndBuildButton = qt.QPushButton("Merge And Build",
                                                  self.allButtonsFrame)
        self.mergeAndBuildButton.objectName = 'MergeStructuresAndBuildModelsButton'
        self.mergeAndBuildButton.setToolTip(
            "Merge all structures into Merge Volume and build models from all structures"
        )
        self.allButtonsFrame.layout().addWidget(self.mergeAndBuildButton)
        # options frame

        self.optionsFrame = qt.QFrame(self.structuresFrame)
        self.optionsFrame.objectName = 'OptionsFrame'
        self.optionsFrame.setLayout(qt.QHBoxLayout())
        self.structuresFrame.layout().addWidget(self.optionsFrame)

        # replace models button

        self.replaceModels = qt.QCheckBox("Replace Models", self.optionsFrame)
        self.replaceModels.objectName = 'ReplaceModelsCheckBox'
        self.replaceModels.setToolTip(
            "Replace any existing models when building")
        self.replaceModels.setChecked(1)
        self.optionsFrame.layout().addWidget(self.replaceModels)

        #
        # signals, slots, and observers
        #

        # signals/slots on qt widgets are automatically when
        # this class destructs, but observers of the scene must be explicitly
        # removed in the destuctor

        # node selected
        self.masterSelector.connect("currentNodeChanged(vtkMRMLNode*)",
                                    self.onSelect)
        # buttons pressed
        self.addStructureButton.connect("clicked()", self.addStructure)
        self.deleteStructuresButton.connect("clicked()", self.deleteStructures)
        # selection changed event
        # invoked event
        self.splitButton.connect("clicked()", self.split)
        self.mergeButton.connect("clicked()", self.mergeStructures)
        self.mergeAndBuildButton.connect("clicked()", self.onMergeAndBuild)
        self.setMergeButton.connect("clicked()", self.labelSelectDialog)

        # so buttons will initially be disabled
        self.master = None
        self.updateStructures()
Beispiel #24
0
    def setup(self):
        # Instantiate and connect widgets ...

        #
        # Reload and Test area
        #
        reloadCollapsibleButton = ctk.ctkCollapsibleButton()
        reloadCollapsibleButton.text = "Reload && Test"
        self.layout.addWidget(reloadCollapsibleButton)
        reloadFormLayout = qt.QFormLayout(reloadCollapsibleButton)

        # reload button
        # (use this during development, but remove it when delivering
        #  your module to users)
        self.reloadButton = qt.QPushButton("Reload")
        self.reloadButton.toolTip = "Reload this module."
        self.reloadButton.name = "NeurosurgicalPlanningTutorialMarkupsSelfTest Reload"
        reloadFormLayout.addWidget(self.reloadButton)
        self.reloadButton.connect('clicked()', self.onReload)

        # reload and test button
        # (use this during development, but remove it when delivering
        #  your module to users)
        self.reloadAndTestButton = qt.QPushButton("Reload and Test")
        self.reloadAndTestButton.toolTip = "Reload this module and then run the self tests."
        reloadFormLayout.addWidget(self.reloadAndTestButton)
        self.reloadAndTestButton.connect('clicked()', self.onReloadAndTest)

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

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

        #
        # check box to trigger taking screen shots for later use in tutorials
        #
        self.enableScreenshotsFlagCheckBox = qt.QCheckBox()
        self.enableScreenshotsFlagCheckBox.checked = 0
        self.enableScreenshotsFlagCheckBox.setToolTip(
            "If checked, take screen shots for tutorials. Use Save Data to write them to disk."
        )
        parametersFormLayout.addRow("Enable Screenshots",
                                    self.enableScreenshotsFlagCheckBox)

        #
        # scale factor for screen shots
        #
        self.screenshotScaleFactorSliderWidget = ctk.ctkSliderWidget()
        self.screenshotScaleFactorSliderWidget.singleStep = 1.0
        self.screenshotScaleFactorSliderWidget.minimum = 1.0
        self.screenshotScaleFactorSliderWidget.maximum = 50.0
        self.screenshotScaleFactorSliderWidget.value = 1.0
        self.screenshotScaleFactorSliderWidget.setToolTip(
            "Set scale factor for the screen shots.")
        parametersFormLayout.addRow("Screenshot scale factor",
                                    self.screenshotScaleFactorSliderWidget)

        # Apply Button
        #
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Run the algorithm."
        self.applyButton.enabled = True
        parametersFormLayout.addRow(self.applyButton)

        # connections
        self.applyButton.connect('clicked(bool)', self.onApplyButton)

        # Add vertical spacer
        self.layout.addStretch(1)
Beispiel #25
0
    def create(self, widgetType='window', showHeader=False, showPreview=False):
        """
    main window is a frame with widgets from the app
    widget repacked into it along with slicer-specific 
    extra widgets
    """

        # find internals of widget for reference and repacking
        self.toolBar = slicer.util.findChildren(self.dicomApp, 'ToolBar')[0]
        self.databaseNameLabel = slicer.util.findChildren(
            self.dicomApp, 'DatabaseNameLabel')[0]
        self.databaseDirectoryButton = slicer.util.findChildren(
            self.dicomApp, 'DirectoryButton')[0]
        self.tree = slicer.util.findChildren(self.dicomApp, 'TreeView')[0]
        self.userFrame = slicer.util.findChildren(self.dicomApp,
                                                  'UserFrame')[0]
        self.thumbs = slicer.util.findChildren(self.dicomApp,
                                               'ThumbnailsWidget')[0]
        self.widthSlider = slicer.util.findChildren(self.dicomApp,
                                                    'ThumbnailWidthSlider')[0]
        self.preview = slicer.util.findChildren(self.dicomApp,
                                                'PreviewFrame')[0]

        self.widgetType = widgetType
        if widgetType == 'dialog':
            self.window = qt.QDialog(self.dicomApp)
        elif widgetType == 'window':
            self.window = qt.QWidget()
        elif widgetType == 'popup':
            self.window = ctk.ctkPopupWidget(self.dicomApp)
            self.window.orientation = 1
            self.window.horizontalDirection = 0
            self.window.alignment = 0x82
        elif widgetType == 'dock':
            self.dock = qt.QDockWidget(slicer.util.mainWindow())
            self.dock.setFeatures(qt.QDockWidget.DockWidgetFloatable
                                  | qt.QDockWidget.DockWidgetMovable
                                  | qt.QDockWidget.DockWidgetClosable)
            slicer.util.mainWindow().addDockWidget(0x15, self.dock)
            self.window = qt.QFrame()
            self.dock.setWidget(self.window)
        else:
            raise "Unknown widget type - should be dialog, window, dock or popup"

        self.window.setWindowTitle('DICOM Details')

        self.layout = qt.QGridLayout()
        self.window.setLayout(self.layout)

        # overall layout - tree on top, preview and selection below
        toolRow = 0
        treeRow = 1
        selectionRow = 2

        # tool row at top, with commands and database
        self.toolLayout = qt.QHBoxLayout()
        self.layout.addLayout(self.toolLayout, toolRow, 0, 1, 2)
        self.toolLayout.addWidget(self.toolBar)
        self.toolLayout.addWidget(self.databaseNameLabel)
        self.toolLayout.addWidget(self.databaseDirectoryButton)

        # tree goes next, spread across 1 row, 2 columns
        self.layout.addWidget(self.tree, treeRow, 0, 1, 2)

        #
        # preview related column
        #
        self.previewLayout = qt.QVBoxLayout()
        self.layout.addLayout(self.previewLayout, selectionRow, 0)

        self.previewLayout.addWidget(self.thumbs)
        self.previewLayout.addWidget(self.widthSlider)
        if showPreview:
            self.previewLayout.addWidget(self.preview)
        else:
            self.preview.hide()

        #
        # action related column (interacting with slicer)
        #
        self.actionLayout = qt.QVBoxLayout()
        self.layout.addLayout(self.actionLayout, selectionRow, 1)
        self.actionLayout.addWidget(self.userFrame)

        tableWidth = 350 if showHeader else 700
        self.loadableTable = DICOMLoadableTable(self.userFrame,
                                                width=tableWidth)
        self.actionLayout.addWidget(self.loadableTable.widget)

        #
        # button row for action column
        #
        self.actionButtonLayout = qt.QHBoxLayout()
        self.actionLayout.addLayout(self.actionButtonLayout)

        self.uncheckAllButton = qt.QPushButton('Uncheck All')
        self.actionButtonLayout.addWidget(self.uncheckAllButton)
        self.uncheckAllButton.connect('clicked()', self.uncheckAllLoadables)

        self.loadButton = qt.QPushButton('Load Selection to Slicer')
        self.loadButton.enabled = False
        self.actionButtonLayout.addWidget(self.loadButton)
        self.loadButton.connect('clicked()', self.loadCheckedLoadables)

        self.closeButton = qt.QPushButton('Close')
        self.actionButtonLayout.addWidget(self.closeButton)
        self.closeButton.connect('clicked()', self.close)

        if self.setBrowserPersistence:
            self.browserPersistentButton = qt.QCheckBox(
                'Make DICOM Browser Persistent')
            self.browserPersistentButton.toolTip = 'When enabled, DICOM Broswer remains open and usable after leaving DICOM module'
            self.actionLayout.addWidget(self.browserPersistentButton)
            self.browserPersistentButton.connect('stateChanged(int)',
                                                 self.setBrowserPersistence)

        #
        # header related column (more details about the selected file)
        #
        if showHeader:
            self.headerLayout = qt.QVBoxLayout()
            self.layout.addLayout(self.headerLayout, selectionRow, 2)
            self.header = DICOMHeaderWidget(self.window)
            self.headerLayout.addWidget(self.header.widget)
Beispiel #26
0
  def setup(self):
    """Init the widget """
    # ScriptedLoadableModuleWidget.setup(self)
         
    settings = qt.QSettings()

    if (SlicerUtil.IsDevelopment):
      # reload button      
      self.reloadButton = qt.QPushButton("Reload")
      self.reloadButton.toolTip = "Reload this module."
      self.reloadButton.name = "Reload"
      self.layout.addWidget(self.reloadButton)      
      self.reloadButton.connect('clicked()', self.onBtnReloadClicked)  
    
    self.logic = PicasaSnapLogic()    
    self.__addObservers__()
   
    ######## Credentials
    self.credentialsCollapsibleButton = ctk.ctkCollapsibleButton()
    self.credentialsCollapsibleButton.text = "Credentials"
    self.layout.addWidget(self.credentialsCollapsibleButton)    
    self.credentialsLayout = qt.QFormLayout(self.credentialsCollapsibleButton)
    
    self.isUserLogged = False
    
    self.loginLineEdit = qt.QLineEdit()
    self.credentialsLayout.addRow("Login:   "******"Password:   "******"Remember my credentials")
    self.rememberCredentialsCheckBox.toolTip = "Check for an automatic login when the application starts"
    self.loginButton = qt.QPushButton("Login")        
    self.loginButton.toolTip = "Login in Picassa service (Google credentials)"    
    self.logoutButton = qt.QPushButton("Logout")        
    self.logoutButton.toolTip = "Logout to connect with another user's credentials"   
    # Add all the items, they will be shown/hidden in refreshCredentialsUI function
    self.credentialsLayout.addRow(self.rememberCredentialsCheckBox, self.loginButton)
    self.credentialsLayout.addRow(None, self.logoutButton)   
    
    ######## Snapshots (main frame)
    self.mainCollapsibleButton = ctk.ctkCollapsibleButton()
    self.mainCollapsibleButton.text = "Snapshots"
    self.layout.addWidget(self.mainCollapsibleButton)    
    self.mainLayout = qt.QVBoxLayout(self.mainCollapsibleButton)
         
    ############### Current snapshots
    self.currentSnapshotsFrame = qt.QFrame()
    self.currentSnapshotsLayout = qt.QVBoxLayout()
    self.currentSnapshotsFrame.setLayout(self.currentSnapshotsLayout)
    self.currentSnapshotsFrame.setFrameShape(qt.QFrame.StyledPanel)
    self.mainLayout.addWidget(self.currentSnapshotsFrame)
      
    self.snapshotsLabel = qt.QLabel("Snapshots to upload:")
    self.snapshotsLabel.setStyleSheet("font-weight:bold; font-size:14px; margin-bottom:10px")
    self.currentSnapshotsLayout.addWidget(self.snapshotsLabel)
    
    # Subframe that contains the checkbox list
    self.currentSnapshotsInnerFrame = qt.QFrame()
    self.currentSnapshotsInnerLayout = qt.QVBoxLayout()
    self.currentSnapshotsInnerFrame.setLayout(self.currentSnapshotsInnerLayout)
    self.currentSnapshotsLayout.addWidget(self.currentSnapshotsInnerFrame)
    
    
    self.noItemsLabel = qt.QLabel("(There are not any snapshots at the moment)")
    # Add the label by default. It will be hidden if there is any snapshot
    self.currentSnapshotsInnerLayout.addWidget(self.noItemsLabel)
    
    self.loadExistingSnapshotsFirstLoad()
    
    ############### Albums
    # Try to login before getting the albums
    self.login()
    
    msgBox = None
    if self.isUserLogged:
      # Show message box while loading the data
      msgBox = qt.QMessageBox(qt.QMessageBox.Information, 'Login','Connecting with Picasa. Please wait...', qt.QMessageBox.Cancel)
      msgBox.show()
    
    try:
      self.albumNameFrame = qt.QFrame()
      self.albumNameLayout = qt.QHBoxLayout()
      self.albumNameFrame.setLayout(self.albumNameLayout)
      self.albumNameFrame.setFrameShape(qt.QFrame.StyledPanel)    
      
      self.albumNameLabel = qt.QLabel("Album name:")    
      self.albumNameLabel.setStyleSheet("font-weight:bold;")
      self.albumNamesComboBox = qt.QComboBox()
      self.loadAlbums()
      self.albumNameLayout.addWidget(self.albumNameLabel)
      self.albumNameLayout.addWidget(self.albumNamesComboBox)
      self.mainLayout.addWidget(self.albumNameFrame)
      
      ############### Tags
      self.tagsFrame = qt.QFrame()
      self.tagsLayout = qt.QGridLayout()
      self.tagsFrame.setLayout(self.tagsLayout)
      self.tagsFrame.setFrameShape(qt.QFrame.StyledPanel)
       
      self.tagsLabel = qt.QLabel("Tags (select all that apply, you can filter o create new tags):")
      self.tagsLabel.setStyleSheet("font-weight: bold; margin-bottom: 10px; margin-top: 5px")
      self.tagsLayout.addWidget(self.tagsLabel, 0, 0, 1, 3)
      
      # Add input to filter tags and button to add a new one
      self.tagsFilterLineEdit = qt.QLineEdit()
      self.tagsFilterLineEdit.toolTip = "Type here to filter your tags. If you press the return key all the visible tags will be checked"
      #self.tagsFilterLineEdit.setStyleSheet(style)
      self.tagsLayout.addWidget(self.tagsFilterLineEdit, 1, 0, 1, 2)
      self.newTagButton = qt.QPushButton("New tag")
      #self.newTagButton.setStyleSheet("background-color: #5D74C6; color:white")
      self.newTagButton.setIconSize(qt.QSize(20,20))
      self.newTagButton.setIcon(qt.QIcon(self.CIP_ICON_DIR + "/Plus - 48.png"))
      self.newTagButton.setFixedWidth(75)
      self.newTagButton.toolTip = "Add a new tag (the tag will not be created until you upload any picture with it)"
      self.tagsLayout.addWidget(self.newTagButton, 1, 2)
        
      self.loadTags()
      
      ############### Upload snapshots controls    
      self.uploadSnapsButtonFrame = qt.QFrame()
      self.uploadSnapsLayout = qt.QHBoxLayout()
      self.uploadSnapsButtonFrame.setLayout(self.uploadSnapsLayout)
      #self(qt.QFrame.HLine)
      self.mainLayout.addWidget(self.uploadSnapsButtonFrame)
      
      self.uploadSnapshotsButton = qt.QPushButton()
      self.uploadSnapshotsButton.text = "Upload to Picasa!"        
      self.uploadSnapshotsButton.toolTip = "Upload selected screenshots to Picassa"      
      self.uploadSnapshotsButton.setStyleSheet("background-color: #5D74C6; color: white; font-weight: bold; font-size:14px")
      self.uploadSnapshotsButton.setIcon(qt.QIcon(self.CIP_ICON_DIR + "/Upload - 64.png"))
      self.uploadSnapshotsButton.setIconSize(qt.QSize(24,24))   
      self.uploadSnapshotsButton.setFixedSize(170, 35)
      self.uploadSnapsLayout.addWidget(self.uploadSnapshotsButton)
      
      ############### Progress bar     
      self.progressBar = qt.QProgressDialog()
      self.progressBar.setMinimum(0)
      self.progressBar.setMinimumDuration(0)
      self.progressBar.setWindowModality(True)

      # Check for updates in CIP
      #autoUpdate = SlicerUtil.settingGetOrSetDefault("PicasaSnap", "AutoUpdate", 1)
      #uw = AutoUpdateWidget(parent=self.parent, autoUpdate=autoUpdate)
      #uw.addAutoUpdateCheckObserver(self.onAutoUpdateStateChanged)

#     self.uploadProgressFrame = qt.QFrame()
#     self.uploadProgressLayout = qt.QVBoxLayout()
#     self.uploadProgressFrame.setLayout(self.uploadProgressLayout)
#        
#     # Gif image   
#     self.imUploading = qt.QMovie("%s/loading.gif" % self.CIP_ICON_DIR, qt.QByteArray())
#     # Label to contain the gif
#     self.lblImLoading = qt.QLabel()
#     # Fix the dimensions of the image (by fixing the dimensions of the label that contains it)
#     self.lblImLoading.setFixedWidth(40)
#     # Other image parameters
#     self.imUploading.setCacheMode(qt.QMovie.CacheAll)
#     self.imUploading.setSpeed(100)
#     # Assign the label to the image (don't start it yet, it will be started when we are uploading)
#     self.lblImLoading.setMovie(self.imUploading)
#     #self.imUploading.start()
#     self.uploadProgressLayout.addWidget(self.lblImLoading)
#     
#     # Label that will show the progress
#     self.lblUploading = qt.QLabel("Uploading %i/%i images...")
#     self.uploadProgressLayout.addWidget(self.lblUploading)
#  
    # Cancel uploading button
#     self.btnCancelUpload = qt.QPushButton("Cancel")        
#     self.btnCancelUpload.toolTip = "Cancel the process"
#     self.btnCancelUpload.setFixedWidth(100)
#     self.uploadProgressLayout.addWidget(self.btnCancelUpload)    
#     self.mainLayout.addWidget(self.uploadProgressFrame)
#      
#     # Hide the progress frame
#     self.uploadProgressFrame.hide() 
     
      ######## Connections
      self.uploadSnapshotsButton.connect('clicked (bool)', self.onUploadSnapshotsButtonClicked)
      self.loginButton.connect('clicked (bool)', self.onLoginButtonClicked)
      self.logoutButton.connect('clicked (bool)', self.onLogoutButtonClicked)
      self.loginLineEdit.returnPressed.connect(self.onLoginPasswordReturnKeyPressed)
      self.passwordLineEdit.returnPressed.connect(self.onLoginPasswordReturnKeyPressed)
      self.albumNamesComboBox.connect("currentIndexChanged (int)", self.onAlbumsCurrentIndexChanged)
      self.newTagButton.connect('clicked (bool)', self.onNewTagButtonClicked)
      self.tagsFilterLineEdit.connect('textEdited (QString)', self.onFilterTagsEdited)
      self.tagsFilterLineEdit.returnPressed.connect(self.onFilterTagsReturnKeyPressed)
      
      # Add vertical spacer
      self.layout.addStretch(1)   
    finally:         
      # Hide MesageBox if it was visible
      if msgBox:
        msgBox.close()
Beispiel #27
0
    def createUserInterface(self):
        self.__layout = self.__parent.createUserInterface()

        self.__previewWindow = ctk.ctkVTKSliceView()

        self.__previewHLayout = qt.QHBoxLayout()
        self.__previewHLayout.addWidget(self.__previewWindow)
        self.__spaceLabel = qt.QLabel("                                    ")
        self.__previewHLayout.addWidget(self.__spaceLabel)
        self.__spaceLabel2 = qt.QLabel("                                   ")
        self.__previewHLayout.addWidget(self.__spaceLabel2)
        self.__layout.addRow(self.__previewHLayout)

        # Frame slider
        #    self.frameSlider = ctk.ctkSliderWidget()
        #   frameSlider.connect('valueChanged(double)', self.frameSliderValueChanged)
        #    self.frameSlider.decimals = 0
        #    self.__layout.addRow("Preview for one Slicer: ", self.frameSlider)

        self.__ioAdvancedToggle = qt.QCheckBox("Show Advanced")
        self.__ioAdvancedToggle.setChecked(False)
        self.__layout.addRow(self.__ioAdvancedToggle)

        #
        # I/O advanced panel
        #
        self.__ioAdvancedPanel = qt.QFrame(self)
        self.__ioAdvancedPanel.hide()
        print "testss"
        self.__ioAdvancedPanel.setFrameStyle(6)
        self.__layout.addRow(self.__ioAdvancedPanel)
        self.__ioAdvancedToggle.connect("clicked()", self.onIOAdvancedToggle)

        ioAdvancedFormLayout = qt.QFormLayout(self.__ioAdvancedPanel)

        # Frame delay slider
        self.frameDelaySlider = ctk.ctkRangeWidget()
        # frameDelaySlider.connect('valueChanged(double)', self.frameDelaySliderValueChanged)
        self.frameDelaySlider.decimals = 0
        self.frameDelaySlider.minimum = 1
        self.frameDelaySlider.maximum = 70
        self.frameDelaySlider.minimumValue = 5
        self.frameDelaySlider.maximumValue = 20
        self.frameDelaySlider.suffix = " vx"
        #    self.frameDelaySlider.value = 20
        ioAdvancedFormLayout.addRow("Diameters [Min-Max]: ",
                                    self.frameDelaySlider)

        # Frame delay slider
        self.frameDelaySlider = ctk.ctkSliderWidget()
        # frameDelaySlider.connect('valueChanged(double)', self.frameDelaySliderValueChanged)
        self.frameDelaySlider.decimals = 0
        self.frameDelaySlider.minimum = 5
        self.frameDelaySlider.maximum = 100
        self.frameDelaySlider.value = 20
        ioAdvancedFormLayout.addRow("Input Contrast: ", self.frameDelaySlider)

        self.__previewButton = qt.QPushButton()
        self.__previewButton.text = "Update preview"
        #    self.__inputVolumeNodeSelector.setMRMLScene(slicer.mrmlScene)

        self.__previewButtonHLayout = qt.QHBoxLayout()
        self.__spaceLabel2 = qt.QLabel("                                   ")
        self.__previewButtonHLayout.addWidget(self.__spaceLabel2)
        self.__spaceLabel = qt.QLabel("                                    ")
        self.__previewButtonHLayout.addWidget(self.__spaceLabel)
        self.__previewButtonHLayout.addWidget(self.__previewButton)
        self.__layout.addRow(self.__previewButtonHLayout)
        self.__previewButton.connect("clicked()", self.updatePreview)
Beispiel #28
0
    def setup(self):
        #
        # the grayscale volume selector
        #
        self.grayscaleSelectorFrame = qt.QFrame(self.parent)
        self.grayscaleSelectorFrame.setLayout(qt.QHBoxLayout())
        self.parent.layout().addWidget(self.grayscaleSelectorFrame)

        self.grayscaleSelectorLabel = qt.QLabel("Grayscale Volume: ",
                                                self.grayscaleSelectorFrame)
        self.grayscaleSelectorLabel.setToolTip(
            "Select the grayscale volume (background grayscale scalar volume node) for statistics calculations"
        )
        self.grayscaleSelectorFrame.layout().addWidget(
            self.grayscaleSelectorLabel)

        self.grayscaleSelector = slicer.qMRMLNodeComboBox(
            self.grayscaleSelectorFrame)
        self.grayscaleSelector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "")
        self.grayscaleSelector.addAttribute("vtkMRMLScalarVolumeNode",
                                            "LabelMap", 0)
        self.grayscaleSelector.selectNodeUponCreation = False
        self.grayscaleSelector.addEnabled = False
        self.grayscaleSelector.removeEnabled = False
        self.grayscaleSelector.noneEnabled = True
        self.grayscaleSelector.showHidden = False
        self.grayscaleSelector.showChildNodeTypes = False
        self.grayscaleSelector.setMRMLScene(slicer.mrmlScene)
        # TODO: need to add a QLabel
        # self.grayscaleSelector.SetLabelText( "Master Volume:" )
        self.grayscaleSelectorFrame.layout().addWidget(self.grayscaleSelector)

        #
        # the label volume selector
        #
        self.labelSelectorFrame = qt.QFrame()
        self.labelSelectorFrame.setLayout(qt.QHBoxLayout())
        self.parent.layout().addWidget(self.labelSelectorFrame)

        self.labelSelectorLabel = qt.QLabel()
        self.labelSelectorLabel.setText("Label Map: ")
        self.labelSelectorFrame.layout().addWidget(self.labelSelectorLabel)

        self.labelSelector = slicer.qMRMLNodeComboBox()
        self.labelSelector.nodeTypes = ("vtkMRMLScalarVolumeNode", "")
        self.labelSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap",
                                        "1")
        # todo addAttribute
        self.labelSelector.selectNodeUponCreation = False
        self.labelSelector.addEnabled = False
        self.labelSelector.noneEnabled = True
        self.labelSelector.removeEnabled = False
        self.labelSelector.showHidden = False
        self.labelSelector.showChildNodeTypes = False
        self.labelSelector.setMRMLScene(slicer.mrmlScene)
        self.labelSelector.setToolTip("Pick the label map to edit")
        self.labelSelectorFrame.layout().addWidget(self.labelSelector)

        # Apply button
        self.applyButton = qt.QPushButton("Apply")
        self.applyButton.toolTip = "Calculate Statistics."
        self.applyButton.enabled = False
        self.parent.layout().addWidget(self.applyButton)

        # model and view for stats table
        self.view = qt.QTableView()
        self.view.sortingEnabled = True
        self.parent.layout().addWidget(self.view)

        # Chart button
        self.chartFrame = qt.QFrame()
        self.chartFrame.setLayout(qt.QHBoxLayout())
        self.parent.layout().addWidget(self.chartFrame)
        self.chartButton = qt.QPushButton("Chart")
        self.chartButton.toolTip = "Make a chart from the current statistics."
        self.chartFrame.layout().addWidget(self.chartButton)
        self.chartOption = qt.QComboBox()
        self.chartOption.addItems(self.chartOptions)
        self.chartFrame.layout().addWidget(self.chartOption)
        self.chartIgnoreZero = qt.QCheckBox()
        self.chartIgnoreZero.setText('Ignore Zero')
        self.chartIgnoreZero.checked = False
        self.chartIgnoreZero.setToolTip(
            'Do not include the zero index in the chart to avoid dwarfing other bars'
        )
        self.chartFrame.layout().addWidget(self.chartIgnoreZero)
        self.chartFrame.enabled = False

        # Save button
        self.saveButton = qt.QPushButton("Save")
        self.saveButton.toolTip = "Calculate Statistics."
        self.saveButton.enabled = False
        self.parent.layout().addWidget(self.saveButton)

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

        # connections
        self.applyButton.connect('clicked()', self.onApply)
        self.chartButton.connect('clicked()', self.onChart)
        self.saveButton.connect('clicked()', self.onSave)
        self.grayscaleSelector.connect('currentNodeChanged(vtkMRMLNode*)',
                                       self.onGrayscaleSelect)
        self.labelSelector.connect('currentNodeChanged(vtkMRMLNode*)',
                                   self.onLabelSelect)
Beispiel #29
0
    def setup(self):
        """This is called one time when the module GUI is initialized
        """
        # Declare ALL the GUI components (depending on the context we will add different ones to the layout)
        self.widgetMainFrame = qt.QFrame()
        self.widgetMainLayout = qt.QGridLayout()
        self.widgetMainFrame.setLayout(self.widgetMainLayout)
        self.layout.addWidget(self.widgetMainFrame)

        ## Context
        self.contextLabel = qt.QLabel("Context")
        self.contextComboBox = qt.QComboBox()
        for context in self.contexts.itervalues():
            self.contextComboBox.addItem(context)

        ## Operation
        self.operationLabel = qt.QLabel("Optimization")
        self.operationComboBox = qt.QComboBox()
        for operation in self.operations.itervalues():
            if operation != self.OPERATION_NONE:
                self.operationComboBox.addItem(operation)
        ## Plane
        self.planeLabel = qt.QLabel("Plane")
        # Buttons group
        self.planesButtonGroup = qt.QButtonGroup()
        # Axial
        self.axialButton = qt.QPushButton()
        self.axialButton.setCheckable(True)
        self.axialButton.toolTip = "Axial plane"
        self.axialButton.setFixedSize(40, 40)
        self.axialButton.setIcon(SlicerUtil.getIcon("axial.png"))
        self.planesButtonGroup.addButton(self.axialButton, self.PLANE_AXIAL)
        # Sagittal
        self.sagittalButton = qt.QPushButton()
        self.sagittalButton.setCheckable(True)
        self.sagittalButton.toolTip = "Sagittal plane"
        self.sagittalButton.setFixedSize(40, 40)
        self.sagittalButton.setIcon(SlicerUtil.getIcon("sagittal.png"))
        self.widgetMainLayout.addWidget(self.sagittalButton, 2, 2,
                                        SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
        self.planesButtonGroup.addButton(self.sagittalButton,
                                         self.PLANE_SAGITTAL)
        # Coronal
        self.coronalButton = qt.QPushButton()
        self.coronalButton.setCheckable(True)
        self.coronalButton.toolTip = "coronal plane"
        self.coronalButton.setFixedSize(40, 40)
        self.coronalButton.setIcon(SlicerUtil.getIcon("coronal.png"))
        self.planesButtonGroup.addButton(self.coronalButton,
                                         self.PLANE_CORONAL)
        # Null button (to uncheck all)
        self.nullPlaneButton = qt.QPushButton()
        self.nullPlaneButton.setCheckable(True)
        self.planesButtonGroup.addButton(self.nullPlaneButton, -1)
        # Buttons labels
        self.axialButtonLabel = qt.QLabel("Axial")
        self.axialButtonLabel.setStyleSheet("margin-bottom: 10px")
        self.sagittalButtonLabel = qt.QLabel("Sagittal")
        self.sagittalButtonLabel.setStyleSheet("margin-bottom: 10px")
        self.coronalButtonLabel = qt.QLabel("Coronal")
        self.coronalButtonLabel.setStyleSheet("margin-bottom: 10px")

        ## Layout
        self.layoutLabel = qt.QLabel("Layout")
        # Buttons group
        self.layoutsButtonGroup = qt.QButtonGroup()
        # Single slice Button
        self.singleSlideViewButton = qt.QPushButton()
        self.singleSlideViewButton.setCheckable(True)
        self.singleSlideViewButton.toolTip = "Single slice view"
        self.singleSlideViewButton.setFixedSize(40, 40)
        self.singleSlideViewButton.setIcon(
            qt.QIcon(":/Icons/LayoutOneUpRedSliceView.png"))
        self.layoutsButtonGroup.addButton(self.singleSlideViewButton,
                                          self.LAYOUT_RED_ONLY)
        # Side by side Button
        self.sideBySideViewButton = qt.QPushButton()
        self.sideBySideViewButton.setCheckable(True)
        self.sideBySideViewButton.toolTip = "Side by side view"
        self.sideBySideViewButton.setFixedSize(40, 40)
        self.sideBySideViewButton.setIcon(
            qt.QIcon(":/Icons/LayoutSideBySideView.png"))
        self.layoutsButtonGroup.addButton(self.sideBySideViewButton,
                                          self.LAYOUT_SIDE_BY_SIDE)
        # Three over three button
        self.threeOverThreeViewButton = qt.QPushButton()
        self.threeOverThreeViewButton.setCheckable(True)
        self.threeOverThreeViewButton.toolTip = "Compare 2 images in their 3 planes"
        self.threeOverThreeViewButton.setFixedSize(40, 40)
        self.threeOverThreeViewButton.setIcon(
            qt.QIcon(":/Icons/LayoutThreeOverThreeView.png"))
        self.layoutsButtonGroup.addButton(self.threeOverThreeViewButton,
                                          self.LAYOUT_THREE_OVER_THREE)
        # Comparative MIP-MinIP button
        self.maxMinCompareViewButton = qt.QPushButton()
        self.maxMinCompareViewButton.setCheckable(True)
        self.maxMinCompareViewButton.toolTip = "MIP and MinIP comparison"
        self.maxMinCompareViewButton.setFixedSize(40, 40)
        self.maxMinCompareViewButton.setIcon(
            qt.QIcon(":/Icons/LayoutFourUpView.png"))
        self.layoutsButtonGroup.addButton(self.maxMinCompareViewButton,
                                          self.LAYOUT_COMPARE)
        # Null button (to uncheck all)
        self.nullLayoutButton = qt.QPushButton()
        self.nullLayoutButton.setCheckable(True)
        self.layoutsButtonGroup.addButton(self.nullLayoutButton, -2)
        # Reset Button
        self.resetViewButton = qt.QPushButton()
        self.resetViewButton.toolTip = "Go back to the original layout"
        self.resetViewButton.setFixedSize(40, 40)
        # self.resetViewButton.setIconSize(qt.QSize(24, 24))
        self.resetViewButton.setIcon(
            qt.QIcon(os.path.join(SlicerUtil.CIP_ICON_DIR, "Reload.png")))
        # Buttons labels
        self.singleSlideButtonLabel = qt.QLabel("Single")
        self.sideBySideButtonLabel = qt.QLabel("Side by side")
        self.threeOverThreeButtonLabel = qt.QLabel("3x3")
        self.maxMinCompareButtonLabel = qt.QLabel("MIP+MinIP")
        self.resetLabel = qt.QLabel("Reset")
        self.resetLabel.setStyleSheet("font-weight: bold")

        # Number of slices (different for each operation). The size of the slider also changes
        self.spacingSliderItems = OrderedDict()
        spacingLabel = qt.QLabel("Slice size " +
                                 self.operations[self.OPERATION_MIP])
        spacingSlider = qt.QSlider()
        spacingSlider.orientation = 1
        spacingSlider.setTickPosition(2)
        spacingSlider.minimum = 0
        spacingSlider.maximum = 1000
        spacingSlider.setPageStep(50)
        spacingMmLabel = qt.QLabel()
        self.spacingSliderItems[self.OPERATION_MIP] = (spacingLabel,
                                                       spacingSlider,
                                                       spacingMmLabel)
        self.setCurrentSpacingInMm(self.OPERATION_MIP, 20)

        spacingLabel = qt.QLabel("Slice size " +
                                 self.operations[self.OPERATION_MinIP])
        spacingSlider = qt.QSlider()
        spacingSlider.orientation = 1
        spacingSlider.setTickPosition(2)
        spacingSlider.minimum = 0
        spacingSlider.maximum = 200
        spacingSlider.setPageStep(50)
        spacingMmLabel = qt.QLabel()
        self.spacingSliderItems[self.OPERATION_MinIP] = (spacingLabel,
                                                         spacingSlider,
                                                         spacingMmLabel)
        self.setCurrentSpacingInMm(self.OPERATION_MinIP, 5)

        spacingLabel = qt.QLabel("Slice size " +
                                 self.operations[self.OPERATION_MEAN])
        spacingSlider = qt.QSlider()
        spacingSlider.orientation = 1
        spacingSlider.setTickPosition(2)
        spacingSlider.minimum = 0
        spacingSlider.maximum = 200
        spacingSlider.setPageStep(50)
        spacingMmLabel = qt.QLabel()
        self.spacingSliderItems[self.OPERATION_MEAN] = (spacingLabel,
                                                        spacingSlider,
                                                        spacingMmLabel)
        self.setCurrentSpacingInMm(self.OPERATION_MEAN, 20)

        # Crosshair
        self.crosshairCheckbox = qt.QCheckBox()
        self.crosshairCheckbox.setText("Crosshair cursor")
        self.crosshairCheckbox.toolTip = "Activate/Desactivate the crosshair cursor for a better visualization"
        self.crosshairCheckbox.setStyleSheet("margin-top:10px")

        # Center button
        self.centerButton = qt.QPushButton()
        self.centerButton.setText("Center volumes")
        self.centerButton.setFixedSize(100, 40)
        self.centerButton.setStyleSheet("margin-top:10px")

        if self.fullModeOn:
            ###### FULL MODE
            # Context
            self.widgetMainLayout.addWidget(self.contextLabel, 0, 0)
            self.widgetMainLayout.addWidget(self.contextComboBox, 0, 1, 1, 3)
            # Operation
            self.widgetMainLayout.addWidget(self.operationLabel, 1, 0)
            self.widgetMainLayout.addWidget(self.operationComboBox, 1, 1, 1, 3)
            # Plane
            self.widgetMainLayout.addWidget(self.planeLabel, 2, 0)
            self.widgetMainLayout.addWidget(
                self.axialButton, 2, 1, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.coronalButton, 2, 3,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.axialButtonLabel, 3, 1,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.sagittalButtonLabel, 3, 2,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.coronalButtonLabel, 3, 3,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            # Layout
            self.widgetMainLayout.addWidget(self.layoutLabel, 4, 0)
            self.widgetMainLayout.addWidget(
                self.singleSlideViewButton, 4, 1,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.sideBySideViewButton, 4, 2,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.threeOverThreeViewButton, 4, 3,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.maxMinCompareViewButton, 4, 4,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.resetViewButton, 4, 5,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.singleSlideButtonLabel, 5, 1,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.sideBySideButtonLabel, 5, 2,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.threeOverThreeButtonLabel, 5, 3,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.maxMinCompareButtonLabel, 5, 4,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.resetLabel, 5, 5, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            # Number of slices
            row = 6
            for structure in self.spacingSliderItems.itervalues():
                self.widgetMainLayout.addWidget(structure[0], row, 0, 1, 2)
                self.widgetMainLayout.addWidget(structure[1], row, 2, 1, 3)
                self.widgetMainLayout.addWidget(structure[2], row, 5)
                row += 1
            self.widgetMainLayout.addWidget(self.crosshairCheckbox, row, 0, 1,
                                            2)
            self.crosshairCheckbox.setChecked(True)
            self.widgetMainLayout.addWidget(self.centerButton, row, 2, 1, 2)

        else:
            ##### COLLAPSED MODE
            # Plane
            self.widgetMainLayout.addWidget(self.planeLabel, 0, 0)
            self.widgetMainLayout.addWidget(
                self.axialButton, 0, 1, SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.sagittalButton, 0, 2,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.coronalButton, 0, 3,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.threeOverThreeViewButton, 0, 4,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.axialButtonLabel, 1, 1,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.sagittalButtonLabel, 1, 2,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.coronalButtonLabel, 1, 3,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            self.widgetMainLayout.addWidget(
                self.threeOverThreeButtonLabel, 1, 4,
                SlicerUtil.ALIGNMENT_HORIZONTAL_CENTER)
            # Number of slices
            row = 2
            for structure in self.spacingSliderItems.itervalues():
                self.widgetMainLayout.addWidget(structure[0], row, 0)
                self.widgetMainLayout.addWidget(structure[1], row, 1, 1, 3)
                self.widgetMainLayout.addWidget(structure[2], row, 4)
                row += 1
            self.widgetMainLayout.addWidget(self.crosshairCheckbox, row, 0)
            self.widgetMainLayout.addWidget(self.centerButton, row, 1, 1, 2)

        self.layout.addStretch(1)

        self.__refreshUI__()

        # Connections
        self.contextComboBox.connect("currentIndexChanged (int)",
                                     self.__onContextIndexChanged__)
        self.operationComboBox.connect("currentIndexChanged (int)",
                                       self.__onOperationIndexChanged__)
        self.planesButtonGroup.connect("buttonClicked(int)",
                                       self.__onPlaneButtonClicked__)
        self.singleSlideViewButton.connect("clicked()",
                                           self.__onSingleSlideButtonClicked__)
        self.sideBySideViewButton.connect("clicked()",
                                          self.__onSideBySideButtonClicked__)
        self.threeOverThreeViewButton.connect(
            "clicked()", self.__onThreeOverThreeViewButtonClicked__)
        self.maxMinCompareViewButton.connect(
            "clicked()", self.__onMaxMinCompareViewButtonClicked__)
        self.resetViewButton.connect("clicked()",
                                     self.__onResetViewButtonClicked__)
        for slicer in (item[1]
                       for item in self.spacingSliderItems.itervalues()):
            slicer.connect('valueChanged(int)',
                           self.__onNumberOfSlicesChanged__)
        self.crosshairCheckbox.connect("stateChanged(int)",
                                       self.__onCrosshairCheckChanged__)
        self.centerButton.connect("clicked()", self.__onCenterButtonClicked__)
Beispiel #30
0
    def setup(self):
        """Init the widget """
        self.modulePath = SlicerUtil.getModuleFolder("CIP_GetImage")

        self.resourcesPath = os.path.join(self.modulePath,
                                          "CIP_GetImage_Resources")
        self.StudyId = ""

        self.logic = CIP_GetImageLogic(self.modulePath)

        # Widget to load cases faster
        self.loadSaveDatabuttonsWidget = CIPUI.LoadSaveDataWidget(
            parentWidget=self.parent)
        self.loadSaveDatabuttonsWidget.setup(moduleName="CIP_GetImage")

        #
        # Obligatory parameters area
        #
        parametersCollapsibleButton = ctk.ctkCollapsibleButton()
        parametersCollapsibleButton.text = "Image data"
        self.layout.addWidget(parametersCollapsibleButton)
        parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton)

        # Study radio buttons
        label = qt.QLabel()
        label.text = "Select the study:"
        parametersFormLayout.addRow(label)

        self.rbgStudy = qt.QButtonGroup()

        for key in self.studyIds:
            rbStudyid = qt.QRadioButton(key)
            self.rbgStudy.addButton(rbStudyid)
            parametersFormLayout.addWidget(rbStudyid)

        self.txtOtherStudy = qt.QLineEdit()
        self.txtOtherStudy.hide()
        parametersFormLayout.addWidget(self.txtOtherStudy)

        # Case id
        self.txtCaseId = qt.QLineEdit()
        parametersFormLayout.addRow("Case ID     ", self.txtCaseId)

        # Image types
        label = qt.QLabel()
        label.text = "Select the images that you want to load:"
        parametersFormLayout.addRow(label)

        self.cbsImageTypes = []
        for key in self.imageTypes:
            check = qt.QCheckBox()
            check.checked = True
            check.setText(key)
            parametersFormLayout.addWidget(check)
            self.cbsImageTypes.append(check)

        # Label maps
        label = qt.QLabel()
        label.text = "Select the label maps that you want to load:"
        parametersFormLayout.addRow(label)

        # Labelmap types checkboxes
        self.cbsLabelMapTypes = []
        for key in self.labelMapTypes:
            check = qt.QCheckBox()
            check.setText(key)
            check.checked = self.labelMapTypes[key][0]
            parametersFormLayout.addWidget(check)
            self.cbsLabelMapTypes.append(check)

        # Load image Button
        self.downloadButton = qt.QPushButton("Download")
        self.downloadButton.toolTip = "Load the image"
        #self.downloadButton.enabled = False
        self.downloadButton.setStyleSheet(
            "background-color: green; font-weight:bold; color:white")
        parametersFormLayout.addRow(self.downloadButton)
        self.downloadButton.connect('clicked (bool)', self.onDownloadButton)

        # Information message
        self.lblDownloading = qt.QLabel()
        self.lblDownloading.text = "Downloading images. Please wait..."
        self.lblDownloading.hide()
        parametersFormLayout.addRow(self.lblDownloading)

        #
        # Optional Parameters
        #
        optionalParametersCollapsibleButton = ctk.ctkCollapsibleButton()
        optionalParametersCollapsibleButton.text = "Optional parameters"
        self.layout.addWidget(optionalParametersCollapsibleButton)
        optionalParametersFormLayout = qt.QFormLayout(
            optionalParametersCollapsibleButton)

        # Local storage (Slicer temporary path)
        self.localStoragePath = "{0}/CIP".format(slicer.app.temporaryPath)
        if not os.path.exists(self.localStoragePath):
            os.makedirs(self.localStoragePath)
            # Make sure that everybody has write permissions (sometimes there are problems because of umask)
            os.chmod(self.localStoragePath, 0777)

        self.storagePathButton = ctk.ctkDirectoryButton()
        self.storagePathButton.directory = self.localStoragePath

        optionalParametersFormLayout.addRow("Local directory: ",
                                            self.storagePathButton)

        # Connection type (SSH, "normal")
        label = qt.QLabel()
        label.text = "Connection type:"
        optionalParametersFormLayout.addRow(label)

        self.rbgConnectionType = qt.QButtonGroup()
        self.rbSSH = qt.QRadioButton("SSH (secure connection)")
        self.rbSSH.setChecked(True)
        self.rbgConnectionType.addButton(self.rbSSH)
        optionalParametersFormLayout.addWidget(self.rbSSH)

        self.rbCP = qt.QRadioButton("Common")
        self.rbgConnectionType.addButton(self.rbCP)
        optionalParametersFormLayout.addWidget(self.rbCP)

        # SSH Server login
        self.txtServer = qt.QLineEdit()
        s = SlicerUtil.settingGetOrSetDefault(
            "CIP_GetImage", "server",
            "This is your ssh user and server. Example: [email protected]")
        self.txtServer.text = s  # This is your ssh user and server. Example: [email protected]"
        optionalParametersFormLayout.addRow("Server:", self.txtServer)

        # Server root path
        self.txtServerpath = qt.QLineEdit()
        s = SlicerUtil.settingGetOrSetDefault(
            "CIP_GetImage", "serverRootPath",
            "This is your root path to search for files. Ex: /Cases/Processed")
        self.txtServerpath.text = s  # This is your root path to search for files. Ex: /Cases/Processed
        optionalParametersFormLayout.addRow("Server root path:",
                                            self.txtServerpath)

        # SSH Private key
        self.txtPrivateKeySSH = qt.QLineEdit()
        s = SlicerUtil.settingGetOrSetDefault("CIP_GetImage", "sshKey", "")
        self.txtPrivateKeySSH.text = s  # this is the full path to your ssh key if you need it. Be aware of Unix/Windows comaptibility (hint: use os.path.join)
        # Please notice that you won't need a SSH key if your computer already has one locally installed"
        optionalParametersFormLayout.addRow(
            "SSH private key (leave blank for computer's default):     ",
            self.txtPrivateKeySSH)

        # Cache mode
        self.cbCacheMode = qt.QCheckBox("Cache mode activated")
        self.cbCacheMode.setChecked(True)  # Cache mode is activated by default
        optionalParametersFormLayout.addRow("", self.cbCacheMode)

        # Clean cache Button
        self.cleanCacheButton = qt.QPushButton("Clean cache")
        self.cleanCacheButton.toolTip = "Remove all the local cached files"
        optionalParametersFormLayout.addRow(self.cleanCacheButton)
        optionalParametersCollapsibleButton.collapsed = True

        if SlicerUtil.IsDevelopment:
            # reload button
            self.reloadButton = qt.QPushButton("Reload (just development)")
            self.reloadButton.toolTip = "Reload this module (for development purposes)."
            self.reloadButton.name = "Reload"
            self.layout.addWidget(self.reloadButton)
            self.reloadButton.connect('clicked()', self.onReload)

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

        # Connections
        self.rbgStudy.connect("buttonClicked (QAbstractButton*)",
                              self.onRbStudyClicked)
        self.txtOtherStudy.connect("textEdited (QString)",
                                   self.onTxtOtherStudyEdited)
        self.rbgConnectionType.connect("buttonClicked (QAbstractButton*)",
                                       self.onRbgConnectionType)

        self.storagePathButton.connect("directorySelected(QString)",
                                       self.onTmpDirChanged)
        self.cleanCacheButton.connect('clicked (bool)',
                                      self.onCleanCacheButtonClicked)