Example #1
0
  def section_LoadDicomDataWitchBatchProcessing(self):
    try:
      # Open Data module so that a subject hierarchy scene model is active
      # (which caused problems with batch processing)
      slicer.util.selectModule('Data')

      # Open test database and empty it
      with DICOMUtils.TemporaryDICOMDatabase(self.dicomDatabaseDir) as db:
        self.assertTrue( db.isOpen )
        self.assertEqual( slicer.dicomDatabase, db)

        slicer.mrmlScene.StartState(slicer.vtkMRMLScene.BatchProcessState)

        # Download, unzip, import, and load data. Verify loaded nodes.
        loadedNodes = {'vtkMRMLScalarVolumeNode':1}
        with DICOMUtils.LoadDICOMFilesToDatabase( \
            self.dicomZipFileUrl, self.dicomZipFilePath, \
            self.dicomDataDir, self.expectedNumOfFilesInDicomDataDir, \
            {}, loadedNodes, checksum=self.dicomZipChecksum) as success:
          self.assertTrue(success)

        slicer.mrmlScene.EndState(slicer.vtkMRMLScene.BatchProcessState)

      self.assertEqual( len( slicer.util.getNodes('vtkMRMLSubjectHierarchyNode*') ), 1 )

      shNode = slicer.mrmlScene.GetSubjectHierarchyNode()
      self.assertIsNotNone( shNode )
      loadedDicomVolumeItemID = shNode.GetItemByName(self.loadedDicomVolumeName)
      loadedDicomStudyItemID = shNode.GetItemByName(self.loadedDicomStudyName)
      self.assertEqual( shNode.GetItemParent(loadedDicomVolumeItemID), loadedDicomStudyItemID )

    except Exception as e:
      import traceback
      traceback.print_exc()
      self.delayDisplay('Test caused exception!\n' + str(e),self.delayMs*2)
  def test_import_labelmap(self):

    self.delayDisplay('Starting %s' % inspect.stack()[0][3])

    qrWidget = slicer.modules.QuantitativeReportingWidget

    with DICOMUtils.TemporaryDICOMDatabase(self.dicomDatabaseDir) as db:
      self.assertTrue(db.isOpen)
      self.assertEqual(slicer.dicomDatabase, db)

      self.loadTestVolume()

      sampleData = TestDataLogic.downloadAndUnzipSampleData(self.collection)
      segmentationsDir = sampleData['seg_nrrd']

      labels = []
      for f in [os.path.join(segmentationsDir, f) for f in os.listdir(segmentationsDir) if f.endswith(".nrrd")]:
        label = slicer.util.loadLabelVolume(f)
        if label:
          labels.append(label)
          
      o = labels[0].GetOrigin()
      qrWidget.segmentEditorWidget.masterVolumeNode.SetOrigin(o[0], o[1], o[2]) # mimic origin as produced by Slicer 4.10

      labelImportLogic = qrWidget.labelMapImportWidget.logic

      for label in labels:
        labelImportLogic.labelmap = label
        labelImportLogic.run(resampleIfNecessary=True)

      segmentation = qrWidget.segmentEditorWidget.segmentationNode.GetSegmentation()
      self.assertEquals(segmentation.GetNumberOfSegments(), len(labels))

      self.delayDisplay('Test passed!')
  def section_LoadDicomData(self):
    try:
      # Download and unzip test CT DICOM data
      import urllib
      downloads = (
          ('http://slicer.kitware.com/midas3/download/item/137843/TestDicomCT.zip', self.dicomZipFilePath),
          )

      downloaded = 0
      for url,filePath in downloads:
        if not os.path.exists(filePath) or os.stat(filePath).st_size == 0:
          if downloaded == 0:
            self.delayDisplay('Downloading input data to folder\n' + self.dicomZipFilePath + '.\n\n  It may take a few minutes...',self.delayMs)
          print('Requesting download from %s...' % (url))
          urllib.urlretrieve(url, filePath)
          downloaded += 1
        else:
          self.delayDisplay('Input data has been found in folder ' + self.dicomZipFilePath, self.delayMs)
      if downloaded > 0:
        self.delayDisplay('Downloading input data finished',self.delayMs)

      numOfFilesInDicomDataDir = len([name for name in os.listdir(self.dicomDataDir) if os.path.isfile(self.dicomDataDir + '/' + name)])
      if (numOfFilesInDicomDataDir != self.expectedNumOfFilesInDicomDataDir):
        slicer.app.applicationLogic().Unzip(self.dicomZipFilePath, self.dicomDataDir)
        self.delayDisplay("Unzipping done",self.delayMs)

      numOfFilesInDicomDataDirTest = len([name for name in os.listdir(self.dicomDataDir) if os.path.isfile(self.dicomDataDir + '/' + name)])
      self.assertEqual( numOfFilesInDicomDataDirTest, self.expectedNumOfFilesInDicomDataDir )

      # Open test database and empty it
      with DICOMUtils.TemporaryDICOMDatabase(self.dicomDatabaseDir, True) as db:
        self.assertTrue( db.isOpen )
        self.assertEqual( slicer.dicomDatabase, db)

        # Import test data in database
        indexer = ctk.ctkDICOMIndexer()
        self.assertIsNotNone( indexer )

        indexer.addDirectory( slicer.dicomDatabase, self.dicomDataDir )

        self.assertEqual( len(slicer.dicomDatabase.patients()), 1 )
        self.assertIsNotNone( slicer.dicomDatabase.patients()[0] )

        # Load test data
        numOfScalarVolumeNodesBeforeLoad = len( slicer.util.getNodes('vtkMRMLScalarVolumeNode*') )
        numOfSubjectHierarchyNodesBeforeLoad = len( slicer.util.getNodes('vtkMRMLSubjectHierarchyNode*') )

        patient = slicer.dicomDatabase.patients()[0]
        DICOMUtils.loadPatientByUID(patient)

        self.assertEqual( len( slicer.util.getNodes('vtkMRMLScalarVolumeNode*') ),  numOfScalarVolumeNodesBeforeLoad + 1 )
        self.assertEqual( len( slicer.util.getNodes('vtkMRMLSubjectHierarchyNode*') ), numOfSubjectHierarchyNodesBeforeLoad + 3 )
      
    except Exception, e:
      import traceback
      traceback.print_exc()
      self.delayDisplay('Test caused exception!\n' + str(e),self.delayMs*2)
  def test_read_report(self):

    self.delayDisplay('Starting %s' % inspect.stack()[0][3])

    def loadTestData():
      for imageType, fileData in six.iteritems(self.data):
        if not len(slicer.dicomDatabase.filesForSeries(fileData['uid'])):
          sampleData = TestDataLogic.downloadAndUnzipSampleData(self.collection)
          TestDataLogic.importIntoDICOMDatabase(sampleData[imageType])

    with DICOMUtils.TemporaryDICOMDatabase(self.dicomDatabaseDir) as db:
      self.assertTrue(db.isOpen)
      self.assertEqual(slicer.dicomDatabase, db)

      loadTestData()

      # dicomWidget = slicer.modules.dicom.widgetRepresentation().self()
      # checkbox = dicomWidget.detailsPopup.pluginSelector.checkBoxByPlugin["DICOMLongitudinalTID1500Plugin"]
      # crntState = checkbox.checked
      # checkbox.checked = False

      qrWidget = slicer.modules.QuantitativeReportingWidget

      settings = 'DICOM/automaticallyLoadReferences'
      cacheAutoLoadReferences = qt.QSettings().value('DICOM/automaticallyLoadReferences')
      qt.QSettings().setValue(settings, qt.QMessageBox.Yes)

      qrWidget.loadSeries(self.data['sr']['uid']) # note: this no longer loads referenced data recursively; this functionality only works whithin the DICOMbrowser GUI
      qrWidget.loadSeries(self.data['volume']['uid']) # load volume manually for test

      qt.QSettings().setValue(settings, cacheAutoLoadReferences)

      # checkbox.checked = crntState

      tableNodes = slicer.util.getNodesByClass("vtkMRMLTableNode")

      self.assertTrue(len(tableNodes),
                      "Loading SR into mrmlScene failed. No vtkMRMLTableNodes were found within the scene.")

      self.delayDisplay('Selecting measurements report')

      qrWidget.measurementReportSelector.setCurrentNode(tableNodes[0])

      self.delayDisplay('Checking number of segments')
      self.assertTrue(len(qrWidget.segmentEditorWidget.segments) == 3,
                      "Number of segments does not match expected count of 3")

      self.delayDisplay('Checking referenced master volume', 2000)
      self.assertIsNotNone(qrWidget.segmentEditorWidget.masterVolumeNode,
                           "Master volume for the selected measurement report is None!")

      self.delayDisplay('Test passed!')
