def onExit(self, goingTo, transitionType):

        if goingTo.id() != 'Landmarks' and goingTo.id(
        ) != 'LoadData':  # Change to next step
            return

        pNode = self.parameterNode()
        # TODO: add storeWidgetStateToParameterNode() -- move all pNode-related stuff
        # there?
        if self.__roi != None:
            self.__roi.RemoveObserver(self.__roiObserverTag)
            self.__roi.SetDisplayVisibility(0)

        if self.__roiSelector.currentNode() != None:
            pNode.SetNodeReferenceID('roiNode',
                                     self.__roiSelector.currentNode().GetID())

        if self.__vrDisplayNode != None:
            #self.__vrDisplayNode.VisibilityOff()
            pNode.SetNodeReferenceID('vrDisplayNode',
                                     self.__vrDisplayNode.GetID())

        if goingTo.id() == 'Landmarks':  # Change to next step

            #create progress bar dialog
            self.progress = qt.QProgressDialog(slicer.util.mainWindow())
            self.progress.minimumDuration = 0
            self.progress.show()
            self.progress.setValue(0)
            self.progress.setMaximum(0)
            self.progress.setCancelButton(0)
            self.progress.setMinimumWidth(500)
            self.progress.setWindowModality(2)

            self.progress.setLabelText('Cropping and resampling volume...')
            slicer.app.processEvents(qt.QEventLoop.ExcludeUserInputEvents)
            self.progress.repaint()

            self.doStepProcessing()

            #close progress bar
            self.progress.setValue(2)
            self.progress.repaint()
            slicer.app.processEvents(qt.QEventLoop.ExcludeUserInputEvents)
            self.progress.close()
            self.progress = None

        super(DefineROIStep, self).onExit(goingTo, transitionType)
Exemplo n.º 2
0
 def onOk(self):
   address = self.dicomEntries['Destination Address'].text
   port = self.dicomEntries['Destination Port'].text
   settings = qt.QSettings()
   settings.setValue('DICOM.sendAddress', address)
   settings.setValue('DICOM.sendPort', port)
   self.progress = qt.QProgressDialog(slicer.util.mainWindow())
   self.progress.minimumDuration = 0
   self.progress.setMaximum(len(self.files))
   self.progressValue = 0
   try:
     DICOMLib.DICOMSender(self.files, address, port, progressCallback = self.onProgress)
   except Exception as result:
     qt.QMessageBox.warning(self.dialog, 'DICOM Send', 'Could not send data: %s' % result)
   self.progress.close()
   self.dialog.close()
Exemplo n.º 3
0
    def loadCheckedLoadables(self):
        """Invoke the load method on each plugin for the DICOMLoadable
    instances that are selected"""
        if self.advancedViewButton.checkState() == 0:
            self.examineForLoading()

        self.loadableTable.updateSelectedFromCheckstate()
        loadableCount = 0
        for plugin in self.loadablesByPlugin:
            for loadable in self.loadablesByPlugin[plugin]:
                if loadable.selected:
                    loadableCount += 1
        self.progress = qt.QProgressDialog(self.window)
        self.progress.minimumDuration = 0
        self.progress.show()
        self.progress.setValue(0)
        self.progress.setMaximum(loadableCount)
        step = 0
        loadingResult = ''
        for plugin in self.loadablesByPlugin:
            for loadable in self.loadablesByPlugin[plugin]:
                if self.progress.wasCanceled:
                    break
                slicer.app.processEvents()
                self.progress.setValue(step)
                slicer.app.processEvents()
                if loadable.selected:
                    self.progress.labelText = '\nLoading %s' % loadable.name
                    slicer.app.processEvents()
                    if not plugin.load(loadable):
                        loadingResult = '%s\nCould not load: %s as a %s' % (
                            loadingResult, loadable.name, plugin.loadType)
                    step += 1
                    self.progress.setValue(step)
                    slicer.app.processEvents()
        self.progress.close()
        self.progress = None
        if loadingResult:
            qt.QMessageBox.warning(slicer.util.mainWindow(), 'DICOM loading',
                                   loadingResult)
        if not self.setBrowserPersistence:
            self.close()
Exemplo n.º 4
0
 def onLoadButton(self):
     self.progress = qt.QProgressDialog(slicer.util.mainWindow())
     self.progress.minimumDuration = 0
     self.progress.show()
     self.progress.setValue(0)
     self.progress.setMaximum(100)
     uid = self.selection.data(self.dicomModelUIDRole)
     role = self.dicomModelTypes[self.selection.data(
         self.dicomModelTypeRole)]
     toLoad = {}
     if role == "Patient":
         self.progress.show()
         self.loadPatient(uid)
     elif role == "Study":
         self.progress.show()
         self.loadStudy(uid)
     elif role == "Series":
         self.loadSeries(uid)
     elif role == "Image":
         pass
     self.progress.close()
     self.progress = None
