Exemplo n.º 1
0
 def _addMissingPreopDataAnnotation(self, widget):
     self._removeMissingPreopDataAnnotation()
     self.noPreopSegmentationAnnotation = SliceAnnotation(
         widget,
         constants.MISSING_PREOP_ANNOTATION_TEXT,
         opacity=0.7,
         color=(1, 0, 0))
Exemplo n.º 2
0
 def addSideBySideSliceAnnotations(self):
   self.removeSliceAnnotations()
   kwargs = {"yPos":55 if ModuleWidgetMixin.isQtVersionOlder() else 80, "size":30}
   self.sliceAnnotations.append(SliceAnnotation(self.redWidget, constants.LEFT_VIEWER_SLICE_ANNOTATION_TEXT, **kwargs))
   self.sliceAnnotations.append(SliceAnnotation(self.yellowWidget, constants.RIGHT_VIEWER_SLICE_ANNOTATION_TEXT, **kwargs))
   self.addNewImageAnnotation(self.yellowWidget, constants.RIGHT_VIEWER_SLICE_NEEDLE_IMAGE_ANNOTATION_TEXT)
   self.addOldImageAnnotation(self.yellowWidget, constants.RIGHT_VIEWER_SLICE_TRANSFORMED_ANNOTATION_TEXT)
   self.addRegistrationResultStatusAnnotation(self.yellowWidget)
Exemplo n.º 3
0
 def addZFrameInstructions(self, step=1):
   self.removeZFrameInstructionAnnotation()
   self.zFrameStep = step
   text = ProstateAblationConstants.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)
Exemplo n.º 4
0
 def addFourUpSliceAnnotations(self):
   self.removeSliceAnnotations()
   if not (self.currentResult.skipped or (self.session.seriesTypeManager.isCoverProstate(self.currentResult.name) and
                                            not self.session.data.usePreopData)):
     self.sliceAnnotations.append(SliceAnnotation(self.redWidget, constants.RIGHT_VIEWER_SLICE_ANNOTATION_TEXT,
                                                  yPos=50 if ModuleWidgetMixin.isQtVersionOlder() else 75, size=20))
     self.addNewImageAnnotation(self.redWidget, constants.RIGHT_VIEWER_SLICE_NEEDLE_IMAGE_ANNOTATION_TEXT, size=15)
     self.addOldImageAnnotation(self.redWidget, constants.RIGHT_VIEWER_SLICE_TRANSFORMED_ANNOTATION_TEXT, size=15)
   self.addRegistrationResultStatusAnnotation(self.redWidget)
Exemplo n.º 5
0
 def addRegistrationResultStatusAnnotation(self, widget):
   annotationText = None
   if self.currentResult.approved:
     annotationText = constants.APPROVED_RESULT_TEXT_ANNOTATION
   elif self.currentResult.rejected:
     annotationText = constants.REJECTED_RESULT_TEXT_ANNOTATION
   elif self.currentResult.skipped:
     annotationText = constants.SKIPPED_RESULT_TEXT_ANNOTATION
   if annotationText:
     self.sliceAnnotations.append(SliceAnnotation(widget, annotationText, yPos=20, size=15))
 def addSliceAnnotations(self):
     self.removeSliceAnnotations()
     widgets = [self.yellowWidget] if self.layoutManager.layout == constants.LAYOUT_SIDE_BY_SIDE else \
       [self.redWidget, self.yellowWidget, self.greenWidget]
     for widget in widgets:
         self.sliceAnnotations.append(
             SliceAnnotation(widget,
                             "Targeting Mode",
                             opacity=0.5,
                             verticalAlign="top",
                             horizontalAlign="center"))
Exemplo n.º 7
0
  def enableTargetMovingMode(self):
    self.clearTargetMovementObserverAndAnnotations()
    targetName = self.targetTableModel.targetList.GetNthFiducialLabel(self.currentlyMovedTargetModelIndex.row())

    widgets = [self.yellowWidget] if self.layoutManager.layout == constants.LAYOUT_SIDE_BY_SIDE else \
                 [self.redWidget, self.yellowWidget, self.greenWidget]
    for widget in widgets:
      sliceView = widget.sliceView()
      interactor = sliceView.interactorStyle().GetInteractor()
      observer = interactor.AddObserver(vtk.vtkCommand.LeftButtonReleaseEvent, self.onViewerClickEvent)
      sliceView.setCursor(qt.Qt.CrossCursor)
      annotation = SliceAnnotation(widget, "Target Movement Mode (%s)" % targetName, opacity=0.5,
                                   verticalAlign="top", horizontalAlign="center")
      self.mouseReleaseEventObservers[widget] = (observer, annotation)
    self.moveTargetMode = True
Exemplo n.º 8
0
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()
Exemplo n.º 9
0
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
Exemplo n.º 10
0
 def addOldImageAnnotation(self, widget, text, size=20):
   self.oldImageAnnotation = SliceAnnotation(widget, text, yPos=35 if ModuleWidgetMixin.isQtVersionOlder() else 45,
                                             size=size)
   self.sliceAnnotations.append(self.oldImageAnnotation)
Exemplo n.º 11
0
 def addNewImageAnnotation(self, widget, text, size=20):
   self.newImageAnnotation = SliceAnnotation(widget, text, yPos=35 if ModuleWidgetMixin.isQtVersionOlder() else 45,
                                             opacity=0.0, color=(0, 0.5, 0), size=size)
   self.sliceAnnotations.append(self.newImageAnnotation)