Example #5
0
  def getImageFromDICOMInformation(self, dcmInfo):
    loadedNodeIDs = []
    with DICOMUtils.TemporaryDICOMDatabase() as database:
      DICOMUtils.importDicom(os.path.join(self.path, 'DICOM'), database)
      series = SlicerDICOMDatabase().geSeriestMatchingDescriptionAndDateTime(dcmInfo['SeriesDescription'], dcmInfo['AcquisitionDateTime'])
      loadedNodeIDs.extend(DICOMUtils.loadSeriesByUID([series]))

    for nodeID in loadedNodeIDs[::-1]:
      volumeNode = slicer.util.getNode(nodeID)
      if re.search('.*' + dcmInfo['SeriesDescription'] + '.*', volumeNode.GetName()):
        return volumeNode

    raise RuntimeError('Unable to find image in DICOM: ' + self.path)
Example #6
0
  def test_BatchStructureSetConversion_FullTest1(self):
    # Create logic
    self.logic = BatchStructureSetConversionLogic()

    # Check for modules
    self.assertTrue(slicer.modules.dicomrtimportexport)
    self.assertTrue(slicer.modules.segmentations)

    self.TestSection_0_SetupPathsAndNames()
    # Open test database and empty it
    with DICOMUtils.TemporaryDICOMDatabase(self.dicomDatabaseDir) as self.db:
      self.TestSection_1_LoadDicomData()
      self.TestSection_2_ConvertStructureSetToLabelmap()
      self.TestSection_3_SaveLabelmaps()
    logging.info('Test finished')
