Example #1
0
  def test_SEGExporterSelfTest1(self):
    """ Test DICOM import, segmentation, export
    """
    self.messageDelay = 50

    import os
    self.delayDisplay("Starting the DICOM SEG Export test")

    #
    # first, get the data - a zip file of dicom data
    #
    filePath = self.logic.downloadSampleData()
    self.delayDisplay('Finished with download\n')

    self.delayDisplay("Unzipping")
    dicomFilesDirectory = self.logic.unzipSampleData(filePath)

    try:
      self.delayDisplay("Switching to temp database directory")
      tempDatabaseDirectory = slicer.app.temporaryPath + '/tempDICOMDatabase'
      import shutil
      try:
        shutil.rmtree(tempDatabaseDirectory)
      except OSError:
        pass
      qt.QDir().mkpath(tempDatabaseDirectory)
      if slicer.dicomDatabase:
        originalDatabaseDirectory = os.path.split(slicer.dicomDatabase.databaseFilename)[0]
      else:
        originalDatabaseDirectory = None
        settings = qt.QSettings()
        settings.setValue('DatabaseDirectory', tempDatabaseDirectory)
      dicomWidget = slicer.modules.dicom.widgetRepresentation().self()
      dicomWidget.onDatabaseDirectoryChanged(tempDatabaseDirectory)

      self.delayDisplay('Importing DICOM')
      mainWindow = slicer.util.mainWindow()
      mainWindow.moduleSelector().selectModule('DICOM')

      self.logic.importIntoDICOMDatabase(dicomFilesDirectory)

      dicomWidget.detailsPopup.open()

      # load the data by series UID
      mrHeadSeriesUID = "2.16.840.1.113662.4.4168496325.1025306170.548651188813145058"
      dicomWidget.detailsPopup.offerLoadables(mrHeadSeriesUID, 'Series')
      dicomWidget.detailsPopup.examineForLoading()
      self.delayDisplay('Loading Selection')
      dicomWidget.detailsPopup.loadCheckedLoadables()

      #
      # create a label map and set it for editing
      #
      masterNode = slicer.util.getNode('2: SAG*')
      volumesLogic = slicer.modules.volumes.logic()
      mergeNode = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, masterNode, masterNode.GetName() + '-label' )
      mergeNode.GetDisplayNode().SetAndObserveColorNodeID('vtkMRMLColorTableNodeFileGenericAnatomyColors.txt')
      selectionNode = slicer.app.applicationLogic().GetSelectionNode()
      selectionNode.SetReferenceActiveVolumeID( masterNode.GetID() )
      selectionNode.SetReferenceActiveLabelVolumeID( mergeNode.GetID() )
      slicer.app.applicationLogic().PropagateVolumeSelection(0)

      #
      # go to the editor and do some drawing
      #
      slicer.util.selectModule('Editor')

      import EditorLib
      from EditorLib.EditUtil import EditUtil
      parameterNode = EditUtil.getParameterNode()
      parameterNode.SetParameter("LabelEffect,paintThreshold", "1")
      parameterNode.SetParameter("LabelEffect,paintThresholdMin", "70.0")
      parameterNode.SetParameter("LabelEffect,paintThresholdMax", "279.75")
      parameterNode.SetParameter("PaintEffect,radius", "40")
      parameterNode.SetParameter("PaintEffect,sphere", "1")

      self.delayDisplay("Paint some things")
      parameterNode = EditUtil.getParameterNode()
      lm = slicer.app.layoutManager()
      paintEffect = EditorLib.PaintEffectOptions()
      paintEffect.setMRMLDefaults()
      paintEffect.__del__()
      sliceWidget = lm.sliceWidget('Red')
      paintTool = EditorLib.PaintEffectTool(sliceWidget)
      EditUtil.setLabel(1)
      paintTool.paintAddPoint(100,100)
      paintTool.paintApply()
      EditUtil.setLabel(2)
      paintTool.paintAddPoint(200,200)
      paintTool.paintApply()
      paintTool.cleanup()
      paintTool = None

      # save these to compare with the one we read back
      originalSegmentationArray = slicer.util.array(mergeNode.GetID())
      originalSegmentationNodeCopy = slicer.vtkMRMLLabelMapVolumeNode()
      originalSegmentationNodeCopy.CopyOrientation(mergeNode)

      # export the volumes into a SEG
      tempSEGDirectory = slicer.app.temporaryPath + '/tempDICOMSEG'
      qt.QDir().mkpath(tempSEGDirectory)
      segFilePath = os.path.join(tempSEGDirectory, "test.SEG.dcm")


      self.delayDisplay('spliting...', 200)
      EditUtil.splitPerStructureVolumes(masterNode, mergeNode)

      self.delayDisplay('exporting...', 200)
      EditUtil.exportAsDICOMSEG(masterNode)

      # close scene re-load the input data and SEG
      slicer.mrmlScene.Clear(0)
      indexer = ctk.ctkDICOMIndexer()
      indexer.addDirectory(slicer.dicomDatabase, tempSEGDirectory, None)
      indexer.waitForImportFinished()

      mrHeadStudyUID = "2.16.840.1.113662.4.4168496325.1025305873.7118351817185979330"
      dicomWidget.detailsPopup.offerLoadables(mrHeadStudyUID, 'Study')
      dicomWidget.detailsPopup.examineForLoading()
      self.delayDisplay('Loading Selection')
      dicomWidget.detailsPopup.loadCheckedLoadables()

      # confirm that segmentations are correctly reloaded
      headLabelName = '2: SAG/RF-FAST/VOL/FLIP 30-label'
      reloadedLabel = slicer.util.getNode(headLabelName)
      reloadedSegmentationArray = slicer.util.array(reloadedLabel.GetID())

      import numpy
      self.assertTrue(numpy.alltrue(originalSegmentationArray == reloadedSegmentationArray))
      geometryWarnings = volumesLogic.CompareVolumeGeometry(mergeNode, reloadedLabel)
      print(geometryWarnings)
      self.assertTrue(geometryWarnings == '')

      # re-export

      # close scene re-load the input data and SEG

      # confirm that segmentations are available again as per-structure volumes


      self.delayDisplay('Test passed!')
    except Exception, e:
      import traceback
      traceback.print_exc()
      self.delayDisplay('Test caused exception!\n' + str(e))