Exemplo n.º 5
0
 def loadCheckedLoadables(self):
     """Invoke the load method on each plugin for the DICOMLoadable
 instances that are selected"""
     self.loadableTable.updateCheckstate()
     loadableCount = 0
     for plugin in self.loadablesByPlugin:
         for loadable in self.loadablesByPlugin[plugin]:
             if loadable.selected:
                 loadableCount += 1
     self.progress = qt.QProgressDialog(self.window)
     self.progress.minimumDuration = 0
     self.progress.show()
     self.progress.setValue(0)
     self.progress.setMaximum(loadableCount)
     step = 0
     for plugin in self.loadablesByPlugin:
         for loadable in self.loadablesByPlugin[plugin]:
             if self.progress.wasCanceled:
                 break
             slicer.app.processEvents()
             self.progress.setValue(step)
             slicer.app.processEvents()
             if loadable.selected:
                 self.progress.labelText = '\nLoading %s' % loadable.name
                 slicer.app.processEvents()
                 if not plugin.load(loadable):
                     qt.QMessageBox.warning(
                         slicer.util.mainWindow(), 'Load',
                         'Could not load: %s as a %s' %
                         (loadable.name, plugin.loadType))
                 step += 1
                 self.progress.setValue(step)
                 slicer.app.processEvents()
     self.progress.close()
     self.progress = None
     self.close()
    def onEntry(self, comingFrom, transitionType):
        super(DefineROIStep, self).onEntry(comingFrom, transitionType)

        # setup the interface
        lm = slicer.app.layoutManager()
        lm.setLayout(3)

        #create progress bar dialog
        self.progress = qt.QProgressDialog(slicer.util.mainWindow())
        self.progress.minimumDuration = 0
        self.progress.show()
        self.progress.setValue(0)
        self.progress.setMaximum(0)
        self.progress.setCancelButton(0)
        self.progress.setMinimumWidth(500)
        self.progress.setWindowModality(2)

        self.progress.setLabelText('Generating Volume Rendering...')
        slicer.app.processEvents(qt.QEventLoop.ExcludeUserInputEvents)
        self.progress.repaint()

        #read scalar volume node ID from previous step
        pNode = self.parameterNode()
        self.__baselineVolume = pNode.GetNodeReference('baselineVolume')

        #if ROI was created previously, get its transformation matrix and update current ROI
        roiTransformNode = pNode.GetNodeReference('roiTransform')
        if not roiTransformNode:
            roiTransformNode = slicer.vtkMRMLLinearTransformNode()
            slicer.mrmlScene.AddNode(roiTransformNode)
            pNode.SetNodeReferenceID('roiTransform', roiTransformNode.GetID())

        dm = vtk.vtkMatrix4x4()
        self.__baselineVolume.GetIJKToRASDirectionMatrix(dm)
        dm.SetElement(0, 3, 0)
        dm.SetElement(1, 3, 0)
        dm.SetElement(2, 3, 0)
        dm.SetElement(0, 0, abs(dm.GetElement(0, 0)))
        dm.SetElement(1, 1, abs(dm.GetElement(1, 1)))
        dm.SetElement(2, 2, abs(dm.GetElement(2, 2)))
        roiTransformNode.SetMatrixTransformToParent(dm)

        Helper.SetBgFgVolumes(self.__baselineVolume.GetID())
        Helper.SetLabelVolume(None)

        # use this transform node to align ROI with the axes of the baseline
        # volume
        self.__roiTransformNode = pNode.GetNodeReference('roiTransform')
        if not self.__roiTransformNode:
            Helper.Error(
                'Internal error! Error code CT-S2-NRT, please report!')

        # get the roiNode from parameters node, if it exists, and initialize the
        # GUI
        self.updateWidgetFromParameterNode(pNode)

        # start VR
        if self.__roi != None:
            self.__roi.SetDisplayVisibility(1)
            # Make sure the GUI is fully initilized because user will see it for a few seconds, while VR is being set up
            slicer.app.processEvents()
            self.InitVRDisplayNode()

        #close progress bar
        self.progress.setValue(2)
        self.progress.repaint()
        slicer.app.processEvents(qt.QEventLoop.ExcludeUserInputEvents)
        self.progress.close()
        self.progress = None

        #pNode.SetParameter('currentStep', self.stepid)

        qt.QTimer.singleShot(0, self.killButton)
