class CIP_ParenchymaAnalysisWidget(ScriptedLoadableModuleWidget): @property def moduleName(self): return os.path.basename(__file__).replace(".py", "") def __init__(self, parent=None): ScriptedLoadableModuleWidget.__init__(self, parent) self.chartOptions = ("LAA%-950", "LAA%-925", "LAA%-910", "LAA%-856", "HAA%-700", "HAA%-600", "HAA%-500", "HAA%-250", "Perc10", "Perc15", "Mean", "Std", "Kurtosis", "Skewness", "Ventilation Heterogeneity", "Mass", "Volume") # Build the column keys. Here all the columns are declared, but an alternative could be just: #self.columnsDict = CaseReportsWidget.getColumnKeysNormalizedDictionary(["Volume Name", "Region", "LAA%-950", ...]) self.columnsDict = OrderedDict() self.columnsDict["VolumeName"] = "Volume Name" self.columnsDict["Region"] = "Region" self.columnsDict["LAA950"] = "LAA%-950" self.columnsDict["LAA925"] = "LAA%-925" self.columnsDict["LAA910"] = "LAA%-910" self.columnsDict["LAA856"] = "LAA%-856" self.columnsDict["HAA700"] = "HAA%-700" self.columnsDict["HAA600"] = "HAA%-600" self.columnsDict["HAA500"] = "HAA%-500" self.columnsDict["HAA250"] = "HAA%-250" self.columnsDict["Perc10"] = "Perc10" self.columnsDict["Perc15"] = "Perc15" self.columnsDict["Mean"] = "Mean" self.columnsDict["Std"] = "Std" self.columnsDict["Kurtosis"] = "Kurtosis" self.columnsDict["Skewness"] = "Skewness" self.columnsDict[ "VentilationHeterogeneity"] = "Ventilation Heterogeneity" self.columnsDict["Mass"] = "Mass" self.columnsDict["Volume"] = "Volume" self.rTags = ("WholeLung", "RightLung", "LeftLung", "RUL", "RLL", "RML", "LUL", "LLL", "LUT", "LMT", "LLT", "RUT", "RMT", "RLT") if not parent: self.parent = slicer.qMRMLWidget() self.parent.setLayout(qt.QVBoxLayout()) self.parent.setMRMLScene(slicer.mrmlScene) else: self.parent = parent self.logic = None self.CTNode = None self.labelNode = None # self.expNode = None # self.explabelNode = None self.fileName = None self.fileDialog = None if not parent: self.setup() self.CTSelector.setMRMLScene(slicer.mrmlScene) # self.expSelector.setMRMLScene(slicer.mrmlScene) self.labelSelector.setMRMLScene(slicer.mrmlScene) # self.explabelSelector.setMRMLScene(slicer.mrmlScene) self.parent.show() def enter(self): if self.labelSelector.currentNode(): for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic( ).GetSliceCompositeNode().SetLabelVolumeID( self.labelSelector.currentNode().GetID()) def exit(self): for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic( ).GetSliceCompositeNode().SetLabelVolumeID('None') def setup(self): ScriptedLoadableModuleWidget.setup(self) # # the inps volume selector # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "IO Volumes" self.parent.layout().addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) parametersFormLayout.setVerticalSpacing(5) self.CTSelector = slicer.qMRMLNodeComboBox() self.CTSelector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "") self.CTSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", 0) self.CTSelector.selectNodeUponCreation = False self.CTSelector.addEnabled = False self.CTSelector.removeEnabled = False self.CTSelector.noneEnabled = True self.CTSelector.showHidden = False self.CTSelector.showChildNodeTypes = False self.CTSelector.setMRMLScene(slicer.mrmlScene) self.CTSelector.setToolTip("Pick the CT image to work on.") parametersFormLayout.addRow("Input CT Volume: ", self.CTSelector) # # the label map volume selector # self.labelSelector = slicer.qMRMLNodeComboBox() # self.labelSelector.nodeTypes = ( ("vtkMRMLScalarVolumeNode"), "" ) # self.labelSelector.addAttribute( "vtkMRMLScalarVolumeNode", "LabelMap", 1 ) self.labelSelector.nodeTypes = (("vtkMRMLLabelMapVolumeNode"), "") self.labelSelector.selectNodeUponCreation = True self.labelSelector.addEnabled = False self.labelSelector.removeEnabled = False self.labelSelector.noneEnabled = True self.labelSelector.showHidden = False self.labelSelector.showChildNodeTypes = False self.labelSelector.setMRMLScene(slicer.mrmlScene) self.labelSelector.setToolTip("Pick the label map to the algorithm.") parametersFormLayout.addRow("Label Map Volume: ", self.labelSelector) # Image filtering section self.preProcessingWidget = PreProcessingWidget( self.moduleName, parentWidget=self.parent) self.preProcessingWidget.setup() # # self.splitRadioButton = qt.QRadioButton() # self.splitRadioButton.setText('Split Label Map') # self.splitRadioButton.setChecked(0) # self.parent.layout().addWidget(self.splitRadioButton, 0, 3) # Apply button self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Calculate Parenchyma Phenotypes." self.applyButton.enabled = False self.applyButton.setFixedSize(300, 30) self.parent.layout().addWidget(self.applyButton, 0, 4) # model and view for stats table self.view = qt.QTableView() self.view.sortingEnabled = True self.parent.layout().addWidget(self.view) # model and view for EXP stats table """self.viewexp = qt.QTableView() self.viewexp.sortingEnabled = True self.parent.layout().addWidget(self.viewexp)""" # Histogram Selection self.HistSection = qt.QFrame() self.HistSection.setLayout(qt.QVBoxLayout()) self.parent.layout().addWidget(self.HistSection) self.HistSection.setObjectName('HistSection') self.HistSection.setStyleSheet( '#HistSection {border: 0.5px solid lightGray; }') HistSectionTitle = qt.QLabel() HistSectionTitle.setText('Histogram Section') # HistSectionTitle.setStyleSheet('border: 1px solid white; color: black') self.HistSection.layout().addWidget(HistSectionTitle) self.histogramCheckBoxes = [] self.histFrame = qt.QFrame() # self.histFrame.setStyleSheet('border: 1px solid white') self.histFrame.setLayout(qt.QHBoxLayout()) self.GlobalHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.GlobalHistCheckBox) self.histFrame.layout().addWidget(self.GlobalHistCheckBox) self.RightHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.RightHistCheckBox) self.histFrame.layout().addWidget(self.RightHistCheckBox) self.LeftHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.LeftHistCheckBox) self.histFrame.layout().addWidget(self.LeftHistCheckBox) self.RULHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.RULHistCheckBox) self.histFrame.layout().addWidget(self.RULHistCheckBox) self.RLLHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.RLLHistCheckBox) self.histFrame.layout().addWidget(self.RLLHistCheckBox) self.RMLHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.RMLHistCheckBox) self.histFrame.layout().addWidget(self.RMLHistCheckBox) self.LULHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.LULHistCheckBox) self.histFrame.layout().addWidget(self.LULHistCheckBox) self.LLLHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.LLLHistCheckBox) self.histFrame.layout().addWidget(self.LLLHistCheckBox) self.LUTHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.LUTHistCheckBox) self.histFrame.layout().addWidget(self.LUTHistCheckBox) self.LMTHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.LMTHistCheckBox) self.histFrame.layout().addWidget(self.LMTHistCheckBox) self.LLTHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.LLTHistCheckBox) self.histFrame.layout().addWidget(self.LLTHistCheckBox) self.RUTHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.RUTHistCheckBox) self.histFrame.layout().addWidget(self.RUTHistCheckBox) self.RMTHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.RMTHistCheckBox) self.histFrame.layout().addWidget(self.RMTHistCheckBox) self.RLTHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.RLTHistCheckBox) self.histFrame.layout().addWidget(self.RLTHistCheckBox) for i in xrange(len(self.histogramCheckBoxes)): self.histogramCheckBoxes[i].setText(self.rTags[i]) self.histogramCheckBoxes[i].hide() self.HistSection.layout().addWidget(self.histFrame) self.HistSection.enabled = False # Chart button self.chartBox = qt.QFrame() self.chartBox.setObjectName("chartBox") self.chartBox.setStyleSheet( '#chartBox {border: 0.5px solid lightGray;}') self.chartBox.setLayout(qt.QVBoxLayout()) self.parent.layout().addWidget(self.chartBox) chartSectionTitle = qt.QLabel() chartSectionTitle.setText('Chart Section') self.chartBox.layout().addWidget(chartSectionTitle) chartFrame = qt.QFrame() chartFrame.setLayout(qt.QHBoxLayout()) self.chartBox.layout().addWidget(chartFrame) self.chartButton = qt.QPushButton("Chart") self.chartButton.toolTip = "Make a chart from the current statistics." chartFrame.layout().addWidget(self.chartButton) self.chartOption = qt.QComboBox() self.chartOption.addItems(self.chartOptions) chartFrame.layout().addWidget(self.chartOption) self.chartBox.enabled = False self.reportsWidget = CaseReportsWidget(self.moduleName, self.columnsDict, parentWidget=self.parent) self.reportsWidget.setup() self.reportsWidget.showPrintButton(True) # self.reportsWidget.saveButton.enabled = False # self.reportsWidget.openButton.enabled = False # self.reportsWidget.exportButton.enabled = False # self.reportsWidget.removeButton.enabled = False # By default, the Print button is hidden # self.reportsWidget.showPrintButton.enabled = False # Add vertical spacer self.parent.layout().addStretch(1) # connections self.applyButton.connect('clicked()', self.onApply) self.chartButton.connect('clicked()', self.onChart) self.reportsWidget.addObservable( self.reportsWidget.EVENT_SAVE_BUTTON_CLICKED, self.onSaveReport) self.reportsWidget.addObservable( self.reportsWidget.EVENT_PRINT_BUTTON_CLICKED, self.onPrintReport) self.CTSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onCTSelect) self.labelSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onLabelSelect) self.GlobalHistCheckBox.connect('clicked()', self.onHistogram) self.RightHistCheckBox.connect('clicked()', self.onHistogram) self.LeftHistCheckBox.connect('clicked()', self.onHistogram) self.RULHistCheckBox.connect('clicked()', self.onHistogram) self.RLLHistCheckBox.connect('clicked()', self.onHistogram) self.RMLHistCheckBox.connect('clicked()', self.onHistogram) self.LULHistCheckBox.connect('clicked()', self.onHistogram) self.LLLHistCheckBox.connect('clicked()', self.onHistogram) self.LUTHistCheckBox.connect('clicked()', self.onHistogram) self.LMTHistCheckBox.connect('clicked()', self.onHistogram) self.LLTHistCheckBox.connect('clicked()', self.onHistogram) self.RUTHistCheckBox.connect('clicked()', self.onHistogram) self.RMTHistCheckBox.connect('clicked()', self.onHistogram) self.RLTHistCheckBox.connect('clicked()', self.onHistogram) def cleanup(self): self.reportsWidget.cleanup() self.reportsWidget = None def onCTSelect(self, node): self.CTNode = node self.applyButton.enabled = bool( self.CTNode) # and bool(self.labelNode) self.preProcessingWidget.enableFilteringFrame(bool(self.CTNode)) self.preProcessingWidget.enableLMFrame(bool(not self.labelNode)) if self.CTNode: for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic( ).GetSliceCompositeNode().SetBackgroundVolumeID( self.CTNode.GetID()) else: for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic( ).GetSliceCompositeNode().SetBackgroundVolumeID('None') def onLabelSelect(self, node): self.labelNode = node self.applyButton.enabled = bool( self.CTNode) # and bool(self.labelNode) self.preProcessingWidget.enableFilteringFrame(bool(self.CTNode)) self.preProcessingWidget.enableLMFrame(bool(not self.labelNode)) SlicerUtil.changeLabelmapOpacity(0.5) if self.labelNode: self.preProcessingWidget.filterApplication.setChecked(1) self.preProcessingWidget.filterApplication.setEnabled(0) for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic( ).GetSliceCompositeNode().SetLabelVolumeID( self.labelNode.GetID()) else: self.preProcessingWidget.filterApplication.setChecked(0) self.preProcessingWidget.filterApplication.setEnabled(1) for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic( ).GetSliceCompositeNode().SetLabelVolumeID('None') def inputVolumesAreValid(self): """Verify that volumes are compatible with label calculation algorithm assumptions""" if not self.CTNode: # or not self.labelNode: qt.QMessageBox.warning(slicer.util.mainWindow(), "Parenchyma Analysis", "Please select a CT Input Volume.") return False if not self.CTNode.GetImageData( ): # or not self.labelNode.GetImageData(): qt.QMessageBox.warning(slicer.util.mainWindow(), "Parenchyma Analysis", "Please select a CT Input Volume.") return False if not self.labelNode or not self.labelNode.GetImageData(): warning = self.preProcessingWidget.warningMessageForLM() if warning == 16384: self.createLungLabelMap() else: qt.QMessageBox.warning(slicer.util.mainWindow(), "Parenchyma Analysis", "Please select a Lung Label Map.") return False return True if self.CTNode.GetImageData().GetDimensions( ) != self.labelNode.GetImageData().GetDimensions(): qt.QMessageBox.warning( slicer.util.mainWindow(), "Parenchyma Analysis", "Input Volumes do not have the same geometry.") return False # if self.preProcessingWidget.filterOnRadioButton.checked: # self.preProcessingWidget.filterApplication.setChecked(1) return True def filterInputCT(self): self.applyButton.enabled = False self.applyButton.text = "Filtering..." # TODO: why doesn't processEvents alone make the label text change? self.applyButton.repaint() slicer.app.processEvents() self.preProcessingWidget.filterInputCT(self.CTNode) def createLungLabelMap(self): """Create the lung label map """ self.applyButton.enabled = False if self.preProcessingWidget.filterOnRadioButton.checked: # and not self.preProcessingWidget.filterApplication.checked: self.filterInputCT() inputNode = self.CTNode self.applyButton.text = "Creating Label Map..." # TODO: why doesn't processEvents alone make the label text change? self.applyButton.repaint() slicer.app.processEvents() self.labelNode = slicer.mrmlScene.AddNode( slicer.vtkMRMLLabelMapVolumeNode()) name = inputNode.GetName() + '_partialLungLabelMap' self.labelNode.SetName(slicer.mrmlScene.GenerateUniqueName(name)) self.preProcessingWidget.createPartialLM(inputNode, self.labelNode) label_image = self.labelNode.GetImageData() shape = list(label_image.GetDimensions()) input_array = vtk.util.numpy_support.vtk_to_numpy( label_image.GetPointData().GetScalars()) original_shape = input_array.shape input_array = input_array.reshape( shape[2], shape[1], shape[0]) # input_array.transpose([2, 1, 0]) would not work! input_image = sitk.GetImageFromArray(input_array) input_image.SetSpacing(self.labelNode.GetSpacing()) input_image.SetOrigin(self.labelNode.GetOrigin()) my_lung_splitter = lung_splitter(split_thirds=True) split_lm = my_lung_splitter.execute(input_image) split = sitk.GetArrayFromImage(split_lm) input_aa = vtk.util.numpy_support.vtk_to_numpy( label_image.GetPointData().GetScalars()) input_aa[:] = split.reshape(original_shape) self.labelNode.StorableModified() self.labelNode.Modified() self.labelNode.InvokeEvent( slicer.vtkMRMLVolumeNode.ImageDataModifiedEvent, self.labelNode) SlicerUtil.changeLabelmapOpacity(0.5) def onApply(self): """Calculate the parenchyma analysis """ if not self.inputVolumesAreValid(): return self.applyButton.enabled = False if self.preProcessingWidget.filterOnRadioButton.checked and self.preProcessingWidget.filterApplication.checked: self.filterInputCT() self.applyButton.text = "Analysing..." # TODO: why doesn't processEvents alone make the label text change? self.applyButton.repaint() slicer.app.processEvents() self.logic = CIP_ParenchymaAnalysisLogic(self.CTNode, self.labelNode) self.populateStats() self.logic.createHistogram() for i in xrange(len(self.histogramCheckBoxes)): self.histogramCheckBoxes[i].setChecked(0) self.histogramCheckBoxes[i].hide() for tag in self.rTags: if tag in self.logic.regionTags: self.histogramCheckBoxes[self.rTags.index(tag)].show() self.HistSection.enabled = True self.chartBox.enabled = True # self.reportsWidget.saveButton.enabled = True # self.reportsWidget.openButton.enabled = True # self.reportsWidget.exportButton.enabled = True # self.reportsWidget.removeButton.enabled = True self.applyButton.enabled = True self.applyButton.text = "Apply" for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic( ).GetSliceCompositeNode().SetBackgroundVolumeID( self.CTNode.GetID()) self.labelSelector.setCurrentNode(self.labelNode) def onHistogram(self): """Histogram of the selected region """ self.histList = [] for i in xrange(len(self.histogramCheckBoxes)): if self.histogramCheckBoxes[i].checked == True: self.histList.append(self.rTags[i]) self.logic.AddSelectedHistograms(self.histList) def onChart(self): """chart the parenchyma analysis """ valueToPlot = self.chartOptions[self.chartOption.currentIndex] self.logic.createStatsChart(self.labelNode, valueToPlot) def onSaveReport(self): """ Save the current values in a persistent csv file """ self.logic.statsAsCSV(self.reportsWidget, self.CTNode) def onPrintReport(self): """ Print a pdf report """ emphysema_image_path, ct_slice_path = self.logic.computeEmphysemaOnSlice( self.CTNode, self.labelNode, op=0.5) pdfReporter = PdfReporter() # Get the values that are going to be inserted in the html template caseName = self.CTNode.GetName() values = dict() values["@@PATH_TO_STATIC@@"] = os.path.join( os.path.dirname(os.path.realpath(__file__)), "Resources/") values["@@SUBJECT@@"] = "Subject: " + str(caseName) values["@@GLOBAL_LEVEL@@"] = "{:.2f}%".format( self.logic.labelStats['LAA%-950', 'WholeLung']) values["@@SUMMARY@@"] = "Emphysema per region: " pdfRows = """""" for tag in self.logic.regionTags: pdfRows += """<tr> <td align="center">{} </td> <td align="center">{:.2f} </td> </tr>""".format(tag, self.logic.labelStats['LAA%-950', tag]) values["@@TABLE_ROWS@@"] = pdfRows # Get the path to the html template htmlTemplatePath = os.path.join( os.path.dirname(os.path.realpath(__file__)), "Resources/CIP_ParenchymaAnalysisReport.html") # Get a list of image absolute paths that may be needed for the report. In this case, we get the ACIL logo imagesFileList = [SlicerUtil.ACIL_LOGO_PATH] values["@@EMPHYSEMA_IMAGE@@"] = emphysema_image_path values["@@CT_IMAGE@@"] = ct_slice_path # Print the report. Remember that we can optionally specify the absolute path where the report is going to # be stored pdfReporter.printPdf(htmlTemplatePath, values, self.reportPrinted, imagesFileList=imagesFileList) def reportPrinted(self, reportPath): Util.openFile(reportPath) def onFileSelected(self, fileName): self.logic.saveStats(fileName) def populateStats(self): if not self.logic: return displayNode = self.labelNode.GetDisplayNode() colorNode = displayNode.GetColorNode() lut = colorNode.GetLookupTable() self.items = [] self.model = qt.QStandardItemModel() self.view.setModel(self.model) self.view.verticalHeader().visible = False row = 0 for regionTag, regionValue in zip(self.logic.regionTags, self.logic.regionValues): color = qt.QColor() rgb = lut.GetTableValue(regionValue[0]) color.setRgb(rgb[0] * 255, rgb[1] * 255, rgb[2] * 255) item = qt.QStandardItem() item.setData(color, 1) item.setText(str(regionTag)) item.setData(regionTag, 1) item.setToolTip(regionTag) item.setTextAlignment(1) self.model.setItem(row, 0, item) self.items.append(item) col = 1 for k in self.logic.keys: item = qt.QStandardItem() item.setText("%.3f" % self.logic.labelStats[k, regionTag]) item.setTextAlignment(4) self.view.setColumnWidth(col, 15 * len(item.text())) self.model.setItem(row, col, item) self.items.append(item) col += 1 row += 1 self.view.setColumnWidth(0, 15 * len('Region')) self.model.setHeaderData(0, 1, "Region") col = 1 for k in self.logic.keys: # self.view.setColumnWidth(col,15*len(k)) self.model.setHeaderData(col, 1, k) col += 1
def setup(self): # Instantiate and connect widgets ... ScriptedLoadableModuleWidget.setup(self) if SlicerUtil.IsDevelopment: self.reloadAndTestButton.visible = False # No valid tests at the moment # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) parametersFormLayout.setVerticalSpacing(5) # # Input volume selector # self.CTSelector = slicer.qMRMLNodeComboBox() self.CTSelector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "") self.CTSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", 0) self.CTSelector.selectNodeUponCreation = False self.CTSelector.addEnabled = False self.CTSelector.removeEnabled = False self.CTSelector.noneEnabled = True self.CTSelector.showHidden = False self.CTSelector.showChildNodeTypes = False self.CTSelector.setMRMLScene(slicer.mrmlScene) self.CTSelector.setToolTip("Pick the CT image to work on.") parametersFormLayout.addRow("Input CT Volume: ", self.CTSelector) # # First input volume selector # self.labelSelector = slicer.qMRMLNodeComboBox() # self.labelSelector.nodeTypes = ( ("vtkMRMLScalarVolumeNode"), "" ) # self.labelSelector.addAttribute( "vtkMRMLScalarVolumeNode", "LabelMap", 1 ) self.labelSelector.nodeTypes = (("vtkMRMLLabelMapVolumeNode"), "") self.labelSelector.selectNodeUponCreation = True self.labelSelector.addEnabled = False self.labelSelector.removeEnabled = False self.labelSelector.noneEnabled = True self.labelSelector.showHidden = False self.labelSelector.showChildNodeTypes = False self.labelSelector.setMRMLScene(slicer.mrmlScene) self.labelSelector.setToolTip("Pick the label map to the algorithm.") parametersFormLayout.addRow("Label Map Volume: ", self.labelSelector) # # output volume selector # self.outputSelector = slicer.qMRMLNodeComboBox() # self.outputSelector.nodeTypes = ( ("vtkMRMLScalarVolumeNode"), "" ) # self.outputSelector.addAttribute( "vtkMRMLScalarVolumeNode", "LabelMap", 1 ) self.outputSelector.nodeTypes = (("vtkMRMLLabelMapVolumeNode"), "") self.outputSelector.selectNodeUponCreation = True self.outputSelector.addEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.noneEnabled = True self.outputSelector.showHidden = False self.outputSelector.showChildNodeTypes = True self.outputSelector.setMRMLScene(slicer.mrmlScene) self.outputSelector.setToolTip("Pick the output to the algorithm.") self.outputSelector.baseName = 'Fissures Segmentation Volume' parametersFormLayout.addRow("Fissures Volume: ", self.outputSelector) self.preProcessingWidget = PreProcessingWidget( self.moduleName, parentWidget=self.parent) self.preProcessingWidget.setup() self.preProcessingWidget.filterApplication.hide() self.preProcessingWidget.enableFilteringFrame(True) self.preProcessingWidget.enableFilterOptions(True) self.preProcessingWidget.enableLMFrame(True) self.layoutCollapsibleButton = ctk.ctkCollapsibleButton() self.layoutCollapsibleButton.text = "Layout Selection" self.layoutCollapsibleButton.setChecked(False) self.layoutCollapsibleButton.setFixedSize(600, 40) self.layout.addWidget(self.layoutCollapsibleButton, 0, 4) self.layoutFormLayout = qt.QFormLayout(self.layoutCollapsibleButton) """spacer = "" for s in range( 20 ): spacer += " """ # self.fiducialsFormLayout.setFormAlignment(4) self.layoutGroupBox = qt.QFrame() self.layoutGroupBox.setLayout(qt.QVBoxLayout()) self.layoutGroupBox.setFixedHeight(86) self.layoutFormLayout.addRow(self.layoutGroupBox) self.buttonGroupBox = qt.QFrame() self.buttonGroupBox.setLayout(qt.QHBoxLayout()) self.layoutGroupBox.layout().addWidget(self.buttonGroupBox) # self.layoutFormLayout.addRow(self.buttonGroupBox) # # Four-Up Button # self.fourUpButton = qt.QPushButton() self.fourUpButton.toolTip = "Four-up view." self.fourUpButton.enabled = True self.fourUpButton.setFixedSize(40, 40) fourUpIcon = qt.QIcon(":/Icons/LayoutFourUpView.png") self.fourUpButton.setIcon(fourUpIcon) self.buttonGroupBox.layout().addWidget(self.fourUpButton) # # Red Slice Button # self.redViewButton = qt.QPushButton() self.redViewButton.toolTip = "Red slice only." self.redViewButton.enabled = True self.redViewButton.setFixedSize(40, 40) redIcon = qt.QIcon(":/Icons/LayoutOneUpRedSliceView.png") self.redViewButton.setIcon(redIcon) self.buttonGroupBox.layout().addWidget(self.redViewButton) # # Yellow Slice Button # self.yellowViewButton = qt.QPushButton() self.yellowViewButton.toolTip = "Yellow slice only." self.yellowViewButton.enabled = True self.yellowViewButton.setFixedSize(40, 40) yellowIcon = qt.QIcon(":/Icons/LayoutOneUpYellowSliceView.png") self.yellowViewButton.setIcon(yellowIcon) self.buttonGroupBox.layout().addWidget(self.yellowViewButton) # # Green Slice Button # self.greenViewButton = qt.QPushButton() self.greenViewButton.toolTip = "Yellow slice only." self.greenViewButton.enabled = True self.greenViewButton.setFixedSize(40, 40) greenIcon = qt.QIcon(":/Icons/LayoutOneUpGreenSliceView.png") self.greenViewButton.setIcon(greenIcon) self.buttonGroupBox.layout().addWidget(self.greenViewButton) # # Buttons labels # self.labelsGroupBox = qt.QFrame() hBox = qt.QHBoxLayout() hBox.setSpacing(10) self.labelsGroupBox.setLayout(hBox) self.labelsGroupBox.setFixedSize(450, 26) self.layoutGroupBox.layout().addWidget(self.labelsGroupBox, 0, 4) fourUpLabel = qt.QLabel(" Four-up") # fourUpLabel.setFixedHeight(10) self.labelsGroupBox.layout().addWidget(fourUpLabel) redLabel = qt.QLabel(" Axial") self.labelsGroupBox.layout().addWidget(redLabel) yellowLabel = qt.QLabel(" Saggital") self.labelsGroupBox.layout().addWidget(yellowLabel) greenLabel = qt.QLabel(" Coronal") self.labelsGroupBox.layout().addWidget(greenLabel) # Layout connections self.fourUpButton.connect('clicked()', self.onFourUpButton) self.redViewButton.connect('clicked()', self.onRedViewButton) self.yellowViewButton.connect('clicked()', self.onYellowViewButton) self.greenViewButton.connect('clicked()', self.onGreenViewButton) # # Fiducials Area # self.groupBox = qt.QFrame() self.groupBox.setLayout(qt.QHBoxLayout()) fiducialsCollapsibleButton = ctk.ctkCollapsibleButton() fiducialsCollapsibleButton.text = "Fiducials Selection" self.layout.addWidget(fiducialsCollapsibleButton) self.fiducialsFormLayout = qt.QFormLayout(fiducialsCollapsibleButton) self.fiducialsFormLayout.setVerticalSpacing(5) self.fiducialsFormLayout.addRow(self.groupBox) # Add fiducial lists button self.AddLeftListButton = qt.QPushButton("Left oblique fissure") self.AddLeftListButton.toolTip = "Create a new fiducial list for the left lung oblique fissure." self.AddLeftListButton.setFixedHeight(40) self.groupBox.layout().addWidget(self.AddLeftListButton) # Add fiducial lists button self.AddRight1ListButton = qt.QPushButton("Right oblique fissure") self.AddRight1ListButton.toolTip = "Create a new fiducial list for the right lung oblique fissure." self.AddRight1ListButton.setFixedHeight(40) self.groupBox.layout().addWidget(self.AddRight1ListButton) # Add fiducial lists button self.AddRight2ListButton = qt.QPushButton("Right horizontal fissure") self.AddRight2ListButton.toolTip = "Create a new fiducial list for the right lung horizontal fissure." self.AddRight2ListButton.setFixedHeight(40) self.groupBox.layout().addWidget(self.AddRight2ListButton) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False self.applyButton.setFixedSize(150, 45) self.layout.addWidget(self.applyButton, 0, 4) # self.layout.setAlignment(2) # # Show Fiducials # fiducialButtonsList = [] fiducialButtonsList.append(self.AddLeftListButton) fiducialButtonsList.append(self.AddRight1ListButton) fiducialButtonsList.append(self.AddRight2ListButton) self.visualizationWidget = ILSVisualizationWidget( self.logic, self.applyButton, fiducialButtonsList) self.fiducialsFormLayout.addRow(self.visualizationWidget.widget) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.CTSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onCTSelect) self.labelSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.AddLeftListButton.connect('clicked()', self.onAddLeftListButton) self.AddRight1ListButton.connect('clicked()', self.onAddRight1ListButton) self.AddRight2ListButton.connect('clicked()', self.onAddRight2ListButton) self.updateList() # Add vertical spacer self.layout.addStretch(1)
def setup(self): ScriptedLoadableModuleWidget.setup(self) # # the inps volume selector # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "IO Volumes" self.parent.layout().addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) parametersFormLayout.setVerticalSpacing(5) self.CTSelector = slicer.qMRMLNodeComboBox() self.CTSelector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "") self.CTSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", 0) self.CTSelector.selectNodeUponCreation = False self.CTSelector.addEnabled = False self.CTSelector.removeEnabled = False self.CTSelector.noneEnabled = True self.CTSelector.showHidden = False self.CTSelector.showChildNodeTypes = False self.CTSelector.setMRMLScene(slicer.mrmlScene) self.CTSelector.setToolTip("Pick the CT image to work on.") parametersFormLayout.addRow("Input CT Volume: ", self.CTSelector) # # the label map volume selector # self.labelSelector = slicer.qMRMLNodeComboBox() # self.labelSelector.nodeTypes = ( ("vtkMRMLScalarVolumeNode"), "" ) # self.labelSelector.addAttribute( "vtkMRMLScalarVolumeNode", "LabelMap", 1 ) self.labelSelector.nodeTypes = (("vtkMRMLLabelMapVolumeNode"), "") self.labelSelector.selectNodeUponCreation = True self.labelSelector.addEnabled = False self.labelSelector.removeEnabled = False self.labelSelector.noneEnabled = True self.labelSelector.showHidden = False self.labelSelector.showChildNodeTypes = False self.labelSelector.setMRMLScene(slicer.mrmlScene) self.labelSelector.setToolTip("Pick the label map to the algorithm.") parametersFormLayout.addRow("Label Map Volume: ", self.labelSelector) # Image filtering section self.preProcessingWidget = PreProcessingWidget( self.moduleName, parentWidget=self.parent) self.preProcessingWidget.setup() # # self.splitRadioButton = qt.QRadioButton() # self.splitRadioButton.setText('Split Label Map') # self.splitRadioButton.setChecked(0) # self.parent.layout().addWidget(self.splitRadioButton, 0, 3) # Apply button self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Calculate Parenchyma Phenotypes." self.applyButton.enabled = False self.applyButton.setFixedSize(300, 30) self.parent.layout().addWidget(self.applyButton, 0, 4) # model and view for stats table self.view = qt.QTableView() self.view.sortingEnabled = True self.parent.layout().addWidget(self.view) # model and view for EXP stats table """self.viewexp = qt.QTableView() self.viewexp.sortingEnabled = True self.parent.layout().addWidget(self.viewexp)""" # Histogram Selection self.HistSection = qt.QFrame() self.HistSection.setLayout(qt.QVBoxLayout()) self.parent.layout().addWidget(self.HistSection) self.HistSection.setObjectName('HistSection') self.HistSection.setStyleSheet( '#HistSection {border: 0.5px solid lightGray; }') HistSectionTitle = qt.QLabel() HistSectionTitle.setText('Histogram Section') # HistSectionTitle.setStyleSheet('border: 1px solid white; color: black') self.HistSection.layout().addWidget(HistSectionTitle) self.histogramCheckBoxes = [] self.histFrame = qt.QFrame() # self.histFrame.setStyleSheet('border: 1px solid white') self.histFrame.setLayout(qt.QHBoxLayout()) self.GlobalHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.GlobalHistCheckBox) self.histFrame.layout().addWidget(self.GlobalHistCheckBox) self.RightHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.RightHistCheckBox) self.histFrame.layout().addWidget(self.RightHistCheckBox) self.LeftHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.LeftHistCheckBox) self.histFrame.layout().addWidget(self.LeftHistCheckBox) self.RULHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.RULHistCheckBox) self.histFrame.layout().addWidget(self.RULHistCheckBox) self.RLLHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.RLLHistCheckBox) self.histFrame.layout().addWidget(self.RLLHistCheckBox) self.RMLHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.RMLHistCheckBox) self.histFrame.layout().addWidget(self.RMLHistCheckBox) self.LULHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.LULHistCheckBox) self.histFrame.layout().addWidget(self.LULHistCheckBox) self.LLLHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.LLLHistCheckBox) self.histFrame.layout().addWidget(self.LLLHistCheckBox) self.LUTHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.LUTHistCheckBox) self.histFrame.layout().addWidget(self.LUTHistCheckBox) self.LMTHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.LMTHistCheckBox) self.histFrame.layout().addWidget(self.LMTHistCheckBox) self.LLTHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.LLTHistCheckBox) self.histFrame.layout().addWidget(self.LLTHistCheckBox) self.RUTHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.RUTHistCheckBox) self.histFrame.layout().addWidget(self.RUTHistCheckBox) self.RMTHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.RMTHistCheckBox) self.histFrame.layout().addWidget(self.RMTHistCheckBox) self.RLTHistCheckBox = qt.QCheckBox() self.histogramCheckBoxes.append(self.RLTHistCheckBox) self.histFrame.layout().addWidget(self.RLTHistCheckBox) for i in xrange(len(self.histogramCheckBoxes)): self.histogramCheckBoxes[i].setText(self.rTags[i]) self.histogramCheckBoxes[i].hide() self.HistSection.layout().addWidget(self.histFrame) self.HistSection.enabled = False # Chart button self.chartBox = qt.QFrame() self.chartBox.setObjectName("chartBox") self.chartBox.setStyleSheet( '#chartBox {border: 0.5px solid lightGray;}') self.chartBox.setLayout(qt.QVBoxLayout()) self.parent.layout().addWidget(self.chartBox) chartSectionTitle = qt.QLabel() chartSectionTitle.setText('Chart Section') self.chartBox.layout().addWidget(chartSectionTitle) chartFrame = qt.QFrame() chartFrame.setLayout(qt.QHBoxLayout()) self.chartBox.layout().addWidget(chartFrame) self.chartButton = qt.QPushButton("Chart") self.chartButton.toolTip = "Make a chart from the current statistics." chartFrame.layout().addWidget(self.chartButton) self.chartOption = qt.QComboBox() self.chartOption.addItems(self.chartOptions) chartFrame.layout().addWidget(self.chartOption) self.chartBox.enabled = False self.reportsWidget = CaseReportsWidget(self.moduleName, self.columnsDict, parentWidget=self.parent) self.reportsWidget.setup() self.reportsWidget.showPrintButton(True) # self.reportsWidget.saveButton.enabled = False # self.reportsWidget.openButton.enabled = False # self.reportsWidget.exportButton.enabled = False # self.reportsWidget.removeButton.enabled = False # By default, the Print button is hidden # self.reportsWidget.showPrintButton.enabled = False # Add vertical spacer self.parent.layout().addStretch(1) # connections self.applyButton.connect('clicked()', self.onApply) self.chartButton.connect('clicked()', self.onChart) self.reportsWidget.addObservable( self.reportsWidget.EVENT_SAVE_BUTTON_CLICKED, self.onSaveReport) self.reportsWidget.addObservable( self.reportsWidget.EVENT_PRINT_BUTTON_CLICKED, self.onPrintReport) self.CTSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onCTSelect) self.labelSelector.connect('currentNodeChanged(vtkMRMLNode*)', self.onLabelSelect) self.GlobalHistCheckBox.connect('clicked()', self.onHistogram) self.RightHistCheckBox.connect('clicked()', self.onHistogram) self.LeftHistCheckBox.connect('clicked()', self.onHistogram) self.RULHistCheckBox.connect('clicked()', self.onHistogram) self.RLLHistCheckBox.connect('clicked()', self.onHistogram) self.RMLHistCheckBox.connect('clicked()', self.onHistogram) self.LULHistCheckBox.connect('clicked()', self.onHistogram) self.LLLHistCheckBox.connect('clicked()', self.onHistogram) self.LUTHistCheckBox.connect('clicked()', self.onHistogram) self.LMTHistCheckBox.connect('clicked()', self.onHistogram) self.LLTHistCheckBox.connect('clicked()', self.onHistogram) self.RUTHistCheckBox.connect('clicked()', self.onHistogram) self.RMTHistCheckBox.connect('clicked()', self.onHistogram) self.RLTHistCheckBox.connect('clicked()', self.onHistogram)
class CIP_InteractiveLobeSegmentationWidget(ScriptedLoadableModuleWidget): def __init__(self, parent=None): ScriptedLoadableModuleWidget.__init__(self, parent) self.logic = CIP_InteractiveLobeSegmentationLogic() self.observerTags = [] if not parent: self.parent = slicer.qMRMLWidget() self.parent.setLayout(qt.QVBoxLayout()) self.parent.setMRMLScene(slicer.mrmlScene) else: self.parent = parent self.layout = self.parent.layout() if not parent: self.setup() self.parent.show() # def enter(self): # """Method that is invoked when we switch to the module in slicer user interface""" # if self.nodeObserver is None: # self.nodeObserver = slicer.mrmlScene.AddObserver(slicer.vtkMRMLScene.NodeAddedEvent, self.onNodeAdded) # self.checkMasterAndLabelMapNodes() def enter(self): if self.labelSelector.currentNode(): for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic( ).GetSliceCompositeNode().SetLabelVolumeID( self.labelSelector.currentNode().GetID()) def exit(self): for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic( ).GetSliceCompositeNode().SetLabelVolumeID('None') # slicer.mrmlScene.RemoveObserver(self.nodeObserver) def setup(self): # Instantiate and connect widgets ... ScriptedLoadableModuleWidget.setup(self) if SlicerUtil.IsDevelopment: self.reloadAndTestButton.visible = False # No valid tests at the moment # # Parameters Area # parametersCollapsibleButton = ctk.ctkCollapsibleButton() parametersCollapsibleButton.text = "Parameters" self.layout.addWidget(parametersCollapsibleButton) # Layout within the dummy collapsible button parametersFormLayout = qt.QFormLayout(parametersCollapsibleButton) parametersFormLayout.setVerticalSpacing(5) # # Input volume selector # self.CTSelector = slicer.qMRMLNodeComboBox() self.CTSelector.nodeTypes = (("vtkMRMLScalarVolumeNode"), "") self.CTSelector.addAttribute("vtkMRMLScalarVolumeNode", "LabelMap", 0) self.CTSelector.selectNodeUponCreation = False self.CTSelector.addEnabled = False self.CTSelector.removeEnabled = False self.CTSelector.noneEnabled = True self.CTSelector.showHidden = False self.CTSelector.showChildNodeTypes = False self.CTSelector.setMRMLScene(slicer.mrmlScene) self.CTSelector.setToolTip("Pick the CT image to work on.") parametersFormLayout.addRow("Input CT Volume: ", self.CTSelector) # # First input volume selector # self.labelSelector = slicer.qMRMLNodeComboBox() # self.labelSelector.nodeTypes = ( ("vtkMRMLScalarVolumeNode"), "" ) # self.labelSelector.addAttribute( "vtkMRMLScalarVolumeNode", "LabelMap", 1 ) self.labelSelector.nodeTypes = (("vtkMRMLLabelMapVolumeNode"), "") self.labelSelector.selectNodeUponCreation = True self.labelSelector.addEnabled = False self.labelSelector.removeEnabled = False self.labelSelector.noneEnabled = True self.labelSelector.showHidden = False self.labelSelector.showChildNodeTypes = False self.labelSelector.setMRMLScene(slicer.mrmlScene) self.labelSelector.setToolTip("Pick the label map to the algorithm.") parametersFormLayout.addRow("Label Map Volume: ", self.labelSelector) # # output volume selector # self.outputSelector = slicer.qMRMLNodeComboBox() # self.outputSelector.nodeTypes = ( ("vtkMRMLScalarVolumeNode"), "" ) # self.outputSelector.addAttribute( "vtkMRMLScalarVolumeNode", "LabelMap", 1 ) self.outputSelector.nodeTypes = (("vtkMRMLLabelMapVolumeNode"), "") self.outputSelector.selectNodeUponCreation = True self.outputSelector.addEnabled = True self.outputSelector.removeEnabled = True self.outputSelector.noneEnabled = True self.outputSelector.showHidden = False self.outputSelector.showChildNodeTypes = True self.outputSelector.setMRMLScene(slicer.mrmlScene) self.outputSelector.setToolTip("Pick the output to the algorithm.") self.outputSelector.baseName = 'Fissures Segmentation Volume' parametersFormLayout.addRow("Fissures Volume: ", self.outputSelector) self.preProcessingWidget = PreProcessingWidget( self.moduleName, parentWidget=self.parent) self.preProcessingWidget.setup() self.preProcessingWidget.filterApplication.hide() self.preProcessingWidget.enableFilteringFrame(True) self.preProcessingWidget.enableFilterOptions(True) self.preProcessingWidget.enableLMFrame(True) self.layoutCollapsibleButton = ctk.ctkCollapsibleButton() self.layoutCollapsibleButton.text = "Layout Selection" self.layoutCollapsibleButton.setChecked(False) self.layoutCollapsibleButton.setFixedSize(600, 40) self.layout.addWidget(self.layoutCollapsibleButton, 0, 4) self.layoutFormLayout = qt.QFormLayout(self.layoutCollapsibleButton) """spacer = "" for s in range( 20 ): spacer += " """ # self.fiducialsFormLayout.setFormAlignment(4) self.layoutGroupBox = qt.QFrame() self.layoutGroupBox.setLayout(qt.QVBoxLayout()) self.layoutGroupBox.setFixedHeight(86) self.layoutFormLayout.addRow(self.layoutGroupBox) self.buttonGroupBox = qt.QFrame() self.buttonGroupBox.setLayout(qt.QHBoxLayout()) self.layoutGroupBox.layout().addWidget(self.buttonGroupBox) # self.layoutFormLayout.addRow(self.buttonGroupBox) # # Four-Up Button # self.fourUpButton = qt.QPushButton() self.fourUpButton.toolTip = "Four-up view." self.fourUpButton.enabled = True self.fourUpButton.setFixedSize(40, 40) fourUpIcon = qt.QIcon(":/Icons/LayoutFourUpView.png") self.fourUpButton.setIcon(fourUpIcon) self.buttonGroupBox.layout().addWidget(self.fourUpButton) # # Red Slice Button # self.redViewButton = qt.QPushButton() self.redViewButton.toolTip = "Red slice only." self.redViewButton.enabled = True self.redViewButton.setFixedSize(40, 40) redIcon = qt.QIcon(":/Icons/LayoutOneUpRedSliceView.png") self.redViewButton.setIcon(redIcon) self.buttonGroupBox.layout().addWidget(self.redViewButton) # # Yellow Slice Button # self.yellowViewButton = qt.QPushButton() self.yellowViewButton.toolTip = "Yellow slice only." self.yellowViewButton.enabled = True self.yellowViewButton.setFixedSize(40, 40) yellowIcon = qt.QIcon(":/Icons/LayoutOneUpYellowSliceView.png") self.yellowViewButton.setIcon(yellowIcon) self.buttonGroupBox.layout().addWidget(self.yellowViewButton) # # Green Slice Button # self.greenViewButton = qt.QPushButton() self.greenViewButton.toolTip = "Yellow slice only." self.greenViewButton.enabled = True self.greenViewButton.setFixedSize(40, 40) greenIcon = qt.QIcon(":/Icons/LayoutOneUpGreenSliceView.png") self.greenViewButton.setIcon(greenIcon) self.buttonGroupBox.layout().addWidget(self.greenViewButton) # # Buttons labels # self.labelsGroupBox = qt.QFrame() hBox = qt.QHBoxLayout() hBox.setSpacing(10) self.labelsGroupBox.setLayout(hBox) self.labelsGroupBox.setFixedSize(450, 26) self.layoutGroupBox.layout().addWidget(self.labelsGroupBox, 0, 4) fourUpLabel = qt.QLabel(" Four-up") # fourUpLabel.setFixedHeight(10) self.labelsGroupBox.layout().addWidget(fourUpLabel) redLabel = qt.QLabel(" Axial") self.labelsGroupBox.layout().addWidget(redLabel) yellowLabel = qt.QLabel(" Saggital") self.labelsGroupBox.layout().addWidget(yellowLabel) greenLabel = qt.QLabel(" Coronal") self.labelsGroupBox.layout().addWidget(greenLabel) # Layout connections self.fourUpButton.connect('clicked()', self.onFourUpButton) self.redViewButton.connect('clicked()', self.onRedViewButton) self.yellowViewButton.connect('clicked()', self.onYellowViewButton) self.greenViewButton.connect('clicked()', self.onGreenViewButton) # # Fiducials Area # self.groupBox = qt.QFrame() self.groupBox.setLayout(qt.QHBoxLayout()) fiducialsCollapsibleButton = ctk.ctkCollapsibleButton() fiducialsCollapsibleButton.text = "Fiducials Selection" self.layout.addWidget(fiducialsCollapsibleButton) self.fiducialsFormLayout = qt.QFormLayout(fiducialsCollapsibleButton) self.fiducialsFormLayout.setVerticalSpacing(5) self.fiducialsFormLayout.addRow(self.groupBox) # Add fiducial lists button self.AddLeftListButton = qt.QPushButton("Left oblique fissure") self.AddLeftListButton.toolTip = "Create a new fiducial list for the left lung oblique fissure." self.AddLeftListButton.setFixedHeight(40) self.groupBox.layout().addWidget(self.AddLeftListButton) # Add fiducial lists button self.AddRight1ListButton = qt.QPushButton("Right oblique fissure") self.AddRight1ListButton.toolTip = "Create a new fiducial list for the right lung oblique fissure." self.AddRight1ListButton.setFixedHeight(40) self.groupBox.layout().addWidget(self.AddRight1ListButton) # Add fiducial lists button self.AddRight2ListButton = qt.QPushButton("Right horizontal fissure") self.AddRight2ListButton.toolTip = "Create a new fiducial list for the right lung horizontal fissure." self.AddRight2ListButton.setFixedHeight(40) self.groupBox.layout().addWidget(self.AddRight2ListButton) # # Apply Button # self.applyButton = qt.QPushButton("Apply") self.applyButton.toolTip = "Run the algorithm." self.applyButton.enabled = False self.applyButton.setFixedSize(150, 45) self.layout.addWidget(self.applyButton, 0, 4) # self.layout.setAlignment(2) # # Show Fiducials # fiducialButtonsList = [] fiducialButtonsList.append(self.AddLeftListButton) fiducialButtonsList.append(self.AddRight1ListButton) fiducialButtonsList.append(self.AddRight2ListButton) self.visualizationWidget = ILSVisualizationWidget( self.logic, self.applyButton, fiducialButtonsList) self.fiducialsFormLayout.addRow(self.visualizationWidget.widget) # connections self.applyButton.connect('clicked(bool)', self.onApplyButton) self.CTSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onCTSelect) self.labelSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.outputSelector.connect("currentNodeChanged(vtkMRMLNode*)", self.onSelect) self.AddLeftListButton.connect('clicked()', self.onAddLeftListButton) self.AddRight1ListButton.connect('clicked()', self.onAddRight1ListButton) self.AddRight2ListButton.connect('clicked()', self.onAddRight2ListButton) self.updateList() # Add vertical spacer self.layout.addStretch(1) def cleanup(self): pass def onCTSelect(self, CTNode): if CTNode: for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic( ).GetSliceCompositeNode().SetBackgroundVolumeID(CTNode.GetID()) else: for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic( ).GetSliceCompositeNode().SetBackgroundVolumeID('None') def onSelect(self): self.layoutCollapsibleButton.setChecked(True) if self.labelSelector.currentNode(): self.preProcessingWidget.enableFilteringFrame(False) self.preProcessingWidget.enableLMFrame(False) for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic( ).GetSliceCompositeNode().SetLabelVolumeID( self.labelSelector.currentNode().GetID()) SlicerUtil.changeLabelmapOpacity(0.5) else: self.preProcessingWidget.enableFilteringFrame(True) self.preProcessingWidget.enableLMFrame(True) for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic( ).GetSliceCompositeNode().SetLabelVolumeID('None') def onFourUpButton(self): applicationLogic = slicer.app.applicationLogic() interactionNode = applicationLogic.GetInteractionNode() interactionNode.Reset(None) interactionNode.SwitchToPersistentPlaceMode() layoutManager = slicer.app.layoutManager() layoutManager.setLayout(3) def onRedViewButton(self): applicationLogic = slicer.app.applicationLogic() interactionNode = applicationLogic.GetInteractionNode() interactionNode.Reset(None) interactionNode.SwitchToPersistentPlaceMode() layoutManager = slicer.app.layoutManager() layoutManager.setLayout(6) def onYellowViewButton(self): applicationLogic = slicer.app.applicationLogic() interactionNode = applicationLogic.GetInteractionNode() interactionNode.Reset(None) interactionNode.SwitchToPersistentPlaceMode() layoutManager = slicer.app.layoutManager() layoutManager.setLayout(7) def onGreenViewButton(self): applicationLogic = slicer.app.applicationLogic() interactionNode = applicationLogic.GetInteractionNode() interactionNode.Reset(None) interactionNode.SwitchToPersistentPlaceMode() layoutManager = slicer.app.layoutManager() layoutManager.setLayout(8) def onAddLeftListButton(self): # self.applyButton.enabled = self.inputSelector.currentNode() and self.labelSelector.currentNode() and self.outputSelector.currentNode() self.AddLeftListButton.setStyleSheet( "background-color: rgb(255,99,71)") self.AddRight1ListButton.setStyleSheet( "background-color: rgb(255,255,255)") self.AddRight2ListButton.setStyleSheet( "background-color: rgb(255,255,255)") logic = CIP_InteractiveLobeSegmentationLogic() self.logic.name = 'LO' logic.createList('LO') def onAddRight1ListButton(self): # self.applyButton.enabled = self.inputSelector.currentNode() and self.labelSelector.currentNode() and self.outputSelector.currentNode() self.AddRight1ListButton.setStyleSheet( "background-color: rgb(255,99,71)") self.AddLeftListButton.setStyleSheet( "background-color: rgb(255,255,255)") self.AddRight2ListButton.setStyleSheet( "background-color: rgb(255,255,255)") logic = CIP_InteractiveLobeSegmentationLogic() self.logic.name = 'RO' logic.createList('RO') def onAddRight2ListButton(self): # self.applyButton.enabled = self.inputSelector.currentNode() and self.labelSelector.currentNode() and self.outputSelector.currentNode() self.AddRight2ListButton.setStyleSheet( "background-color: rgb(255,99,71)") self.AddLeftListButton.setStyleSheet( "background-color: rgb(255,255,255)") self.AddRight1ListButton.setStyleSheet( "background-color: rgb(255,255,255)") logic = CIP_InteractiveLobeSegmentationLogic() self.logic.name = 'RH' logic.createList('RH') def onApplyButton(self): red_logic = slicer.app.layoutManager().sliceWidget("Red").sliceLogic() red_cn = red_logic.GetSliceCompositeNode() volumeID = red_cn.GetBackgroundVolumeID() CTNode = SlicerUtil.getNode(volumeID) if self.labelSelector.currentNode() == None: warning = self.preProcessingWidget.warningMessageForLM() if warning == 16384: labelNode = slicer.mrmlScene.AddNode( slicer.vtkMRMLLabelMapVolumeNode()) labelNode.SetName(CTNode.GetName() + '_partialLungLabelMap') if not CTNode: self.applyButton.enabled = True return False if self.preProcessingWidget.filterOnRadioButton.checked: volumesLogic = slicer.modules.volumes.logic() clonedCTNode = volumesLogic.CloneVolume( slicer.mrmlScene, CTNode, 'Cloned Volume') self.filterInputCT(clonedCTNode) self.createLungLabelMap(clonedCTNode, labelNode) slicer.mrmlScene.RemoveNode(clonedCTNode) for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget( color).sliceLogic().GetSliceCompositeNode( ).SetBackgroundVolumeID(CTNode.GetID()) else: self.createLungLabelMap(CTNode, labelNode) else: qt.QMessageBox.warning(slicer.util.mainWindow(), "Parenchyma Analysis", "Please select a Lung Label Map.") self.applyButton.enabled = True return False self.visualizationWidget.updateScene() self.applyButton.text = "Segmenting Lobes..." self.applyButton.repaint() slicer.app.processEvents() logic = CIP_InteractiveLobeSegmentationLogic() self.visualizationWidget.pendingUpdate = True outputNode = self.outputSelector.currentNode() if not outputNode: outputNode = slicer.vtkMRMLLabelMapVolumeNode() slicer.mrmlScene.AddNode(outputNode) fissureVolume = None try: fissureVolume = logic.run(self.labelSelector.currentNode(), outputNode) except Exception as e: import traceback traceback.print_exc() qt.QMessageBox.warning( slicer.util.mainWindow(), "Running", 'Exception!\n\n' + str(e) + "\n\nSee Python Console for Stack Trace") # if fissureVolume is not None: self.outputSelector.setCurrentNode(fissureVolume) SlicerUtil.changeLabelmapOpacity(0.5) self.onFourUpButton() self.applyButton.text = "Apply" self.applyButton.repaint() slicer.app.processEvents() self.applyButton.enabled = True applicationLogic = slicer.app.applicationLogic() interactionNode = applicationLogic.GetInteractionNode() interactionNode.Reset(None) self.visualizationWidget.pendingUpdate = False for color in ['Red', 'Yellow', 'Green']: slicer.app.layoutManager().sliceWidget(color).sliceLogic( ).GetSliceCompositeNode().SetBackgroundVolumeID(CTNode.GetID()) slicer.app.layoutManager().sliceWidget( color).sliceLogic().GetSliceCompositeNode().SetLabelVolumeID( self.outputSelector.currentNode().GetID()) def filterInputCT(self, input_node): # self.applyButton.enabled = False self.applyButton.text = "Filtering..." self.applyButton.repaint() slicer.app.processEvents() self.preProcessingWidget.filterInputCT(input_node) def createLungLabelMap(self, input_node, label_node): """Create the lung label map """ self.applyButton.text = "Creating Label Map..." self.applyButton.repaint() slicer.app.processEvents() self.preProcessingWidget.createPartialLM(input_node, label_node) SlicerUtil.changeLabelmapOpacity(0.5) self.labelSelector.setCurrentNode(label_node) def updateList(self): """Observe the mrml scene for changes that we wish to respond to.""" tag = slicer.mrmlScene.AddObserver(slicer.mrmlScene.EndCloseEvent, self.clearTable) tag = slicer.mrmlScene.AddObserver( slicer.mrmlScene.NodeAddedEvent, self.visualizationWidget.requestNodeAddedUpdate) self.observerTags.append((slicer.mrmlScene, tag)) def clearTable(self, caller, event): self.onFourUpButton() self.visualizationWidget.tableWidget.clearContents() self.visualizationWidget.tableWidget.setRowCount(0) self.visualizationWidget.leftRow = 0 self.visualizationWidget.rightObliqueRow = 0 self.visualizationWidget.rightHorizontalRow = 0 self.visualizationWidget.updateScene() self.visualizationWidget.fiducialsCollapsibleButton.hide() self.visualizationWidget.removeFiducialObservers()