Example #7
0
    def test_PETPhantomAnalysis(self):
        """ test standard processing
    """
        try:
            self.assertIsNotNone(slicer.modules.petphantomanalysis)
            with DICOMUtils.TemporaryDICOMDatabase(
                    self.tempDicomDatabaseDir) as db:
                self.assertTrue(db.isOpen)
                self.assertEqual(slicer.dicomDatabase, db)

                self.delayDisplay(
                    'Loading PET DICOM dataset (including download if necessary)'
                )
                petNode = self.loadTestData()

                self.delayDisplay('Running segmentation')
                m = slicer.util.mainWindow()
                m.moduleSelector().selectModule('PETPhantomAnalysis')
                qrWidget = slicer.modules.PETPhantomAnalysisWidget
                qrWidget.inputSelector.setCurrentNode(petNode)
                segmentationNode = qrWidget.segmentationSelector.addNode()
                qrWidget.inputVolumeSelected()
                qrWidget.segmentButton.click()

                # assert measurements are correct
                self.assertTrue(
                    abs(float(qrWidget.meanValueLineEdit.text) -
                        0.982502) < 0.01)
                self.assertTrue(
                    abs(float(qrWidget.stdValueLineEdit.text) -
                        0.031612) < 0.01)
                self.assertTrue(
                    abs(
                        float(qrWidget.maxRelDiffValueLineEdit.text) +
                        0.0203663) < 0.01)

                ## clean up data from DICOM database
                patientUID = DICOMUtils.getDatabasePatientUIDByPatientName(
                    self.patienName)
                db.removePatient(patientUID)

                self.delayDisplay('Test passed!')

        except Exception as e:
            import traceback
            traceback.print_exc()
            self.delayDisplay('Test caused exception!\n' + str(e),
                              self.delayMs * 2)
  def test_create_report(self):

    self.delayDisplay('Starting %s' % inspect.stack()[0][3])

    qrWidget = slicer.modules.QuantitativeReportingWidget

    with DICOMUtils.TemporaryDICOMDatabase(self.dicomDatabaseDir) as db:
      self.assertTrue(db.isOpen)
      self.assertEqual(slicer.dicomDatabase, db)

      self.loadTestVolume()
      success, err = qrWidget.saveReport()
      self.assertFalse(success)

      self.delayDisplay('Add segments')

      qrWidget = slicer.modules.QuantitativeReportingWidget
      segmentation = qrWidget.segmentEditorWidget.segmentationNode.GetSegmentation()

      segmentGeometries = {
        'Tumor': [[2, 30, 30, -127.7], [2, 40, 40, -127.7], [2, 50, 50, -127.7], [2, 40, 80, -127.7]],
        'Air': [[2, 60, 100, -127.7], [2, 80, 30, -127.7]]
      }

      for segmentName, segmentGeometry in six.iteritems(segmentGeometries):
        appender = vtk.vtkAppendPolyData()

        for sphere in segmentGeometry:
          sphereSource = vtk.vtkSphereSource()
          sphereSource.SetRadius(sphere[0])
          sphereSource.SetCenter(sphere[1], sphere[2], sphere[3])
          appender.AddInputConnection(sphereSource.GetOutputPort())

        segment = vtkSegmentationCore.vtkSegment()
        segment.SetName(segmentation.GenerateUniqueSegmentID(segmentName))

        appender.Update()
        representationName = vtkSegmentationCore.vtkSegmentationConverter.GetSegmentationClosedSurfaceRepresentationName()
        segment.AddRepresentation(representationName, appender.GetOutput())
        segmentation.AddSegment(segment)

      self.delayDisplay('Save report')

      success, err = qrWidget.saveReport()
      self.assertTrue(success)

      self.delayDisplay('Test passed!')
  def test_import_segmentation(self):

    self.delayDisplay('Starting %s' % inspect.stack()[0][3])

    uid = self.data["seg_dcm"]["uid"]

    with DICOMUtils.TemporaryDICOMDatabase(self.dicomDatabaseDir) as db:
      self.assertTrue(db.isOpen)
      self.assertEqual(slicer.dicomDatabase, db)

      self.loadTestVolume()

      if not len(slicer.dicomDatabase.filesForSeries(uid)):
        sampleData = TestDataLogic.downloadAndUnzipSampleData(self.collection)
        TestDataLogic.importIntoDICOMDatabase(sampleData["seg_dcm"])

      qrWidget = slicer.modules.QuantitativeReportingWidget

      settings = 'DICOM/automaticallyLoadReferences'
      cacheAutoLoadReferences = qt.QSettings().value('DICOM/automaticallyLoadReferences')
      qt.QSettings().setValue(settings, qt.QMessageBox.Yes)

      qrWidget.loadSeries(uid)

      qt.QSettings().setValue(settings, cacheAutoLoadReferences)

      segmentationNode = slicer.util.getNodesByClass('vtkMRMLSegmentationNode')[-1]

      qrWidget.importSegmentationCollapsibleButton.collapsed = False

      importWidget = qrWidget.segmentImportWidget
      importWidget.otherSegmentationNodeSelector.setCurrentNode(segmentationNode)

      segmentIDs = qrWidget.segmentEditorWidget.logic.getSegmentIDs(segmentationNode, False)
      importWidget.otherSegmentsTableView.setSelectedSegmentIDs(segmentIDs)

      importWidget.copyOtherToCurrentButton.click()

      self.delayDisplay('Checking number of imported segments')
      self.assertTrue(len(qrWidget.segmentEditorWidget.segments) == 3,
                      "Number of segments does not match expected count of 3")

      self.delayDisplay('Test passed!')
  def section_LoadDicomData(self):
    try:
      # Open test database and empty it
      with DICOMUtils.TemporaryDICOMDatabase(self.dicomDatabaseDir) as db:
        self.assertTrue( db.isOpen )
        self.assertEqual( slicer.dicomDatabase, db)

        # Download, unzip, import, and load data. Verify loaded nodes.
        loadedNodes = {'vtkMRMLScalarVolumeNode':1}
        with DICOMUtils.LoadDICOMFilesToDatabase( \
            self.dicomZipFileUrl, self.dicomZipFilePath, \
            self.dicomDataDir, self.expectedNumOfFilesInDicomDataDir, \
            {}, loadedNodes, checksum=self.dicomZipChecksum) as success:
          self.assertTrue(success)

      self.assertEqual( len( slicer.util.getNodes('vtkMRMLSubjectHierarchyNode*') ), 1 )

    except Exception as e:
      import traceback
      traceback.print_exc()
      self.delayDisplay('Test caused exception!\n' + str(e),self.delayMs*2)
  def TestSection_01_LoadDicomData(self):
    try:
      # Open test database and empty it
      with DICOMUtils.TemporaryDICOMDatabase(self.dicomDatabaseDir) as db:
        self.assertTrue( db.isOpen )
        self.assertEqual( slicer.dicomDatabase, db)

        # Download, unzip, import, and load data. Verify selected plugins and loaded nodes.
        selectedPlugins = { 'Scalar Volume':2, 'RT':3 }
        loadedNodes = { 'vtkMRMLScalarVolumeNode':2, \
                        'vtkMRMLSegmentationNode':1, \
                        'vtkMRMLModelHierarchyNode':7 }
        with DICOMUtils.LoadDICOMFilesToDatabase( \
            self.dicomZipFileUrl, self.dicomZipFilePath, \
            self.dicomDataDir, self.expectedNumOfFilesInDicomDataDir, \
            {}, loadedNodes) as success:
          self.assertTrue(success)

    except Exception, e:
      import traceback
      traceback.print_exc()
      self.delayDisplay('Test caused exception!\n' + str(e),self.delayMs*2)
    def ProceduralSegmentation(self, inputDir, outputDir):

        # Importing Dicom into temporary database
        dicomDataDir = inputDir
        from DICOMLib import DICOMUtils
        loadedNodeIDs = []

        with DICOMUtils.TemporaryDICOMDatabase() as db:
            DICOMUtils.importDicom(dicomDataDir, db)
            patientUIDs = db.patients()
            for patientUID in patientUIDs:
                loadedNodeIDs.extend(DICOMUtils.loadPatientByUID(patientUID))

