def __init__(self, parent=None): qt.QFrame.__init__(self) self.parameterNode = None # # Parameters area # self.parametersLayout = qt.QFormLayout(self) self.setLayout(self.parametersLayout) # # Stop criteria for splitting spin box # self.stopCriteriaSpinBox = qt.QDoubleSpinBox() self.stopCriteriaSpinBox.setRange(0, 1) self.stopCriteriaSpinBox.setSingleStep(0.01) self.stopCriteriaSpinBox.setToolTip( "Choose the stop criteria for splitting. Maximum variance for leaf." ) self.parametersLayout.addRow("Stop criteria ", self.stopCriteriaSpinBox) # connections self.stopCriteriaSpinBox.connect('valueChanged(double)', self.onStopCriteriaChanged)
def setupSpinBoxControllers(self): """ Set up the spin box controllers to calculate the ECV map """ self.SB_NBlodd_Label = qt.QLabel('Native T1 Blood') self.SB_EBlodd_Label = qt.QLabel('Enhanced T1 Blood') self.SB_Haematocrit_Label = qt.QLabel('Haematocrit Percentage') self.SB_Haematocrit = qt.QDoubleSpinBox() self.SB_NBlodd = qt.QDoubleSpinBox() self.SB_EBlodd = qt.QDoubleSpinBox() self.ConfigSpinBox(self.SB_Haematocrit, self.SB_Haematocrit_Label, 1, 0, 100, Suffix='%') self.ConfigSpinBox(self.SB_NBlodd, self.SB_NBlodd_Label, 1, 0, 2000) self.ConfigSpinBox(self.SB_EBlodd, self.SB_EBlodd_Label, 1, 0, 1000)
def __init__(self, parent=None): qt.QFrame.__init__(self) self.parameterNode = None # # Parameters area # self.parametersLayout = qt.QFormLayout(self) self.setLayout(self.parametersLayout) # # Benchmark criterion combo box # self.benchmarkCriterionComboBox = qt.QComboBox() self.benchmarkCriterionComboBox.addItem(BENCHMARK_CRITERION_ZSCORE) self.benchmarkCriterionComboBox.addItem(BENCHMARK_CRITERION_PERCENTILE) self.benchmarkCriterionComboBox.setToolTip( "Choose the benchmark criterion.") self.parametersLayout.addRow("Benchmark criterion ", self.benchmarkCriterionComboBox) # # Numerical level for benchmark spin box # self.numericalLevelSpinBox = qt.QDoubleSpinBox() self.numericalLevelSpinBox.setRange(-100, 100) self.numericalLevelSpinBox.setSingleStep(0.1) self.numericalLevelSpinBox.setToolTip( "Choose the numerical level for benchmarking.") self.parametersLayout.addRow("Numerical level ", self.numericalLevelSpinBox) # # Comparison method combo box # self.comparisonMethodComboBox = qt.QComboBox() self.comparisonMethodComboBox.addItem(COMPARISON_METHOD_MEAN) self.comparisonMethodComboBox.addItem(COMPARISON_METHOD_MEDIAN) self.comparisonMethodComboBox.addItem(COMPARISON_METHOD_MAXIMUM) self.comparisonMethodComboBox.addItem(COMPARISON_METHOD_MINIMUM) self.comparisonMethodComboBox.setToolTip( "Choose the comparison method.") self.parametersLayout.addRow("Comparison method ", self.comparisonMethodComboBox) # connections self.benchmarkCriterionComboBox.connect( 'currentIndexChanged(QString)', self.onBenchmarkCriterionChanged) self.numericalLevelSpinBox.connect('valueChanged(double)', self.onNumericalLevelChanged) self.comparisonMethodComboBox.connect('currentIndexChanged(QString)', self.onComparisonMethodChanged)
def build_spin_box(minimum, maximum, click=None, decimals=0, step=1.0, initial=0.0, width=None): box = qt.QDoubleSpinBox() box.setMinimum(minimum) box.setMaximum(maximum) box.setSingleStep(step) box.setDecimals(decimals) box.setValue(initial) if width is not None: box.setFixedWidth(width) if click is not None: box.connect('valueChanged(double)', click) return box
def setupOpacity(self): self.opacitySpinBox = qt.QDoubleSpinBox() self.opacitySpinBox.minimum = 0 self.opacitySpinBox.maximum = 1.0 self.opacitySpinBox.value = 1 self.opacitySpinBox.singleStep = 0.05 self.opacitySliderPopup = ctk.ctkPopupWidget(self.opacitySpinBox) popupLayout = qt.QHBoxLayout(self.opacitySliderPopup) self.opacitySlider = ctk.ctkDoubleSlider(self.opacitySliderPopup) self.opacitySlider.orientation = qt.Qt.Horizontal self.opacitySlider.minimum = 0 self.opacitySlider.maximum = 1.0 self.opacitySlider.value = 1 self.opacitySlider.singleStep = 0.05 popupLayout.addWidget(self.opacitySlider) self.opacitySliderPopup.verticalDirection = ctk.ctkBasePopupWidget.TopToBottom self.opacitySliderPopup.animationEffect = ctk.ctkBasePopupWidget.FadeEffect self.opacitySliderPopup.orientation = qt.Qt.Horizontal #self.opacitySliderPopup.easingCurve = qt.QEasingCurve.OutQuart self.opacitySliderPopup.effectDuration = 100
def numericInputFrame(parent, label, tooltip, minimum, maximum, step, decimals): inputFrame = qt.QFrame(parent) inputFrame.setLayout(qt.QHBoxLayout()) inputLabel = qt.QLabel(label, inputFrame) inputLabel.setToolTip(tooltip) inputFrame.layout().addWidget(inputLabel) inputSpinBox = qt.QDoubleSpinBox(inputFrame) inputSpinBox.setToolTip(tooltip) inputSpinBox.minimum = minimum inputSpinBox.maximum = maximum inputSpinBox.singleStep = step inputSpinBox.decimals = decimals inputFrame.layout().addWidget(inputSpinBox) inputSlider = ctk.ctkDoubleSlider(inputFrame) inputSlider.minimum = minimum inputSlider.maximum = maximum inputSlider.orientation = 1 inputSlider.singleStep = step inputSlider.setToolTip(tooltip) inputFrame.layout().addWidget(inputSlider) return inputFrame, inputSlider, inputSpinBox
def onInputShapesDirectoryChanged(self): inputShapesDirectory = self.shapeInputDirectory.directory.encode( 'utf-8') row = 0 for file in sorted(os.listdir(inputShapesDirectory)): if file.endswith(".vtk"): self.tableWidget_inputShapeParameters.setRowCount(row + 1) # Column 0: rootname = os.path.basename(file).split(".")[0] labelVTKFile = qt.QLabel(rootname) labelVTKFile.setAlignment(0x84) self.tableWidget_inputShapeParameters.setCellWidget( row, 0, labelVTKFile) # Column 1-2-3-4: for column in range(1, 5): widget = qt.QWidget() layout = qt.QHBoxLayout(widget) if not column == 2: spinBox = qt.QSpinBox() if column == 1: spinBox.connect('valueChanged(int)', self.onDefaultTimePointRange) if column == 4: spinBox.value = 1 else: spinBox = qt.QDoubleSpinBox() spinBox.setMinimum(0) layout.addWidget(spinBox) layout.setAlignment(0x84) layout.setContentsMargins(0, 0, 0, 0) widget.setLayout(layout) self.tableWidget_inputShapeParameters.setCellWidget( row, column, widget) row = row + 1
def setup(self): ScriptedLoadableModuleWidget.setup(self) # # Parameter Combobox # self.parameterSelector = slicer.qMRMLNodeComboBox() self.parameterLabel = qt.QLabel(" Parameter set: ") self.parameterSelector.nodeTypes = ["vtkMRMLScriptedModuleNode"] self.parameterSelector.removeEnabled = False self.parameterSelector.showHidden = True self.parameterSelector.setMRMLScene( slicer.mrmlScene ) self.parameterLayout = qt.QHBoxLayout() self.parameterLayout.addWidget(self.parameterLabel) self.parameterLayout.addWidget(self.parameterSelector) self.layout.addLayout(self.parameterLayout) # # Input Area # inputCollapsibleButton = ctk.ctkCollapsibleButton() inputCollapsibleButton.text = "Input" self.layout.addWidget(inputCollapsibleButton) # Layout within the dummy collapsible button inputFormLayout = qt.QFormLayout(inputCollapsibleButton) # # Input first DVH selector # self.dvh1Selector = slicer.qMRMLNodeComboBox() self.dvh1Selector.nodeTypes = ["vtkMRMLTableNode"] self.dvh1Selector.addAttribute("vtkMRMLTableNode", "DoseVolumeHistogram.DVH") self.dvh1Selector.removeEnabled = False self.dvh1Selector.setMRMLScene( slicer.mrmlScene ) inputFormLayout.addRow("DVH 1: ", self.dvh1Selector) # # Input second DVH selector # self.dvh2Selector = slicer.qMRMLNodeComboBox() self.dvh2Selector.nodeTypes = ["vtkMRMLTableNode"] self.dvh1Selector.addAttribute("vtkMRMLTableNode", "DoseVolumeHistogram.DVH") self.dvh2Selector.removeEnabled = False self.dvh2Selector.setMRMLScene( slicer.mrmlScene ) inputFormLayout.addRow("DVH 2: ", self.dvh2Selector) # # Input the dose volume # self.doseVolumeSelector = slicer.qMRMLNodeComboBox() self.doseVolumeSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.doseVolumeSelector.addAttribute("vtkMRMLScalarVolumeNode", "DicomRtImport.DoseVolume") self.doseVolumeSelector.removeEnabled = False self.doseVolumeSelector.setMRMLScene( slicer.mrmlScene ) inputFormLayout.addRow("Dose Volume: ", self.doseVolumeSelector) # # Dose volume only check box # self.showDoseVolumeOnlyCheckbox = qt.QCheckBox("Show dose volume only") self.showDoseVolumeOnlyCheckbox.setChecked(2) inputFormLayout.addWidget(self.showDoseVolumeOnlyCheckbox) # # Volume difference criterion spin box # self.volumeDifferenceSpinbox = qt.QDoubleSpinBox() self.volumeDifferenceSpinbox.setValue(1.0) self.volumeDifferenceSpinbox.setDecimals(1) self.volumeDifferenceSpinbox.setSingleStep(0.1) inputFormLayout.addRow("Volume difference criterion: ", self.volumeDifferenceSpinbox) # # Dose to agreement criterion spin box # self.doseToAgreementSpinbox = qt.QDoubleSpinBox() self.doseToAgreementSpinbox.setValue(1.0) self.doseToAgreementSpinbox.setDecimals(1) self.doseToAgreementSpinbox.setSingleStep(0.1) inputFormLayout.addRow("Dose to agreement criterion: ", self.doseToAgreementSpinbox) # # Compute button # self.computeButton = qt.QPushButton("Compute") self.computeButtonLayout = qt.QVBoxLayout() self.computeButtonLayout.addStrut(100) self.computeButtonLayout.setAlignment(2) self.computeButtonLayout.addWidget(self.computeButton) self.computeButtonFont = qt.QFont() self.computeButtonFont.setBold(True) self.computeButton.setFont(self.computeButtonFont) inputFormLayout.addRow(self.computeButtonLayout) # # Output Area # outputCollapsibleButton = ctk.ctkCollapsibleButton() outputCollapsibleButton.text = "Output" self.layout.addWidget(outputCollapsibleButton) # Layout within the dummy collapsible button outputFormLayout = qt.QFormLayout(outputCollapsibleButton) self.agreementAcceptanceOutput = qt.QLineEdit() self.agreementAcceptanceOutput.setReadOnly(True) outputFormLayout.addRow("Agreement acceptance %: ", self.agreementAcceptanceOutput) # # Visualize Area # visualizeCollapsibleButton = ctk.ctkCollapsibleButton() visualizeCollapsibleButton.text = "Visualize" sizePolicy = qt.QSizePolicy() sizePolicy.setHorizontalPolicy(qt.QSizePolicy.Preferred) sizePolicy.setVerticalPolicy(qt.QSizePolicy.Expanding) visualizeCollapsibleButton.setSizePolicy(sizePolicy) self.layout.addWidget(visualizeCollapsibleButton) # Layout within the dummy collapsible button visualizeLayout = qt.QVBoxLayout(visualizeCollapsibleButton) # # DVH Table # self.dvhTable = slicer.qMRMLTableView() self.dvhTable.setMRMLScene(slicer.mrmlScene) self.dvhTable.setSelectionMode(qt.QAbstractItemView.NoSelection) self.dvhTable.setSizePolicy(sizePolicy) visualizeLayout.addWidget(self.dvhTable) # Connections self.parameterSelector.connect('nodeAddedByUser(vtkMRMLNode*)', self.parameterNodeCreated) self.parameterSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.updateWidgetFromMRML) self.showDoseVolumeOnlyCheckbox.connect('stateChanged(int)', self.showDoseVolumesOnlyCheckboxChanged) self.dvh1Selector.connect("currentNodeChanged(vtkMRMLNode*)", self.dvh1SelectorChanged) self.dvh2Selector.connect("currentNodeChanged(vtkMRMLNode*)", self.dvh2SelectorChanged) self.doseVolumeSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.doseVolumeSelectorChanged) self.volumeDifferenceSpinbox.connect("valueChanged(double)", self.volumeDifferenceSpinboxChanged) self.doseToAgreementSpinbox.connect("valueChanged(double)", self.doseToAgreementSpinboxChanged) self.computeButton.connect('clicked(bool)', self.onComputeButton) self.updateWidgetFromMRML()
def setup(self): ScriptedLoadableModuleWidget.setup(self) self.logic = MyModuleLogic() # ------ 1. CREATE LAYOUT AND BUTTONS ------ # Layout setup: 3D Only self.layoutManager = slicer.app.layoutManager() self.layoutManager.setLayout( slicer.vtkMRMLLayoutNode.SlicerLayoutOneUp3DView) # # LOAD DATA # # Create layout collapsibleButtonLoad = ctk.ctkCollapsibleButton() collapsibleButtonLoad.text = "LOAD DATA" # title for layout self.layout.addWidget(collapsibleButtonLoad) formLayout_load = qt.QFormLayout(collapsibleButtonLoad) # Segment 1 Selector self.segment1_pathSelector = ctk.ctkPathLineEdit() self.segment1_pathSelector.enabled = True self.segment1_pathSelector.setMaximumWidth(400) self.segment1_pathSelector.currentPath = slicer.modules.mymodule.path.replace( "MyModule.py", "") + 'Data/Liver1.stl' formLayout_load.addRow("Segment 1: ", self.segment1_pathSelector) # Segment 1 Selector self.segment2_pathSelector = ctk.ctkPathLineEdit() self.segment2_pathSelector.enabled = True self.segment2_pathSelector.setMaximumWidth(400) self.segment2_pathSelector.currentPath = slicer.modules.mymodule.path.replace( "MyModule.py", "") + 'Data/Liver1beforeMM.stl' formLayout_load.addRow("Segment 2: ", self.segment2_pathSelector) # Button to load segments self.loadSegmentsButton = qt.QPushButton( "LOAD MODELS AS SEGMENTS") # text in button self.loadSegmentsButton.toolTip = "Load segments as segments" # hint text for button (appears when cursor is above the button for more than one second) self.loadSegmentsButton.enabled = True # if True it can be clicked formLayout_load.addRow( self.loadSegmentsButton) # include button in layout # # ALIGNMENT # # Create Layout collapsibleButtonAlignment = ctk.ctkCollapsibleButton() collapsibleButtonAlignment.text = "ALIGNMENT" self.layout.addWidget(collapsibleButtonAlignment) formLayout_alignment = qt.QFormLayout(collapsibleButtonAlignment) # Button for masks alignment self.alignSegmentsButton = qt.QPushButton( "ALIGN MODELS") # text in button self.alignSegmentsButton.toolTip = "Align segments" # hint text for button (appears when cursor is above the button for more than one second) self.alignSegmentsButton.enabled = True formLayout_alignment.addRow(self.alignSegmentsButton) # COMPARISON BETWEEN MASKS # # SORENSEN-DICE COEFFICIENT & HOUSDORFF DISTANCE BUTTONS # # Create layout collapsibleButtonComparison = ctk.ctkCollapsibleButton() collapsibleButtonComparison.text = "COMPARISON" # title for layout self.layout.addWidget(collapsibleButtonComparison) formLayout_comparison = qt.QFormLayout(collapsibleButtonComparison) # Button to obtain the Sorensen-Dice Coefficient self.diceCoeffButton = qt.QPushButton( "SORENSEN-DICE COEFFICIENT") # text in button self.diceCoeffButton.toolTip = "Sorensen-Dice Coefficient" # hint text for button (appears when the cursor is above the button for more than one second) self.diceCoeffButton.enabled = True # if true it can be clicked formLayout_comparison.addRow( self.diceCoeffButton) # include button in layout #Button to obtain the Hausdorff Distance self.hausDistButton = qt.QPushButton( "HAUSDORFF DISTANCE") # text in button self.hausDistButton.toolTip = qt.QPushButton( "Hausdorff Distance" ) # hint text for button (appears when the cursor is above the button for more than a second) self.hausDistButton.enabled = True # if true it can be clicked formLayout_comparison.addRow( self.hausDistButton) # include button in layout # # VISUALIZATION # # Create layout collapsibleButtonVisualization = ctk.ctkCollapsibleButton() collapsibleButtonVisualization.text = "VISUALIZATION" # title for layout self.layout.addWidget(collapsibleButtonVisualization) formLayout_visualization = qt.QFormLayout( collapsibleButtonVisualization) # # Segment visibility layout # # Create collapsible button inside layout segmentVisibility_GroupBox = ctk.ctkCollapsibleGroupBox() segmentVisibility_GroupBox.setTitle( "MODEL VISIBILITY") # title for collapsible button segmentVisibility_GroupBox.collapsed = False # if True it appears collapsed formLayout_visualization.addRow( segmentVisibility_GroupBox) # add collapsible button to layout # Create layout inside collapsible button segmentVisibility_GroupBox_Layout = qt.QFormLayout( segmentVisibility_GroupBox) # Create horizontal section segmentVisibilityLayout_1 = qt.QHBoxLayout() segmentVisibility_GroupBox_Layout.addRow( segmentVisibilityLayout_1) # insert section in current layout # Show or Hide Segment 1 in 3D scene self.segment1_checkBox = qt.QCheckBox('Segment 1') # text in checkbox self.segment1_checkBox.checked = True # if True it is initially checked self.segment1_checkBox.enabled = True # if True it can be checked segmentVisibilityLayout_1.addWidget( self.segment1_checkBox) # add checkbox to layout # Show or Hide Segment 2 in 3D scene self.segment2_checkBox = qt.QCheckBox('Segment 2') # text in checkbox self.segment2_checkBox.checked = True # if True it is initially checked self.segment2_checkBox.checked = True # if True it can be checked segmentVisibilityLayout_1.addWidget( self.segment2_checkBox) # add checkbox to layout # # Segment transparency layout # # Create collapsible button inside layout segmentOpacity_GroupBox = ctk.ctkCollapsibleGroupBox() segmentOpacity_GroupBox.setTitle( "MODEL OPACITY") # title for collapsible button segmentOpacity_GroupBox.collapsed = False # if True it appears collapsed formLayout_visualization.addRow( segmentOpacity_GroupBox) # add collapsible button to layout # Create layout inside collapsible button segmentOpacity_GroupBox_Layout = qt.QFormLayout( segmentOpacity_GroupBox) # Create an opacity Value Slider - Segment 1 self.opacityValueSliderWidget_1 = ctk.ctkSliderWidget() self.opacityValueSliderWidget_1.singleStep = 5 # step for range of values to be selected self.opacityValueSliderWidget_1.minimum = 0 # minimum value self.opacityValueSliderWidget_1.maximum = 100 # maximum value self.opacityValueSliderWidget_1.value = 100 # initial value segmentOpacity_GroupBox_Layout.addRow( "[%]: ", self.opacityValueSliderWidget_1) # add slider to layout # Create an opacity Value Slider - Segment 2 self.opacityValueSliderWidget_2 = ctk.ctkSliderWidget() self.opacityValueSliderWidget_2.singleStep = 5 # step for range of values to be selected self.opacityValueSliderWidget_2.minimum = 0 # minimum value self.opacityValueSliderWidget_2.maximum = 100 # maximum value self.opacityValueSliderWidget_2.value = 100 # initial value segmentOpacity_GroupBox_Layout.addRow( "[%]: ", self.opacityValueSliderWidget_2) # add slider to layout # # COLOR MAP # collapsibleButtonColorMap = ctk.ctkCollapsibleButton() collapsibleButtonColorMap.text = "COLOR MAP" self.layout.addWidget(collapsibleButtonColorMap) formLayout_colorMap = qt.QFormLayout(collapsibleButtonColorMap) self.showColorMapButton = qt.QPushButton( "SHOW COLOR MAP") # text in button self.showColorMapButton.toolTip = "Align segments" # hint text for button (appears when cursor is above the button for more than one second) self.showColorMapButton.enabled = True formLayout_colorMap.addRow(self.showColorMapButton) # Displayed Range group box self.displayedRange_GroupBox = ctk.ctkCollapsibleGroupBox() self.displayedRange_GroupBox.setTitle("Displayed Range") self.displayedRange_GroupBox.collapsed = False self.displayedRange_GroupBox.enabled = False formLayout_colorMap.addRow(self.displayedRange_GroupBox) displayedRange_GroupBox_Layout = qt.QFormLayout( self.displayedRange_GroupBox) displayedRange_H_Layout = qt.QHBoxLayout() displayedRange_GroupBox_Layout.addRow(displayedRange_H_Layout) ## Minimum value - displayed range self.minDisplayedRange_SpinBox = qt.QDoubleSpinBox() self.minDisplayedRange_SpinBox.setMaximum(40.0) self.minDisplayedRange_SpinBox.setMinimum(-40.0) self.minDisplayedRange_SpinBox.setSingleStep(0.1) self.minDisplayedRange_SpinBox.enabled = True self.minDisplayedRange_SpinBox.value = 0.0 displayedRange_H_Layout.addWidget(self.minDisplayedRange_SpinBox) ## Displayed range Slider self.displayedRange_SliderWidget = ctk.ctkDoubleRangeSlider() self.displayedRange_SliderWidget.setValues(0.0, 10.0) self.displayedRange_SliderWidget.orientation = 1 self.displayedRange_SliderWidget.singleStep = 0.1 self.displayedRange_SliderWidget.minimum = -40.0 self.displayedRange_SliderWidget.maximum = 40.0 displayedRange_H_Layout.addWidget(self.displayedRange_SliderWidget) ## Maximum value - displayed range self.maxDisplayedRange_SpinBox = qt.QDoubleSpinBox() self.maxDisplayedRange_SpinBox.setMaximum(40.0) self.maxDisplayedRange_SpinBox.setMinimum(-40.0) self.maxDisplayedRange_SpinBox.setSingleStep(0.1) self.maxDisplayedRange_SpinBox.enabled = True self.maxDisplayedRange_SpinBox.value = 10.0 displayedRange_H_Layout.addWidget(self.maxDisplayedRange_SpinBox) # Scalar Bar Visibility Checkbox self.ScalarBar_visibility_checkBox = qt.QCheckBox('Scalar Bar Visible') self.ScalarBar_visibility_checkBox.checked = True displayedRange_GroupBox_Layout.addRow( self.ScalarBar_visibility_checkBox) # Add vertical spacing self.layout.addStretch(1) # ------ 2. CONNECT BUTTONS WITH FUNCTIONS ------ # Connect each button with a function self.loadSegmentsButton.connect( 'clicked(bool)', self.onloadSegmentsButton ) # when the button is pressed we call the function onLoadSegment1Button self.segment1_checkBox.connect('stateChanged(int)', self.onupdateSegment1Visibility) self.segment2_checkBox.connect('stateChanged(int)', self.onupdateSegment2Visibility) self.opacityValueSliderWidget_1.connect("valueChanged(double)", self.onupdateSegment1Opacity) self.opacityValueSliderWidget_2.connect("valueChanged(double)", self.onupdateSegment2Opacity) self.alignSegmentsButton.connect('clicked(bool)', self.onAlignSegmentsButton) self.diceCoeffButton.connect('clicked(bool)', self.onDiceCoeffButton) self.hausDistButton.connect('clicked(bool)', self.onHausdorffDistButton) self.showColorMapButton.connect('clicked(bool)', self.onShowColorMapButton) self.displayedRange_SliderWidget.connect( "valuesChanged(double,double)", self.onDisplayedRangeSliderChanged) self.minDisplayedRange_SpinBox.connect( "valueChanged(double)", self.onDisplayedRangeSpinBoxChanged) self.maxDisplayedRange_SpinBox.connect( "valueChanged(double)", self.onDisplayedRangeSpinBoxChanged) self.ScalarBar_visibility_checkBox.connect( 'stateChanged(int)', self.onScalarBarVisibilityChecked)
def setup(self): ScriptedLoadableModuleWidget.setup(self) #################### # For debugging # # 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 = "Reload" reloadFormLayout.addWidget(self.reloadButton) self.reloadButton.connect('clicked()', self.onReload) # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # input magnitude volume # self.magnitudevolume = slicer.qMRMLNodeComboBox() self.magnitudevolume.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.magnitudevolume.selectNodeUponCreation = True self.magnitudevolume.addEnabled = True self.magnitudevolume.removeEnabled = True self.magnitudevolume.noneEnabled = True self.magnitudevolume.showHidden = False self.magnitudevolume.showChildNodeTypes = False self.magnitudevolume.setMRMLScene(slicer.mrmlScene) self.magnitudevolume.setToolTip("Select the magnitude image") parametersFormLayout.addRow("Magnitude Image: ", self.magnitudevolume) # # input phase volume # self.phasevolume = slicer.qMRMLNodeComboBox() self.phasevolume.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.phasevolume.selectNodeUponCreation = True self.phasevolume.addEnabled = True self.phasevolume.removeEnabled = True self.phasevolume.noneEnabled = True self.phasevolume.showHidden = False self.phasevolume.showChildNodeTypes = False self.phasevolume.setMRMLScene(slicer.mrmlScene) self.phasevolume.setToolTip("Select the phase image") parametersFormLayout.addRow("Phase Image: ", self.phasevolume) # # True phase points (vtkMRMLMarkupsFiducialNode) # self.truePhasePointSelector = slicer.qMRMLNodeComboBox() self.truePhasePointSelector.nodeTypes = (( "vtkMRMLMarkupsFiducialNode"), "") self.truePhasePointSelector.addEnabled = True self.truePhasePointSelector.removeEnabled = False self.truePhasePointSelector.noneEnabled = True self.truePhasePointSelector.showHidden = False self.truePhasePointSelector.renameEnabled = True self.truePhasePointSelector.showChildNodeTypes = False self.truePhasePointSelector.setMRMLScene(slicer.mrmlScene) self.truePhasePointSelector.setToolTip( "Pick up a Markups node listing a true phase point.") parametersFormLayout.addRow("True Phase Point: ", self.truePhasePointSelector) # # Select which scene view to track # self.sceneViewButton_red = qt.QRadioButton('Red') self.sceneViewButton_yellow = qt.QRadioButton('Yellow') self.sceneViewButton_green = qt.QRadioButton('Green') self.sceneViewButton_green.checked = 1 layout = qt.QHBoxLayout(parametersCollapsibleButton) layout.addWidget(self.sceneViewButton_red) layout.addWidget(self.sceneViewButton_yellow) layout.addWidget(self.sceneViewButton_green) parametersFormLayout.addRow("Scene view:", layout) # Auto slice selecter self.autosliceselecterButton = qt.QPushButton("Segment Needle") self.autosliceselecterButton.toolTip = "Observe slice from scene viewer" self.autosliceselecterButton.enabled = False parametersFormLayout.addRow(self.autosliceselecterButton) realtimebutton = qt.QHBoxLayout() # # Start Real-Time Tracking # self.trackingButton = qt.QPushButton("Start Simulated Tracking") self.trackingButton.toolTip = "Observe slice from scene viewer" self.trackingButton.enabled = False self.trackingButton.clicked.connect(self.SimStartTimer) realtimebutton.addWidget(self.trackingButton) self.SimTimer = qt.QTimer() self.SimTimer.timeout.connect(self.onRealTimeTracking) # Stop Real-Time Tracking self.stopsequence = qt.QPushButton('Stop Simulated Tracking') self.stopsequence.clicked.connect(self.SimStopTimer) realtimebutton.addWidget(self.stopsequence) parametersFormLayout.addRow("", realtimebutton) # Add vertical spacer self.layout.addStretch(1) #################################### ## ## ## Scanner Remote Control Protocol## ## ## #################################### SRCcollapsibleButton = ctk.ctkCollapsibleButton() SRCcollapsibleButton.text = "Scanner Remote Control Protocol" self.layout.addWidget(SRCcollapsibleButton) SRCFormLayout = qt.QFormLayout(SRCcollapsibleButton) realtimebutton = qt.QHBoxLayout() # FPS self.fpsBox = qt.QDoubleSpinBox() self.fpsBox.setSingleStep(0.1) self.fpsBox.setMaximum(40) self.fpsBox.setMinimum(0.1) self.fpsBox.setSuffix(" FPS") self.fpsBox.value = 0.5 SRCFormLayout.addRow("Update Rate:", self.fpsBox) # Start SRC Real-Time Tracking self.SRCtrackingButton = qt.QPushButton("Start Live Tracking") self.SRCtrackingButton.toolTip = "Observe slice from scene viewer" self.SRCtrackingButton.enabled = False self.SRCtrackingButton.clicked.connect(self.StartTimer) realtimebutton.addWidget(self.SRCtrackingButton) self.timer = qt.QTimer() self.timer.timeout.connect(self.SRCRealTimeTracking) # Stop Real-Time Tracking self.stopsequence = qt.QPushButton('Stop Live Tracking') self.stopsequence.clicked.connect(self.StopTimer) realtimebutton.addWidget(self.stopsequence) SRCFormLayout.addRow("", realtimebutton) # Add vertical spacer self.layout.addStretch(1) ###################### # Advanced Parameters# ###################### advancedCollapsibleButton = ctk.ctkCollapsibleButton() advancedCollapsibleButton.text = "Advanced" advancedCollapsibleButton.collapsed = 1 self.layout.addWidget(advancedCollapsibleButton) # Layout within the collapsible button advancedFormLayout = qt.QFormLayout(advancedCollapsibleButton) # # 2D slice value # self.imageSliceSliderWidget = ctk.ctkSliderWidget() self.imageSliceSliderWidget.singleStep = 1 self.imageSliceSliderWidget.minimum = 0 self.imageSliceSliderWidget.maximum = 70 self.imageSliceSliderWidget.value = 1 self.imageSliceSliderWidget.setToolTip("Select 2D slice") advancedFormLayout.addRow("2D Slice ", self.imageSliceSliderWidget) # # Mask Threshold # self.maskThresholdWidget = ctk.ctkSliderWidget() self.maskThresholdWidget.singleStep = 1 self.maskThresholdWidget.minimum = 0 self.maskThresholdWidget.maximum = 100 self.maskThresholdWidget.value = 20 self.maskThresholdWidget.setToolTip( "Set threshold value for computing the output image. Voxels that have intensities lower than this value will set to zero." ) advancedFormLayout.addRow("Mask Threshold ", self.maskThresholdWidget) # # Ridge operator filter # self.ridgeOperatorWidget = ctk.ctkSliderWidget() self.ridgeOperatorWidget.singleStep = 1 self.ridgeOperatorWidget.minimum = 0 self.ridgeOperatorWidget.maximum = 100 self.ridgeOperatorWidget.value = 5 self.ridgeOperatorWidget.setToolTip( "set up meijering filter threshold") advancedFormLayout.addRow("Ridge Operator Threshold", self.ridgeOperatorWidget) # # 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) # # Manual apply Button # self.applyButton = qt.QPushButton("Manual") self.applyButton.toolTip = "Select slice manually" self.applyButton.enabled = False advancedFormLayout.addRow(self.applyButton) # Refresh Apply button state self.onSelect() # # check box to trigger preview final processed image # self.enableprocessedimagecheckbox = qt.QCheckBox() self.enableprocessedimagecheckbox.checked = 0 self.enableprocessedimagecheckbox.setToolTip( "If checked, take screen shots for tutorials. Use Save Data to write them to disk." ) advancedFormLayout.addRow("Enable Processed Image", self.enableprocessedimagecheckbox) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.trackingButton.connect('clicked(bool)', self.onRealTimeTracking) self.SRCtrackingButton.connect('clicked(bool)', self.SRCRealTimeTracking) self.autosliceselecterButton.connect('clicked(bool)', self.autosliceselecter) self.magnitudevolume.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.phasevolume.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.lastMatrix = vtk.vtkMatrix4x4() self.timer = qt.QTimer() self.timer.timeout.connect(self.SRCRealTimeTracking) self.SimTimer = qt.QTimer() self.SimTimer.timeout.connect(self.onRealTimeTracking)
def setup(self): ScriptedLoadableModuleWidget.setup(self) ################################### # Import node graph json file Area ################################### self.fileCollapsibleButton = ctk.ctkCollapsibleButton() self.fileCollapsibleButton.text = "Import Node Graph Json File" self.layout.addWidget(self.fileCollapsibleButton) self.fileImportFormLayout = qt.QFormLayout(self.fileCollapsibleButton) self.fileImport = ctk.ctkPathLineEdit() self.fileImport.filters = ctk.ctkPathLineEdit.Files self.fileImport.settingKey = 'JsonInputFile' self.fileImport.currentPath = os.path.normpath( os.path.join(os.path.dirname(os.path.realpath(__file__)), './Resources/nodeGraph_3D.json')) self.fileImportFormLayout.addRow("Input Json File:", self.fileImport) self.fileImportButton = qt.QPushButton('Load File') self.fileImportFormLayout.addRow(self.fileImportButton) ################################### # Node Table Area ################################### parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Node Table" self.layout.addWidget(parametersCollapsibleButton) # Layout within the collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) # # Checkbox to see whether or not the input table has a header # self.headerCheckBox = qt.QCheckBox() self.headerCheckBox.checked = 0 self.headerCheckBox.setToolTip( "If checked, it means that the input node table contains a header." ) parametersFormLayout.addRow("Header in Node Table", self.headerCheckBox) # # input table selector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLTableNode"] 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( "The input file loaded trough the import Data module should be a one line table (with or without header)." ) parametersFormLayout.addRow("Input Table: ", self.inputSelector) # # Table start column spinBox # self.min_column = 1 self.tableStartSpinBox = qt.QDoubleSpinBox() self.tableStartSpinBox.singleStep = 1 self.tableStartSpinBox.setValue(self.min_column) self.tableStartSpinBox.setDecimals(0) self.tableStartSpinBox.setToolTip( "Set start column, if the first column contains a string of characters(ex: subject name) then this column should be skipped and the start column is thus 1. This should be an integer (int)" ) parametersFormLayout.addRow("Start Column:", self.tableStartSpinBox) ################################### # Region Selector Area ################################### self.nodeselectCollapsibleButton = ctk.ctkCollapsibleButton() self.nodeselectCollapsibleButton.text = "Selection of Node Region" self.layout.addWidget(self.nodeselectCollapsibleButton) # Layout within the collapsible button self.nodeselectFormLayout = qt.QFormLayout( self.nodeselectCollapsibleButton) # Search Box to filter regions to display self.searchLayout = qt.QHBoxLayout() self.nodeselectFormLayout.addRow('Search:', self.searchLayout) self.regionSearchBox = ctk.ctkSearchBox() self.regionSearchBox.placeholderText = "search region" self.regionSearchBox.searchIcon self.searchLayout.addWidget(self.regionSearchBox) self.logic = visuThreeDLogic() self.regionsLayout = qt.QHBoxLayout() self.nodeselectFormLayout.addRow('Regions:', self.regionsLayout) self.regionButtons = ctk.ctkCheckableComboBox() self.regionsLayout.addWidget(self.regionButtons) # Add buttons to select all or no region self.buttonsLayout = qt.QHBoxLayout() self.nodeselectFormLayout.addRow('Select:', self.buttonsLayout) self.calculateAllregionsButton = qt.QPushButton('Select All') self.calculateAllregionsButton.toolTip = 'Select all regions.' self.calculateAllregionsButton.enabled = True self.buttonsLayout.addWidget(self.calculateAllregionsButton) self.calculateAllFilteredregionsButton = qt.QPushButton( 'Select Filtered') self.calculateAllFilteredregionsButton.toolTip = 'Select all filtered regions.' self.calculateAllFilteredregionsButton.enabled = True self.buttonsLayout.addWidget(self.calculateAllFilteredregionsButton) self.deselectButtonsLayout = qt.QHBoxLayout() self.nodeselectFormLayout.addRow('Deselect:', self.deselectButtonsLayout) self.calculateNoregionsButton = qt.QPushButton('Deselect All') self.calculateNoregionsButton.toolTip = 'Deselect all regions.' self.calculateNoregionsButton.enabled = True self.deselectButtonsLayout.addWidget(self.calculateNoregionsButton) self.calculateNoFilteredregionsButton = qt.QPushButton( 'Deselect Filtered') self.calculateNoFilteredregionsButton.toolTip = 'Deselect all filtered regions.' self.calculateNoFilteredregionsButton.enabled = True self.deselectButtonsLayout.addWidget( self.calculateNoFilteredregionsButton) ################################### # Node Size and colorbar thresholding Area ################################### self.colorbarCollapsibleButton = ctk.ctkCollapsibleButton() self.colorbarCollapsibleButton.text = "Node Size and Color Thresholding" self.layout.addWidget(self.colorbarCollapsibleButton) # Layout within the collapsible button self.regioncheckFormLayout = qt.QFormLayout( self.colorbarCollapsibleButton) self.ColorTable = slicer.qMRMLColorTableComboBox() self.ColorTable.nodeTypes = ["vtkMRMLColorTableNode"] self.ColorTable.addEnabled = True self.ColorTable.removeEnabled = True self.ColorTable.noneEnabled = True self.ColorTable.showHidden = True self.ColorTable.setMRMLScene(slicer.mrmlScene) self.regioncheckFormLayout.addRow("Input Color Map: ", self.ColorTable) # # Threshold node value # # default values self.minVal = 0.0 self.maxVal = 1.0 self.nodeThresholdSliderWidget = ctk.ctkRangeWidget() self.nodeThresholdSliderWidget.singleStep = 0.01 self.nodeThresholdSliderWidget.setValues(self.minVal, self.maxVal) self.nodeThresholdSliderWidget.setMaximumValue(self.maxVal) self.nodeThresholdSliderWidget.setMinimumValue(self.minVal) self.nodeThresholdSliderWidget.setRange(self.minVal, self.maxVal) self.nodeThresholdSliderWidget.setMouseTracking(True) self.nodeThresholdSliderWidget.setEnabled(True) self.nodeThresholdSliderWidget.setToolTip( "Set threshold node value for computing the node value.") self.regioncheckFormLayout.addRow("Plot Property Range:", self.nodeThresholdSliderWidget) # # Node size min spinBox # # default value for min size (l: lowest , h: highest) self.minSize_l = 0.0 self.minSize_h = 100.0 self.nodeMinSizeSpinBox = qt.QDoubleSpinBox() self.nodeMinSizeSpinBox.singleStep = 0.01 self.nodeMinSizeSpinBox.setRange(self.minSize_l, self.minSize_h) self.nodeMinSizeSpinBox.setToolTip("Set minimum node size.") self.regioncheckFormLayout.addRow("Min Size:", self.nodeMinSizeSpinBox) # # Node size max spinBox # # default value for max size (l: lowest , h: highest) self.maxSize_l = 0.0 self.maxSize_h = 100.0 self.nodeMaxSizeSpinBox = qt.QDoubleSpinBox() self.nodeMaxSizeSpinBox.singleStep = 0.01 self.nodeMaxSizeSpinBox.setRange(self.maxSize_l, self.maxSize_h) self.nodeMaxSizeSpinBox.setToolTip("Set maximum node size.") self.regioncheckFormLayout.addRow("Max Size:", self.nodeMaxSizeSpinBox) ################################### # Connections line/tube Area ################################### self.lineCollapsibleButton = ctk.ctkCollapsibleButton() self.lineCollapsibleButton.text = "Connection Size and Color Thresholding" self.layout.addWidget(self.lineCollapsibleButton) # Layout within the collapsible button self.lineconnectFormLayout = qt.QFormLayout(self.lineCollapsibleButton) # # input connection matrix selector # self.matrixConnectSelector = slicer.qMRMLNodeComboBox() self.matrixConnectSelector.nodeTypes = ["vtkMRMLTableNode"] self.matrixConnectSelector.selectNodeUponCreation = True self.matrixConnectSelector.addEnabled = False self.matrixConnectSelector.removeEnabled = False self.matrixConnectSelector.noneEnabled = False self.matrixConnectSelector.showHidden = False self.matrixConnectSelector.showChildNodeTypes = False self.matrixConnectSelector.setMRMLScene(slicer.mrmlScene) self.matrixConnectSelector.setToolTip( "Pick the connection matrix input to the algorithm.") self.lineconnectFormLayout.addRow("Input Connection Table: ", self.matrixConnectSelector) # # Checkbox to choose whether or not the connection distribution follows a log scale or else a linear distribution # self.connectionDistCheckBox = qt.QCheckBox() self.connectionDistCheckBox.checked = 0 self.connectionDistCheckBox.setToolTip( "If checked, it means that the connection distribution follows a log scale." ) self.lineconnectFormLayout.addRow("Log Distribution", self.connectionDistCheckBox) self.connectionColorTable = slicer.qMRMLColorTableComboBox() self.connectionColorTable.nodeTypes = ["vtkMRMLColorTableNode"] self.connectionColorTable.addEnabled = True self.connectionColorTable.removeEnabled = True self.connectionColorTable.noneEnabled = True self.connectionColorTable.showHidden = True self.connectionColorTable.setMRMLScene(slicer.mrmlScene) self.lineconnectFormLayout.addRow("Input Color Map: ", self.connectionColorTable) # # Threshold node connection strength # # default values self.logic = visuThreeDLogic() self.min_strength = 0.0 self.max_strength = 1.0 self.connectionThresholdSliderWidget = ctk.ctkRangeWidget() self.connectionThresholdSliderWidget.singleStep = 0.01 self.connectionThresholdSliderWidget.setValues(self.min_strength, self.max_strength) self.connectionThresholdSliderWidget.setMaximumValue(self.max_strength) self.connectionThresholdSliderWidget.setMinimumValue(self.min_strength) self.connectionThresholdSliderWidget.setRange(self.minVal, self.max_strength) self.connectionThresholdSliderWidget.setMouseTracking(True) self.connectionThresholdSliderWidget.setEnabled(True) self.connectionThresholdSliderWidget.setToolTip( "Set threshold node value for computing the node value.") self.lineconnectFormLayout.addRow("Plot Strength Range:", self.connectionThresholdSliderWidget) # # Connection min strength spinBox # # default value for min strength (l: lowest , h: highest) self.minStrength_l = 0.0 self.minStrength_h = 50.0 self.minConnectionSpinBox = qt.QDoubleSpinBox() self.minConnectionSpinBox.singleStep = 0.01 self.minConnectionSpinBox.setRange(self.minStrength_l, self.minStrength_h) self.minConnectionSpinBox.setToolTip( "Set minimum connection strength.") self.lineconnectFormLayout.addRow("Min Strength:", self.minConnectionSpinBox) # # Node size max spinBox # # default value for max size (l: lowest , h: highest) self.maxStrength_l = 0.0 self.maxStrength_h = 100.0 self.maxConnectionSpinBox = qt.QDoubleSpinBox() self.maxConnectionSpinBox.singleStep = 0.01 self.maxConnectionSpinBox.setRange(self.maxStrength_l, self.maxStrength_h) self.maxConnectionSpinBox.setToolTip( "Set maximum connection strength.") self.lineconnectFormLayout.addRow("Max Strenght:", self.maxConnectionSpinBox) ################################### # Advanced Connections scale factors Area ################################### self.scaleCollapsibleButton = ctk.ctkCollapsibleButton() self.scaleCollapsibleButton.text = "Advanced Connection Scale Factors" self.layout.addWidget(self.scaleCollapsibleButton) # Layout within the collapsible button self.scaleconnectFormLayout = qt.QFormLayout( self.scaleCollapsibleButton) #Double SpinBox for default scale factor "f" : #computation of value in matrix by the number of connexions * f factor self.fscaleDoubleSpinBox = ctk.ctkDoubleSpinBox() self.fscaleDoubleSpinBox.setValue(0.000033) self.fscaleDoubleSpinBox.setDecimals(6) self.fscaleDoubleSpinBox.enabled = True self.scaleconnectFormLayout.addWidget(self.fscaleDoubleSpinBox) self.scaleconnectFormLayout.addRow("f Scale:", self.fscaleDoubleSpinBox) #Double SpinBox for log scale factor "C" : self.logScaleDoubleSpinBox = ctk.ctkDoubleSpinBox() self.logScaleDoubleSpinBox.setValue(10) self.logScaleDoubleSpinBox.setDecimals(0.) self.logScaleDoubleSpinBox.enabled = False self.scaleconnectFormLayout.addWidget(self.logScaleDoubleSpinBox) self.scaleconnectFormLayout.addRow("C Log Scale:", self.logScaleDoubleSpinBox) ################################### # Connections ################################### self.coord = [] self.index = [] self.position = [] self.visu = [] self.fileImportButton.connect('clicked(bool)', self.on_node_graph_json_load) self.inputSelector.connect("nodeActivated(vtkMRMLNode*)", self.on_select) self.regionButtons.connect('checkedIndexesChanged()', self.on_regions_checked) self.calculateAllFilteredregionsButton.connect( 'clicked(bool)', self.on_select_all_filtered_regionButtons) self.calculateAllregionsButton.connect( 'clicked(bool)', self.on_select_all_regionButtons) self.calculateNoregionsButton.connect( 'clicked(bool)', self.on_deselect_all_regionButtons) self.calculateNoFilteredregionsButton.connect( 'clicked(bool)', self.on_deselect_all_filtered_regionButtons) self.regionSearchBox.connect("textChanged(QString)", self.on_search) self.ColorTable.connect("currentNodeChanged(vtkMRMLNode*)", self.on_node_color_clicked) self.nodeThresholdSliderWidget.connect("valuesChanged(double, double)", self.sliderbar_changed) self.nodeMinSizeSpinBox.connect("valueChanged(double)", self.min_nodesize_changed) self.nodeMaxSizeSpinBox.connect("valueChanged(double)", self.max_nodesize_changed) self.tableStartSpinBox.connect("valueChanged(double)", self.table_start_changed) self.matrixConnectSelector.connect("nodeActivated(vtkMRMLNode*)", self.on_select_matrix) self.connectionThresholdSliderWidget.connect( "valuesChanged(double, double)", self.sliderbar2_changed) self.maxConnectionSpinBox.connect("valueChanged(double)", self.max_connection_changed) self.connectionColorTable.connect("currentNodeChanged(vtkMRMLNode*)", self.on_connect_color_clicked) self.fscaleDoubleSpinBox.connect("valueChanged(double)", self.on_fscale_changed) self.logScaleDoubleSpinBox.connect("valueChanged(double)", self.on_logscale_changed) # Add vertical spacer self.layout.addStretch(1) self.header = None self.connection_d = None self.value = 'None' self.on_node_graph_json_load()
def setup(self): ScriptedLoadableModuleWidget.setup(self) ########################################################################################## # Set model name ########################################################################################## modelNameButton = ctk.ctkCollapsibleButton() modelNameButton.text = "Simulation name" self.layout.addWidget(modelNameButton) modelNameButtonLayout = qt.QFormLayout(modelNameButton) self.nameBox = qt.QLineEdit() now = datetime.datetime.now() self.nameBox.text = "TEST_" + str(now.minute) + "_" + str(now.second) modelNameButtonLayout.addRow("Model_name", self.nameBox) ########################################################################################## # Input medical image ########################################################################################## medicalimageButton = ctk.ctkCollapsibleButton() medicalimageButton.text = "Input CT image" self.layout.addWidget(medicalimageButton) medicalimageFormLayout = qt.QFormLayout(medicalimageButton) 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 CT image.") medicalimageFormLayout.addRow("Input CT Volume: ", self.inputSelector) ########################################################################################## # Set Location Area ########################################################################################## locationCollapsibleButton = ctk.ctkCollapsibleButton() locationCollapsibleButton.text = "Set Locations" self.layout.addWidget(locationCollapsibleButton) locationFormLayout = qt.QFormLayout(locationCollapsibleButton) # Set Entry location self.entry = qt.QLabel("Entry Position") self.entry.setFixedWidth(100) locationFormLayout.addRow(self.entry) self.eXLabel = qt.QLabel("X") self.eXLabel.setFixedWidth(10) self.eX = qt.QDoubleSpinBox() self.eX.setRange(-300, 300) self.eX.value = 87.275 self.eYLabel = qt.QLabel("Y") self.eYLabel.setFixedWidth(10) self.eY = qt.QDoubleSpinBox() self.eY.setRange(-300, 300) self.eY.value = -45.256 self.eZLabel = qt.QLabel("Z") self.eZLabel.setFixedWidth(10) self.eZ = qt.QDoubleSpinBox() self.eZ.setRange(-300, 300) self.eZ.value = 83.913 entryLayout = qt.QHBoxLayout() entryLayout.addWidget(self.eXLabel) entryLayout.addWidget(self.eX) entryLayout.addWidget(self.eYLabel) entryLayout.addWidget(self.eY) entryLayout.addWidget(self.eZLabel) entryLayout.addWidget(self.eZ) locationFormLayout.addRow(entryLayout) # Set Target location self.target = qt.QLabel("Target Position") self.target.setFixedWidth(100) locationFormLayout.addRow(self.target) self.pXLabel = qt.QLabel("X") self.pXLabel.setFixedWidth(10) self.pX = qt.QDoubleSpinBox() self.pX.setRange(-300, 300) self.pX.value = 49.694 self.pYLabel = qt.QLabel("Y") self.pYLabel.setFixedWidth(10) self.pY = qt.QDoubleSpinBox() self.pY.setRange(-300, 300) self.pY.value = -39.790 self.pZLabel = qt.QLabel("Z") self.pZLabel.setFixedWidth(10) self.pZ = qt.QDoubleSpinBox() self.pZ.setRange(-300, 300) self.pZ.value = 43.826 targetLayout = qt.QHBoxLayout() targetLayout.addWidget(self.pXLabel) targetLayout.addWidget(self.pX) targetLayout.addWidget(self.pYLabel) targetLayout.addWidget(self.pY) targetLayout.addWidget(self.pZLabel) targetLayout.addWidget(self.pZ) locationFormLayout.addRow(targetLayout) self.setLocation = qt.QPushButton("Set Location") self.setLocation.toolTip = "Set entry and target location" self.setLocation.enabled = True locationFormLayout.addRow(self.setLocation) self.setLocation.connect('clicked(bool)', self.setLocationPrint) ########################################################################################## # Transducer parameters ########################################################################################## transducerCollapsibleButton = ctk.ctkCollapsibleButton() transducerCollapsibleButton.text = "Transducer & voxelization Parameters" self.layout.addWidget(transducerCollapsibleButton) transducerFormLayout = qt.QFormLayout(transducerCollapsibleButton) self.ROC = qt.QDoubleSpinBox() self.ROC.setRange(0, 300) self.ROC.value = 71 self.width = qt.QDoubleSpinBox() self.width.setRange(0, 300) self.width.value = 65 self.freq = qt.QDoubleSpinBox() self.freq.setRange(0, 2) self.freq.value = 0.25 self.PPW = qt.QDoubleSpinBox() self.PPW.setRange(2, 20) self.PPW.value = 10 self.sizeSmallRadioButton = qt.QRadioButton() self.sizeSmallRadioButton.text = 'Small' self.sizeSmallRadioButton.checked = True self.sizeLargeRadioButton = qt.QRadioButton() self.sizeLargeRadioButton.text = 'Large' #self.sizeBigRadioButton.setchecked(False) boundaryLayout = qt.QHBoxLayout() boundaryLayout.addWidget(self.sizeSmallRadioButton) boundaryLayout.addWidget(self.sizeLargeRadioButton) transducerFormLayout.addRow("ROC", self.ROC) transducerFormLayout.addRow("Width", self.width) transducerFormLayout.addRow("MHz", self.freq) transducerFormLayout.addRow("Point per wavelength", self.PPW) transducerFormLayout.addRow("Boundary size", boundaryLayout) self.transButton = qt.QPushButton("Transducer and Voxelization") self.transButton.toolTip = "Make transducer and voxelization for simulation." self.transButton.enabled = True transducerFormLayout.addRow(self.transButton) self.transButton.connect('clicked(bool)', self.voxelization) ########################################################################################## # Simulation parameters ########################################################################################## simulationCollapsibleButton = ctk.ctkCollapsibleButton() simulationCollapsibleButton.text = "Simulation Parameters" self.layout.addWidget(simulationCollapsibleButton) simulationFormLayout = qt.QFormLayout(simulationCollapsibleButton) self.endTime = qt.QDoubleSpinBox() self.endTime.setRange(0, 300) self.endTime.value = 150 self.CFL = qt.QDoubleSpinBox() self.CFL.setRange(0, 1) self.CFL.value = 0.1 simulationFormLayout.addRow("End time (μs)", self.endTime) simulationFormLayout.addRow("CFL", self.CFL) self.simulationButton = qt.QPushButton("Run simulation") self.simulationButton.toolTip = "Run the algorithm." self.simulationButton.enabled = True # Run simulation button simulationFormLayout.addRow(self.simulationButton) self.simulationButton.connect('clicked(bool)', self.runSimulation) # Add vertical spacer self.layout.addStretch(1) self.simul = makeSimulation() # Make model dir self.newdir = current_path + '/' + self.nameBox.text if not os.path.exists(self.newdir): os.makedirs(self.newdir)
def createEditor(self, parent, option, index): spinBox = qt.QDoubleSpinBox(parent) spinBox.setSingleStep(1) spinBox.maximum = 50 spinBox.minimum = 5 return spinBox
def create(self): super(WatershedFromMarkerEffectOptions, self).create() if not HAVE_SIMPLEITK: self.warningLabel = qt.QLabel() self.warningLabel.text = "WatershedFromMarker is not available because\nSimpleITK is not available in this build" self.widgets.append(self.warningLabel) self.frame.layout().addWidget(self.warningLabel) return labelVolume = EditUtil.getLabelVolume() if labelVolume and labelVolume.GetImageData(): spacing = labelVolume.GetSpacing() self.minimumSigma = 0.1 * min(spacing) self.maximumSigma = 100 * self.minimumSigma else: self.minimumSigma = 0.1 self.maximumSigma = 10 self.sigmaFrame = qt.QFrame(self.frame) self.sigmaFrame.setLayout(qt.QHBoxLayout()) self.frame.layout().addWidget(self.sigmaFrame) self.widgets.append(self.sigmaFrame) tip = "Increasing this value smooths the segmentation and reduces leaks. This is the sigma used for edge detection." self.sigmaLabel = qt.QLabel("Object Scale: ", self.frame) self.sigmaLabel.setToolTip(tip) self.sigmaFrame.layout().addWidget(self.sigmaLabel) self.widgets.append(self.sigmaLabel) self.sigmaSlider = qt.QSlider(qt.Qt.Horizontal, self.frame) self.sigmaFrame.layout().addWidget(self.sigmaSlider) self.sigmaFrame.setToolTip(tip) self.widgets.append(self.sigmaSlider) self.sigmaSpinBox = qt.QDoubleSpinBox(self.frame) self.sigmaSpinBox.setToolTip(tip) self.sigmaSpinBox.suffix = "mm" self.sigmaFrame.layout().addWidget(self.sigmaSpinBox) self.widgets.append(self.sigmaSpinBox) self.sigmaSpinBox.minimum = self.minimumSigma self.sigmaSlider.minimum = self.minimumSigma self.sigmaSpinBox.maximum = self.maximumSigma self.sigmaSlider.maximum = self.maximumSigma decimals = math.floor(math.log(self.minimumSigma, 10)) if decimals < 0: self.sigmaSpinBox.decimals = -decimals + 2 self.apply = qt.QPushButton("Apply", self.frame) self.apply.objectName = self.__class__.__name__ + 'Apply' self.apply.setToolTip("Apply the extension operation") self.frame.layout().addWidget(self.apply) self.widgets.append(self.apply) helpDoc = \ """Use this effect to apply the watershed from markers segmentation from multiple initial labels. The input to this filter is current labelmap image which is expected to contain multiple labels as initial marks. The marks or labels are grown to fill the image and with edges defining the bondaries between. To segment a single object, mark the object, and then it is suggested to surround the object with a negative label on each axis. The "Object Scale" parameter is use to adjust the smoothness of the output image and prevent leakage. It is used internally for the sigma of the gradient magnitude. """ HelpButton(self.frame, helpDoc) self.sigmaSlider.connect('valueChanged(int)', self.sigmaSpinBox.setValue) self.sigmaSpinBox.connect('valueChanged(double)', self.sigmaSlider.setValue) # if either widget is changed both should change and this should be triggered self.connections.append((self.sigmaSpinBox, 'valueChanged(double)', self.onSigmaValueChanged)) self.connections.append((self.apply, 'clicked()', self.onApply)) # Add vertical spacer self.frame.layout().addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... self.logic = Tissue_Scanning_ModuleLogic() # Load widget from .ui file (created by Qt Designer) #uiWidget = slicer.util.loadUI(self.resourcePath('UI/Tissue_Scanning_Module.ui')) #self.layout.addWidget(uiWidget) #self.ui = slicer.util.childWidgetVariables(uiWidget) # # Parameters Area # CameraControlCollapsibleButton = ctk.ctkCollapsibleButton() CameraControlCollapsibleButton.text = "Camera Control " self.layout.addWidget(CameraControlCollapsibleButton) CameraControlFormLayout = qt.QFormLayout(CameraControlCollapsibleButton) # # # IGT Link Connector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLIGTLConnectorNode"] self.inputSelector.selectNodeUponCreation = False 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("Connect to OpenIGTLink to control printer from module.") CameraControlFormLayout.addRow("Connect to: ", self.inputSelector) self.inputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onCameraSelect) #self.ui.cameraInputSelector.setMRMLScene(slicer.mrmlScene) #self.ui.outputSelector.setMRMLScene(slicer.mrmlScene) # set max and min values of step size microm self.stepSizeNumSpinBox = qt.QDoubleSpinBox() self.stepSizeNumSpinBox.setMinimum(1) self.stepSizeNumSpinBox.setMaximum(10000) self.stepSizeNumSpinBox.setValue(500) CameraControlFormLayout.addRow("Step size (um) :", self.stepSizeNumSpinBox) # connections self.calibrateButton = qt.QPushButton("Calibrate Camera") self.calibrateButton.connect('clicked(bool)', self.onCalibrateButton) self.calibrateButton.enabled = True CameraControlFormLayout.addRow(self.calibrateButton) self.pictureButton = qt.QPushButton("Take Slide Picture") self.pictureButton.connect('clicked(bool)', self.onPictureButton) self.pictureButton.enabled = True CameraControlFormLayout.addRow(self.pictureButton) self.contourButton = qt.QPushButton("Determine Tissue Contour") self.contourButton.connect('clicked(bool)', self.onContourButton) self.contourButton.enabled = True CameraControlFormLayout.addRow(self.contourButton) self.scanningButton = qt.QPushButton("Generate Scanning Pattern") self.scanningButton.connect('clicked(bool)', self.onScanningButton) self.scanningButton.enabled = True CameraControlFormLayout.addRow(self.scanningButton) self.testButton = qt.QPushButton("Gnew button") self.testButton.connect('clicked(bool)', self.onTestButton) self.testButton.enabled = True CameraControlFormLayout.addRow(self.testButton) #self.ui.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onInputSelect) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onCameraSelect()
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Input Parameters Area # parametersInputCollapsibleButton = ctk.ctkCollapsibleButton() parametersInputCollapsibleButton.text = "Input Parameters" self.layout.addWidget(parametersInputCollapsibleButton) # Layout within the dummy collapsible button parametersInputFormLayout = qt.QFormLayout(parametersInputCollapsibleButton) # # input T1 volume selector # self.inputT1Selector = slicer.qMRMLNodeComboBox() self.inputT1Selector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputT1Selector.selectNodeUponCreation = True self.inputT1Selector.addEnabled = False self.inputT1Selector.removeEnabled = True self.inputT1Selector.noneEnabled = True self.inputT1Selector.showHidden = False self.inputT1Selector.showChildNodeTypes = False self.inputT1Selector.setMRMLScene(slicer.mrmlScene) self.inputT1Selector.setToolTip("A T1 weighted MRI image from a healthy individual.") parametersInputFormLayout.addRow("T1 Volume ", self.inputT1Selector) # # input T2 volume selector # self.inputT2Selector = slicer.qMRMLNodeComboBox() self.inputT2Selector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputT2Selector.selectNodeUponCreation = False self.inputT2Selector.addEnabled = False self.inputT2Selector.removeEnabled = True self.inputT2Selector.noneEnabled = True self.inputT2Selector.showHidden = False self.inputT2Selector.showChildNodeTypes = False self.inputT2Selector.setMRMLScene(slicer.mrmlScene) self.inputT2Selector.setToolTip("A T2 weighted MRI image from a healthy individual.") parametersInputFormLayout.addRow("T2 Volume ", self.inputT2Selector) # # input FLAIR volume selector # self.inputFLAIRSelector = slicer.qMRMLNodeComboBox() self.inputFLAIRSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputFLAIRSelector.selectNodeUponCreation = False self.inputFLAIRSelector.addEnabled = False self.inputFLAIRSelector.removeEnabled = True self.inputFLAIRSelector.noneEnabled = True self.inputFLAIRSelector.showHidden = False self.inputFLAIRSelector.showChildNodeTypes = False self.inputFLAIRSelector.setMRMLScene(slicer.mrmlScene) self.inputFLAIRSelector.setToolTip("A T2-FLAIR weighted MRI image from a healthy individual.") parametersInputFormLayout.addRow("T2-FLAIR Volume ", self.inputFLAIRSelector) # # input PD volume selector # self.inputPDSelector = slicer.qMRMLNodeComboBox() self.inputPDSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputPDSelector.selectNodeUponCreation = False self.inputPDSelector.addEnabled = False self.inputPDSelector.removeEnabled = True self.inputPDSelector.noneEnabled = True self.inputPDSelector.showHidden = False self.inputPDSelector.showChildNodeTypes = False self.inputPDSelector.setMRMLScene(slicer.mrmlScene) self.inputPDSelector.setToolTip("A PD weighted MRI image from a healthy individual.") parametersInputFormLayout.addRow("PD Volume ", self.inputPDSelector) # # input DTI-FA volume selector # self.inputFASelector = slicer.qMRMLNodeComboBox() self.inputFASelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputFASelector.selectNodeUponCreation = False self.inputFASelector.addEnabled = False self.inputFASelector.removeEnabled = True self.inputFASelector.noneEnabled = True self.inputFASelector.showHidden = False self.inputFASelector.showChildNodeTypes = False self.inputFASelector.setMRMLScene(slicer.mrmlScene) self.inputFASelector.setToolTip("A DTI-FA map from a healthy individual.") parametersInputFormLayout.addRow("DTI-FA Map ", self.inputFASelector) # # input DTI-ADC volume selector # self.inputADCSelector = slicer.qMRMLNodeComboBox() self.inputADCSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputADCSelector.selectNodeUponCreation = False self.inputADCSelector.addEnabled = False self.inputADCSelector.removeEnabled = True self.inputADCSelector.noneEnabled = True self.inputADCSelector.showHidden = False self.inputADCSelector.showChildNodeTypes = False self.inputADCSelector.setMRMLScene(slicer.mrmlScene) self.inputADCSelector.setToolTip("A DTI-ADC map from a healthy individual.") parametersInputFormLayout.addRow("DTI-ADC Map ", self.inputADCSelector) # # Return inputs to original space # self.setReturnOriginalSpaceBooleanWidget = ctk.ctkCheckBox() self.setReturnOriginalSpaceBooleanWidget.setChecked(False) self.setReturnOriginalSpaceBooleanWidget.setToolTip( "Choose if you want to transform the final images to its original space. If not, all the input images will be in T1 space. NOTE: This choice only takes " "effect on the baseline MS lesion simulation, i.e. the longitudinal lesion simulation (if checked) will always return the data using the T1 space.") parametersInputFormLayout.addRow("Return output data in the original space", self.setReturnOriginalSpaceBooleanWidget) # # Is brain extracted? # self.setIsBETBooleanWidget = ctk.ctkCheckBox() self.setIsBETBooleanWidget.setChecked(False) self.setIsBETBooleanWidget.setToolTip( "Is the input data already brain extracted? This information is only used for MNI152 template, where it helps to the registration process.") parametersInputFormLayout.addRow("Is brain extraced?", self.setIsBETBooleanWidget) # # is input data on MNI space? # self.setIsMNIBooleanWidget = ctk.ctkCheckBox() self.setIsMNIBooleanWidget.setChecked(False) self.setIsMNIBooleanWidget.setToolTip( "Is the input data already in MNI space? If the input volumes are already in the MNI space, the time-consuming registration step will be skipped.") parametersInputFormLayout.addRow("Is data in MNI space?", self.setIsMNIBooleanWidget) # # Lesion Load value # self.lesionLoadSliderWidget = ctk.ctkSliderWidget() self.lesionLoadSliderWidget.singleStep = 1 self.lesionLoadSliderWidget.minimum = 5 self.lesionLoadSliderWidget.maximum = 50 self.lesionLoadSliderWidget.value = 10 self.lesionLoadSliderWidget.setToolTip("Set the desired lesion load to be used for MS lesion generation.") parametersInputFormLayout.addRow("Lesion Load", self.lesionLoadSliderWidget) # # MS Longitudinal Lesion Simulation Parameters Area # parametersMSLongitudinalLesionSimulationCollapsibleButton = ctk.ctkCollapsibleButton() parametersMSLongitudinalLesionSimulationCollapsibleButton.text = "MS Longitudinal Lesion Simulation Parameters" self.layout.addWidget(parametersMSLongitudinalLesionSimulationCollapsibleButton) # Layout within the dummy collapsible button parametersMSLongitudinalLesionSimulationFormLayout = qt.QFormLayout(parametersMSLongitudinalLesionSimulationCollapsibleButton) # # Simulate follow-up? # self.setSimulateFollowUpBooleanWidget = ctk.ctkCheckBox() self.setSimulateFollowUpBooleanWidget.setChecked(False) self.setSimulateFollowUpBooleanWidget.setToolTip( "Simulate an additional longitudinal sequence (given the same input data)? If checked, the MS Lesion Simulator tool will recreate a sequence of exams with " "longitudinal MS lesion pattern.") parametersMSLongitudinalLesionSimulationFormLayout.addRow("Simulate Longitudinal Exams?", self.setSimulateFollowUpBooleanWidget) # # Follow-ups # self.followUpsSliderWidget = ctk.ctkSliderWidget() self.followUpsSliderWidget.singleStep = 1 self.followUpsSliderWidget.minimum = 2 self.followUpsSliderWidget.maximum = 6 self.followUpsSliderWidget.value = 2 self.followUpsSliderWidget.setToolTip("Set the desired number of follow-up acquisitions that will be simulated.") parametersMSLongitudinalLesionSimulationFormLayout.addRow("Follow-ups", self.followUpsSliderWidget) # # Balance: Hypointense to isointense lesions # self.setBalanceHypo2IsoWidget = qt.QSpinBox() self.setBalanceHypo2IsoWidget.setMaximum(100) self.setBalanceHypo2IsoWidget.setMinimum(1) self.setBalanceHypo2IsoWidget.setSingleStep(0.1) self.setBalanceHypo2IsoWidget.setValue(56) self.setBalanceHypo2IsoWidget.setToolTip( "Set the percentage of lesions that will change its original signal state along the follow-ups.") parametersMSLongitudinalLesionSimulationFormLayout.addRow("Changing Contrast Balance ", self.setBalanceHypo2IsoWidget) # # output follow-ups selector # self.outputFollowUpsSelector = ctk.ctkDirectoryButton() self.outputFollowUpsSelector.setToolTip("Output folder where follow-up image files will be saved.") if platform.system() is "Windows": home = expanduser("%userprofile%") else: home = expanduser("~") self.outputFollowUpsSelector.directory = home parametersMSLongitudinalLesionSimulationFormLayout.addRow("Output Follow-Up ", self.outputFollowUpsSelector) # # Advanced Parameters Area # parametersAdvancedParametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersAdvancedParametersCollapsibleButton.text = "Advanced Parameters" self.layout.addWidget(parametersAdvancedParametersCollapsibleButton) parametersAdvancedParametersCollapsibleButton.click() # Layout within the dummy collapsible button parametersAdvancedParametersFormLayout = qt.QFormLayout(parametersAdvancedParametersCollapsibleButton) # # White Matter Threshold # self.setWMThresholdWidget = qt.QDoubleSpinBox() self.setWMThresholdWidget.setMaximum(5) self.setWMThresholdWidget.setMinimum(0.1) self.setWMThresholdWidget.setSingleStep(0.01) self.setWMThresholdWidget.setValue(1.5) self.setWMThresholdWidget.setToolTip("Set the White Matter threshold used to refine the simulated lesion map. The simulation supose that the MS lesions" "belongs only in the White Matter space. This variable is related to the voxel intensity and the White Matter probability" " distribution (standard deviation).") parametersAdvancedParametersFormLayout.addRow("White Matter Threshold ", self.setWMThresholdWidget) # # Percentage Sampling Area # self.setPercSamplingQWidget = qt.QDoubleSpinBox() self.setPercSamplingQWidget.setDecimals(4) self.setPercSamplingQWidget.setMaximum(1) self.setPercSamplingQWidget.setMinimum(0.0001) self.setPercSamplingQWidget.setSingleStep(0.001) self.setPercSamplingQWidget.setValue(0.05) self.setPercSamplingQWidget.setToolTip("Percentage of voxel used in registration.") parametersAdvancedParametersFormLayout.addRow("Percentage Of Samples ", self.setPercSamplingQWidget) # # BSpline Grid # self.setBSplineGridWidget = qt.QLineEdit() self.setBSplineGridWidget.setText('5,5,5') self.setBSplineGridWidget.setToolTip("Set the BSpline grid for non linear structural adjustments.") parametersAdvancedParametersFormLayout.addRow("BSpline Grid ", self.setBSplineGridWidget) # # Initiation Method Area # self.setInitiationRegistrationBooleanWidget = ctk.ctkComboBox() self.setInitiationRegistrationBooleanWidget.addItem("useCenterOfHeadAlign") self.setInitiationRegistrationBooleanWidget.addItem("Off") self.setInitiationRegistrationBooleanWidget.addItem("useMomentsAlign") self.setInitiationRegistrationBooleanWidget.addItem("useGeometryAlign") self.setInitiationRegistrationBooleanWidget.setToolTip( "Initialization method used for the MNI152 registration.") parametersAdvancedParametersFormLayout.addRow("Initiation Method ", self.setInitiationRegistrationBooleanWidget) # # Number of Threads in Segmentation Steps # self.setNumberOfThreadsWidget = qt.QSpinBox() self.setNumberOfThreadsWidget.setMaximum(multiprocessing.cpu_count()) self.setNumberOfThreadsWidget.setMinimum(-1) self.setNumberOfThreadsWidget.setSingleStep(1) self.setNumberOfThreadsWidget.setValue(-1) self.setNumberOfThreadsWidget.setToolTip("Number of threads to be used in segmentation steps. -1 equals to all possible threads being used.") parametersAdvancedParametersFormLayout.addRow("Number of Threads ", self.setNumberOfThreadsWidget) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False parametersInputFormLayout.addRow(self.applyButton) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.inputT1Selector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.inputT2Selector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.inputFLAIRSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.inputPDSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) # Add vertical spacer self.layout.addStretch(1) # Refresh Apply button state self.onSelect()
def setup(self): #->> TODO could also specify with Qt Designer instead in future (QtUiTools) # IO COLLAPSIBLE BUTTON ioCollapsibleButton = ctk.ctkCollapsibleButton() ioCollapsibleButton.text = "IO" self.layout.addWidget(ioCollapsibleButton) # Layout within the io collapsible button ioFormLayout = qt.QFormLayout(ioCollapsibleButton) # inputVolume node selector 1 inputNodeSelector1 = slicer.qMRMLNodeComboBox() inputNodeSelector1.objectName = 'inputNodeSelector1' inputNodeSelector1.toolTip = "Select the 1st input volume to be segmented." inputNodeSelector1.nodeTypes = ['vtkMRMLScalarVolumeNode'] inputNodeSelector1.noneEnabled = False inputNodeSelector1.addEnabled = False inputNodeSelector1.removeEnabled = False inputNodeSelector1.editEnabled = True inputNodeSelector1.connect('currentNodeChanged(vtkMRMLNode*)', self.setInputNode1) ioFormLayout.addRow("Input Volume 1:", inputNodeSelector1) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', inputNodeSelector1, 'setMRMLScene(vtkMRMLScene*)') self.inputNodeSelector1 = inputNodeSelector1 #->> TODO for all parameters, provide slots to set them, and use internal values to eventually pass them into the PDF segmenter - for using the interactive PDF segmenter somewhere else, ex in editor module # inputVolume node selector 2 inputNodeSelector2 = slicer.qMRMLNodeComboBox() inputNodeSelector2.objectName = 'inputNodeSelector2' inputNodeSelector2.toolTip = "Select the 2nd input volume to be segmented." inputNodeSelector2.nodeTypes = ['vtkMRMLScalarVolumeNode'] inputNodeSelector2.noneEnabled = True inputNodeSelector2.addEnabled = False inputNodeSelector2.removeEnabled = False inputNodeSelector2.editEnabled = True inputNodeSelector2.connect('currentNodeChanged(vtkMRMLNode*)', self.setInputNode2) ioFormLayout.addRow("Input Volume 2 (optional):", inputNodeSelector2) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', inputNodeSelector2, 'setMRMLScene(vtkMRMLScene*)') self.inputNodeSelector2 = inputNodeSelector2 # inputVolume node selector 3 inputNodeSelector3 = slicer.qMRMLNodeComboBox() inputNodeSelector3.objectName = 'inputNodeSelector3' inputNodeSelector3.toolTip = "Select the 3rd input volume to be segmented." inputNodeSelector3.nodeTypes = ['vtkMRMLScalarVolumeNode'] inputNodeSelector3.noneEnabled = True inputNodeSelector3.addEnabled = False inputNodeSelector3.removeEnabled = False inputNodeSelector3.editEnabled = True inputNodeSelector3.connect('currentNodeChanged(vtkMRMLNode*)', self.setInputNode3) ioFormLayout.addRow("Input Volume 3 (optional):", inputNodeSelector3) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', inputNodeSelector3, 'setMRMLScene(vtkMRMLScene*)') self.inputNodeSelector3 = inputNodeSelector3 # outputVolume node selector outputNodeSelector = slicer.qMRMLNodeComboBox() outputNodeSelector.objectName = 'outputNodeSelector' outputNodeSelector.toolTip = "Select the output volume to be segmented." outputNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] outputNodeSelector.noneEnabled = False outputNodeSelector.addEnabled = True outputNodeSelector.removeEnabled = False outputNodeSelector.editEnabled = True outputNodeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.setOutputNode) ioFormLayout.addRow("Output Volume:", outputNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', outputNodeSelector, 'setMRMLScene(vtkMRMLScene*)') self.outputNodeSelector = outputNodeSelector # LABEL MAP COLLAPSIBLE BUTTON labelMapCollapsibleButton = ctk.ctkCollapsibleButton() labelMapCollapsibleButton.text = "Label Maps" self.layout.addWidget(labelMapCollapsibleButton) # Layout within the labelMap collapsible button labelMapFormLayout = qt.QFormLayout(labelMapCollapsibleButton) # labelMap node selector labelMapNodeSelector = slicer.qMRMLNodeComboBox() labelMapNodeSelector.objectName = 'labelMapNodeSelector' labelMapNodeSelector.toolTip = "Select the label map roughly outlining the structure to be segmented and its background." labelMapNodeSelector.nodeTypes = ['vtkMRMLScalarVolumeNode'] labelMapNodeSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", True) labelMapNodeSelector.noneEnabled = False labelMapNodeSelector.addEnabled = True labelMapNodeSelector.removeEnabled = False labelMapNodeSelector.editEnabled = True labelMapNodeSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.setLabelMapNode) labelMapFormLayout.addRow("Label Map:", labelMapNodeSelector) self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', labelMapNodeSelector, 'setMRMLScene(vtkMRMLScene*)') self.labelMapNodeSelector = labelMapNodeSelector # Create frame editor widget editorFrame = qt.QFrame() editorFrame.setLayout(qt.QVBoxLayout()) palette = editorFrame.palette bgColor = 240 palette.setColor(qt.QPalette.Background, qt.QColor(bgColor, bgColor, bgColor)) editorFrame.setPalette(palette) editorFrame.setAutoFillBackground(True) labelMapFormLayout.addRow(editorFrame) self.editorFrame = editorFrame # initialize editor widget: using parent frame, embedded is true and list of effects self.editorWidget = __main__.EditorWidget( parent=self.editorFrame, embedded=True, suppliedEffects=self.editorEffects, showVolumesFrame=False) # voidLabel selector # The voidLabel selector selects which label corresponds to the void label # All other labels in the label map will be extracted and set to object labels voidLabelSpinBox = qt.QSpinBox() voidLabelSpinBox.objectName = 'voidLabelSpinBox' voidLabelSpinBox.toolTip = "Value that represents nothing in the label map. All other labels represent objects." voidLabelSpinBox.setMinimum(0) voidLabelSpinBox.setMaximum(255) # temporary value to start voidLabelSpinBox.enabled = False labelMapFormLayout.addRow("Void Id:", voidLabelSpinBox) self.voidLabelSpinBox = voidLabelSpinBox #->> TODO: later on, would like a label combo box that shows only those labels # that are included in the label map # The following code starts in that direction, but does not work # BEGIN hacking ## voidLabelSelector = slicer.qMRMLLabelComboBox() ## voidLabelSelector.maximumColorCount = 256 #->> TODO ## labelMapFormLayout.addRow("Void Label:", voidLabelSelector) ## self.parent.connect('mrmlSceneChanged(vtkMRMLScene*)', ## voidLabelSelector, 'setMRMLScene(vtkMRMLScene*)') ## # create a new vtkMRMLColorTableNode to hold the labels in the label map ## colorLogic = slicer.vtkSlicerColorLogic() ## defaultID = colorLogic.GetDefaultEditorColorNodeID() ## defaultNode = slicer.mrmlScene.GetNodeByID(defaultID) ## if defaultNode: ## # create the node based on the default editor color node ## self.labelsColorNode = slicer.vtkMRMLColorTableNode() ## self.labelsColorNode.Copy(defaultNode) ## # substitute in a new lookup table that we will manipulate ## lookupTable = vtk.vtkLookupTable() ## lookupTable.DeepCopy(defaultNode.GetLookupTable()) ## defaultLookupTable = defaultNode.GetLookupTable() ## list = [3,5,7,9] ## lookupTable.SetNumberOfTableValues(len(list)) ## for i in range(0, len(list)): ## orig = [] ## defaultLookupTable.GetTableValue(list[i], orig) ## lookupTable.SetTableValue(i, defaultNode.GetLookupTable(). ## self.labelsColorNode.SetLookupTable(lookupTable) ## # set the new color node to the selector ## # voidLabelSelector.setMRMLColorNode(self.labelsColorNode) ## print "lut:", self.labelsColorNode.GetLookupTable() ## self.voidLabelSelector = voidLabelSelector # END hacking #->> TODO: another alternative is to use an EditColor - but it is heavily coupled # to the editor logic, using an editor parameter node that ties it with the editor # widget's EditColor # Create a frame to give the EditColor a suitable parent ## voidLabelFrame = qt.QFrame() ## voidLabelFrame.setLayout(qt.QHBoxLayout()) ## voidLabelFrame.toolTip = "Value that represents nothing in the label map. All labels not equal to the void id represent objects." ## voidLabelSelector = EditorLib.EditColor(parent=voidLabelFrame) ## labelMapFormLayout.addRow("Void Id", voidLabelFrame) ## self.voidLabelSelector = voidLabelSelector # SEGMENTATION PARAMETERS COLLAPSIBLE BUTTON segmentationCollapsibleButton = ctk.ctkCollapsibleButton() segmentationCollapsibleButton.text = "Segmentation Parameters" self.layout.addWidget(segmentationCollapsibleButton) # Layout within the parameters collapsible button segmentationFormLayout = qt.QFormLayout(segmentationCollapsibleButton) # segmentation "goal" buttons self.goalButtonList = [] goalButtonGroup = qt.QButtonGroup() goalGroupBox = qt.QGroupBox() goalGroupBox.objectName = 'goalGroupBox' goalGroupBox.toolTip = "Select what the goal segmentation looks like" goalGroupBoxLayout = qt.QHBoxLayout() for i in range(0, len(self.goalButtonTexts)): button = qt.QToolButton() button.setText(self.goalButtonTexts[i]) button.setCheckable(True) goalButtonGroup.addButton(button, i) goalGroupBoxLayout.addWidget(button) self.goalButtonList.append(button) self.goalButtonList[self.goalButtonDefault].setChecked(True) goalButtonGroup.setExclusive(True) goalButtonGroup.connect('buttonClicked(int)', self.setGoalSegmentationType) goalGroupBox.setLayout(goalGroupBoxLayout) goalGroupBox.setFlat(True) segmentationFormLayout.addRow("Goal Segmentation:", goalGroupBox) self.goalButtonGroup = goalButtonGroup # ADVANCED PARAMETERS COLLAPSIBLE BUTTON advancedCollapsibleButton = ctk.ctkCollapsibleButton() advancedCollapsibleButton.text = "Advanced Parameters" self.layout.addWidget(advancedCollapsibleButton) # Layout within the parameters collapsible button advancedFormLayout = qt.QFormLayout(advancedCollapsibleButton) # Erosion radius spin box erosionSpinBox = qt.QSpinBox() erosionSpinBox.objectName = 'erosionSpinBox' erosionSpinBox.toolTip = "Set the erosion radius." erosionSpinBox.setMinimum(0) erosionSpinBox.connect('valueChanged(int)', self.setErosionRadius) advancedFormLayout.addRow("Erosion Radius:", erosionSpinBox) self.erosionSpinBox = erosionSpinBox # Hole fill iterations spin box holeFillSpinBox = qt.QSpinBox() holeFillSpinBox.objectName = 'holeFillSpinBox' holeFillSpinBox.toolTip = "Set the number of hole filling iterations." holeFillSpinBox.setMinimum(0) holeFillSpinBox.connect('valueChanged(int)', self.setHoleFillIterations) advancedFormLayout.addRow("Hole Fill Iterations:", holeFillSpinBox) self.holeFillSpinBox = holeFillSpinBox # falsePositiveRatio spin box falsePositiveRatioSpinBox = qt.QDoubleSpinBox() falsePositiveRatioSpinBox.objectName = 'falsePositiveRatioSpinBox' falsePositiveRatioSpinBox.toolTip = "Relative Cost of False Positive vs. false negative." falsePositiveRatioSpinBox.setMinimum(0.0) falsePositiveRatioSpinBox.setValue(1.0) # Default falsePositiveRatioSpinBox.setSingleStep(0.1) advancedFormLayout.addRow("False Positive Ratio:", falsePositiveRatioSpinBox) self.falsePositiveRatioSpinBox = falsePositiveRatioSpinBox # probabilitySmoothingStandardDeviation spin box probabilitySmoothingStdDevSpinBox = qt.QDoubleSpinBox() probabilitySmoothingStdDevSpinBox.objectName = 'probabilitySmoothingStdDevSpinBox' probabilitySmoothingStdDevSpinBox.toolTip = "Standard deviation of blur applied to probability images prior to computing maximum likelihood of each class at each pixel." probabilitySmoothingStdDevSpinBox.setMinimum(0.0) probabilitySmoothingStdDevSpinBox.setValue(3.0) # Default probabilitySmoothingStdDevSpinBox.setSingleStep(0.1) advancedFormLayout.addRow("Probability Smoothing Standard Deviation:", probabilitySmoothingStdDevSpinBox) self.probabilitySmoothingStdDevSpinBox = probabilitySmoothingStdDevSpinBox # draft check box draftCheckBox = qt.QCheckBox() draftCheckBox.objectName = 'draftCheckBox' draftCheckBox.toolTip = "Generate draft results?" advancedFormLayout.addRow("Draft Mode:", draftCheckBox) self.draftCheckBox = draftCheckBox # reclassifyObjectMask check box reclassifyObjectMaskCheckBox = qt.QCheckBox() reclassifyObjectMaskCheckBox.objectName = 'reclassifyObjectMaskCheckBox' reclassifyObjectMaskCheckBox.toolTip = "Perform classification on voxels within the object mask?" reclassifyObjectMaskCheckBox.setChecked(True) advancedFormLayout.addRow("Reclassify Object Mask:", reclassifyObjectMaskCheckBox) self.reclassifyObjectMaskCheckBox = reclassifyObjectMaskCheckBox # reclassifyNotObjectMask check box reclassifyNotObjectMaskCheckBox = qt.QCheckBox() reclassifyNotObjectMaskCheckBox.objectName = 'reclassifyNotObjectMaskCheckBox' reclassifyNotObjectMaskCheckBox.toolTip = "Perform classification on all non-void voxels?" reclassifyNotObjectMaskCheckBox.setChecked(True) advancedFormLayout.addRow("Reclassify Not Object Mask:", reclassifyNotObjectMaskCheckBox) self.reclassifyNotObjectMaskCheckBox = reclassifyNotObjectMaskCheckBox # SEGMENTATION BUTTON segmentCollapsibleButton = ctk.ctkCollapsibleButton() segmentCollapsibleButton.text = "Run Segmentation" self.layout.addWidget(segmentCollapsibleButton) # Layout within the parameters collapsible button segmentFormLayout = qt.QFormLayout(segmentCollapsibleButton) # segmentation button segmentationButton = qt.QPushButton("Segment") segmentationButton.toolTip = "Perform PDF Segmentation." segmentFormLayout.addRow(segmentationButton) segmentationButton.connect('clicked()', self.onSegmentationButtonClicked) # Now that we've created all UI elements, apply the default goal segmentation type self.setGoalSegmentationType(self.goalButtonDefault)
def setup(self): self.developerMode = True ScriptedLoadableModuleWidget.setup(self) # inspect current Scene and search for files called ?h_pial and ?h_white # if found fill the lists with relative nodes lhPialNode = slicer.mrmlScene.GetNodesByName( 'lh_pial').GetItemAsObject(0) rhPialNode = slicer.mrmlScene.GetNodesByName( 'rh_pial').GetItemAsObject(0) lhWhiteNode = slicer.mrmlScene.GetNodesByName( 'lh_white').GetItemAsObject(0) rhWhiteNode = slicer.mrmlScene.GetNodesByName( 'rh_white').GetItemAsObject(0) reconFileNode = slicer.mrmlScene.GetNodesByName( 'recon').GetItemAsObject(0) self.gmpiCB = ctk.ctkCollapsibleButton() self.gmpiCB.text = "GMPI Computation" self.layout.addWidget(self.gmpiCB) self.gmpiFL = qt.QFormLayout(self.gmpiCB) #### Left Pial selection box self.leftPialCBox = slicer.qMRMLNodeComboBox() self.leftPialCBox.nodeTypes = (("vtkMRMLModelNode"), "") self.leftPialCBox.selectNodeUponCreation = True self.leftPialCBox.addEnabled = False self.leftPialCBox.removeEnabled = False self.leftPialCBox.noneEnabled = True self.leftPialCBox.showHidden = False self.leftPialCBox.showChildNodeTypes = False self.leftPialCBox.setMRMLScene(slicer.mrmlScene) self.leftPialCBox.setToolTip("Pick the left pial.") self.gmpiFL.addRow("Left Pial: ", self.leftPialCBox) #### Left White selection box self.leftWhiteCBox = slicer.qMRMLNodeComboBox() self.leftWhiteCBox.nodeTypes = (("vtkMRMLModelNode"), "") self.leftWhiteCBox.selectNodeUponCreation = True self.leftWhiteCBox.addEnabled = False self.leftWhiteCBox.removeEnabled = False self.leftWhiteCBox.noneEnabled = True self.leftWhiteCBox.showHidden = False self.leftWhiteCBox.showChildNodeTypes = False self.leftWhiteCBox.setMRMLScene(slicer.mrmlScene) self.leftWhiteCBox.setToolTip("Pick the left pial.") #### Right Pial selection box self.rightPialCBox = slicer.qMRMLNodeComboBox() self.rightPialCBox.nodeTypes = (("vtkMRMLModelNode"), "") self.rightPialCBox.selectNodeUponCreation = True self.rightPialCBox.addEnabled = False self.rightPialCBox.removeEnabled = False self.rightPialCBox.noneEnabled = True self.rightPialCBox.showHidden = False self.rightPialCBox.showChildNodeTypes = False self.rightPialCBox.setMRMLScene(slicer.mrmlScene) self.rightPialCBox.setToolTip("Pick the right pial.") self.gmpiFL.addRow("Right Pial: ", self.rightPialCBox) #### Right White selection box self.rightWhiteCBox = slicer.qMRMLNodeComboBox() self.rightWhiteCBox.nodeTypes = (("vtkMRMLModelNode"), "") self.rightWhiteCBox.selectNodeUponCreation = True self.rightWhiteCBox.addEnabled = False self.rightWhiteCBox.removeEnabled = False self.rightWhiteCBox.noneEnabled = True self.rightWhiteCBox.showHidden = False self.rightWhiteCBox.showChildNodeTypes = False self.rightWhiteCBox.setMRMLScene(slicer.mrmlScene) self.rightWhiteCBox.setToolTip("Pick the right pial.") self.gmpiFL.addRow("Right White: ", self.rightWhiteCBox) self.gmpiFL.addRow("Left White: ", self.leftWhiteCBox) #### Fiducials list Combo Box self.fiducialsCBox = slicer.qMRMLNodeComboBox() self.fiducialsCBox.nodeTypes = (("vtkMRMLMarkupsFiducialNode"), "") self.fiducialsCBox.selectNodeUponCreation = False self.fiducialsCBox.addEnabled = False self.fiducialsCBox.removeEnabled = False self.fiducialsCBox.noneEnabled = True self.fiducialsCBox.setMRMLScene(slicer.mrmlScene) self.fiducialsCBox.setToolTip("Select a fiducial list") self.gmpiFL.addRow("Fiducial : ", self.fiducialsCBox) # if nodes already exist load them in ComboBoxes if lhWhiteNode: self.leftWhiteCBox.setCurrentNode(lhWhiteNode) if rhWhiteNode: self.rightWhiteCBox.setCurrentNode(rhWhiteNode) if rhPialNode: self.rightPialCBox.setCurrentNode(rhPialNode) if lhPialNode: self.leftPialCBox.setCurrentNode(lhPialNode) if reconFileNode: self.fiducialsCBox.setCurrentNode(reconFileNode) #### GMPI Threshold Slider self.gmpiSlider = qt.QSlider(qt.Qt.Horizontal) self.gmpiSlider.setMinimum(-9) self.gmpiSlider.setMaximum(9) self.gmpiSlider.setValue(-3) #### GMPI Spin Box self.gmpiSpinBox = qt.QDoubleSpinBox() self.gmpiSpinBox.setRange(-1, 1) self.gmpiSpinBox.setSingleStep(0.1) self.gmpiSpinBox.setValue(float(self.gmpiSlider.value) / 10) #### GMPI Slider e SpinBox Layout # self.gmpiverticalLayout = qt.QHBoxLayout() # # self.gmpiverticalLayout.addWidget(self.gmpiSlider) # self.gmpiverticalLayout.addWidget(self.gmpiSpinBox) # self.gmpiFL.addRow("GMPI Threshold : ", self.gmpiverticalLayout) # GMPI Computation Detection button self.gmpiPB = qt.QPushButton("Apply") self.gmpiPB.toolTip = "Run the algorithm." self.gmpiPB.enabled = True # Create montage files self.montagePB = qt.QPushButton("Create Montage") self.montagePB.toolTip = "Create Montage" self.montagePB.enabled = True #### Aggiungo il bottone al layout self.gmpiFL.addRow(self.gmpiPB) # self.gmpiFL.addRow(self.montagePB) # connections self.gmpiPB.connect('clicked(bool)', self.onGMPIComputation)
def setup(self): """ Called when the user opens the module the first time and the widget is initialized. """ super().setup() ParametersCollapsibleButton = ctk.ctkCollapsibleButton() ParametersCollapsibleButton.text = "Parameters" self.layout.addWidget(ParametersCollapsibleButton) ParameterLayout = qt.QHBoxLayout(ParametersCollapsibleButton) ParametersWidget = qt.QWidget() ParameterLayout.addWidget(ParametersWidget) ParametersFormLayout = qt.QFormLayout(ParametersWidget) # distance_threshold=1, interp_fraction=10, dose_threshold=1, lower_dose_cutoff=20 self.distanceThreshold = qt.QDoubleSpinBox() self.distanceThreshold.setDecimals(1) self.distanceThreshold.setMinimum(0.1) self.distanceThreshold.setMaximum(50) self.distanceThreshold.value = 1 self.distanceThreshold.setToolTip( "This is the distance (mm) to do gamma comparisons") self.interpolationFactor = qt.QSpinBox() self.interpolationFactor.setMinimum(1) self.interpolationFactor.setMaximum(30) self.interpolationFactor.value = 10 self.interpolationFactor.setToolTip( "This is the factor to divide the grid for interpolations") self.doseThreshold = qt.QDoubleSpinBox() self.doseThreshold.setDecimals(1) self.doseThreshold.setMinimum(0.1) self.doseThreshold.setMaximum(10) self.doseThreshold.value = 1 self.doseThreshold.setToolTip( "This is the dose threshold (%) to accept the gamma comparison") self.lowerDoseCutoff = qt.QDoubleSpinBox() self.lowerDoseCutoff.setDecimals(1) self.lowerDoseCutoff.setMinimum(0.1) self.lowerDoseCutoff.setMaximum(20) self.lowerDoseCutoff.value = 1 self.lowerDoseCutoff.setToolTip( "This is the dose cutoff (%) to reject dose values") ParametersFormLayout.addRow("Distance Threshold (mm)", self.distanceThreshold) ParametersFormLayout.addRow("Interpolation Factor", self.interpolationFactor) ParametersFormLayout.addRow("Dose Threshold (%)", self.doseThreshold) ParametersFormLayout.addRow("Lower Dose Cutoff (%)", self.lowerDoseCutoff) InputCollapsibleButton = ctk.ctkCollapsibleButton() InputCollapsibleButton.text = "Input Volumes" self.layout.addWidget(InputCollapsibleButton) InputLayout = qt.QHBoxLayout(InputCollapsibleButton) InputWidget = qt.QWidget() InputLayout.addWidget(InputWidget) InputFormLayout = qt.QFormLayout(InputWidget) # input volume selector self.Image1 = slicer.qMRMLNodeComboBox() self.Image1.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.Image1.selectNodeUponCreation = True self.Image1.addEnabled = False self.Image1.removeEnabled = False self.Image1.noneEnabled = False self.Image1.showHidden = False self.Image1.showChildNodeTypes = False self.Image1.setMRMLScene(slicer.mrmlScene) self.Image1.setToolTip("Select ADR Image 1.") InputFormLayout.addRow("ADR Image 1: ", self.Image1) # input volume selector self.Image2 = slicer.qMRMLNodeComboBox() self.Image2.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.Image2.selectNodeUponCreation = True self.Image2.addEnabled = False self.Image2.removeEnabled = False self.Image2.noneEnabled = False self.Image2.showHidden = False self.Image2.showChildNodeTypes = False self.Image2.setMRMLScene(slicer.mrmlScene) self.Image2.setToolTip("Select ADR Image 1.") InputFormLayout.addRow("ADR Image 2: ", self.Image2) self.ApplyButton = qt.QPushButton("Calculate Gamma") self.ApplyButton.toolTip = "Calculates Gamma image." InputFormLayout.addRow(self.ApplyButton) self.ApplyButton.clicked.connect(self.onApplyButton) # Add vertical spacer self.layout.addStretch(1) # Create a new parameterNode # This parameterNode stores all user choices in parameter values, node selections, etc. # so that when the scene is saved and reloaded, these settings are restored. self.logic = GammaLogic()
def onInputShapesDirectoryChanged(self): inputShapesDirectory = self.shapeInputDirectory.directory.encode('utf-8') # Set this directory as the default output directory as well self.outputDirectory.directory = str(inputShapesDirectory) row = 0 allShapeSigmaWs = [] for curFile in sorted(os.listdir(inputShapesDirectory)): if not (curFile.endswith(".vtk")): continue self.tableWidget_inputShapeParameters.setRowCount(row + 1) # Read the vtk file to set a default kernel width shapeFile = '%s/%s' %(inputShapesDirectory, curFile) polyReader = vtk.vtkPolyDataReader() polyReader.SetFileName(shapeFile) polyReader.Update() shape = polyReader.GetOutput() shapeBounds = shape.GetBounds() xRange = shapeBounds[1] - shapeBounds[0] yRange = shapeBounds[3] - shapeBounds[2] zRange = shapeBounds[5] - shapeBounds[4] smallestRange = min(xRange, yRange, zRange) initSigmaW = int(smallestRange*0.50) allShapeSigmaWs.append(initSigmaW) # Try to extract the time point as a suffix curTimePoint = 0.0 numsInFilename = re.findall(r'[-+]?\d*\.\d+|\d+', curFile) if (len(numsInFilename) > 0): curTimePoint = numsInFilename[-1] # We assume the final number in the filename is the time point # Column 0: #rootname = os.path.basename(curFile).split(".")[0] rootname = os.path.splitext(os.path.basename(curFile))[0] labelVTKFile = qt.QLabel(rootname) labelVTKFile.setAlignment(0x84) self.tableWidget_inputShapeParameters.setCellWidget(row, 0, labelVTKFile) # Column 1-2-3-4: (Time Point, Sigma W, Tris, Weight) # We might want to consider using different UI elements for Time Point and Kernel Width that do not have explicit ranges for column in range(1,5): widget = qt.QWidget() layout = qt.QHBoxLayout(widget) # If this is the 'Shape Index' column we limit this to an integer if (column == 3): spinBox = qt.QSpinBox() spinBox.setRange(0,1000) spinBox.value = 0 # The rest of the columns are doubles else: spinBox = qt.QDoubleSpinBox() if column == 1: # Time Point spinBox.value = float(curTimePoint) spinBox.connect('valueChanged(double)', self.onSetTimePointRange) spinBox.setRange(-1e10, 1e10) if column == 2: # Kernel Width spinBox.setRange(0.001, 1e10) spinBox.value = initSigmaW if column == 4: # Weight spinBox.value = 1 spinBox.setRange(0,1) spinBox.setSingleStep(0.1); layout.addWidget(spinBox) layout.setAlignment(0x84) layout.setContentsMargins(0, 0, 0, 0) widget.setLayout(layout) self.tableWidget_inputShapeParameters.setCellWidget(row, column, widget) row = row + 1 # We can set a default for deformation kernel width as smallest shape kernel self.defKernelWidth.value = min(allShapeSigmaWs) # Update the time range (if time point suffixes provided initialization) self.onSetTimePointRange()
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 fiber bundle selector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLFiberBundleNode"] 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 tractography data to use for input.") parametersFormLayout.addRow("Input FiberBundle: ", self.inputSelector) # # output fiber bundle selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = ["vtkMRMLFiberBundleNode"] self.outputSelector.selectNodeUponCreation = True self.outputSelector.addEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.renameEnabled = 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 FiberBundle: ", self.outputSelector) # # step size value # #self.fiberStepSizeSliderWidget = ctk.ctkSliderWidget() #self.fiberStepSizeSliderWidget.singleStep = 0.1 #self.fiberStepSizeSliderWidget.minimum = 0 #self.fiberStepSizeSliderWidget.maximum = 100 #self.fiberStepSizeSliderWidget.value = 2 #self.fiberStepSizeSliderWidget.setToolTip("Set step size value (in mm) for the output tractography. Points will be removed along the fiber such that the output step size is approximately this value (max possible step less than or equal to this value).") #parametersFormLayout.addRow("Output step size", self.fiberStepSizeSliderWidget) # step size output goal value self.fiberStepSizeWidget = qt.QDoubleSpinBox() self.fiberStepSizeWidget.singleStep = 0.1 self.fiberStepSizeWidget.setValue(2.0) self.fiberStepSizeWidget.setToolTip( "Set step size value (in mm) for the output tractography. Points will be removed along the fiber such that the output step size is approximately this value (max possible step less than or equal to this value)." ) parametersFormLayout.addRow("Output step size (mm):", self.fiberStepSizeWidget) # fiber percentage output value self.fiberPercentageWidget = qt.QDoubleSpinBox() self.fiberPercentageWidget.singleStep = 0.1 self.fiberPercentageWidget.maximum = 100.0 self.fiberPercentageWidget.minimum = 0.01 self.fiberPercentageWidget.setValue(50) self.fiberPercentageWidget.setToolTip( "Set percentage of input fibers to retain in output.") parametersFormLayout.addRow("Output fiber percent:", self.fiberPercentageWidget) # fiber minimum points to keep the fiber output value self.fiberMinimumPointsWidget = qt.QSpinBox() self.fiberMinimumPointsWidget.singleStep = 0.1 self.fiberMinimumPointsWidget.setValue(3) self.fiberMinimumPointsWidget.setToolTip( "Set minimum length of input fibers (in points) to retain in output. This is best used as a sanity check to remove any very short fibers where the algorithm was not successful in tracing. For example, a minimum length of 3 points means that any spurious fibers with only 1 or 2 points will be removed." ) parametersFormLayout.addRow("Output min points:", self.fiberMinimumPointsWidget) # fiber minimum length to keep the fiber self.fiberMinimumLengthWidget = qt.QDoubleSpinBox() self.fiberMinimumLengthWidget.singleStep = 1 self.fiberMinimumLengthWidget.maximum = 250.0 self.fiberMinimumLengthWidget.minimum = 0.01 self.fiberMinimumLengthWidget.setValue(10) self.fiberMinimumLengthWidget.setToolTip( "Set minimum length of input fibers (in mm) to retain in output. For example, a minimum length of 10mm means that any fibers under 10mm in length will be removed." ) parametersFormLayout.addRow("Output min length (mm):", self.fiberMinimumLengthWidget) # fiber maximum length to keep the fiber self.fiberMaximumLengthWidget = qt.QDoubleSpinBox() self.fiberMaximumLengthWidget.singleStep = 0.1 self.fiberMaximumLengthWidget.maximum = 250.0 self.fiberMaximumLengthWidget.minimum = 0.01 self.fiberMaximumLengthWidget.setValue(200) self.fiberMaximumLengthWidget.setToolTip( "Set maximum length of input fibers (in mm) to retain in output. For example, a maximum length of 35mm means that any fibers over 35mm in length will be removed. This is useful to clean any long artifactual fibers from a particular bundle." ) parametersFormLayout.addRow("Output max length (mm):", self.fiberMaximumLengthWidget) # # 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() # # Advanced Area # advancedCollapsibleButton = ctk.ctkCollapsibleButton() advancedCollapsibleButton.text = "Advanced" advancedCollapsibleButton.collapsed = True self.layout.addWidget(advancedCollapsibleButton) # Layout within the dummy collapsible button advancedFormLayout = qt.QFormLayout(advancedCollapsibleButton) # # Apply Button # self.advancedApplyButton = qt.QPushButton( "Apply to ALL tractography (fiber bundles)") self.advancedApplyButton.toolTip = "Downsample ALL fiber bundles in the Slicer scene. Be careful when saving the scene to choose a NEW directory to avoid over-writing your input data." self.advancedApplyButton.enabled = True advancedFormLayout.addRow(self.advancedApplyButton) # connections self.advancedApplyButton.connect('clicked(bool)', self.onAdvancedApplyButton)
def create(self): super(TraceAndSelectOptions, self).create() ## Custom threshold box # Note: This is needed because other tools can disable, hide, or manipulate the default threshold box # We need one unique to our tool self.threshLabel = qt.QLabel("Threshold", self.frame) self.threshLabel.setToolTip( "In threshold mode, the label will only be set if the background value is within this range." ) self.frame.layout().addWidget(self.threshLabel) self.widgets.append(self.threshLabel) self.thresh = ctk.ctkRangeWidget(self.frame) self.thresh.spinBoxAlignment = 0xff # put enties on top self.thresh.singleStep = 0.01 self.setRangeWidgetToBackgroundRange(self.thresh) self.frame.layout().addWidget(self.thresh) self.widgets.append(self.thresh) ## End custom threshold box ## Preview checkbox self.preview = qt.QCheckBox("Preview outlines", self.frame) self.preview.setToolTip( "Preview the outline of a selection with right-click.") self.frame.layout().addWidget(self.preview) ## End preview checkbox self.modeButtons = qt.QButtonGroup(self.frame) self.tissueRadioButton = qt.QRadioButton("Tissue Mode", self.frame) self.boneRadioButton = qt.QRadioButton("Bone/Nerve Mode", self.frame) self.hbox = qt.QHBoxLayout() self.hbox.addWidget(self.boneRadioButton) self.hbox.addWidget(self.tissueRadioButton) self.frame.layout().addLayout(self.hbox) self.modeButtons.addButton(self.boneRadioButton) self.modeButtons.addButton(self.tissueRadioButton) self.widgets.append(self.tissueRadioButton) self.widgets.append(self.boneRadioButton) ## ERROR MESSAGE FRAME self.errorMessageFrame = qt.QTextEdit(self.frame) self.frame.layout().addWidget(self.errorMessageFrame) #self.errorMessageFrame.setLayout(qt.QHBoxLayout) self.errorMessageFrame.setFixedWidth(280) self.errorMessageFrame.setReadOnly(True) self.errorMessageFrame.setText('No Error Detected') self.errorMessageFrame.setStyleSheet("QTextEdit {color:green}") self.widgets.append(self.errorMessageFrame) ## END ERROR MESSAGE FRAME ## For the offset value selection process self.offsetvalueFrame = qt.QFrame(self.frame) self.offsetvalueFrame.setLayout(qt.QHBoxLayout()) self.frame.layout().addWidget(self.offsetvalueFrame) self.widgets.append(self.offsetvalueFrame) self.offsetvalueLabel = qt.QLabel("Offset Value:", self.offsetvalueFrame) self.offsetvalueLabel.setToolTip( "Set the offset value shift upon an action") self.offsetvalueFrame.layout().addWidget(self.offsetvalueLabel) self.widgets.append(self.offsetvalueLabel) self.offsetvalueSpinBox = qt.QDoubleSpinBox(self.offsetvalueFrame) self.offsetvalueSpinBox.setToolTip( "Set the offset value shift upon an action") self.offsetvalueSpinBox.minimum = -1000 self.offsetvalueSpinBox.maximum = 1000 self.offsetvalueSpinBox.suffix = "" self.offsetvalueFrame.layout().addWidget(self.offsetvalueSpinBox) self.widgets.append(self.offsetvalueSpinBox) ## End offset value selection self.maxPixelsFrame = qt.QFrame(self.frame) self.maxPixelsFrame.setLayout(qt.QHBoxLayout()) self.frame.layout().addWidget(self.maxPixelsFrame) self.widgets.append(self.maxPixelsFrame) self.maxPixelsLabel = qt.QLabel("Max Pixels per click:", self.maxPixelsFrame) self.maxPixelsLabel.setToolTip("Set the maxPixels for each click") self.maxPixelsFrame.layout().addWidget(self.maxPixelsLabel) self.widgets.append(self.maxPixelsLabel) self.maxPixelsSpinBox = qt.QDoubleSpinBox(self.maxPixelsFrame) self.maxPixelsSpinBox.setToolTip("Set the maxPixels for each click") self.maxPixelsSpinBox.minimum = 1 self.maxPixelsSpinBox.maximum = 100000 self.maxPixelsSpinBox.suffix = "" self.maxPixelsFrame.layout().addWidget(self.maxPixelsSpinBox) self.widgets.append(self.maxPixelsSpinBox) # Help Browser self.helpBrowser = qt.QPushButton("Visit the Webpage") # End Help Browser self.frame.layout().addWidget(self.helpBrowser) HelpButton( self.frame, "Use this tool to help you label all voxels enclosed in an area bounded by the the largest path of pixels within the specified threshold." ) # don't connect the signals and slots directly - instead, add these # to the list of connections so that gui callbacks can be cleanly # disabled while the gui is being updated. This allows several gui # elements to be interlinked with signal/slots but still get updated # as a unit to the new value of the mrml node. # self.thresholdPaint.hide() self.connections.append((self.maxPixelsSpinBox, 'valueChanged(double)', self.onMaxPixelsSpinBoxChanged)) self.connections.append( (self.preview, "clicked()", self.onPreviewChanged)) self.connections.append( (self.tissueRadioButton, "clicked()", self.onTissueButtonChanged)) self.connections.append( (self.boneRadioButton, "clicked()", self.onBoneButtonChanged)) self.connections.append( (self.offsetvalueSpinBox, 'valueChanged(double)', self.onOffsetValueSpinBoxChanged)) self.connections.append((self.thresh, "valuesChanged(double,double)", self.onThreshValuesChange)) self.connections.append( (self.helpBrowser, "clicked()", self.onHelpBrowserPressed)) # Add vertical spacer self.frame.layout().addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "I/O Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersIOLayout = 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 = True 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. This should be an MRI strutural images with a type listed in the Image Modality option." ) parametersIOLayout.addRow("Input Volume: ", self.inputSelector) # # Image Modality # self.setImageModalityBooleanWidget = ctk.ctkComboBox() self.setImageModalityBooleanWidget.addItem("T1") self.setImageModalityBooleanWidget.addItem("T2") self.setImageModalityBooleanWidget.addItem("PD") self.setImageModalityBooleanWidget.setToolTip( "MRI strutural image inserted as a input volume.") parametersIOLayout.addRow("Image Modality ", self.setImageModalityBooleanWidget) # # Is brain extracted? # self.setIsBETWidget = ctk.ctkCheckBox() self.setIsBETWidget.setChecked(True) self.setIsBETWidget.setToolTip( "Is the input data already brain extracted? If not, the ROBEX brain extraction method is used.") parametersIOLayout.addRow("Is Brain Extracted?", self.setIsBETWidget) # # output volume selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] self.outputSelector.selectNodeUponCreation = True self.outputSelector.addEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.renameEnabled = 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." ) parametersIOLayout.addRow("Output Volume: ", self.outputSelector) # # Parameters Area # parametersTissueCollapsibleButton = ctk.ctkCollapsibleButton() parametersTissueCollapsibleButton.text = "Segmentation Parameters" self.layout.addWidget(parametersTissueCollapsibleButton) # Layout within the dummy collapsible button parametersTissueLayout = qt.QFormLayout(parametersTissueCollapsibleButton) # # Separate one tissue? # self.setSeparateTissueBooleanWidget = ctk.ctkCheckBox() self.setSeparateTissueBooleanWidget.setChecked(False) self.setSeparateTissueBooleanWidget.setToolTip( "Select one tissue type desired to be passed as the output. If checked, the tissue type in Tissue Type option is used.") parametersTissueLayout.addRow("Separate One Tissue?", self.setSeparateTissueBooleanWidget) # # Tissue Type # self.setTissueTypeWidget = ctk.ctkComboBox() self.setTissueTypeWidget.addItem("White Matter") self.setTissueTypeWidget.addItem("Gray Matter") self.setTissueTypeWidget.addItem("CSF") self.setTissueTypeWidget.setToolTip( "Tissue type that will be resulted from the brain segmentation.") parametersTissueLayout.addRow("Tissue Type ", self.setTissueTypeWidget) # # Apply AAD filtering # self.setApplyAADBooleanWidget = ctk.ctkCheckBox() self.setApplyAADBooleanWidget.setChecked(True) self.setApplyAADBooleanWidget.setToolTip( "Apply the AAD filter on the input data. This is recommended since the image noise level may affect the segmentation performance.") parametersTissueLayout.addRow("Apply AAD filter", self.setApplyAADBooleanWidget) # # Apply Bias Correction # self.setApplyBiasCorrectionBooleanWidget = ctk.ctkCheckBox() self.setApplyBiasCorrectionBooleanWidget.setChecked(True) self.setApplyBiasCorrectionBooleanWidget.setToolTip( "Apply a bias field correction in the input data. This is recommended since the global signal fluctuation provided by magnetic fiel inhomogeneity may affect the segmentation performance.") parametersTissueLayout.addRow("Apply Bias Field Correction", self.setApplyBiasCorrectionBooleanWidget) # # Apply Label Smoothing # self.setApplyLabelSmoothingBooleanWidget = ctk.ctkCheckBox() self.setApplyLabelSmoothingBooleanWidget.setChecked(True) self.setApplyLabelSmoothingBooleanWidget.setToolTip( "Apply a post processing procedure to reduce the label variability. Here the label smoothing method based on morphological convolution is applied.") parametersTissueLayout.addRow("Apply Label Smoothing", self.setApplyLabelSmoothingBooleanWidget) # # Parameters Area # parametersSegmentationCollapsibleButton = ctk.ctkCollapsibleButton() parametersSegmentationCollapsibleButton.text = "Expert Segmentation Parameters" parametersSegmentationCollapsibleButton.collapsed = True self.layout.addWidget(parametersSegmentationCollapsibleButton) # Layout within the dummy collapsible button parametersSegmentationLayout = qt.QFormLayout(parametersSegmentationCollapsibleButton) # # Segmentation modality # self.groupBoxRadioButtons = qt.QGroupBox("Segmentation Method") RadioButtonLayout = qt.QFormLayout() self.groupBoxRadioButtons.setLayout(RadioButtonLayout) self.setRadioKMeans = qt.QRadioButton('K-Means') self.setRadioKMeans.setToolTip("K-Means algorithm used in the Basic Brain Segmentation module.") self.setRadioBLS = qt.QRadioButton('BLS') self.setRadioBLS.setChecked(True) self.setRadioBLS.setToolTip("Brain Logistic Segmentation (BLS) method.") RadioButtonLayout.addRow(self.setRadioKMeans) RadioButtonLayout.addRow(self.setRadioBLS) parametersSegmentationLayout.addRow(self.groupBoxRadioButtons) # # # # Tissue Threshold # # self.setTissueThresholdWidget = ctk.ctkSliderWidget() self.setTissueThresholdWidget.singleStep = 0.01 self.setTissueThresholdWidget.minimum = 0.01 self.setTissueThresholdWidget.maximum = 0.99 self.setTissueThresholdWidget.value = 0.50 self.setTissueThresholdWidget.setToolTip( "Regulates the local logistic classification to each brian tissue. The ideal value is 0.50 which does not offer label overlay, however, if you need a rough estimate of partial tissue volume (PTV), one can set it to other threshold (t<0.5 offer a numbered label estimate to PTV and t>0.5 offer a zero mask to PTV). This parameter is only used when BLS segmentation method is called." " Example: t=0.50 means that ...") parametersSegmentationLayout.addRow("Tissue Threshold", self.setTissueThresholdWidget) # # Use manual number of bins? # self.setManualBinsBooleanWidget = ctk.ctkCheckBox() self.setManualBinsBooleanWidget.setChecked(False) self.setManualBinsBooleanWidget.setToolTip( "Set this if you want to regulate the number of bins manually. This parameter is only used when BLS segmentation method is called.") parametersSegmentationLayout.addRow("Use Manual Bins", self.setManualBinsBooleanWidget) # # Number of Bins: manual setting # self.setNumberOfBinsWidget = ctk.ctkSliderWidget() self.setNumberOfBinsWidget.maximum = 255 self.setNumberOfBinsWidget.minimum = 12 self.setNumberOfBinsWidget.value = 32 self.setNumberOfBinsWidget.singleStep = 1 self.setNumberOfBinsWidget.setToolTip("Select the number of bins that should be used for the image histogram analysis. This parameter is only used when BLS segmentation method is called") parametersSegmentationLayout.addRow("Number Of Bins ", self.setNumberOfBinsWidget) # # Noise Attenuation Parameters Area # parametersNoiseAttenuationCollapsibleButton = ctk.ctkCollapsibleButton() parametersNoiseAttenuationCollapsibleButton.text = "Noise Attenuation Parameters" parametersNoiseAttenuationCollapsibleButton.collapsed = True self.layout.addWidget(parametersNoiseAttenuationCollapsibleButton) # Layout within the dummy collapsible button parametersNoiseAttenuationFormLayout = qt.QFormLayout(parametersNoiseAttenuationCollapsibleButton) # # Filtering Parameters: Condutance # self.setFilteringCondutanceWidget = ctk.ctkSliderWidget() self.setFilteringCondutanceWidget.maximum = 50 self.setFilteringCondutanceWidget.minimum = 0 self.setFilteringCondutanceWidget.value = 10 self.setFilteringCondutanceWidget.singleStep = 1 self.setFilteringCondutanceWidget.setToolTip("Condutance parameter.") parametersNoiseAttenuationFormLayout.addRow("Condutance ", self.setFilteringCondutanceWidget) # # Filtering Parameters: Number of iterations # self.setFilteringNumberOfIterationWidget = ctk.ctkSliderWidget() self.setFilteringNumberOfIterationWidget.maximum = 50 self.setFilteringNumberOfIterationWidget.minimum = 1 self.setFilteringNumberOfIterationWidget.value = 5 self.setFilteringNumberOfIterationWidget.singleStep = 1 self.setFilteringNumberOfIterationWidget.setToolTip("Number of iterations parameter.") parametersNoiseAttenuationFormLayout.addRow("Number Of Iterations ", self.setFilteringNumberOfIterationWidget) # # Filtering Parameters: Q value # self.setFilteringQWidget = ctk.ctkSliderWidget() self.setFilteringQWidget.singleStep = 0.01 self.setFilteringQWidget.minimum = 0.01 self.setFilteringQWidget.maximum = 1.99 self.setFilteringQWidget.value = 1.2 self.setFilteringQWidget.setToolTip("Q value parameter.") parametersNoiseAttenuationFormLayout.addRow("Q Value ", self.setFilteringQWidget) # # Label Refinement Area # parametersLabelRefinementCollapsibleButton = ctk.ctkCollapsibleButton() parametersLabelRefinementCollapsibleButton.text = "Label Refinement Parameters" parametersLabelRefinementCollapsibleButton.collapsed = True self.layout.addWidget(parametersLabelRefinementCollapsibleButton) # Layout within the dummy collapsible button parametersLabelRefinementLayout = qt.QFormLayout(parametersLabelRefinementCollapsibleButton) # # Gaussian Smooth Label Mask # self.setGaussianLabelQWidget = qt.QDoubleSpinBox() self.setGaussianLabelQWidget.setDecimals(3) self.setGaussianLabelQWidget.setMaximum(10) self.setGaussianLabelQWidget.setMinimum(0.1) self.setGaussianLabelQWidget.setSingleStep(0.1) self.setGaussianLabelQWidget.setValue(0.2) self.setGaussianLabelQWidget.setToolTip("Label smoothing by a gaussian distribution with variance sigma. The units here is given in mm.") parametersLabelRefinementLayout.addRow("Gaussian Sigma ", self.setGaussianLabelQWidget) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False parametersIOLayout.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()
def __init__(self, parent, developerMode=False, widgetClass=None): VTKObservationMixin.__init__(self) # Set up main frame self.parent = parent self.parent.setLayout(qt.QHBoxLayout()) self.layout = self.parent.layout() self.layout.setMargin(0) self.layout.setSpacing(0) self.sliceletPanel = qt.QFrame(self.parent) self.sliceletPanelLayout = qt.QVBoxLayout(self.sliceletPanel) self.sliceletPanelLayout.setMargin(4) self.sliceletPanelLayout.setSpacing(0) self.layout.addWidget(self.sliceletPanel,1) #Set Advanced Parameters Collapsible Button self.parametersCollapsibleButton = ctk.ctkCollapsibleButton() self.parametersCollapsibleButton.text = "Set Advanced Segmentation Parameters" self.parametersCollapsibleButton.collapsed = True self.sliceletPanelLayout.addWidget(self.parametersCollapsibleButton) # Layout within the collapsible button self.parametersLayout = qt.QFormLayout(self.parametersCollapsibleButton) # Set Minimum Threshold of Percentage Increase to First Post-Contrast Image self.inputMinimumThreshold = qt.QLabel("Minimum Threshold of Increase", self.parametersCollapsibleButton) self.inputMinimumThreshold.setToolTip('Minimum Threshold of Percentage Increase (Pre- to First Post-contrast (Range: 10% to 150%)') self.inputSelectorMinimumThreshold = qt.QDoubleSpinBox(self.parametersCollapsibleButton) self.inputSelectorMinimumThreshold.setSuffix("%") self.inputSelectorMinimumThreshold.singleStep = (1) self.inputSelectorMinimumThreshold.minimum = (10) self.inputSelectorMinimumThreshold.maximum = (150) self.inputSelectorMinimumThreshold.value = (75) self.inputSelectorMinimumThreshold.setToolTip('Minimum Threshold of Percentage Increase (Pre- to First Post-contrast (Range: 10% to 150%)') self.parametersLayout.addRow(self.inputMinimumThreshold, self.inputSelectorMinimumThreshold) # Curve 1 Type Parameters (Slopes from First to Fourth Post-Contrast Images) self.inputCurve1 = qt.QLabel("Type 1 (Persistent) Curve Minimum Slope", self.parametersCollapsibleButton) self.inputCurve1.setToolTip('Minimum Slope of Delayed Curve to classify as Persistent (Range: 0.02 to 0.3)') self.inputSelectorCurve1 = qt.QDoubleSpinBox(self.parametersCollapsibleButton) self.inputSelectorCurve1.singleStep = (0.02) self.inputSelectorCurve1.minimum = (0.02) self.inputSelectorCurve1.maximum = (0.30) self.inputSelectorCurve1.value = (0.20) self.inputSelectorCurve1.setToolTip('Minimum Slope of Delayed Curve to classify as Persistent (Range: 0.02 to 0.3)') self.parametersLayout.addRow(self.inputCurve1, self.inputSelectorCurve1) # Curve 3 Type Parameters (Slopes from First to Fourth Post-Contrast Images) self.inputCurve3 = qt.QLabel("Type 3 (Washout) Curve Maximum Slope", self.parametersCollapsibleButton) self.inputCurve3.setToolTip('Maximum Slope of Delayed Curve to classify as Washout (Range: -0.02 to -0.3)') self.inputSelectorCurve3 = qt.QDoubleSpinBox(self.parametersCollapsibleButton) self.inputSelectorCurve3.singleStep = (0.02) self.inputSelectorCurve3.setPrefix("-") self.inputSelectorCurve3.minimum = (0.02) self.inputSelectorCurve3.maximum = (0.30) self.inputSelectorCurve3.value = (0.20) self.inputSelectorCurve3.setToolTip('Maximum Slope of Delayed Curve to classify as Washout (Range: -0.02 to -0.3)') self.parametersLayout.addRow(self.inputCurve3, self.inputSelectorCurve3) # Path input for dicom data to analyze self.inputPath = qt.QFileDialog() self.inputPath.setFileMode(qt.QFileDialog.Directory) self.sliceletPanelLayout.addWidget(self.inputPath) self.inputPath.connect('accepted()', self.createLogic) ############## self.layoutWidget = slicer.qMRMLLayoutWidget() self.layoutWidget.setMRMLScene(slicer.mrmlScene) self.layoutWidget.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutOneUp3DView) self.layout.addWidget(self.layoutWidget,2) if widgetClass: self.widget = widgetClass(self.parent) self.parent.show()
def setupTrainingTab(self): self.trainingLayout = qt.QVBoxLayout(self.trainingTabWidget) gridLayoutTrain = qt.QGridLayout() self.lr_spinbox = qt.QDoubleSpinBox() self.lr_spinbox.setSingleStep(0.001) self.lr_spinbox.setValue(0.01) self.lr_spinbox.setDecimals(3) self.num_epochs_spinbox = qt.QSpinBox() self.num_epochs_spinbox.setSingleStep(1) self.num_epochs_spinbox.setValue(1) gridLayoutTrain.addWidget(qt.QLabel("Learning Rate"), 0, 0) gridLayoutTrain.addWidget(self.lr_spinbox, 0, 1) gridLayoutTrain.addWidget(qt.QLabel("Number of Epochs"), 1, 0) gridLayoutTrain.addWidget(self.num_epochs_spinbox, 1, 1) gridLayoutSumdir = qt.QGridLayout() self.sumDirTrainSelector = qt.QPushButton("Browse") self.sumDirTrain = qt.QLineEdit("") self.modelDirTrainSelector = qt.QPushButton("Browse") self.modelDirTrain = qt.QLineEdit("") self.dataDirTrainSelector = qt.QPushButton("Browse") self.dataDirTrain = qt.QLineEdit("") gridLayoutSumdir.addWidget(qt.QLabel("Data Directory"), 1, 0) gridLayoutSumdir.addWidget(self.dataDirTrain, 1, 1) gridLayoutSumdir.addWidget(self.dataDirTrainSelector, 1, 2) gridLayoutSumdir.addWidget(qt.QLabel("Model Directory"), 2, 0) gridLayoutSumdir.addWidget(self.modelDirTrain, 2, 1) gridLayoutSumdir.addWidget(self.modelDirTrainSelector, 2, 2) gridLayoutSumdir.addWidget(qt.QLabel("Summary Directory"), 3, 0) gridLayoutSumdir.addWidget(self.sumDirTrain, 3, 1) gridLayoutSumdir.addWidget(self.sumDirTrainSelector, 3, 2) gridResTrain = qt.QGridLayout() self.trainReset = qt.QPushButton("RESET") self.trainTrain = qt.QPushButton("TRAIN") gridResTrain.addWidget(self.trainReset, 0, 0) gridResTrain.addWidget(self.trainTrain, 0, 1) self.trainingLayout.addLayout(gridLayoutTrain) self.trainingLayout.addLayout(gridLayoutSumdir) self.trainingLayout.addLayout(gridResTrain) self.trainingLayout.addStretch(1) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # CONNECTIONS # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # self.trainReset.connect("clicked(bool)", self.OnTrainReset) self.trainTrain.connect("clicked(bool)", self.OnTrainTrain) self.dataDirTrainSelector.connect("clicked(bool)", self.OnDataDirTrain) self.modelDirTrainSelector.connect("clicked(bool)", self.OnModelDirTrain) self.sumDirTrainSelector.connect("clicked(bool)", self.OnSumDirTrain) self.dataDirTrain.connect("editingFinished()", self.CheckDataDirTrain) self.modelDirTrain.connect("editingFinished()", self.CheckModelDirTrain) self.sumDirTrain.connect("editingFinished()", self.CheckSumDirTrain) # self.trainingWidget = widget return
def setup(self): # ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Input Parameters Area # parametersInputCollapsibleButton = ctk.ctkCollapsibleButton() parametersInputCollapsibleButton.text = "Input/Output Parameters" self.layout.addWidget(parametersInputCollapsibleButton) # Layout within the dummy collapsible button parametersInputFormLayout = qt.QFormLayout( parametersInputCollapsibleButton) # # input FLAIR volume selector # self.inputFLAIRSelector = slicer.qMRMLNodeComboBox() self.inputFLAIRSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputFLAIRSelector.selectNodeUponCreation = False self.inputFLAIRSelector.addEnabled = False self.inputFLAIRSelector.removeEnabled = True self.inputFLAIRSelector.noneEnabled = False self.inputFLAIRSelector.showHidden = False self.inputFLAIRSelector.showChildNodeTypes = False self.inputFLAIRSelector.setMRMLScene(slicer.mrmlScene) self.inputFLAIRSelector.setToolTip("T2-FLAIR Volume") parametersInputFormLayout.addRow("T2-FLAIR Volume ", self.inputFLAIRSelector) # # output label selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] self.outputSelector.selectNodeUponCreation = True self.outputSelector.addEnabled = True self.outputSelector.renameEnabled = 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("Output a global lesion mask.") parametersInputFormLayout.addRow("Lesion Label ", self.outputSelector) # # Is brain extracted? # self.setIsBETWidget = ctk.ctkCheckBox() self.setIsBETWidget.setChecked(False) self.setIsBETWidget.setToolTip( "Is the input data (T1 and T2-FLAIR) already brain extracted?") parametersInputFormLayout.addRow("Is brain extracted?", self.setIsBETWidget) # # MNI152 space? # self.setMNISpaceWidget = ctk.ctkCheckBox() self.setMNISpaceWidget.setChecked(False) self.setMNISpaceWidget.setToolTip( "Is the input data already registered to MNI152 space?") parametersInputFormLayout.addRow("MNI152 space?", self.setMNISpaceWidget) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False parametersInputFormLayout.addRow(self.applyButton) # # Segmentation Parameters Area # parametersSegmentationParametersCollapsibleButton = ctk.ctkCollapsibleButton( ) parametersSegmentationParametersCollapsibleButton.text = "Segmentation Parameters" self.layout.addWidget( parametersSegmentationParametersCollapsibleButton) # Layout within the dummy collapsible button parametersSegmentationFormLayout = qt.QFormLayout( parametersSegmentationParametersCollapsibleButton) # # Lesion Threshold # self.setLesionThresholdWidget = ctk.ctkSliderWidget() self.setLesionThresholdWidget.singleStep = 0.01 self.setLesionThresholdWidget.minimum = 0.05 self.setLesionThresholdWidget.maximum = 0.99 self.setLesionThresholdWidget.value = 0.95 self.setLesionThresholdWidget.setToolTip( "Define the lesion threshold used in the probability map, i.e. the percentage of voxels that do not belongs to the MS lesion region." " Example: l=0.95 means that only 5% of voxels are actual MS lesions." ) parametersSegmentationFormLayout.addRow("Lesion Threshold", self.setLesionThresholdWidget) # # White Matter Search Matching # self.setWMMatchWidget = qt.QDoubleSpinBox() self.setWMMatchWidget.setMinimum(0.1) self.setWMMatchWidget.setMaximum(1.0) self.setWMMatchWidget.setSingleStep(0.1) self.setWMMatchWidget.setValue(0.6) self.setWMMatchWidget.setToolTip( "Set the local neighborhood searching for label refinement step. This metric defines the percentage of white matter" " tissue surrounding the hyperintense lesions. Large values defines a conservative segmentation, i.e. in order to define a true MS lesion" "it must be close to certain percentage of white matter area.") parametersSegmentationFormLayout.addRow("White Matter Matching ", self.setWMMatchWidget) # # Minimum Lesion Size # self.setMinimumLesionWidget = qt.QSpinBox() self.setMinimumLesionWidget.setMinimum(1) self.setMinimumLesionWidget.setMaximum(5000) self.setMinimumLesionWidget.setValue(50) self.setMinimumLesionWidget.setToolTip( "Set the minimum lesion size adopted as a true lesion in the final lesion map. Units given in number of voxels." ) parametersSegmentationFormLayout.addRow("Minimum Lesion Size ", self.setMinimumLesionWidget) # # Lesions Map Iterative Updates # self.setLesionMapUpdatesWidget = ctk.ctkSliderWidget() self.setLesionMapUpdatesWidget.singleStep = 1 self.setLesionMapUpdatesWidget.minimum = 1 self.setLesionMapUpdatesWidget.maximum = 10 self.setLesionMapUpdatesWidget.value = 3 self.setLesionMapUpdatesWidget.setToolTip( "Set the number of updates that will be applied over the lesion probability map. Usually 4 iterations result " "in a reasonbale lesion segmentation, but if the lesions are subtle you may increase this parameter." ) parametersSegmentationFormLayout.addRow("Lesion Map Iterative Updates", self.setLesionMapUpdatesWidget) # # Threshold Method Area # self.setThresholdLFMethodBooleanWidget = ctk.ctkComboBox() self.setThresholdLFMethodBooleanWidget.addItem("MaximumEntropy") self.setThresholdLFMethodBooleanWidget.addItem("Otsu") self.setThresholdLFMethodBooleanWidget.addItem("Moments") self.setThresholdLFMethodBooleanWidget.setToolTip( "Choose the threhsold method for the lesion enhancement procedure. Options: MaximumEntropy, Otsu, Moments, Intermodes and IsoData" ) parametersSegmentationFormLayout.addRow( "Threshold Method ", self.setThresholdLFMethodBooleanWidget) # # Number Of Bins # self.setNumberOfBinsWidget = qt.QSpinBox() self.setNumberOfBinsWidget.setMaximum(256) self.setNumberOfBinsWidget.setMinimum(10) self.setNumberOfBinsWidget.setValue(128) self.setNumberOfBinsWidget.setToolTip( "Number Of Bins for the histogram calculation") parametersSegmentationFormLayout.addRow("Number Of Bins ", self.setNumberOfBinsWidget) # # Registration Parameters Area # parametersRegistrationCollapsibleButton = ctk.ctkCollapsibleButton() parametersRegistrationCollapsibleButton.text = "Registration Parameters" parametersRegistrationCollapsibleButton.collapsed = True self.layout.addWidget(parametersRegistrationCollapsibleButton) # Layout within the dummy collapsible button parametersRegistrationFormLayout = qt.QFormLayout( parametersRegistrationCollapsibleButton) # # Percentage Sampling Area # self.setPercSamplingQWidget = qt.QDoubleSpinBox() self.setPercSamplingQWidget.setDecimals(4) self.setPercSamplingQWidget.setMaximum(1) self.setPercSamplingQWidget.setMinimum(0.0001) self.setPercSamplingQWidget.setSingleStep(0.001) self.setPercSamplingQWidget.setValue(0.02) self.setPercSamplingQWidget.setToolTip( "Percentage of voxel used in registration.") parametersRegistrationFormLayout.addRow("Percentage Of Samples ", self.setPercSamplingQWidget) # # Initiation Method Area # self.setInitiationRegistrationBooleanWidget = ctk.ctkComboBox() self.setInitiationRegistrationBooleanWidget.addItem("useMomentsAlign") self.setInitiationRegistrationBooleanWidget.addItem("Off") self.setInitiationRegistrationBooleanWidget.addItem( "useCenterOfHeadAlign") self.setInitiationRegistrationBooleanWidget.addItem("useGeometryAlign") self.setInitiationRegistrationBooleanWidget.setToolTip( "Initialization method used for the MNI152 registration.") parametersRegistrationFormLayout.addRow( "Initiation Method ", self.setInitiationRegistrationBooleanWidget) # # Interpolation Method Area # self.setInterpolationMethodBooleanWidget = ctk.ctkComboBox() self.setInterpolationMethodBooleanWidget.addItem("Linear") self.setInterpolationMethodBooleanWidget.addItem("BSpline") self.setInterpolationMethodBooleanWidget.addItem("NearestNeighbor") self.setInterpolationMethodBooleanWidget.setToolTip( "Choose the interpolation method used to register the standard space to input image space. Options: Linear, NearestNeighbor, B-Spline" ) parametersRegistrationFormLayout.addRow( "Interpolation ", self.setInterpolationMethodBooleanWidget) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.inputFLAIRSelector.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()
def setup(self): # ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Input Parameters Area # parametersInputCollapsibleButton = ctk.ctkCollapsibleButton() parametersInputCollapsibleButton.text = "Input/Output Parameters" self.layout.addWidget(parametersInputCollapsibleButton) # Layout within the dummy collapsible button parametersInputFormLayout = qt.QFormLayout( parametersInputCollapsibleButton) # # input volume selector # self.inputSelector = slicer.qMRMLNodeComboBox() self.inputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.inputSelector.selectNodeUponCreation = False self.inputSelector.addEnabled = False self.inputSelector.removeEnabled = True self.inputSelector.noneEnabled = False self.inputSelector.showHidden = False self.inputSelector.showChildNodeTypes = False self.inputSelector.setMRMLScene(slicer.mrmlScene) self.inputSelector.setToolTip("Input Volume.") parametersInputFormLayout.addRow("Input Volume ", self.inputSelector) # # output enhanced volume selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = ["vtkMRMLScalarVolumeNode"] self.outputSelector.selectNodeUponCreation = True self.outputSelector.addEnabled = True self.outputSelector.renameEnabled = 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("Output enhanced volume.") parametersInputFormLayout.addRow("Output Volume ", self.outputSelector) # # Is brain extracted? # self.setIsBETWidget = ctk.ctkCheckBox() self.setIsBETWidget.setChecked(False) self.setIsBETWidget.setToolTip( "Is the input data already brain extracted? This is information is useful when choosing the brain template that will be adjusted to the native space." ) parametersInputFormLayout.addRow("Is brain extracted?", self.setIsBETWidget) # # Lesion Enhancement Function Parameters Area # parametersLesionEnhancementCollapsibleButton = ctk.ctkCollapsibleButton( ) parametersLesionEnhancementCollapsibleButton.text = "Lesion Enhancement Function Parameters" self.layout.addWidget(parametersLesionEnhancementCollapsibleButton) # Layout within the dummy collapsible button parametersLesionEnhancementFormLayout = qt.QFormLayout( parametersLesionEnhancementCollapsibleButton) # # Weighted Lesion Enhancement # self.setWeightedEnhancementWidget = ctk.ctkSliderWidget() self.setWeightedEnhancementWidget.maximum = 0.5 self.setWeightedEnhancementWidget.minimum = -0.5 self.setWeightedEnhancementWidget.value = 0 self.setWeightedEnhancementWidget.singleStep = 0.001 self.setWeightedEnhancementWidget.setToolTip( "The weighting controller that is useful to adjust how much the image signal should be changed. " "The contrast map is the baseline spatial weighting distribution to increase the voxel contrast, which should inform the image areas that would be enhanced. " "Negative values informs that a smooth increase of signal should be applied (w = -0.5 will not affect the original image). " "Positive values indicates a more aggressive signal adjustment, resulting in more signal contrast (w = 0.5 will double the contrast map signal adjustment). " "If this weighting value is equal to zero, the contrast map is followed as is. NOTE: If the signal gaussianity is true, the weight value is passed as an absolute value." ) parametersLesionEnhancementFormLayout.addRow( "Weighting Enhancement ", self.setWeightedEnhancementWidget) # # Maintaing signal gaussianity # self.setKeepGaussianSignalWidget = ctk.ctkCheckBox() self.setKeepGaussianSignalWidget.setChecked(False) self.setKeepGaussianSignalWidget.setToolTip( "Choose if the enhanced image should maintain the global signal gaussianity, i.e. if the output signal keep the Gaussian distribution after the local contrast enhancement process being made." ) parametersLesionEnhancementFormLayout.addRow( "Maintaing signal gaussianity", self.setKeepGaussianSignalWidget) # # Threshold Method Area # self.setThresholdLFMethodBooleanWidget = ctk.ctkComboBox() self.setThresholdLFMethodBooleanWidget.addItem("MaximumEntropy") self.setThresholdLFMethodBooleanWidget.addItem("Otsu") self.setThresholdLFMethodBooleanWidget.addItem("Moments") self.setThresholdLFMethodBooleanWidget.addItem("Intermodes") self.setThresholdLFMethodBooleanWidget.addItem("IsoData") self.setThresholdLFMethodBooleanWidget.setToolTip( "Choose the threhsold method for the lesion enhancement procedure. Options: MaximumEntropy, Otsu, Moments, Intermodes and IsoData" ) parametersLesionEnhancementFormLayout.addRow( "Threshold Method ", self.setThresholdLFMethodBooleanWidget) # # Number Of Bins # self.setNumberOfBinsWidget = qt.QSpinBox() self.setNumberOfBinsWidget.setMaximum(256) self.setNumberOfBinsWidget.setMinimum(10) self.setNumberOfBinsWidget.setValue(128) self.setNumberOfBinsWidget.setToolTip( "Number Of Bins for the histogram calculation") parametersLesionEnhancementFormLayout.addRow( "Number Of Bins ", self.setNumberOfBinsWidget) # # Flip Object # self.setFlipObjectWidget = ctk.ctkCheckBox() self.setFlipObjectWidget.setChecked(False) self.setFlipObjectWidget.setToolTip( "Flip object in the image. This informs if the dark part of the histogram that should be enhanced." ) parametersLesionEnhancementFormLayout.addRow("Flip Object", self.setFlipObjectWidget) # # Noise Attenuation Parameters Area # parametersNoiseAttenuationCollapsibleButton = ctk.ctkCollapsibleButton( ) parametersNoiseAttenuationCollapsibleButton.text = "Noise Attenuation Parameters" parametersNoiseAttenuationCollapsibleButton.collapsed = True self.layout.addWidget(parametersNoiseAttenuationCollapsibleButton) # Layout within the dummy collapsible button parametersNoiseAttenuationFormLayout = qt.QFormLayout( parametersNoiseAttenuationCollapsibleButton) # # Filtering Parameters: Condutance # self.setFilteringCondutanceWidget = ctk.ctkSliderWidget() self.setFilteringCondutanceWidget.maximum = 50 self.setFilteringCondutanceWidget.minimum = 1 self.setFilteringCondutanceWidget.value = 5 self.setFilteringCondutanceWidget.singleStep = 1 self.setFilteringCondutanceWidget.setToolTip("Condutance parameter.") parametersNoiseAttenuationFormLayout.addRow( "Condutance ", self.setFilteringCondutanceWidget) # # Filtering Parameters: Number of iterations # self.setFilteringNumberOfIterationWidget = ctk.ctkSliderWidget() self.setFilteringNumberOfIterationWidget.maximum = 50 self.setFilteringNumberOfIterationWidget.minimum = 1 self.setFilteringNumberOfIterationWidget.value = 5 self.setFilteringNumberOfIterationWidget.singleStep = 1 self.setFilteringNumberOfIterationWidget.setToolTip( "Number of iterations parameter.") parametersNoiseAttenuationFormLayout.addRow( "Number Of Iterations ", self.setFilteringNumberOfIterationWidget) # # Filtering Parameters: Q value # self.setFilteringQWidget = ctk.ctkSliderWidget() self.setFilteringQWidget.singleStep = 0.1 self.setFilteringQWidget.minimum = 0.01 self.setFilteringQWidget.maximum = 2.0 self.setFilteringQWidget.value = 1.2 self.setFilteringQWidget.setToolTip("Q value parameter.") parametersNoiseAttenuationFormLayout.addRow("Q Value ", self.setFilteringQWidget) # # Registration Parameters Area # parametersRegistrationCollapsibleButton = ctk.ctkCollapsibleButton() parametersRegistrationCollapsibleButton.text = "Registration Parameters" parametersRegistrationCollapsibleButton.collapsed = True self.layout.addWidget(parametersRegistrationCollapsibleButton) # Layout within the dummy collapsible button parametersRegistrationFormLayout = qt.QFormLayout( parametersRegistrationCollapsibleButton) # # Percentage Sampling Area # self.setPercSamplingQWidget = qt.QDoubleSpinBox() self.setPercSamplingQWidget.setDecimals(4) self.setPercSamplingQWidget.setMaximum(1) self.setPercSamplingQWidget.setMinimum(0.0001) self.setPercSamplingQWidget.setSingleStep(0.001) self.setPercSamplingQWidget.setValue(0.002) self.setPercSamplingQWidget.setToolTip( "Percentage of voxel used in registration.") parametersRegistrationFormLayout.addRow("Percentage Of Samples ", self.setPercSamplingQWidget) # # Initiation Method Area # self.setInitiationRegistrationBooleanWidget = ctk.ctkComboBox() self.setInitiationRegistrationBooleanWidget.addItem("useMomentsAlign") self.setInitiationRegistrationBooleanWidget.addItem("Off") self.setInitiationRegistrationBooleanWidget.addItem( "useCenterOfHeadAlign") self.setInitiationRegistrationBooleanWidget.addItem("useGeometryAlign") self.setInitiationRegistrationBooleanWidget.setToolTip( "Initialization method used for the MNI152 registration.") parametersRegistrationFormLayout.addRow( "Initiation Method ", self.setInitiationRegistrationBooleanWidget) # # Interpolation Method Area # self.setInterpolationMethodBooleanWidget = ctk.ctkComboBox() self.setInterpolationMethodBooleanWidget.addItem("Linear") self.setInterpolationMethodBooleanWidget.addItem("BSpline") self.setInterpolationMethodBooleanWidget.addItem("NearestNeighbor") self.setInterpolationMethodBooleanWidget.setToolTip( "Choose the interpolation method used to register the standard space to the native space. Options: Linear, NearestNeighbor, B-Spline" ) parametersRegistrationFormLayout.addRow( "Interpolation ", self.setInterpolationMethodBooleanWidget) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False parametersInputFormLayout.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()
def setup(self): # ScriptedLoadableModuleWidget.setup(self) # Instantiate and connect widgets ... # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "I/O Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersIOLayout = 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 = True 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. This should be an MRI strutural images with a type listed in the Image Modality option." ) parametersIOLayout.addRow("Input Volume: ", self.inputSelector) # # Image Modality # self.setImageModalityBooleanWidget = ctk.ctkComboBox() self.setImageModalityBooleanWidget.addItem("T1") self.setImageModalityBooleanWidget.addItem("T2") self.setImageModalityBooleanWidget.addItem("PD") self.setImageModalityBooleanWidget.setToolTip( "MRI strutural image inserted as a input volume.") parametersIOLayout.addRow("Image Modality ", self.setImageModalityBooleanWidget) # # Is brain extracted? # self.setIsBETWidget = ctk.ctkCheckBox() self.setIsBETWidget.setChecked(True) self.setIsBETWidget.setToolTip( "Is the input data already brain extracted? If not, the ROBEX brain extraction method is used.") parametersIOLayout.addRow("Is brain extracted?", self.setIsBETWidget) # # output volume selector # self.outputSelector = slicer.qMRMLNodeComboBox() self.outputSelector.nodeTypes = ["vtkMRMLLabelMapVolumeNode"] self.outputSelector.selectNodeUponCreation = True self.outputSelector.addEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.renameEnabled = 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." ) parametersIOLayout.addRow("Output Volume: ", self.outputSelector) # # Parameters Area # parametersTissueCollapsibleButton = ctk.ctkCollapsibleButton() parametersTissueCollapsibleButton.text = "Tissue Segmentation Parameters" self.layout.addWidget(parametersTissueCollapsibleButton) # Layout within the dummy collapsible button parametersTissueLayout = qt.QFormLayout(parametersTissueCollapsibleButton) # # Separate one tissue? # self.setSeparateTissueBooleanWidget = ctk.ctkCheckBox() self.setSeparateTissueBooleanWidget.setChecked(False) self.setSeparateTissueBooleanWidget.setToolTip( "Select one tissue type desired to be passed as the output. If checked, the tissue type in Tissue Type option is used.") parametersTissueLayout.addRow("Separate one tissue?", self.setSeparateTissueBooleanWidget) # # Tissue Type # self.setTissueTypeWidget = ctk.ctkComboBox() self.setTissueTypeWidget.addItem("White Matter") self.setTissueTypeWidget.addItem("Gray Matter") self.setTissueTypeWidget.addItem("CSF") self.setTissueTypeWidget.setToolTip( "Tissue type that will be resulted from the brain segmentation.") parametersTissueLayout.addRow("Tissue Type ", self.setTissueTypeWidget) # # Noise Attenuation Parameters Area # parametersNoiseAttenuationCollapsibleButton = ctk.ctkCollapsibleButton() parametersNoiseAttenuationCollapsibleButton.text = "Noise Attenuation Parameters" self.layout.addWidget(parametersNoiseAttenuationCollapsibleButton) # Layout within the dummy collapsible button parametersNoiseAttenuationFormLayout = qt.QFormLayout(parametersNoiseAttenuationCollapsibleButton) # # Filtering Parameters: Condutance # self.setFilteringCondutanceWidget = ctk.ctkSliderWidget() self.setFilteringCondutanceWidget.maximum = 30 self.setFilteringCondutanceWidget.minimum = 0 self.setFilteringCondutanceWidget.value = 10 self.setFilteringCondutanceWidget.singleStep = 1 self.setFilteringCondutanceWidget.setToolTip("Condutance parameter.") parametersNoiseAttenuationFormLayout.addRow("Condutance ", self.setFilteringCondutanceWidget) # # Filtering Parameters: Number of iterations # self.setFilteringNumberOfIterationWidget = ctk.ctkSliderWidget() self.setFilteringNumberOfIterationWidget.maximum = 50 self.setFilteringNumberOfIterationWidget.minimum = 1 self.setFilteringNumberOfIterationWidget.value = 5 self.setFilteringNumberOfIterationWidget.singleStep = 1 self.setFilteringNumberOfIterationWidget.setToolTip("Number of iterations parameter.") parametersNoiseAttenuationFormLayout.addRow("Number Of Iterations ", self.setFilteringNumberOfIterationWidget) # # Filtering Parameters: Q value # self.setFilteringQWidget = ctk.ctkSliderWidget() self.setFilteringQWidget.singleStep = 0.01 self.setFilteringQWidget.minimum = 0.01 self.setFilteringQWidget.maximum = 1.99 self.setFilteringQWidget.value = 1.2 self.setFilteringQWidget.setToolTip("Q value parameter.") parametersNoiseAttenuationFormLayout.addRow("Q Value ", self.setFilteringQWidget) # # Label Refinement Area # parametersLabelRefinementCollapsibleButton = ctk.ctkCollapsibleButton() parametersLabelRefinementCollapsibleButton.text = "Label Refinement Parameters" self.layout.addWidget(parametersLabelRefinementCollapsibleButton) # Layout within the dummy collapsible button parametersLabelRefinementLayout = qt.QFormLayout(parametersLabelRefinementCollapsibleButton) # # Gaussian Smooth Label Mask # self.setGaussianLabelQWidget = qt.QDoubleSpinBox() self.setGaussianLabelQWidget.setDecimals(3) self.setGaussianLabelQWidget.setMaximum(10) self.setGaussianLabelQWidget.setMinimum(0.1) self.setGaussianLabelQWidget.setSingleStep(0.1) self.setGaussianLabelQWidget.setValue(0.2) self.setGaussianLabelQWidget.setToolTip("Label smoothing by a gaussian distribution with variance sigma. The units here is given in mm.") parametersLabelRefinementLayout.addRow("Gaussian Sigma ", self.setGaussianLabelQWidget) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False parametersIOLayout.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()