Exemplo n.º 7
0
  def onEntry(self,comingFrom,transitionType):
    super(ApproachStep, self).onEntry(comingFrom, transitionType)

    # setup the interface
    lm = slicer.app.layoutManager()
    if lm == None:
        return
    #lm.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutSideBySideView)

    customLayout = ("<layout type=\"horizontal\" split=\"true\" >"
        " <item>"
        "  <view class=\"vtkMRMLSliceNode\" singletontag=\"Red\">"
        "    <property name=\"orientation\" action=\"default\">Axial</property>"
        "    <property name=\"viewlabel\" action=\"default\">R</property>"
        "    <property name=\"viewcolor\" action=\"default\">#F34A33</property>"
        "  </view>"
        " </item>"
        " <item>"
        "  <view class=\"vtkMRMLSliceNode\" singletontag=\"Yellow\">"
        "    <property name=\"orientation\" action=\"default\">Axial</property>"
        "    <property name=\"viewlabel\" action=\"default\">Y</property>"
        "    <property name=\"viewcolor\" action=\"default\">#EDD54C</property>"
        "  </view>"
        " </item>"
        " <item>"
        "  <view class=\"vtkMRMLSliceNode\" singletontag=\"Green\">"
        "    <property name=\"orientation\" action=\"default\">Axial</property>"
        "    <property name=\"viewlabel\" action=\"default\">G</property>"
        "    <property name=\"viewcolor\" action=\"default\">#6EB04B</property>"
        "  </view>"
        " </item>"
        "</layout>")

    customLayoutId=502

    #layoutManager = slicer.app.layoutManager()
    lm.layoutLogic().GetLayoutNode().AddLayoutDescription(customLayoutId, customLayout)
    lm.setLayout(customLayoutId)

    markup = slicer.modules.markups.logic()
    markup.AddNewFiducialNode('Vertebrae Labels')
    landmarks = slicer.mrmlScene.GetNodesByName('Vertebrae Labels')
    self.fidNode = landmarks.GetItemAsObject(0)

    slicer.app.applicationLogic().PropagateVolumeSelection(1)

    #create progress bar dialog
    self.progress = qt.QProgressDialog(slicer.util.mainWindow())
    self.progress.minimumDuration = 0
    self.progress.show()
    self.progress.setValue(0)
    self.progress.setMaximum(0)
    self.progress.setCancelButton(0)
    self.progress.setMinimumWidth(500)
    self.progress.setWindowModality(2)

    self.progress.setLabelText('Generating Volume Rendering...')
    slicer.app.processEvents(qt.QEventLoop.ExcludeUserInputEvents)
    self.progress.repaint()

    #read scalar volume node ID from previous step
    pNode = self.__parameterNode
    baselineVolume = Helper.getNodeByID(pNode.GetParameter('baselineVolumeID'))
    self.__baselineVolume = baselineVolume
    
    roiTransformID = pNode.GetParameter('roiTransformID')
    roiTransformNode = None

    if roiTransformID != '':
      roiTransformNode = Helper.getNodeByID(roiTransformID)
    else:
      roiTransformNode = slicer.vtkMRMLLinearTransformNode()
      slicer.mrmlScene.AddNode(roiTransformNode)
      pNode.SetParameter('roiTransformID', roiTransformNode.GetID())

    dm = vtk.vtkMatrix4x4()
    baselineVolume.GetIJKToRASDirectionMatrix(dm)
    dm.SetElement(0,3,0)
    dm.SetElement(1,3,0)
    dm.SetElement(2,3,0)
    dm.SetElement(0,0,abs(dm.GetElement(0,0)))
    dm.SetElement(1,1,abs(dm.GetElement(1,1)))
    dm.SetElement(2,2,abs(dm.GetElement(2,2)))
    roiTransformNode.SetAndObserveMatrixTransformToParent(dm)

    Helper.SetBgFgVolumes(pNode.GetParameter('baselineVolumeID'))
    Helper.SetLabelVolume(None)

    # use this transform node to align ROI with the axes of the baseline
    # volume
    roiTfmNodeID = pNode.GetParameter('roiTransformID')
    if roiTfmNodeID != '':
      self.__roiTransformNode = Helper.getNodeByID(roiTfmNodeID)
    else:
      Helper.Error('Internal error! Error code CT-S2-NRT, please report!')

    # get the roiNode from parameters node, if it exists, and initialize the
    # GUI
    self.updateWidgetFromParameterNode(pNode)

    if self.__roi != None:
      self.__roi.SetDisplayVisibility(0)
      self.InitVRDisplayNode()

    #close progress bar
    self.progress.setValue(2)
    self.progress.repaint()
    slicer.app.processEvents(qt.QEventLoop.ExcludeUserInputEvents)
    self.progress.close()
    self.progress = None

    #turn off rendering to save memory
    slicer.mrmlScene.GetNodesByName('GPURayCastVolumeRendering').GetItemAsObject(0).SetVisibility(0)
    #pNode.SetParameter('currentStep', self.stepid)

    # Enable Slice Intersections
    viewNodes = slicer.mrmlScene.GetNodesByClass('vtkMRMLSliceCompositeNode')
    viewNodes.UnRegister(slicer.mrmlScene)
    viewNodes.InitTraversal()
    viewNode = viewNodes.GetNextItemAsObject()
    while viewNode:
        viewNode.SetSliceIntersectionVisibility(1)
        viewNode = viewNodes.GetNextItemAsObject()

    self.redTransform = vtk.vtkTransform()
    viewSlice = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeRed')
    self.redTransform.SetMatrix(viewSlice.GetSliceToRAS())
    #print "Red Transform"
    #print self.redTransform
    self.yellowTransform = vtk.vtkTransform()
    viewSlice = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeYellow')
    self.yellowTransform.SetMatrix(viewSlice.GetSliceToRAS())
    #print "Yellow Transform"
    #print self.yellowTransform
    self.greenTransform = vtk.vtkTransform()
    viewSlice = slicer.mrmlScene.GetNodeByID('vtkMRMLSliceNodeGreen')
    self.greenTransform.SetMatrix(viewSlice.GetSliceToRAS())
    #print "Green Transform"
    #print self.greenTransform

    n =  self.__baselineVolume
    for color in ['Red', 'Yellow', 'Green']:
        a = slicer.app.layoutManager().sliceWidget(color).sliceLogic().GetSliceNode().GetFieldOfView()
        slicer.app.layoutManager().sliceWidget(color).sliceLogic().GetSliceCompositeNode().SetBackgroundVolumeID(n.GetID())
  
    lm.sliceWidget("Yellow").sliceController().fitSliceToBackground()
    lm.sliceWidget("Red").sliceController().fitSliceToBackground()
    lm.sliceWidget("Green").sliceController().fitSliceToBackground()

    qt.QTimer.singleShot(0, self.killButton)
    self.showThreshold()
    self.loadLandmarks()