# Loading Dicom into scene
        seriesVolumeNode = slicer.util.getNode(loadedNodeIDs[0])
        storageVolumeNode = seriesVolumeNode.CreateDefaultStorageNode()
        slicer.mrmlScene.AddNode(storageVolumeNode)
        storageVolumeNode.UnRegister(slicer.mrmlScene)
        seriesVolumeNode.SetAndObserveStorageNodeID(storageVolumeNode.GetID())

        # Access segmentation module
        slicer.util.selectModule('Segment Editor')
        segmentationNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentationNode")
        slicer.mrmlScene.AddNode(segmentationNode)
        segmentationNode.CreateDefaultDisplayNodes()  # only needed for display
        segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(
            seriesVolumeNode)

        # TODO Automate creation of different segments in the future (using some form of -type argument)
        # Create spine segment
        segmentTypeID = "Spine"
        newSegment = slicer.vtkSegment()
        newSegment.SetName(segmentTypeID)
        newSegment.SetColor([0.89, 0.85, 0.78])
        segmentationNode.GetSegmentation().AddSegment(newSegment,
                                                      segmentTypeID)

        # Create segment editor widget to get access to effects
        segmentEditorWidget = slicer.qMRMLSegmentEditorWidget()
        segmentEditorWidget.setMRMLScene(slicer.mrmlScene)

        # Access segment editor node
        segmentEditorNode = slicer.mrmlScene.AddNewNodeByClass(
            "vtkMRMLSegmentEditorNode")
        slicer.mrmlScene.AddNode(segmentEditorNode)
        segmentEditorWidget.setMRMLSegmentEditorNode(segmentEditorNode)
        segmentEditorWidget.setSegmentationNode(segmentationNode)
        segmentEditorWidget.setMasterVolumeNode(seriesVolumeNode)

        # Segment Editor Effect: Thresholding
        segmentEditorWidget.setActiveEffectByName("Threshold")
        effect = segmentEditorWidget.activeEffect()
        effect.setParameter("MinimumThreshold", "90")
        effect.setParameter("MaximumThreshold", "1600")
        effect.self().onApply()

        # Setting Closed Surface Representation Values
        segmentationNode.GetSegmentation().SetConversionParameter(
            "Oversampling factor", "1.0")
        segmentationNode.GetSegmentation().SetConversionParameter(
            "Joint smoothing", "0.50")
        segmentationNode.GetSegmentation().SetConversionParameter(
            "Smoothing factor", "0.50")

        # Segment Editor Effect: Smoothing
        segmentEditorWidget.setActiveEffectByName("Smoothing")
        effect = segmentEditorWidget.activeEffect()
        # 2mm MEDIAN Smoothing
        effect.setParameter("SmoothingMethod", "MEDIAN")
        effect.setParameter("KernelSizeMm", 2.5)
        effect.self().onApply()
        # 2mm OPEN Smoothing
        #effect.setParameter("SmoothingMethod", "MORPHOLOGICAL_OPENING")
        #effect.setParameter("KernelSizeMm", 2)
        #effect.self().onApply
        # 1.5mm CLOSED Smoothing
        #effect.setParameter("SmoothingMethod", "MORPHOLOGICAL_CLOSING")
        #effect.setParameter("KernelSizeMm", 1.5)
        #effect.self().onApply

        # Create Closed Surface Representation
        segmentationNode.CreateClosedSurfaceRepresentation()

        # Export Segmentation to Model Node
        shNode = slicer.mrmlScene.GetSubjectHierarchyNode()
        exportFolderItemId = shNode.CreateFolderItem(shNode.GetSceneItemID(),
                                                     "Segments")
        slicer.modules.segmentations.logic().ExportAllSegmentsToModels(
            segmentationNode, exportFolderItemId)

        segmentID = segmentationNode.GetSegmentation().GetNthSegmentID(0)
        surfaceMesh = segmentationNode.GetClosedSurfaceInternalRepresentation(
            segmentID)

        # Decimate Model
        decimator = vtk.vtkDecimatePro()
        decimator.SplittingOff()
        decimator.PreserveTopologyOn()
        decimator.SetTargetReduction(0.95)
        decimator.SetInputData(surfaceMesh)
        decimator.Update()
        surfaceMesh = decimator.GetOutput()

        # Smooth the Model
        smoothingFactor = 0.5
        smoother = vtk.vtkWindowedSincPolyDataFilter()
        smoother.SetInputData(surfaceMesh)
        smoother.SetNumberOfIterations(50)
        smoother.SetPassBand(pow(10.0, -4.0 * smoothingFactor))
        smoother.BoundarySmoothingOff()
        smoother.FeatureEdgeSmoothingOff()
        smoother.NonManifoldSmoothingOn()
        smoother.NormalizeCoordinatesOn()
        smoother.Update()
        surfaceMesh = smoother.GetOutput()

        # Clean up Model
        cleaner = vtk.vtkCleanPolyData()
        #cleaner.PointMergingOff()
        #cleaner.ConvertLinesToPointsOn()
        #cleaner.ConvertPolysToLinesOn()
        #cleaner.ConvertStripsToPolysOn()
        cleaner.SetInputData(surfaceMesh)
        cleaner.Update()
        surfaceMesh = cleaner.GetOutput()

        # Write to OBJ File
        outputFileName = outputDir + "segmentation.obj"
        writer = vtk.vtkOBJWriter()
        writer.SetFileName(outputFileName)
        writer.SetInputData(surfaceMesh)
        writer.Update()

        # Clean up
        segmentEditorWidget = None
        slicer.mrmlScene.RemoveNode(segmentEditorNode)
