class SliceTrackerZFrameRegistrationStep(SliceTrackerStep): NAME = "ZFrame Registration" LogicClass = SliceTrackerZFrameRegistrationStepLogic LayoutClass = qt.QVBoxLayout def __init__(self): self.annotationLogic = slicer.modules.annotations.logic() self.zFrameRegistrationClass = getattr( sys.modules[__name__], self.getSetting("ZFrame_Registration_Class_Name")) self.roiObserverTag = None self.coverTemplateROI = None self.zFrameCroppedVolume = None self.zFrameLabelVolume = None self.zFrameMaskedVolume = None self.zFrameClickObserver = None self.zFrameInstructionAnnotation = None super(SliceTrackerZFrameRegistrationStep, self).__init__() self.logic.templateVolume = None def setupIcons(self): self.zFrameIcon = self.createIcon('icon-zframe.png') self.needleIcon = self.createIcon('icon-needle.png') self.templateIcon = self.createIcon('icon-template.png') def setup(self): super(SliceTrackerZFrameRegistrationStep, self).setup() self.setupManualIndexesGroupBox() self.setupActionButtons() self.layout().addWidget(self.zFrameRegistrationManualIndexesGroupBox) self.layout().addWidget( self.createHLayout([ self.runZFrameRegistrationButton, self.retryZFrameRegistrationButton, self.approveZFrameRegistrationButton ])) self.layout().addStretch(1) def setupManualIndexesGroupBox(self): self.zFrameRegistrationManualIndexesGroupBox = qt.QGroupBox( "Use manual start/end indexes") self.zFrameRegistrationManualIndexesGroupBox.setCheckable(True) self.zFrameRegistrationManualIndexesGroupBoxLayout = qt.QGridLayout() self.zFrameRegistrationManualIndexesGroupBox.setLayout( self.zFrameRegistrationManualIndexesGroupBoxLayout) self.zFrameRegistrationManualIndexesGroupBox.checked = False self.zFrameRegistrationStartIndex = qt.QSpinBox() self.zFrameRegistrationEndIndex = qt.QSpinBox() hBox = self.createHLayout([ qt.QLabel("start"), self.zFrameRegistrationStartIndex, qt.QLabel("end"), self.zFrameRegistrationEndIndex ]) self.zFrameRegistrationManualIndexesGroupBoxLayout.addWidget( hBox, 1, 1, qt.Qt.AlignRight) def setupActionButtons(self): iconSize = qt.QSize(36, 36) self.runZFrameRegistrationButton = self.createButton( "", icon=Icons.start, iconSize=iconSize, enabled=False, toolTip="Run ZFrame Registration") self.approveZFrameRegistrationButton = self.createButton( "", icon=Icons.apply, iconSize=iconSize, enabled=self.zFrameRegistrationClass is LineMarkerRegistration, toolTip="Confirm registration accuracy", ) self.retryZFrameRegistrationButton = self.createButton( "", icon=Icons.retry, iconSize=iconSize, enabled=False, visible=self.zFrameRegistrationClass is OpenSourceZFrameRegistration, toolTip="Reset") def setupAdditionalViewSettingButtons(self): iconSize = qt.QSize(24, 24) self.showZFrameModelButton = self.createButton( "", icon=self.zFrameIcon, iconSize=iconSize, checkable=True, toolTip="Display zFrame model") self.showTemplateButton = self.createButton("", icon=self.templateIcon, iconSize=iconSize, checkable=True, toolTip="Display template") # self.showNeedlePathButton = self.createButton("", icon=self.needleIcon, iconSize=iconSize, checkable=True, toolTip="Display needle path") self.showTemplatePathButton = self.createButton( "", icon=self.templateIcon, iconSize=iconSize, checkable=True, toolTip="Display template paths") self.viewSettingButtons = [ self.showZFrameModelButton, self.showTemplateButton ] def setupConnections(self): self.retryZFrameRegistrationButton.clicked.connect( self.onRetryZFrameRegistrationButtonClicked) self.approveZFrameRegistrationButton.clicked.connect( self.onApproveZFrameRegistrationButtonClicked) self.runZFrameRegistrationButton.clicked.connect( self.onApplyZFrameRegistrationButtonClicked) self.showZFrameModelButton.connect('toggled(bool)', self.onShowZFrameModelToggled) self.showTemplateButton.connect('toggled(bool)', self.onShowZFrameTemplateToggled) self.showTemplatePathButton.connect('toggled(bool)', self.onShowTemplatePathToggled) # self.showNeedlePathButton.connect('toggled(bool)', self.onShowNeedlePathToggled) def addSessionObservers(self): super(SliceTrackerZFrameRegistrationStep, self).addSessionObservers() self.session.addEventObserver( self.session.InitiateZFrameCalibrationEvent, self.onInitiateZFrameCalibration) def removeSessionEventObservers(self): super(SliceTrackerZFrameRegistrationStep, self).removeSessionEventObservers() self.session.removeEventObserver( self.session.InitiateZFrameCalibrationEvent, self.onInitiateZFrameCalibration) def onShowZFrameModelToggled(self, checked): self.logic.setZFrameVisibility(checked) def onShowZFrameTemplateToggled(self, checked): self.logic.setTemplateVisibility(checked) self.logic.setTemplatePathVisibility(checked) def onShowTemplatePathToggled(self, checked): self.logic.setTemplatePathVisibility(checked) def onShowNeedlePathToggled(self, checked): self.logic.setNeedlePathVisibility(checked) def resetViewSettingButtons(self): self.showTemplateButton.enabled = self.logic.templateSuccessfulLoaded self.showTemplatePathButton.enabled = self.logic.templateSuccessfulLoaded self.showZFrameModelButton.enabled = self.logic.zFrameSuccessfulLoaded def onInitiateZFrameCalibration(self, caller, event): self.logic.templateVolume = self.session.currentSeriesVolume self.active = True @vtk.calldata_type(vtk.VTK_STRING) def onNewImageSeriesReceived(self, caller, event, callData): # TODO: control here to automatically activate the step if not self.active: return newImageSeries = ast.literal_eval(callData) for series in reversed(newImageSeries): if self.session.seriesTypeManager.isCoverTemplate(series): if self.logic.templateVolume and series != self.logic.templateVolume.GetName( ): if not slicer.util.confirmYesNoDisplay( "Another %s was received. Do you want to use this one for " "calibration?" % self.getSetting("COVER_TEMPLATE_PATTERN")): return self.session.currentSeries = series self.removeZFrameInstructionAnnotation() self.logic.templateVolume = self.session.currentSeriesVolume self.initiateZFrameRegistrationStep() return def onLoadingMetadataSuccessful(self, caller, event): if self.session.zFrameRegistrationSuccessful: self.applyZFrameTransform() def onActivation(self): super(SliceTrackerZFrameRegistrationStep, self).onActivation() self.layoutManager.setLayout(SliceTrackerConstants.LAYOUT_FOUR_UP) self.showZFrameModelButton.checked = True self.showTemplateButton.checked = True self.showTemplatePathButton.checked = True self.zFrameRegistrationManualIndexesGroupBox.checked = False if self.logic.templateVolume: self.initiateZFrameRegistrationStep() def onDeactivation(self): super(SliceTrackerZFrameRegistrationStep, self).onDeactivation() self.showZFrameModelButton.checked = False self.showTemplateButton.checked = False self.showTemplatePathButton.checked = False self.logic.templateVolume = None def initiateZFrameRegistrationStep(self): self.resetZFrameRegistration() self.setupFourUpView(self.logic.templateVolume) self.redSliceNode.SetSliceVisible(True) if self.zFrameRegistrationClass is OpenSourceZFrameRegistration: self.addROIObserver() self.activateCreateROIMode() self.addZFrameInstructions() def resetZFrameRegistration(self): self.runZFrameRegistrationButton.enabled = False self.approveZFrameRegistrationButton.enabled = False self.retryZFrameRegistrationButton.enabled = False self.removeNodeFromMRMLScene(self.coverTemplateROI) self.removeNodeFromMRMLScene(self.zFrameCroppedVolume) self.removeNodeFromMRMLScene(self.zFrameLabelVolume) self.removeNodeFromMRMLScene(self.zFrameMaskedVolume) if self.session.data.zFrameRegistrationResult: self.removeNodeFromMRMLScene( self.session.data.zFrameRegistrationResult.transform) self.session.data.zFrameRegistrationResult = None def addROIObserver(self): @vtk.calldata_type(vtk.VTK_OBJECT) def onNodeAdded(caller, event, calldata): node = calldata if isinstance(node, slicer.vtkMRMLAnnotationROINode): self.removeROIObserver() self.coverTemplateROI = node self.runZFrameRegistrationButton.enabled = self.isRegistrationPossible( ) if self.roiObserverTag: self.removeROIObserver() self.roiObserverTag = slicer.mrmlScene.AddObserver( slicer.vtkMRMLScene.NodeAddedEvent, onNodeAdded) def isRegistrationPossible(self): return self.coverTemplateROI is not None def removeROIObserver(self): if self.roiObserverTag: self.roiObserverTag = slicer.mrmlScene.RemoveObserver( self.roiObserverTag) def activateCreateROIMode(self): mrmlScene = self.annotationLogic.GetMRMLScene() selectionNode = mrmlScene.GetNthNodeByClass(0, "vtkMRMLSelectionNode") selectionNode.SetReferenceActivePlaceNodeClassName( "vtkMRMLAnnotationROINode") # self.annotationLogic.StopPlaceMode(False) # BUG: http://na-mic.org/Mantis/view.php?id=4355 self.annotationLogic.StartPlaceMode(False) def addZFrameInstructions(self, step=1): self.removeZFrameInstructionAnnotation() self.zFrameStep = step text = SliceTrackerConstants.ZFrame_INSTRUCTION_STEPS[self.zFrameStep] self.zFrameInstructionAnnotation = SliceAnnotation( self.redWidget, text, yPos=55, horizontalAlign="center", opacity=0.6, color=(0, 0.6, 0)) self.zFrameClickObserver = self.redSliceViewInteractor.AddObserver( vtk.vtkCommand.LeftButtonReleaseEvent, self.onZFrameStepAccomplished) # TODO # self.onShowAnnotationsToggled(self.showAnnotationsButton.checked) def onZFrameStepAccomplished(self, observee, event): self.removeZFrameInstructionAnnotation() nextStep = self.zFrameStep + 1 if nextStep in SliceTrackerConstants.ZFrame_INSTRUCTION_STEPS.keys(): self.addZFrameInstructions(nextStep) def removeZFrameInstructionAnnotation(self): if hasattr(self, "zFrameInstructionAnnotation" ) and self.zFrameInstructionAnnotation: self.zFrameInstructionAnnotation.remove() self.zFrameInstructionAnnotation = None if self.zFrameClickObserver: self.redSliceViewInteractor.RemoveObserver( self.zFrameClickObserver) self.zFrameClickObserver = None def onApplyZFrameRegistrationButtonClicked(self): zFrameTemplateVolume = self.logic.templateVolume try: if self.zFrameRegistrationClass is OpenSourceZFrameRegistration: self.annotationLogic.SetAnnotationLockedUnlocked( self.coverTemplateROI.GetID()) self.zFrameCroppedVolume = self.logic.createCroppedVolume( zFrameTemplateVolume, self.coverTemplateROI) self.zFrameLabelVolume = self.logic.createLabelMapFromCroppedVolume( self.zFrameCroppedVolume, "labelmap") self.zFrameMaskedVolume = self.logic.createMaskedVolume( zFrameTemplateVolume, self.zFrameLabelVolume, outputVolumeName="maskedTemplateVolume") self.zFrameMaskedVolume.SetName( zFrameTemplateVolume.GetName() + "-label") if not self.zFrameRegistrationManualIndexesGroupBox.checked: start, center, end = self.logic.getROIMinCenterMaxSliceNumbers( self.coverTemplateROI) otsuOutputVolume = self.logic.applyOtsuFilter( self.zFrameMaskedVolume) self.logic.dilateMask(otsuOutputVolume) start, end = self.logic.getStartEndWithConnectedComponents( otsuOutputVolume, center) self.zFrameRegistrationStartIndex.value = start self.zFrameRegistrationEndIndex.value = end else: start = self.zFrameRegistrationStartIndex.value end = self.zFrameRegistrationEndIndex.value self.logic.runZFrameRegistration(self.zFrameMaskedVolume, self.zFrameRegistrationClass, startSlice=start, endSlice=end) else: self.logic.runZFrameRegistration(zFrameTemplateVolume, self.zFrameRegistrationClass) self.applyZFrameTransform() except AttributeError as exc: slicer.util.errorDisplay( "An error occurred. For further information click 'Show Details...'", windowTitle=self.__class__.__name__, detailedText=str(exc.message)) else: self.setBackgroundToVolumeID(zFrameTemplateVolume) self.approveZFrameRegistrationButton.enabled = True self.retryZFrameRegistrationButton.enabled = True def applyZFrameTransform(self): for node in [ node for node in [ self.logic.pathModelNode, self.logic.tempModelNode, self.logic.zFrameModelNode, self.logic.needleModelNode ] if node ]: node.SetAndObserveTransformNodeID( self.session.data.zFrameRegistrationResult.transform.GetID()) def onApproveZFrameRegistrationButtonClicked(self): self.redSliceNode.SetSliceVisible(False) if self.zFrameRegistrationClass is OpenSourceZFrameRegistration: self.annotationLogic.SetAnnotationVisibility( self.coverTemplateROI.GetID()) self.session.approvedCoverTemplate = self.logic.templateVolume def onRetryZFrameRegistrationButtonClicked(self): self.removeZFrameInstructionAnnotation() self.annotationLogic.SetAnnotationVisibility( self.coverTemplateROI.GetID()) self.initiateZFrameRegistrationStep()
class SliceTrackerSegmentationStep(SliceTrackerStep): NAME = "Segmentation" LogicClass = SliceTrackerSegmentationStepLogic LayoutClass = qt.QVBoxLayout def __init__(self): super(SliceTrackerSegmentationStep, self).__init__() self.session.retryMode = False self.segmentationData = None def setup(self): super(SliceTrackerSegmentationStep, self).setup() self._setupTargetingPlugin() self._setupManualSegmentationPlugin() self._setupAutomaticSegmentationPlugin() self._setupNavigationButtons() self.layout().addWidget(self.manualSegmentationPlugin) self.layout().addWidget( self.createHLayout([self.backButton, self.finishStepButton])) self.layout().addWidget(self.targetingPlugin) self.layout().addStretch(1) def _setupTargetingPlugin(self): self.targetingPlugin = SliceTrackerTargetingPlugin() self.targetingPlugin.addEventObserver( self.targetingPlugin.TargetingStartedEvent, self._onTargetingStarted) self.targetingPlugin.addEventObserver( self.targetingPlugin.TargetingFinishedEvent, self._onTargetingFinished) self.addPlugin(self.targetingPlugin) def _setupManualSegmentationPlugin(self): self.manualSegmentationPlugin = SliceTrackerManualSegmentationPlugin() self.manualSegmentationPlugin.addEventObserver( self.manualSegmentationPlugin.SegmentationStartedEvent, self._onSegmentationStarted) self.manualSegmentationPlugin.addEventObserver( self.manualSegmentationPlugin.SegmentationCanceledEvent, self._onSegmentationCanceled) self.manualSegmentationPlugin.addEventObserver( self.manualSegmentationPlugin.SegmentationFinishedEvent, self._onManualSegmentationFinished) self.manualSegmentationPlugin.surfaceCutToLabelWidget.segmentEditorButtonVisible = False self.addPlugin(self.manualSegmentationPlugin) def _setupAutomaticSegmentationPlugin(self): self.automaticSegmentationPlugin = SliceTrackerAutomaticSegmentationPlugin( ) self.automaticSegmentationPlugin.addEventObserver( self.automaticSegmentationPlugin.SegmentationStartedEvent, self._onAutomaticSegmentationStarted) self.automaticSegmentationPlugin.addEventObserver( self.automaticSegmentationPlugin.SegmentationFailedEvent, self._onSegmentationFailed) self.automaticSegmentationPlugin.addEventObserver( self.automaticSegmentationPlugin.SegmentationFinishedEvent, self._onAutomaticSegmentationFinished) self.addPlugin(self.automaticSegmentationPlugin) def _setupNavigationButtons(self): iconSize = qt.QSize(36, 36) self.backButton = self.createButton("", icon=Icons.back, iconSize=iconSize, toolTip="Return to last step") self.finishStepButton = self.createButton( "", icon=Icons.start, iconSize=iconSize, toolTip="Run Registration/Finish Step") def setupConnections(self): super(SliceTrackerSegmentationStep, self).setupConnections() self.backButton.clicked.connect(self._onBackButtonClicked) self.finishStepButton.clicked.connect(self._onFinishStepButtonClicked) def addSessionObservers(self): super(SliceTrackerSegmentationStep, self).addSessionObservers() self.session.addEventObserver(self.session.InitiateSegmentationEvent, self.onInitiateSegmentation) def removeSessionEventObservers(self): super(SliceTrackerSegmentationStep, self).removeSessionEventObservers() self.session.removeEventObserver( self.session.InitiateSegmentationEvent, self.onInitiateSegmentation) def onActivation(self): self.segmentationData = None self.finishStepButton.enabled = False self.session.fixedVolume = self.session.currentSeriesVolume if not self.session.fixedVolume: return self._updateAvailableLayouts() super(SliceTrackerSegmentationStep, self).onActivation() def onDeactivation(self): super(SliceTrackerSegmentationStep, self).onDeactivation() self._removeMissingPreopDataAnnotation() @onModuleSelected(SliceTrackerStep.MODULE_NAME) def onLayoutChanged(self, layout=None): if self.layoutManager.layout == constants.LAYOUT_SIDE_BY_SIDE: self._setupSideBySideSegmentationView() elif self.layoutManager.layout in [ constants.LAYOUT_FOUR_UP, constants.LAYOUT_RED_SLICE_ONLY ]: self._removeMissingPreopDataAnnotation() self.setBackgroundToVolumeID(self.session.currentSeriesVolume, clearLabels=False) @vtk.calldata_type(vtk.VTK_STRING) def onInitiateSegmentation(self, caller, event, callData): self._initiateSegmentation(ast.literal_eval(callData)) def _initiateSegmentation(self, retryMode=False): self.session.retryMode = retryMode self.finishStepButton.setEnabled( True if self.logic.inputsAreSet() else False) if self.session.seriesTypeManager.isCoverProstate( self.session.currentSeries): self.initializeCoverProstate() else: self._loadLatestCoverProstateResultData() self.active = True def initializeCoverProstate(self): if self.session.data.usePreopData: if self.session.retryMode: if not self._loadLatestCoverProstateResultData(): self.logic.loadInitialData() else: self.logic.loadInitialData() else: self.session.movingVolume = self.session.currentSeriesVolume def _loadLatestCoverProstateResultData(self): coverProstate = self.session.data.getMostRecentApprovedCoverProstateRegistration( ) if coverProstate: self.session.movingVolume = coverProstate.volumes.fixed self.session.movingLabel = coverProstate.labels.fixed self.session.movingTargets = coverProstate.targets.approved return True return False def _updateAvailableLayouts(self): layouts = [constants.LAYOUT_RED_SLICE_ONLY, constants.LAYOUT_FOUR_UP] if self.session.data.usePreopData or self.session.retryMode: layouts.append(constants.LAYOUT_SIDE_BY_SIDE) self.setAvailableLayouts(layouts) def _setupSideBySideSegmentationView(self): # TODO: red slice view should not be possible to set target coverProstate = self.session.data.getMostRecentApprovedCoverProstateRegistration( ) redVolume = coverProstate.volumes.fixed if coverProstate and self.session.retryMode else self.session.data.initialVolume redLabel = coverProstate.labels.fixed if coverProstate and self.session.retryMode else self.session.data.initialLabel if redVolume and redLabel: self.redCompositeNode.SetBackgroundVolumeID(redVolume.GetID()) self.redCompositeNode.SetLabelVolumeID(redLabel.GetID()) self.redCompositeNode.SetLabelOpacity(1) else: self.redCompositeNode.SetBackgroundVolumeID(None) self.redCompositeNode.SetLabelVolumeID(None) self._addMissingPreopDataAnnotation(self.redWidget) self.yellowCompositeNode.SetBackgroundVolumeID( self.session.currentSeriesVolume.GetID()) self.setAxialOrientation() if redVolume and redLabel: self.redSliceNode.SetUseLabelOutline(True) self.redSliceNode.RotateToVolumePlane(redVolume) def _addMissingPreopDataAnnotation(self, widget): self._removeMissingPreopDataAnnotation() self.noPreopSegmentationAnnotation = SliceAnnotation( widget, constants.MISSING_PREOP_ANNOTATION_TEXT, opacity=0.7, color=(1, 0, 0)) def _removeMissingPreopDataAnnotation(self): self.noPreopSegmentationAnnotation = getattr( self, "noPreopSegmentationAnnotation", None) if self.noPreopSegmentationAnnotation: self.noPreopSegmentationAnnotation.remove() self.noPreopSegmentationAnnotation = None def _onBackButtonClicked(self): if self.session.retryMode: self.session.retryMode = False if self.session.previousStep: self.session.previousStep.active = True def _onFinishStepButtonClicked(self): self.session.data.segmentModelNode = self.manualSegmentationPlugin.segmentModelNode self.session.data.inputMarkupNode = self.manualSegmentationPlugin.inputMarkupNode if not self.session.data.usePreopData and not self.session.retryMode: self._createCoverProstateRegistrationResultManually() else: self.session.onInvokeRegistration( initial=True, retryMode=self.session.retryMode, segmentationData=self.segmentationData) def _createCoverProstateRegistrationResultManually(self): fixedVolume = self.session.currentSeriesVolume result = self.session.generateNameAndCreateRegistrationResult( fixedVolume) approvedRegistrationType = "bSpline" result.targets.original = self.session.movingTargets targetName = str( result.seriesNumber ) + '-TARGETS-' + approvedRegistrationType + result.suffix clone = self.logic.cloneFiducials(self.session.movingTargets, targetName) self.session.applyDefaultTargetDisplayNode(clone) result.setTargets(approvedRegistrationType, clone) result.volumes.fixed = fixedVolume result.labels.fixed = self.session.fixedLabel result.receivedTime = self.session.seriesTimeStamps[ result.name.replace(result.suffix, "")] result.segmentationData = self.segmentationData if self.session.seriesTypeManager.isCoverProstate(self.session.currentResult.name) and \ self.session.data.getMostRecentApprovedCoverProstateRegistration() is not None: self.session.data.getMostRecentApprovedCoverProstateRegistration( ).skip() result.approve(approvedRegistrationType, consentedBy="Clinician") def _onAutomaticSegmentationStarted(self, caller, event): self.manualSegmentationPlugin.enabled = False self._onSegmentationStarted(caller, event) def _onSegmentationStarted(self, caller, event): # self.setAvailableLayouts([constants.LAYOUT_RED_SLICE_ONLY, constants.LAYOUT_SIDE_BY_SIDE, constants.LAYOUT_FOUR_UP]) self.targetingPlugin.enabled = False self.backButton.enabled = False self.finishStepButton.enabled = False def _onSegmentationCanceled(self, caller, event): # self.setAvailableLayouts([constants.LAYOUT_FOUR_UP]) self.layoutManager.setLayout(constants.LAYOUT_FOUR_UP) self.backButton.enabled = True self.targetingPlugin.enabled = True if self.logic.inputsAreSet(): self._displaySegmentationComparison() self.finishStepButton.setEnabled( 1 if self.logic.inputsAreSet() else 0) # TODO: need to revise that def _onSegmentationFailed(self, caller, event): import logging logging.debug("Segmentation failed") self.setAvailableLayouts([constants.LAYOUT_FOUR_UP]) self.layoutManager.setLayout(constants.LAYOUT_FOUR_UP) self.backButton.enabled = True self.finishStepButton.setEnabled(False) @vtk.calldata_type(vtk.VTK_STRING) def onNewImageSeriesReceived(self, caller, event, callData): if not self.active: return newImageSeries = ast.literal_eval(callData) for series in reversed(newImageSeries): if self.session.seriesTypeManager.isCoverProstate(series): if series != self.session.currentSeries: if slicer.util.confirmYesNoDisplay( "Another %s was received. Do you want to use this one?" % self.getSetting("COVER_PROSTATE_PATTERN")): self.session.currentSeries = series self.active = False self._initiateSegmentation() @vtk.calldata_type(vtk.VTK_OBJECT) def _onAutomaticSegmentationFinished(self, caller, event, labelNode): self.manualSegmentationPlugin.enabled = True surfaceCutToLabelWidget = self.manualSegmentationPlugin.surfaceCutToLabelWidget # segmentationsLogic = slicer.modules.segmentations.logic() # # segmentationNode = surfaceCutToLabelWidget.segmentationNode # map(lambda x: segmentationNode.RemoveSegment(x), surfaceCutToLabelWidget.getSegmentIDs()) # segmentationsLogic.ImportLabelmapToSegmentationNode(labelNode, segmentationNode) # surfaceCutToLabelWidget.configureSegmentVisibility() # surfaceCutToLabelWidget.segmentEditorWidgetButton.enabled = True surfaceCutToLabelWidget.imageVolume = self.session.currentSeriesVolume surfaceCutToLabelWidget.labelVolume = labelNode self.createSegmentationDataOrSetModified( self.automaticSegmentationPlugin, labelNode) self._onSegmentationFinished(caller, event, labelNode) def createSegmentationDataOrSetModified(self, plugin, labelNode): if not self.segmentationData or self.segmentationData.algorithm == "Manual": self.segmentationData = SegmentationData( segmentationType="Prostate", algorithm=plugin.ALGORITHM_TYPE, startTime=plugin.startTime, endTime=plugin.endTime, label=labelNode) else: self.segmentationData.setModified(startTime=plugin.startTime, endTime=plugin.endTime, label=labelNode) @vtk.calldata_type(vtk.VTK_OBJECT) def _onManualSegmentationFinished(self, caller, event, labelNode): self.createSegmentationDataOrSetModified(self.manualSegmentationPlugin, labelNode) self._onSegmentationFinished(caller, event, labelNode) @vtk.calldata_type(vtk.VTK_OBJECT) def _onSegmentationFinished(self, caller, event, labelNode): _, suffix = self.session.getRegistrationResultNameAndGeneratedSuffix( self.session.currentSeries) if labelNode.GetName( ).find(suffix) == -1 and not labelNode.GetName().endswith("_modified"): labelNode.SetName(labelNode.GetName() + suffix) self.session.fixedLabel = labelNode self.finishStepButton.setEnabled(1 if self.logic.inputsAreSet() else 0) self.backButton.enabled = True self._displaySegmentationComparison() def _displaySegmentationComparison(self): self.setAvailableLayouts([constants.LAYOUT_SIDE_BY_SIDE]) if self.session.data.usePreopData or self.session.retryMode: self.setAxialOrientation() self._removeMissingPreopDataAnnotation() self.targetingPlugin.enabled = True if self.session.data.usePreopData or self.session.retryMode: self.layoutManager.setLayout(constants.LAYOUT_SIDE_BY_SIDE) self._setBackgroundAndLabel("red", self.session.movingVolume, self.session.movingLabel) self._setBackgroundAndLabel("yellow", self.session.fixedVolume, self.session.fixedLabel) self._centerLabelsOnVisibleSliceWidgets() elif not self.session.movingTargets: self.targetingPlugin.startTargeting() else: for compositeNode, sliceNode in zip(self._compositeNodes, self._sliceNodes): compositeNode.SetLabelVolumeID(self.session.fixedLabel.GetID()) compositeNode.SetLabelOpacity(1) sliceNode.SetUseLabelOutline(True) def _setBackgroundAndLabel(self, viewName, volume, label): compositeNode = getattr(self, viewName + "CompositeNode") compositeNode.SetReferenceBackgroundVolumeID(volume.GetID()) compositeNode.SetLabelVolumeID(label.GetID()) compositeNode.SetLabelOpacity(1) sliceNode = getattr(self, viewName + "SliceNode") sliceNode.SetOrientationToAxial() sliceNode.RotateToVolumePlane(volume) sliceNode.SetUseLabelOutline(True) def _centerLabelsOnVisibleSliceWidgets(self): for widget in self.getAllVisibleWidgets(): compositeNode = widget.mrmlSliceCompositeNode() sliceNode = widget.sliceLogic().GetSliceNode() labelID = compositeNode.GetLabelVolumeID() if labelID: label = slicer.mrmlScene.GetNodeByID(labelID) centroid = self.logic.getCentroidForLabel( label, self.session.segmentedLabelValue) if centroid: sliceNode.JumpSliceByCentering(centroid[0], centroid[1], centroid[2]) def _onTargetingStarted(self, caller, event): self.manualSegmentationPlugin.enabled = False self.backButton.enabled = False def _onTargetingFinished(self, caller, event): self.finishStepButton.setEnabled(1 if self.logic.inputsAreSet() else 0) self.manualSegmentationPlugin.enabled = True self.backButton.enabled = True