Exemplo n.º 8
0
    def offerLoadables(self, uid, role):
        """Get all the loadable options at the currently selected level
    and present them in the loadable table"""
        fileLists = []
        if role == "Series":
            fileLists.append(slicer.dicomDatabase.filesForSeries(uid))
        if role == "Study":
            series = slicer.dicomDatabase.seriesForStudy(uid)
            for serie in series:
                fileLists.append(slicer.dicomDatabase.filesForSeries(serie))
        if role == "Patient":
            studies = slicer.dicomDatabase.studiesForPatient(uid)
            for study in studies:
                series = slicer.dicomDatabase.seriesForStudy(study)
                for serie in series:
                    fileList = slicer.dicomDatabase.filesForSeries(serie)
                    fileLists.append(fileList)

        allFileCount = missingFileCount = 0
        for fileList in fileLists:
            for filePath in fileList:
                allFileCount += 1
                if not os.path.exists(filePath):
                    missingFileCount += 1

        if missingFileCount > 0:
            qt.QMessageBox.warning(
                self.window, "DICOM",
                "Warning: %d of %d files listed in the database for this %s cannot be found on disk."
                % (missingFileCount, allFileCount, role))

        if missingFileCount == allFileCount:
            return

        self.progress = qt.QProgressDialog(self.window)
        self.progress.modal = True
        self.progress.minimumDuration = 0
        self.progress.show()
        self.progress.setValue(0)
        self.progress.setMaximum(len(slicer.modules.dicomPlugins))
        step = 0

        loadEnabled = False
        self.loadablesByPlugin = {}
        for pluginClass in slicer.modules.dicomPlugins:
            if not self.pluginInstances.has_key(pluginClass):
                self.pluginInstances[
                    pluginClass] = slicer.modules.dicomPlugins[pluginClass]()
            plugin = self.pluginInstances[pluginClass]
            if self.progress.wasCanceled:
                break
            self.progress.labelText = '\nChecking %s' % pluginClass
            slicer.app.processEvents()
            self.progress.setValue(step)
            slicer.app.processEvents()
            try:
                self.loadablesByPlugin[plugin] = plugin.examine(fileLists)
                loadEnabled = loadEnabled or self.loadablesByPlugin[
                    plugin] != []
            except Exception, e:
                import traceback
                traceback.print_exc()
                qt.QMessageBox.warning(
                    self.window, "DICOM",
                    "Warning: Plugin failed: %s\n\nSee python console for error message."
                    % pluginClass)
                print("DICOM Plugin failed: %s", str(e))

            step += 1