Example #13
0
parser.add_argument("--output", help="Output directory")

args = parser.parse_args()
if args.dcmtk and args.gdcm:
    raise ValueError("Cannot specify both gdcm and dcmtk")
if args.dcmtk:
    setDICOMReaderApproach('DCMTK')
if args.gdcm:
    setDICOMReaderApproach('GDCM')

from DICOMLib import DICOMUtils

indexer = ctk.ctkDICOMIndexer()
dbDir = "/tmp/SlicerDB"
print("Temporary directory: "+dbDir)
with DICOMUtils.TemporaryDICOMDatabase(dbDir) as db:
  indexer.addDirectory(db, args.input)
  indexer.waitForImportFinished()

slicer.util.selectModule('DICOM')

popup = slicer.modules.DICOMWidget.detailsPopup
popup.open()

fileLists = []
for patient in slicer.dicomDatabase.patients():
    print(patient)
    for study in slicer.dicomDatabase.studiesForPatient(patient):
        print(study)
        for series in slicer.dicomDatabase.seriesForStudy(study):
            print(series)
Example #14
0
    def test_SegmentEditorEffect(self):

        self.assertIsNotNone(slicer.vtkSlicerPETTumorSegmentationLogic)
        with DICOMUtils.TemporaryDICOMDatabase(
                self.tempDicomDatabaseDir) as db:
            self.assertTrue(db.isOpen)
            self.assertEqual(slicer.dicomDatabase, db)

            self.delayDisplay(
                'Loading PET DICOM dataset (including download if necessary)')
            petNode = self.loadTestData()
            self.delayDisplay('Switching to Segment Editor')
            slicer.util.mainWindow().moduleSelector().selectModule(
                'SegmentEditor')
            widget = slicer.modules.SegmentEditorWidget
            editor = widget.editor
            params = widget.parameterSetNode
            seg = widget.editor.segmentationNode()

            self.delayDisplay('Adding emtpy segment')
            # add segment similar to onAddSegment: https://github.com/Slicer/Slicer/blob/28ea2ebef031788d706a3085a46fac41d0017c05/Modules/Loadable/Segmentations/Widgets/qMRMLSegmentEditorWidget.cxx#L1894
            editor.saveStateForUndo()
            addedSegmentID = seg.GetSegmentation().AddEmptySegment()
            editor.setCurrentSegmentID(addedSegmentID)

            # switch to PET tumor segmentation effect
            self.delayDisplay('Activating PET Tumor Segmentation effect')
            editor.setActiveEffectByName('PET Tumor Segmentation')
            effect = editor.activeEffect()
            self.assertIsNotNone(effect)

            # one-click segmentation
            self.delayDisplay('Applying one-click segmentation')
            effect.self().onApplyMouseClick([41.3, 220.1, -980.2])
            self.assertEqual(self.getSignature(seg), 2890720391)

            # global refinement
            self.delayDisplay('Applying global refinement')
            effect.self().globalRefinementRadioButton.click()
            effect.self().onApplyMouseClick([40.1, 264.2, -969.2])
            self.assertEqual(self.getSignature(seg), 3700505133)

            # local refinement
            self.delayDisplay('Applying local refinement')
            effect.self().localRefinementRadioButton.click()
            effect.self().onApplyMouseClick([40.1, 258.1, -1025.1])
            self.assertEqual(self.getSignature(seg), 3550788737)

            # undo with local refinement
            self.delayDisplay('Testing undo with local refinement')
            editor.undo()
            self.assertEqual(self.getSignature(seg), 3700505133)
            effect.self().onApplyMouseClick([40.1, 234.2, 934.7])

            # go back to initial segmentation before refinement and use splitting option
            self.delayDisplay('Applying splitting option')
            editor.undo()
            editor.undo()
            effect.self().splittingCheckBox.checked = True
            effect.self().onApplyParameters()
            self.assertEqual(self.getSignature(seg), 4231292517)

            # add second segment
            self.delayDisplay('Adding second segment')
            editor.saveStateForUndo()
            addedSegmentID = seg.GetSegmentation().AddEmptySegment()
            editor.setCurrentSegmentID(addedSegmentID)

            # one-click segmentation
            self.delayDisplay('Applying one-click segmentation')
            effect.self().onApplyMouseClick([41.3, 229.1, -952.5])
            effect.self().onApplyParameters()
            self.assertEqual(self.getSignature(seg), 4226190476)

            # assist centering
            self.delayDisplay('Applying assist centering option')
            effect.self().assistCenteringCheckBox.checked = False
            effect.self().onApplyParameters()
            self.assertEqual(self.getSignature(seg), 4401777778)

            # sealing centering
            self.delayDisplay('Applying sealing option')
            effect.self().sealingCheckBox.checked = True
            effect.self().onApplyParameters()
            self.assertEqual(self.getSignature(seg), 4451555556)

            # overwriting
            self.delayDisplay('Applying overwriting option')
            effect.self().allowOverwritingCheckBox.checked = True
            effect.self().onApplyParameters()
            self.assertEqual(self.getSignature(seg), 5756378601)

            editor.undo()
            self.assertEqual(self.getSignature(seg), 4451555556)

            self.delayDisplay('Test passed!')