Example #2
0
    def test_SEGExporterSelfTest1(self):
        """ Test DICOM import, segmentation, export
    """
        self.messageDelay = 50

        import os
        self.delayDisplay("Starting the DICOM SEG Export test")

        #
        # first, get the data - a zip file of dicom data
        #
        import urllib
        downloads = ((
            'http://slicer.kitware.com/midas3/download/item/220834/PieperMRHead.zip',
            'PieperMRHead.zip'), )
        self.delayDisplay("Downloading")
        for url, name in downloads:
            filePath = slicer.app.temporaryPath + '/' + name
            if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
                self.delayDisplay('Requesting download %s from %s...\n' %
                                  (name, url))
                urllib.urlretrieve(url, filePath)
        self.delayDisplay('Finished with download\n')

        self.delayDisplay("Unzipping")
        dicomFilesDirectory = slicer.app.temporaryPath + '/dicomFiles'
        qt.QDir().mkpath(dicomFilesDirectory)
        slicer.app.applicationLogic().Unzip(filePath, dicomFilesDirectory)

        try:
            self.delayDisplay("Switching to temp database directory")
            tempDatabaseDirectory = slicer.app.temporaryPath + '/tempDICOMDatabase'
            import shutil
            shutil.rmtree(tempDatabaseDirectory)
            qt.QDir().mkpath(tempDatabaseDirectory)
            if slicer.dicomDatabase:
                originalDatabaseDirectory = os.path.split(
                    slicer.dicomDatabase.databaseFilename)[0]
            else:
                originalDatabaseDirectory = None
                settings = qt.QSettings()
                settings.setValue('DatabaseDirectory', tempDatabaseDirectory)
            dicomWidget = slicer.modules.dicom.widgetRepresentation().self()
            dicomWidget.onDatabaseDirectoryChanged(tempDatabaseDirectory)

            self.delayDisplay('Importing DICOM')
            mainWindow = slicer.util.mainWindow()
            mainWindow.moduleSelector().selectModule('DICOM')

            indexer = ctk.ctkDICOMIndexer()
            indexer.addDirectory(slicer.dicomDatabase, dicomFilesDirectory,
                                 None)
            indexer.waitForImportFinished()

            dicomWidget.detailsPopup.open()

            # load the data by series UID
            mrHeadSeriesUID = "2.16.840.1.113662.4.4168496325.1025306170.548651188813145058"
            dicomWidget.detailsPopup.offerLoadables(mrHeadSeriesUID, 'Series')
            dicomWidget.detailsPopup.examineForLoading()
            self.delayDisplay('Loading Selection')
            dicomWidget.detailsPopup.loadCheckedLoadables()

            #
            # create a label map and set it for editing
            #
            masterNode = slicer.util.getNode('2: SAG*')
            volumesLogic = slicer.modules.volumes.logic()
            mergeNode = volumesLogic.CreateAndAddLabelVolume(
                slicer.mrmlScene, masterNode,
                masterNode.GetName() + '-label')
            mergeNode.GetDisplayNode().SetAndObserveColorNodeID(
                'vtkMRMLColorTableNodeFileGenericAnatomyColors.txt')
            selectionNode = slicer.app.applicationLogic().GetSelectionNode()
            selectionNode.SetReferenceActiveVolumeID(masterNode.GetID())
            selectionNode.SetReferenceActiveLabelVolumeID(mergeNode.GetID())
            slicer.app.applicationLogic().PropagateVolumeSelection(0)

            #
            # go to the editor and do some drawing
            #
            slicer.util.selectModule('Editor')

            import EditorLib
            from EditorLib.EditUtil import EditUtil
            parameterNode = EditUtil.getParameterNode()
            parameterNode.SetParameter("LabelEffect,paintThreshold", "1")
            parameterNode.SetParameter("LabelEffect,paintThresholdMin", "70.0")
            parameterNode.SetParameter("LabelEffect,paintThresholdMax",
                                       "279.75")
            parameterNode.SetParameter("PaintEffect,radius", "40")
            parameterNode.SetParameter("PaintEffect,sphere", "1")

            self.delayDisplay("Paint some things")
            parameterNode = EditUtil.getParameterNode()
            lm = slicer.app.layoutManager()
            paintEffect = EditorLib.PaintEffectOptions()
            paintEffect.setMRMLDefaults()
            paintEffect.__del__()
            sliceWidget = lm.sliceWidget('Red')
            paintTool = EditorLib.PaintEffectTool(sliceWidget)
            EditUtil.setLabel(1)
            paintTool.paintAddPoint(100, 100)
            paintTool.paintApply()
            EditUtil.setLabel(2)
            paintTool.paintAddPoint(200, 200)
            paintTool.paintApply()
            paintTool.cleanup()
            paintTool = None

            # save these to compare with the one we read back
            originalSegmentationArray = slicer.util.array(mergeNode.GetID())
            originalSegmentationNodeCopy = slicer.vtkMRMLLabelMapVolumeNode()
            originalSegmentationNodeCopy.CopyOrientation(mergeNode)

            # export the volumes into a SEG
            tempSEGDirectory = slicer.app.temporaryPath + '/tempDICOMSEG'
            qt.QDir().mkpath(tempSEGDirectory)
            segFilePath = os.path.join(tempSEGDirectory, "test.SEG.dcm")

            self.delayDisplay('spliting...', 200)
            EditUtil.splitPerStructureVolumes(masterNode, mergeNode)

            self.delayDisplay('exporting...', 200)
            EditUtil.exportAsDICOMSEG(masterNode)

            # close scene re-load the input data and SEG
            slicer.mrmlScene.Clear(0)
            indexer.addDirectory(slicer.dicomDatabase, tempSEGDirectory, None)
            indexer.waitForImportFinished()

            mrHeadStudyUID = "2.16.840.1.113662.4.4168496325.1025305873.7118351817185979330"
            dicomWidget.detailsPopup.offerLoadables(mrHeadStudyUID, 'Study')
            dicomWidget.detailsPopup.examineForLoading()
            self.delayDisplay('Loading Selection')
            dicomWidget.detailsPopup.loadCheckedLoadables()

            # confirm that segmentations are correctly reloaded
            headLabelName = '2: SAG/RF-FAST/VOL/FLIP 30-label'
            reloadedLabel = slicer.util.getNode(headLabelName)
            reloadedSegmentationArray = slicer.util.array(
                reloadedLabel.GetID())

            import numpy
            self.assertTrue(
                numpy.alltrue(
                    originalSegmentationArray == reloadedSegmentationArray))
            geometryWarnings = volumesLogic.CompareVolumeGeometry(
                mergeNode, reloadedLabel)
            print(geometryWarnings)
            self.assertTrue(geometryWarnings == '')

            # re-export

            # close scene re-load the input data and SEG

            # confirm that segmentations are available again as per-structure volumes

            self.delayDisplay('Test passed!')
        except Exception, e:
            import traceback
            traceback.print_exc()
            self.delayDisplay('Test caused exception!\n' + str(e))