Exemplo n.º 9
0
    def setup(self):
        """Init the widget """
        # ScriptedLoadableModuleWidget.setup(self)

        settings = qt.QSettings()

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

        self.logic = PicasaSnapLogic()
        self.__addObservers__()

        ######## Credentials
        self.credentialsCollapsibleButton = ctk.ctkCollapsibleButton()
        self.credentialsCollapsibleButton.text = "Credentials"
        self.layout.addWidget(self.credentialsCollapsibleButton)
        self.credentialsLayout = qt.QFormLayout(
            self.credentialsCollapsibleButton)

        self.isUserLogged = False

        self.loginLineEdit = qt.QLineEdit()
        self.credentialsLayout.addRow("Login:   "******"Password:   "******"Remember my credentials")
        self.rememberCredentialsCheckBox.toolTip = "Check for an automatic login when the application starts"
        self.loginButton = qt.QPushButton("Login")
        self.loginButton.toolTip = "Login in Picassa service (Google credentials)"
        self.logoutButton = qt.QPushButton("Logout")
        self.logoutButton.toolTip = "Logout to connect with another user's credentials"
        # Add all the items, they will be shown/hidden in refreshCredentialsUI function
        self.credentialsLayout.addRow(self.rememberCredentialsCheckBox,
                                      self.loginButton)
        self.credentialsLayout.addRow(None, self.logoutButton)

        ######## Snapshots (main frame)
        self.mainCollapsibleButton = ctk.ctkCollapsibleButton()
        self.mainCollapsibleButton.text = "Snapshots"
        self.layout.addWidget(self.mainCollapsibleButton)
        self.mainLayout = qt.QVBoxLayout(self.mainCollapsibleButton)

        ############### Current snapshots
        self.currentSnapshotsFrame = qt.QFrame()
        self.currentSnapshotsLayout = qt.QVBoxLayout()
        self.currentSnapshotsFrame.setLayout(self.currentSnapshotsLayout)
        self.currentSnapshotsFrame.setFrameShape(qt.QFrame.StyledPanel)
        self.mainLayout.addWidget(self.currentSnapshotsFrame)

        self.snapshotsLabel = qt.QLabel("Snapshots to upload:")
        self.snapshotsLabel.setStyleSheet(
            "font-weight:bold; font-size:14px; margin-bottom:10px")
        self.currentSnapshotsLayout.addWidget(self.snapshotsLabel)

        # Subframe that contains the checkbox list
        self.currentSnapshotsInnerFrame = qt.QFrame()
        self.currentSnapshotsInnerLayout = qt.QVBoxLayout()
        self.currentSnapshotsInnerFrame.setLayout(
            self.currentSnapshotsInnerLayout)
        self.currentSnapshotsLayout.addWidget(self.currentSnapshotsInnerFrame)

        self.noItemsLabel = qt.QLabel(
            "(There are not any snapshots at the moment)")
        # Add the label by default. It will be hidden if there is any snapshot
        self.currentSnapshotsInnerLayout.addWidget(self.noItemsLabel)

        self.loadExistingSnapshotsFirstLoad()

        ############### Albums
        # Try to login before getting the albums
        self.login()

        msgBox = None
        if self.isUserLogged:
            # Show message box while loading the data
            msgBox = qt.QMessageBox(qt.QMessageBox.Information, 'Login',
                                    'Connecting with Picasa. Please wait...',
                                    qt.QMessageBox.Cancel)
            msgBox.show()

        try:
            self.albumNameFrame = qt.QFrame()
            self.albumNameLayout = qt.QHBoxLayout()
            self.albumNameFrame.setLayout(self.albumNameLayout)
            self.albumNameFrame.setFrameShape(qt.QFrame.StyledPanel)

            self.albumNameLabel = qt.QLabel("Album name:")
            self.albumNameLabel.setStyleSheet("font-weight:bold;")
            self.albumNamesComboBox = qt.QComboBox()
            self.loadAlbums()
            self.albumNameLayout.addWidget(self.albumNameLabel)
            self.albumNameLayout.addWidget(self.albumNamesComboBox)
            self.mainLayout.addWidget(self.albumNameFrame)

            ############### Tags
            self.tagsFrame = qt.QFrame()
            self.tagsLayout = qt.QGridLayout()
            self.tagsFrame.setLayout(self.tagsLayout)
            self.tagsFrame.setFrameShape(qt.QFrame.StyledPanel)

            self.tagsLabel = qt.QLabel(
                "Tags (select all that apply, you can filter o create new tags):"
            )
            self.tagsLabel.setStyleSheet(
                "font-weight: bold; margin-bottom: 10px; margin-top: 5px")
            self.tagsLayout.addWidget(self.tagsLabel, 0, 0, 1, 3)

            # Add input to filter tags and button to add a new one
            self.tagsFilterLineEdit = qt.QLineEdit()
            self.tagsFilterLineEdit.toolTip = "Type here to filter your tags. If you press the return key all the visible tags will be checked"
            #self.tagsFilterLineEdit.setStyleSheet(style)
            self.tagsLayout.addWidget(self.tagsFilterLineEdit, 1, 0, 1, 2)
            self.newTagButton = qt.QPushButton("New tag")
            #self.newTagButton.setStyleSheet("background-color: #5D74C6; color:white")
            self.newTagButton.setIconSize(qt.QSize(20, 20))
            self.newTagButton.setIcon(
                qt.QIcon(self.CIP_ICON_DIR + "/Plus - 48.png"))
            self.newTagButton.setFixedWidth(75)
            self.newTagButton.toolTip = "Add a new tag (the tag will not be created until you upload any picture with it)"
            self.tagsLayout.addWidget(self.newTagButton, 1, 2)

            self.loadTags()

            ############### Upload snapshots controls
            self.uploadSnapsButtonFrame = qt.QFrame()
            self.uploadSnapsLayout = qt.QHBoxLayout()
            self.uploadSnapsButtonFrame.setLayout(self.uploadSnapsLayout)
            #self(qt.QFrame.HLine)
            self.mainLayout.addWidget(self.uploadSnapsButtonFrame)

            self.uploadSnapshotsButton = qt.QPushButton()
            self.uploadSnapshotsButton.text = "Upload to Picasa!"
            self.uploadSnapshotsButton.toolTip = "Upload selected screenshots to Picassa"
            self.uploadSnapshotsButton.setStyleSheet(
                "background-color: #5D74C6; color: white; font-weight: bold; font-size:14px"
            )
            self.uploadSnapshotsButton.setIcon(
                qt.QIcon(self.CIP_ICON_DIR + "/Upload - 64.png"))
            self.uploadSnapshotsButton.setIconSize(qt.QSize(24, 24))
            self.uploadSnapshotsButton.setFixedSize(170, 35)
            self.uploadSnapsLayout.addWidget(self.uploadSnapshotsButton)

            ############### Progress bar
            self.progressBar = qt.QProgressDialog()
            self.progressBar.setMinimum(0)
            self.progressBar.setMinimumDuration(0)
            self.progressBar.setWindowModality(True)

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

            #     self.uploadProgressFrame = qt.QFrame()
            #     self.uploadProgressLayout = qt.QVBoxLayout()
            #     self.uploadProgressFrame.setLayout(self.uploadProgressLayout)
            #
            #     # Gif image
            #     self.imUploading = qt.QMovie("%s/loading.gif" % self.CIP_ICON_DIR, qt.QByteArray())
            #     # Label to contain the gif
            #     self.lblImLoading = qt.QLabel()
            #     # Fix the dimensions of the image (by fixing the dimensions of the label that contains it)
            #     self.lblImLoading.setFixedWidth(40)
            #     # Other image parameters
            #     self.imUploading.setCacheMode(qt.QMovie.CacheAll)
            #     self.imUploading.setSpeed(100)
            #     # Assign the label to the image (don't start it yet, it will be started when we are uploading)
            #     self.lblImLoading.setMovie(self.imUploading)
            #     #self.imUploading.start()
            #     self.uploadProgressLayout.addWidget(self.lblImLoading)
            #
            #     # Label that will show the progress
            #     self.lblUploading = qt.QLabel("Uploading %i/%i images...")
            #     self.uploadProgressLayout.addWidget(self.lblUploading)
            #
            # Cancel uploading button
            #     self.btnCancelUpload = qt.QPushButton("Cancel")
            #     self.btnCancelUpload.toolTip = "Cancel the process"
            #     self.btnCancelUpload.setFixedWidth(100)
            #     self.uploadProgressLayout.addWidget(self.btnCancelUpload)
            #     self.mainLayout.addWidget(self.uploadProgressFrame)
            #
            #     # Hide the progress frame
            #     self.uploadProgressFrame.hide()

            ######## Connections
            self.uploadSnapshotsButton.connect(
                'clicked (bool)', self.onUploadSnapshotsButtonClicked)
            self.loginButton.connect('clicked (bool)',
                                     self.onLoginButtonClicked)
            self.logoutButton.connect('clicked (bool)',
                                      self.onLogoutButtonClicked)
            self.loginLineEdit.returnPressed.connect(
                self.onLoginPasswordReturnKeyPressed)
            self.passwordLineEdit.returnPressed.connect(
                self.onLoginPasswordReturnKeyPressed)
            self.albumNamesComboBox.connect("currentIndexChanged (int)",
                                            self.onAlbumsCurrentIndexChanged)
            self.newTagButton.connect('clicked (bool)',
                                      self.onNewTagButtonClicked)
            self.tagsFilterLineEdit.connect('textEdited (QString)',
                                            self.onFilterTagsEdited)
            self.tagsFilterLineEdit.returnPressed.connect(
                self.onFilterTagsReturnKeyPressed)

            # Add vertical spacer
            self.layout.addStretch(1)
        finally:
            # Hide MesageBox if it was visible
            if msgBox:
                msgBox.close()
  def doStepProcessing(self):
    print 'Step processing'
    
    '''
    timer = qt.QTimer()
    timer.setInterval(1000)
    timer.setSingleShot(0)
    timer.connect('timeout()', self.updateProgress)
    '''

    # pop up progress dialog to prevent user from messing around
    self.progress = qt.QProgressDialog(slicer.util.mainWindow())
    self.progress.minimumDuration = 0
    self.progress.show()
    self.progress.setValue(0)
    self.progress.setMaximum(0)
    self.progress.setCancelButton(0)
    self.progress.setWindowModality(2)
 
    self.progress.setLabelText('Registering followup image to baseline')
    slicer.app.processEvents(qt.QEventLoop.ExcludeUserInputEvents)
    self.progress.repaint()
    
    # qt.QTimer.singleShot(0, self.updateProgress)

    '''
    Step logic:
      1) register followup to baseline
      2) resample followup to baseline ROI
      3) given baselineROI, followupROI and baseline segmentation, run each of
      the change detection metrics
    '''
    pNode = self.parameterNode()

    # (1) register followup to baseline
    # If the followup transform is initialized, do not register!
    if pNode.GetParameter('followupTransformID') == '':
      baselineVolumeID = pNode.GetParameter('baselineVolumeID')
      followupVolumeID = pNode.GetParameter('followupVolumeID')
      self.__followupTransform = slicer.vtkMRMLLinearTransformNode()
      slicer.mrmlScene.AddNode(self.__followupTransform)

      parameters = {}
      parameters["fixedVolume"] = baselineVolumeID
      parameters["movingVolume"] = followupVolumeID
      parameters["initializeTransformMode"] = "useMomentsAlign"
      parameters["useRigid"] = True
      parameters["useScaleVersor3D"] = False
      parameters["useScaleSkewVersor3D"] = False
      parameters["useAffine"] = True
      parameters["linearTransform"] = self.__followupTransform.GetID()
      # apparently this is needed even if not b-spline (see bug report 1542)
      parameters["forceMINumberOfThreads"] = -1

      # FIXME: make sure brainsfit is available first?
      cliNode = None
      cliNode = slicer.cli.run(slicer.modules.brainsfit, cliNode, parameters, wait_for_completion = True)
      
      status = cliNode.GetStatusString()

      '''
      while status != 'Completed':
      # while status == 'Running' or status == 'Scheduled' or status == 'Idle':
        slicer.app.processEvents(qt.QEventLoop.ExcludeUserInputEvents)
        self.progress.repaint()
        status = cliNode.GetStatusString()

      print 'Registration completed: status = ', status
      '''

      if status == 'Completed':
        Helper.Info('registration completed OK')
      else:
        Helper.ErrorPopup('Registration step failed. Unable to proceed. Please quit Slicer and report this issue including the output from the error log.')
        return

      pNode.SetParameter('followupTransformID', self.__followupTransform.GetID())

      print 'AnalyzeROIStep: registration completed!'
    else:
      print 'AnalyzeROIStep: registration not required!'

    self.progress.setLabelText('Estimating changes')
    slicer.app.processEvents(qt.QEventLoop.ExcludeUserInputEvents)
    self.progress.repaint()

    # self.__cliObserverTag = self.__cliNode.AddObserver('ModifiedEvent', self.processRegistrationCompletion)
    # self.__registrationStatus.setText('Wait ...')
    # self.__registrationButton.setEnabled(0)

    # (2) resample followup to baselineROI
    baselineVolumeROI = slicer.mrmlScene.GetNodeByID(pNode.GetParameter('croppedBaselineVolumeID'))
    followupVolume = slicer.mrmlScene.GetNodeByID(pNode.GetParameter('followupVolumeID'))
    followupVolumeROI = slicer.modules.volumes.logic().CloneVolume(slicer.mrmlScene, followupVolume, 'followupROI')

    parameters = {}
    parameters["inputVolume"] = pNode.GetParameter('followupVolumeID')
    parameters["referenceVolume"] = pNode.GetParameter('croppedBaselineVolumeID')
    parameters["outputVolume"] = followupVolumeROI.GetID()
    parameters["transformationFile"] = pNode.GetParameter('followupTransformID')
    parameters["interpolationType"] = "bs"

    cliNode = None
    cliNode = slicer.cli.run(slicer.modules.resamplescalarvectordwivolume, cliNode, parameters, 1)

    status = cliNode.GetStatusString()
    if status == 'Completed':
      Helper.Info('ResampleScalarVectorDWIVolume completed OK')
      pNode.SetParameter('croppedFollowupVolumeID', followupVolumeROI.GetID())
    else:
      Helper.Error('Failed to resample!')

    # (3) calculate each of the metrics
    # most of the parameters will be the same for all metrics
    parameters = {}
    parameters['baselineVolume'] = pNode.GetParameter('croppedBaselineVolumeID')
    parameters['followupVolume'] = pNode.GetParameter('croppedFollowupVolumeID')
    parameters['baselineSegmentationVolume'] = pNode.GetParameter('croppedBaselineVolumeSegmentationID')
    
    baselineVolume = slicer.mrmlScene.GetNodeByID(pNode.GetParameter('croppedBaselineVolumeID'))

    metricsList = pNode.GetParameter('metrics')

    if metricsList == '':
      Helper.Error('doStepProcessing(): metrics list is empty!')
      
    resultVolumesList = ''

    moduleManager = slicer.app.moduleManager()
    for m in string.split(metricsList,','):
      # TODO: processing should be separated from the workflow! need to move
      # this into a different place
      pluginName = m
      # pluginName = pluginName.lower()
        
      vl = slicer.modules.volumes.logic()
      outputVolume = vl.CreateLabelVolume(slicer.mrmlScene, baselineVolume, 'changesVolume_'+m)
      outputReport =  slicer.app.temporaryPath+os.sep+pluginName+'_report.txt'

      parameters["tmpDirectory"] = slicer.app.temporaryPath
      parameters['outputVolume'] = outputVolume.GetID()
      parameters['reportFileName'] = outputReport

      plugin = moduleManager.module(pluginName)
      if plugin != None:
        cliNode = None
        Helper.Info('About to run '+m+' metric!')
        cliNode = slicer.cli.run(plugin, cliNode, parameters, 1)

      '''
      TODO: error checking for CLI!
      '''
      labelsColorNode = slicer.modules.colors.logic().GetColorTableNodeID(10)
      outputVolume.GetDisplayNode().SetAndObserveColorNodeID(labelsColorNode)
        
      if resultVolumesList != '':
          resultVolumesList = resultVolumesList + ','
      resultVolumesList = resultVolumesList + outputVolume.GetID()

      outputVolume.SetDescription(Helper.readFileAsString(outputReport))

    pNode.SetParameter('resultVolumes', resultVolumesList)

    Helper.Info('Selected metrics: '+pNode.GetParameter('metrics'))
    Helper.Info('Metrics processing results:'+pNode.GetParameter('resultVolumes'))

    # close the progress window 
    '''
    timer.stop()
    '''
    self.progress.setValue(2)
    self.progress.repaint()
    slicer.app.processEvents(qt.QEventLoop.ExcludeUserInputEvents)
    self.progress.close()
    self.progress = None
Exemplo n.º 11
0
    def __init__(self, dataNode, labelNode, featureParameterDict,
                 featureClassParametersDict, keys):
        self.dataNode = dataNode
        self.labelNode = labelNode
        self.featureParameterDict = featureParameterDict  # ( keys=featureNames,values=dict(keys=parameterNames,values=parameterValues) )
        self.featureClassParametersDict = featureClassParametersDict  # ( keys=featureClassNames,values=dict(keys=parameterNames,values=parameterValues) )
        self.keys = keys

        # initialize Progress Bar
        self.progressBar = qt.QProgressDialog(slicer.util.mainWindow())
        self.progressBar.minimumDuration = 0
        self.progressBar.show()
        self.progressBar.setValue(0)
        self.progressBar.setMaximum(len(self.keys))
        self.progressBar.labelText = 'Calculating for %s: ' % self.dataNode.GetName(
        )

        # create Numpy Arrays
        self.nodeArrayVolume = self.createNumpyArray(self.dataNode)
        self.nodeArrayLabelMapROI = self.createNumpyArray(self.labelNode)

        # extract voxel coordinates (ijk) and values from self.dataNode within the ROI defined by self.labelNode
        self.targetVoxels, self.targetVoxelsCoordinates = self.tumorVoxelsAndCoordinates(
            self.nodeArrayLabelMapROI, self.nodeArrayVolume)

        # create a padded, rectangular matrix with shape equal to the shape of the tumor
        self.matrix, self.matrixCoordinates = self.paddedTumorMatrixAndCoordinates(
            self.targetVoxels, self.targetVoxelsCoordinates)

        # get Histogram data
        self.bins, self.grayLevels, self.numGrayLevels = self.getHistogramData(
            self.targetVoxels)

        ########
        # Manage feature classes for Heterogeneity feature calculations and consolidate into self.FeatureVector
        # TODO: create a parent class for all feature classes
        self.FeatureVector = collections.OrderedDict()

        # Node Information
        self.updateProgressBar(self.progressBar, self.dataNode.GetName(),
                               "Node Information", len(self.FeatureVector))
        self.nodeInformation = FeatureExtractionLib.NodeInformation(
            self.dataNode, self.labelNode, self.keys)
        self.FeatureVector.update(self.nodeInformation.EvaluateFeatures())

        # First Order Statistics
        self.updateProgressBar(self.progressBar, self.dataNode.GetName(),
                               "First Order Statistics",
                               len(self.FeatureVector))
        self.firstOrderStatistics = FeatureExtractionLib.FirstOrderStatistics(
            self.targetVoxels, self.bins, self.numGrayLevels, self.keys)
        self.FeatureVector.update(self.firstOrderStatistics.EvaluateFeatures())

        # Shape/Size and Morphological Features)
        self.updateProgressBar(self.progressBar, self.dataNode.GetName(),
                               "Morphology Statistics",
                               len(self.FeatureVector))
        # extend padding by one row/column for all 6 directions
        maxDimsSA = tuple(map(operator.add, self.matrix.shape, ([2, 2, 2])))
        matrixSA, matrixSACoordinates = self.padMatrix(self.matrix,
                                                       self.matrixCoordinates,
                                                       maxDimsSA,
                                                       self.targetVoxels)
        self.morphologyStatistics = FeatureExtractionLib.MorphologyStatistics(
            self.labelNode, matrixSA, matrixSACoordinates, self.targetVoxels,
            self.keys)
        self.FeatureVector.update(self.morphologyStatistics.EvaluateFeatures())

        # Texture Features(GLCM)
        self.updateProgressBar(self.progressBar, self.dataNode.GetName(),
                               "GLCM Texture Features",
                               len(self.FeatureVector))
        self.textureFeaturesGLCM = FeatureExtractionLib.TextureGLCM(
            self.grayLevels, self.numGrayLevels, self.matrix,
            self.matrixCoordinates, self.targetVoxels, self.keys)
        self.FeatureVector.update(self.textureFeaturesGLCM.EvaluateFeatures())

        # Texture Features(GLRL)
        self.updateProgressBar(self.progressBar, self.dataNode.GetName(),
                               "GLRL Texture Features",
                               len(self.FeatureVector))
        self.textureFeaturesGLRL = FeatureExtractionLib.TextureGLRL(
            self.grayLevels, self.numGrayLevels, self.matrix,
            self.matrixCoordinates, self.targetVoxels, self.keys)
        self.FeatureVector.update(self.textureFeaturesGLRL.EvaluateFeatures())

        # Geometrical Measures
        # TODO: progress bar does not update to Geometrical Measures while calculating (create separate thread?)
        self.updateProgressBar(self.progressBar, self.dataNode.GetName(),
                               "Geometrical Measures", len(self.FeatureVector))
        self.geometricalMeasures = FeatureExtractionLib.GeometricalMeasures(
            self.labelNode, self.matrix, self.matrixCoordinates,
            self.targetVoxels, self.keys)
        self.FeatureVector.update(self.geometricalMeasures.EvaluateFeatures())

        # Renyi Dimensions
        self.updateProgressBar(self.progressBar, self.dataNode.GetName(),
                               "Renyi Dimensions", len(self.FeatureVector))
        # extend padding to dimension lengths equal to next power of 2
        maxDims = tuple(
            [int(pow(2, math.ceil(numpy.log2(numpy.max(self.matrix.shape)))))
             ] * 3)
        matrixPadded, matrixPaddedCoordinates = self.padMatrix(
            self.matrix, self.matrixCoordinates, maxDims, self.targetVoxels)
        self.renyiDimensions = FeatureExtractionLib.RenyiDimensions(
            matrixPadded, matrixPaddedCoordinates, self.keys)
        self.FeatureVector.update(self.renyiDimensions.EvaluateFeatures())

        # close progress bar
        self.updateProgressBar(self.progressBar, self.dataNode.GetName(),
                               "Populating Summary Table",
                               len(self.FeatureVector))
        self.progressBar.close()
        self.progressBar = None

        # filter for user-queried features only
        self.FeatureVector = collections.OrderedDict(
            (k, self.FeatureVector[k]) for k in self.keys)