Example #1
0
    def __init__(self,
                 database,
                 fileToBeAddedCallback=None,
                 fileAddedCallback=None):
        super(DICOMListener, self).__init__()
        self.dicomDatabase = database
        self.indexer = ctk.ctkDICOMIndexer()
        self.fileToBeAddedCallback = fileToBeAddedCallback
        self.fileAddedCallback = fileAddedCallback
        self.lastFileAdded = None
        settings = qt.QSettings()

        dir = settings.value('DatabaseDirectory')
        if not dir:
            raise (UserWarning(
                'Database directory not set: cannot start DICOMListener'))
        if not os.path.exists(dir):
            os.mkdir(dir)
        self.incomingDir = dir + "/incoming"
        if not os.path.exists(self.incomingDir):
            os.mkdir(self.incomingDir)

        self.port = settings.value('StoragePort')
        if not self.port:
            settings.setValue('StoragePort', '11112')
            self.port = settings.value('StoragePort')
 def addFilesToDatabase(self):
     indexer = ctk.ctkDICOMIndexer()
     destinationDir = os.path.dirname(slicer.dicomDatabase.databaseFilename)
     if self.sdbFile:
         files = [self.sdbFile]
     else:
         files = glob.glob("%s/*" % self.dicomDirectory)
     for file in files:
         indexer.addFile(slicer.dicomDatabase, file, destinationDir)
         slicer.util.showStatusMessage("Loaded: %s" % file, 1000)
Example #3
0
 def importDicomDir(self, outputDirPath):
   """
   Utility function to import DICOM files from a directory
   """
   self.addLog('Directory: '+outputDirPath)
   self.addLog('DICOM importing started...')
   dicomWidget = slicer.modules.dicom.widgetRepresentation().self()
   indexer = ctk.ctkDICOMIndexer()
   indexer.addDirectory( slicer.dicomDatabase, outputDirPath )
   self.addLog('DICOM importing completed.')
Example #4
0
 def importDicomDir(self, outputDirPath):
   """
   Utility function to import DICOM files from a directory
   """
   self.addLog('Directory: '+outputDirPath)
   self.addLog('DICOM importing started...')
   dicomWidget = slicer.modules.dicom.widgetRepresentation().self()
   indexer = ctk.ctkDICOMIndexer()
   indexer.addDirectory( slicer.dicomDatabase, outputDirPath )
   self.addLog('DICOM importing completed.')
Example #5
0
 def addFilesToDatabase(self):
     indexer = ctk.ctkDICOMIndexer()
     destinationDir = os.path.dirname(slicer.dicomDatabase.databaseFilename)
     if self.sdbFile:
         files = [self.sdbFile]
     else:
         files = glob.glob('%s/*' % self.dicomDirectory)
     for file in files:
         indexer.addFile(slicer.dicomDatabase, file, destinationDir)
         slicer.util.showStatusMessage("Loaded: %s" % file, 1000)
Example #6
0
  def TestSection_2ImportStudy(self):
    self.delayDisplay("Import study",self.delayMs)

    indexer = ctk.ctkDICOMIndexer()
    self.assertIsNotNone( indexer )

    # Import study to database
    indexer.addDirectory( slicer.dicomDatabase, self.dataDir )
    indexer.waitForImportFinished()

    self.assertEqual( len(slicer.dicomDatabase.patients()), 1 )
    self.assertIsNotNone( slicer.dicomDatabase.patients()[0] )
 def importStudy(self, inputDir, progressCallback=None):
   self.progressCallback = progressCallback
   self.canceled = False
   print('Database location: '+self.dicomDatabaseDir)
   print('FIXME: revert back to the original DB location when done!')
   self.openDatabase()
   print('Input directory: ' + inputDir)
   if not self.indexer:
     self.indexer = ctk.ctkDICOMIndexer()
     self.indexer.connect("progress(int)", self.updateProgress)
   self.indexer.addDirectory(slicer.dicomDatabase, inputDir)
   self.patients = slicer.dicomDatabase.patients()
   print('Import completed, total '+str(len(slicer.dicomDatabase.patients()))+' patients imported')
 def ImportStudy(self, dicomDataDir):
     indexer = ctk.ctkDICOMIndexer()
     # Import study to database
     indexer.addDirectory( slicer.dicomDatabase, dicomDataDir )
     indexer.waitForImportFinished()
     
     # Check if import added any new patients to the database
     if len(slicer.dicomDatabase.patients()) > self.databases[self.dbCounter]['NumberPatients']:     
         patientsAdded = slicer.dicomDatabase.patients()[self.databases[self.dbCounter]['NumberPatients']:]
         self.databases[self.dbCounter]['NumberPatients'] = len(slicer.dicomDatabase.patients())
         return patientsAdded
     else:
         return 0
Example #9
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()
        try:
          for derivedItem in loadable.derivedItems:
            indexer = ctk.ctkDICOMIndexer()
            self.progress.labelText = '\nIndexing %s' % derivedItem
            slicer.app.processEvents()
            indexer.addFile(slicer.dicomDatabase, derivedItem)
        except AttributeError:
          # no derived items or some other attribute error
          pass
    self.progress.close()
    self.progress = None
    if loadingResult:
      qt.QMessageBox.warning(slicer.util.mainWindow(), 'DICOM loading', loadingResult)
    if not self.browserPersistent:
      self.close()
Example #10
0
  def loadCheckedLoadables(self):
    """Invoke the load method on each plugin for the loadable
    (DICOMLoadable or qSlicerDICOMLoadable) 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()
        try:
          for derivedItem in loadable.derivedItems:
            indexer = ctk.ctkDICOMIndexer()
            self.progress.labelText = '\nIndexing %s' % derivedItem
            slicer.app.processEvents()
            indexer.addFile(slicer.dicomDatabase, derivedItem)
        except AttributeError:
          # no derived items or some other attribute error
          pass
    self.progress.close()
    self.progress = None
    if loadingResult:
      qt.QMessageBox.warning(slicer.util.mainWindow(), 'DICOM loading', loadingResult)
    if not self.browserPersistent:
      self.close()
Example #11
0
    def ImportStudy(self, dicomDataDir):
        indexer = ctk.ctkDICOMIndexer()
        # Import study to database
        indexer.addDirectory(slicer.dicomDatabase, dicomDataDir)
        indexer.waitForImportFinished()

        # Check if import added any new patients to the database
        if len(slicer.dicomDatabase.patients()) > self.databases[
                self.dbCounter]['NumberPatients']:
            patientsAdded = slicer.dicomDatabase.patients(
            )[self.databases[self.dbCounter]['NumberPatients']:]
            self.databases[self.dbCounter]['NumberPatients'] = len(
                slicer.dicomDatabase.patients())
            return patientsAdded
        else:
            return 0
Example #12
0
  def __init__(self,database,fileToBeAddedCallback=None,fileAddedCallback=None):
    super(DICOMListener,self).__init__()
    self.dicomDatabase = database
    self.indexer = ctk.ctkDICOMIndexer()
    self.fileToBeAddedCallback = fileToBeAddedCallback
    self.fileAddedCallback = fileAddedCallback
    self.lastFileAdded = None
    settings = qt.QSettings()

    dir = settings.value('DatabaseDirectory')
    if not dir:
      raise( UserWarning('Database directory not set: cannot start DICOMListener') )
    if not os.path.exists(dir):
      os.mkdir(dir)
    self.incomingDir = dir + "/incoming"
    if not os.path.exists(self.incomingDir):
      os.mkdir(self.incomingDir)

    self.port = settings.value('StoragePort')
    if not self.port:
      settings.setValue('StoragePort', '11112')
def DoIt(inputDir, rgbDir, outputDir):


  #
  # Read the input DICOM series as a volume
  #
  dcmList = []
  for dcm in os.listdir(inputDir):
    if len(dcm)-dcm.rfind('.dcm') == 4:
      dcmList.append(inputDir+'/'+dcm)

  scalarVolumePlugin = slicer.modules.dicomPlugins['DICOMScalarVolumePlugin']()

  print 'Will examine: ',dcmList


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

  loadables = scalarVolumePlugin.examine([dcmList])

  if len(loadables) == 0:
    print 'Could not parse the DICOM Study!'
    exit()

  inputVolume = scalarVolumePlugin.load(loadables[0])

  sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
  '''
  sNode.ResetFileNameList()
  for f in loadables[0].files:
    sNode.AddFileName(f)
  sNode.SetFileName(loadables[0].files[0])
  sNode.SetSingleFile(0)
  inputVolume = slicer.vtkMRMLScalarVolumeNode()
  sNode.ReadData(inputVolume)
  '''

  sNode.SetWriteFileFormat('nrrd')
  sNode.SetFileName(os.path.join(outputDir,'input_volume.nrrd'))
  sNode.WriteData(inputVolume)

  #
  # Order the input RGBs and rename in a temp directory
  #
  rgbList = []
  for rgb in os.listdir(rgbDir):
    if len(rgb)-rgb.rfind('.bmp') == 4:
      rgbList.append(rgb)

  tmpDir = slicer.app.settings().value('Modules/TemporaryDirectory')
  tmpDir = tmpDir+'/PNGStackLabelConverter'
  if not os.path.exists(tmpDir):
    os.mkdir(tmpDir)

  oldFiles = os.listdir(tmpDir)
  # just in case there is anything in that directory
  for f in oldFiles:
    os.unlink(tmpDir+'/'+f)

  rgbOrdered = [None] * len(loadables[0].files)
  rgbCnt = 0
  rgbExt = rgbList[0][rgbList[0].rfind('.')+1:len(rgbList[0])]
  print 'Extension for RGBs: ',rgbExt

  dcmFileList = loadables[0].files
  rgbRenamedList = []

  print 'Number of dcm files: ',len(dcmFileList), ' and rgb files: ',len(rgbOrdered)

  dcmIdx = 0
  for dcm in dcmFileList:
    rgbIdx = 0

    for rgb in rgbList:

      dcmPrefix = dcm[dcm.rfind('/')+1:dcm.rfind('.')]

      if rgb.find(dcmPrefix) != -1:
        name = string.zfill(str(dcmIdx),5)
        rgbCnt = rgbCnt+1
        src = rgbDir+'/'+rgb
        dest = tmpDir+'/'+name+'.'+rgbExt
        rgbRenamedList.append(dest)
        shutil.copy(src,dest)

        break
      rgbIdx = rgbIdx+1

    # remove the matched DICOM file from the list
    if rgbIdx == len(rgbList):
      print('ERROR: failed to find matching label file for DICOM file '+dcm)
      return

    del rgbList[rgbIdx]
    dcmIdx = dcmIdx+1

  if len(rgbRenamedList) == 0:
    print 'Could not parse the DICOM Study!'
    return

  sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
  sNode.ResetFileNameList()
  for f in rgbRenamedList:
    sNode.AddFileName(f)
  sNode.SetFileName(rgbRenamedList[0])
  sNode.SetSingleFile(0)
  inputRGBVolume = slicer.vtkMRMLVectorVolumeNode()
  sNode.ReadData(inputRGBVolume)


  # run the filter
  # - extract the RGB portions
  extract = vtk.vtkImageExtractComponents()
  extract.SetComponents(0,1,2)
  if vtk.vtkVersion().GetVTKMajorVersion() < 6:
    extract.SetInput(inputRGBVolume.GetImageData())
  else:
    extract.SetInputData(inputRGBVolume.GetImageData())

  luminance = vtk.vtkImageLuminance()
  if vtk.vtkVersion().GetVTKMajorVersion() < 6:
    luminance.SetInput(extract.GetOutput())
  else:
    luminance.SetInputData(extract.GetOutput())

  cast = vtk.vtkImageCast()
  if vtk.vtkVersion().GetVTKMajorVersion() < 6:
    cast.SetInput(luminance.GetOutput())
  else:
    cast.SetInputData(luminance.GetOutput())
  cast.SetOutputScalarTypeToShort()
  cast.GetOutput().Update()

  ijkToRAS = vtk.vtkMatrix4x4()
  inputVolume.GetIJKToRASMatrix(ijkToRAS)

  outputLabel = slicer.vtkMRMLLabelMapVolumeNode()
  outputLabel.SetIJKToRASMatrix(ijkToRAS)
  outputLabel.SetAndObserveImageData(cast.GetOutput())

  reportingLogic = slicer.modules.reporting.logic()

  displayNode = slicer.vtkMRMLLabelMapVolumeDisplayNode()
  displayNode.SetAndObserveColorNodeID(reportingLogic.GetDefaultColorNode().GetID())
  slicer.mrmlScene.AddNode(displayNode)
  outputLabel.SetAndObserveDisplayNodeID(displayNode.GetID())

  sNode.SetWriteFileFormat('nrrd')
  sNode.SetFileName(os.path.join(outputDir,'label_output.nrrd'))
  sNode.WriteData(outputLabel)

  # save as DICOM SEG
  labelCollection = vtk.vtkCollection()
  labelCollection.AddItem(outputLabel)

  slicer.mrmlScene.AddNode(inputVolume)
  outputLabel.SetAttribute('AssociatedNodeID',inputVolume.GetID())
  slicer.mrmlScene.AddNode(outputLabel)

  # initialize the DICOM DB for Reporting logic
  settings = qt.QSettings()
  dbFileName = settings.value('DatabaseDirectory','')
  if dbFileName =='':
    print('ERROR: database must be initialized')
  else:
    dbFileName = dbFileName +'/ctkDICOM.sql'
    reportingLogic.InitializeDICOMDatabase(dbFileName)

    reportingLogic.DicomSegWrite(labelCollection, outputDir)
Example #14
0
  def test_Part1DICOM(self):
    """ Test the DICOM part of the test using the head atlas
    """

    import os
    self.delayDisplay("Starting the DICOM test")
    #
    # first, get the data - a zip file of dicom data
    #
    import urllib
    downloads = (
        ('http://slicer.kitware.com/midas3/download?items=8610', 'dicom.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 + '/tempDICOMDatbase'
      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')
      dicomWidget.dicomApp.suspendModel()
      indexer = ctk.ctkDICOMIndexer()
      indexer.addDirectory(slicer.dicomDatabase, dicomFilesDirectory, None)
      indexer.waitForImportFinished()
      dicomWidget.dicomApp.resumeModel()
      dicomWidget.detailsPopup.open()
      # click on the first row of the tree
      index = dicomWidget.tree.indexAt(qt.QPoint(0,0))
      dicomWidget.onTreeClicked(index)

      self.delayDisplay('Loading Selection')
      dicomWidget.detailsPopup.loadCheckedLoadables()

      self.delayDisplay('Change Level')
      layoutManager = slicer.app.layoutManager()
      redWidget = layoutManager.sliceWidget('Red')
      self.clickAndDrag(redWidget,start=(10,10),end=(10,40))

      self.delayDisplay('Change Window')
      self.clickAndDrag(redWidget,start=(10,10),end=(40,10))

      self.delayDisplay('Change Layout')
      layoutManager = slicer.app.layoutManager()
      layoutManager.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutOneUpRedSliceView)

      self.delayDisplay('Zoom')
      self.clickAndDrag(redWidget,button='Right',start=(10,10),end=(10,40))

      self.delayDisplay('Pan')
      self.clickAndDrag(redWidget,button='Middle',start=(10,10),end=(40,40))

      self.delayDisplay('Center')
      redWidget.sliceController().fitSliceToBackground()

      self.delayDisplay('Lightbox')
      redWidget.sliceController().setLightboxTo6x6()

      self.delayDisplay('Conventional Layout')
      layoutManager.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutConventionalView)

      self.delayDisplay('No Lightbox')
      redWidget.sliceController().setLightboxTo1x1()

      self.delayDisplay('Four Up Layout')
      layoutManager.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutFourUpView)

      self.delayDisplay('Shift Mouse')
      self.clickAndDrag(redWidget,button='None',start=(100,100),end=(140,140),modifiers=['Shift'])

      self.delayDisplay('Conventional, Link, Slice Model')
      layoutManager.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutConventionalView)
      redWidget.sliceController().setSliceLink(True)
      redWidget.sliceController().setSliceVisible(True);

      self.delayDisplay('Rotate')
      threeDView = layoutManager.threeDWidget(0).threeDView()
      self.clickAndDrag(threeDView)

      self.delayDisplay('Zoom')
      threeDView = layoutManager.threeDWidget(0).threeDView()
      self.clickAndDrag(threeDView,button='Right')

      self.delayDisplay('Test passed!')
    except Exception, e:
      import traceback
      traceback.print_exc()
      self.delayDisplay('Test caused exception!\n' + str(e))
Example #15
0
  def proceedWithReferencedLoadablesSelection(self):
    # each check box corresponds to a referenced loadable
    # that was selected by examine; if the user confirmed
    # that reference should be loaded, add it to the self.loadablesByPlugin
    # dictionary
    if self.referencesDialog:
      children = self.referencesDialog.children()
      loadableCnt = 0
      for plugin in self.referencedLoadables:
        for loadable in self.referencedLoadables[plugin]:
          if loadable.selected:
            if children[loadableCnt+2].checked:
              self.loadablesByPlugin[plugin].append(loadable)

      self.referencesDialog.close()
      self.referencesDialog = None

    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()
        try:
          for derivedItem in loadable.derivedItems:
            indexer = ctk.ctkDICOMIndexer()
            self.progress.labelText = '\nIndexing %s' % derivedItem
            slicer.app.processEvents()
            indexer.addFile(slicer.dicomDatabase, derivedItem)
        except AttributeError:
          # no derived items or some other attribute error
          pass
    self.progress.close()
    self.progress = None
    if loadingResult:
      qt.QMessageBox.warning(slicer.util.mainWindow(), 'DICOM loading', loadingResult)
    if not self.browserPersistent:
      self.close()

    return
Example #16
0
  def proceedWithReferencedLoadablesSelection(self):
    # each check box corresponds to a referenced loadable
    # that was selected by examine; if the user confirmed
    # that reference should be loaded, add it to the self.loadablesByPlugin
    # dictionary
    if self.referencesDialog:
      children = self.referencesDialog.children()
      loadableCnt = 0
      for plugin in self.referencedLoadables:
        for loadable in self.referencedLoadables[plugin]:
          if loadable.selected:
            if children[loadableCnt+2].checked:
              self.loadablesByPlugin[plugin].append(loadable)

      self.referencesDialog.close()
      self.referencesDialog = None

    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 = ''

    loadedNodeIDs = []

    @vtk.calldata_type(vtk.VTK_OBJECT)
    def onNodeAdded(caller, event, calldata):
      node = calldata
      if isinstance(node, slicer.vtkMRMLVolumeNode):
        loadedNodeIDs.append(node.GetID())

    self.addObserver(slicer.mrmlScene, slicer.vtkMRMLScene.NodeAddedEvent, onNodeAdded);

    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()
        try:
          for derivedItem in loadable.derivedItems:
            indexer = ctk.ctkDICOMIndexer()
            self.progress.labelText = '\nIndexing %s' % derivedItem
            slicer.app.processEvents()
            indexer.addFile(slicer.dicomDatabase, derivedItem)
        except AttributeError:
          # no derived items or some other attribute error
          pass

    self.removeObserver(slicer.mrmlScene, slicer.vtkMRMLScene.NodeAddedEvent, onNodeAdded);

    loadedFileParameters = {}
    loadedFileParameters['nodeIDs'] = loadedNodeIDs
    slicer.app.ioManager().emitNewFileLoaded(loadedFileParameters)

    self.progress.close()
    self.progress = None
    if loadingResult:
      qt.QMessageBox.warning(slicer.util.mainWindow(), 'DICOM loading', loadingResult)
    if not self.browserPersistent:
      self.close()

    return
Example #17
0
    def test_Part1DICOM(self,
                        enableScreenshotsFlag=0,
                        screenshotScaleFactor=1):
        """ Test the DICOM part of the test using the head atlas
    """

        self.enableScreenshots = enableScreenshotsFlag
        self.screenshotScaleFactor = screenshotScaleFactor

        import os
        self.delayDisplay("Starting the DICOM test")
        #
        # first, get the data - a zip file of dicom data
        #
        import urllib
        downloads = (('http://slicer.kitware.com/midas3/download?items=124183',
                      'dataset1_Thorax_Abdomen.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'
            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
            dicomWidget.detailsPopup.offerLoadables(
                '1.3.12.2.1107.5.1.4.50025.30000005060811542834300000776',
                'Series')
            dicomWidget.detailsPopup.examineForLoading()

            self.delayDisplay('Loading Selection')
            dicomWidget.detailsPopup.loadCheckedLoadables()

            self.takeScreenshot('LoadingADICOMVolume-Loaded',
                                'Loaded DICOM Volume', -1)

            layoutManager = slicer.app.layoutManager()
            redWidget = layoutManager.sliceWidget('Red')
            self.clickAndDrag(redWidget, start=(10, 10), end=(10, 40))
            self.clickAndDrag(redWidget, start=(10, 10), end=(40, 10))

            self.takeScreenshot('LoadingADICOMVolume-WL',
                                'Changed level and window', -1)

            redWidget.sliceController().setSliceLink(True)
            redWidget.sliceController().setSliceVisible(True)
            self.takeScreenshot('LoadingADICOMVolume-LinkView',
                                'Linked and visible', -1)

            self.clickAndDrag(redWidget,
                              button='Right',
                              start=(10, 10),
                              end=(10, 40))
            self.takeScreenshot('LoadingADICOMVolume-Zoom', 'Zoom', -1)

            threeDView = layoutManager.threeDWidget(0).threeDView()
            self.clickAndDrag(threeDView)
            self.takeScreenshot('LoadingADICOMVolume-Rotate', 'Rotate', -1)

            threeDView.resetFocalPoint()
            self.takeScreenshot('LoadingADICOMVolume-Center',
                                'Center the view', -1)

            layoutManager.setLayout(slicer.vtkMRMLLayoutNode.
                                    SlicerLayoutConventionalWidescreenView)
            self.takeScreenshot('LoadingADICOMVolume-ConventionalWidescreen',
                                'Conventional Widescreen Layout', -1)

            slicer.util.mainWindow().moduleSelector().selectModule(
                'VolumeRendering')
            self.takeScreenshot('VolumeRendering-Module', 'Volume Rendering',
                                -1)

            volumeRenderingWidgetRep = slicer.modules.volumerendering.widgetRepresentation(
            )
            abdomenVolume = slicer.mrmlScene.GetFirstNodeByName(
                '6: CT_Thorax_Abdomen')
            volumeRenderingWidgetRep.setMRMLVolumeNode(abdomenVolume)
            self.takeScreenshot('VolumeRendering-SelectVolume',
                                'Select the volume 6: CT_Thorax_Abdomen', -1)

            presetsScene = slicer.modules.volumerendering.logic(
            ).GetPresetsScene()
            ctCardiac3 = presetsScene.GetFirstNodeByName('CT-Cardiac3')
            volumeRenderingWidgetRep.applyPreset(ctCardiac3)
            self.takeScreenshot('VolumeRendering-SelectPreset',
                                'Select the Preset CT-Cardiac-3')

            self.delayDisplay('Skipping: Select VTK CPU Ray Casting')

            volumeRenderingNode = slicer.mrmlScene.GetFirstNodeByName(
                'VolumeRendering')
            volumeRenderingNode.SetVisibility(1)
            self.takeScreenshot('VolumeRendering-ViewRendering',
                                'View Volume Rendering', -1)

            self.delayDisplay('Skipping Move the Shift slider')

            redWidget.sliceController().setSliceVisible(False)
            self.takeScreenshot('VolumeRendering-SlicesOff',
                                'Turn off visibility of slices in 3D', -1)

            threeDView = layoutManager.threeDWidget(0).threeDView()
            self.clickAndDrag(threeDView)
            self.takeScreenshot('VolumeRendering-RotateVolumeRendering',
                                'Rotate volume rendered image', -1)

            volumeRenderingNode.SetVisibility(0)
            self.takeScreenshot('VolumeRendering-TurnOffVolumeRendering',
                                'Turn off volume rendered image', -1)

            volumeRenderingNode.SetCroppingEnabled(1)
            annotationROI = slicer.mrmlScene.GetFirstNodeByName(
                'AnnotationROI')
            annotationROI.SetDisplayVisibility(1)
            self.takeScreenshot('VolumeRendering-DisplayROI',
                                'Enable cropping and display ROI', -1)

            redWidget.sliceController().setSliceVisible(True)
            self.takeScreenshot('VolumeRendering-SlicesOn',
                                'Turn on visibility of slices in 3D', -1)

            annotationROI.SetXYZ(-79.61, 154.16, -232.591)
            annotationROI.SetRadiusXYZ(43.4, 65.19, 70.5)
            self.takeScreenshot('VolumeRendering-SizedROI',
                                'Position the ROI over a kidney', -1)

            volumeRenderingNode.SetVisibility(1)
            self.takeScreenshot('VolumeRendering-ROIRendering',
                                'ROI volume rendered', -1)

            annotationROI.SetXYZ(15, 146, -186)
            annotationROI.SetRadiusXYZ(138, 57, 61)
            self.takeScreenshot('VolumeRendering-BothKidneys',
                                'Rendered both kidneys', -1)

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

    #
    # Read the input DICOM series as a volume
    #
    dcmList = []
    for dcm in os.listdir(inputDir):
        if len(dcm) - dcm.rfind('.dcm') == 4:
            dcmList.append(inputDir + '/' + dcm)

    scalarVolumePlugin = slicer.modules.dicomPlugins[
        'DICOMScalarVolumePlugin']()

    print 'Will examine: ', dcmList

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

    loadables = scalarVolumePlugin.examine([dcmList])

    if len(loadables) == 0:
        print 'Could not parse the DICOM Study!'
        exit()

    inputVolume = scalarVolumePlugin.load(loadables[0])

    sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
    '''
  sNode.ResetFileNameList()
  for f in loadables[0].files:
    sNode.AddFileName(f)
  sNode.SetFileName(loadables[0].files[0])
  sNode.SetSingleFile(0)
  inputVolume = slicer.vtkMRMLScalarVolumeNode()
  sNode.ReadData(inputVolume)
  '''

    sNode.SetWriteFileFormat('nrrd')
    sNode.SetFileName(os.path.join(outputDir, 'input_volume.nrrd'))
    sNode.WriteData(inputVolume)

    #
    # Order the input RGBs and rename in a temp directory
    #
    rgbList = []
    for rgb in os.listdir(rgbDir):
        if len(rgb) - rgb.rfind('.bmp') == 4:
            rgbList.append(rgb)

    tmpDir = slicer.app.settings().value('Modules/TemporaryDirectory')
    tmpDir = tmpDir + '/PNGStackLabelConverter'
    if not os.path.exists(tmpDir):
        os.mkdir(tmpDir)

    oldFiles = os.listdir(tmpDir)
    # just in case there is anything in that directory
    for f in oldFiles:
        os.unlink(tmpDir + '/' + f)

    rgbOrdered = [None] * len(loadables[0].files)
    rgbCnt = 0
    rgbExt = rgbList[0][rgbList[0].rfind('.') + 1:len(rgbList[0])]
    print 'Extension for RGBs: ', rgbExt

    dcmFileList = loadables[0].files
    rgbRenamedList = []

    print 'Number of dcm files: ', len(dcmFileList), ' and rgb files: ', len(
        rgbOrdered)

    dcmIdx = 0
    for dcm in dcmFileList:
        rgbIdx = 0

        for rgb in rgbList:

            dcmPrefix = dcm[dcm.rfind('/') + 1:dcm.rfind('.')]

            if rgb.find(dcmPrefix) != -1:
                name = string.zfill(str(dcmIdx), 5)
                rgbCnt = rgbCnt + 1
                src = rgbDir + '/' + rgb
                dest = tmpDir + '/' + name + '.' + rgbExt
                rgbRenamedList.append(dest)
                shutil.copy(src, dest)

                break
            rgbIdx = rgbIdx + 1

        # remove the matched DICOM file from the list
        if rgbIdx == len(rgbList):
            print('ERROR: failed to find matching label file for DICOM file ' +
                  dcm)
            return

        del rgbList[rgbIdx]
        dcmIdx = dcmIdx + 1

    if len(rgbRenamedList) == 0:
        print 'Could not parse the DICOM Study!'
        return

    sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
    sNode.ResetFileNameList()
    for f in rgbRenamedList:
        sNode.AddFileName(f)
    sNode.SetFileName(rgbRenamedList[0])
    sNode.SetSingleFile(0)
    inputRGBVolume = slicer.vtkMRMLVectorVolumeNode()
    sNode.ReadData(inputRGBVolume)

    # run the filter
    # - extract the RGB portions
    extract = vtk.vtkImageExtractComponents()
    extract.SetComponents(0, 1, 2)
    if vtk.vtkVersion().GetVTKMajorVersion() < 6:
        extract.SetInput(inputRGBVolume.GetImageData())
    else:
        extract.SetInputData(inputRGBVolume.GetImageData())

    luminance = vtk.vtkImageLuminance()
    if vtk.vtkVersion().GetVTKMajorVersion() < 6:
        luminance.SetInput(extract.GetOutput())
    else:
        luminance.SetInputData(extract.GetOutput())

    cast = vtk.vtkImageCast()
    if vtk.vtkVersion().GetVTKMajorVersion() < 6:
        cast.SetInput(luminance.GetOutput())
    else:
        cast.SetInputData(luminance.GetOutput())
    cast.SetOutputScalarTypeToShort()
    cast.GetOutput().Update()

    ijkToRAS = vtk.vtkMatrix4x4()
    inputVolume.GetIJKToRASMatrix(ijkToRAS)

    outputLabel = slicer.vtkMRMLLabelMapVolumeNode()
    outputLabel.SetIJKToRASMatrix(ijkToRAS)
    outputLabel.SetAndObserveImageData(cast.GetOutput())

    reportingLogic = slicer.modules.reporting.logic()

    displayNode = slicer.vtkMRMLLabelMapVolumeDisplayNode()
    displayNode.SetAndObserveColorNodeID(
        reportingLogic.GetDefaultColorNode().GetID())
    slicer.mrmlScene.AddNode(displayNode)
    outputLabel.SetAndObserveDisplayNodeID(displayNode.GetID())

    sNode.SetWriteFileFormat('nrrd')
    sNode.SetFileName(os.path.join(outputDir, 'label_output.nrrd'))
    sNode.WriteData(outputLabel)

    # save as DICOM SEG
    labelCollection = vtk.vtkCollection()
    labelCollection.AddItem(outputLabel)

    slicer.mrmlScene.AddNode(inputVolume)
    outputLabel.SetAttribute('AssociatedNodeID', inputVolume.GetID())
    slicer.mrmlScene.AddNode(outputLabel)

    # initialize the DICOM DB for Reporting logic
    settings = qt.QSettings()
    dbFileName = settings.value('DatabaseDirectory', '')
    if dbFileName == '':
        print('ERROR: database must be initialized')
    else:
        dbFileName = dbFileName + '/ctkDICOM.sql'
        reportingLogic.InitializeDICOMDatabase(dbFileName)

        reportingLogic.DicomSegWrite(labelCollection, outputDir)
Example #19
0
    def test_Part1DICOM(self, enableScreenshotsFlag=0, screenshotScaleFactor=1):
        """ Test the DICOM part of the test using the head atlas
    """

        self.enableScreenshots = enableScreenshotsFlag
        self.screenshotScaleFactor = screenshotScaleFactor

        import os

        self.delayDisplay("Starting the DICOM test")
        #
        # first, get the data - a zip file of dicom data
        #
        import urllib

        downloads = (("http://slicer.kitware.com/midas3/download?items=124183", "dataset1_Thorax_Abdomen.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"
            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
            dicomWidget.detailsPopup.offerLoadables("1.3.12.2.1107.5.1.4.50025.30000005060811542834300000776", "Series")
            dicomWidget.detailsPopup.examineForLoading()

            self.delayDisplay("Loading Selection")
            dicomWidget.detailsPopup.loadCheckedLoadables()

            self.takeScreenshot("LoadingADICOMVolume-Loaded", "Loaded DICOM Volume", -1)

            layoutManager = slicer.app.layoutManager()
            redWidget = layoutManager.sliceWidget("Red")
            self.clickAndDrag(redWidget, start=(10, 10), end=(10, 40))
            self.clickAndDrag(redWidget, start=(10, 10), end=(40, 10))

            self.takeScreenshot("LoadingADICOMVolume-WL", "Changed level and window", -1)

            redWidget.sliceController().setSliceLink(True)
            redWidget.sliceController().setSliceVisible(True)
            self.takeScreenshot("LoadingADICOMVolume-LinkView", "Linked and visible", -1)

            self.clickAndDrag(redWidget, button="Right", start=(10, 10), end=(10, 40))
            self.takeScreenshot("LoadingADICOMVolume-Zoom", "Zoom", -1)

            threeDView = layoutManager.threeDWidget(0).threeDView()
            self.clickAndDrag(threeDView)
            self.takeScreenshot("LoadingADICOMVolume-Rotate", "Rotate", -1)

            threeDView.resetFocalPoint()
            self.takeScreenshot("LoadingADICOMVolume-Center", "Center the view", -1)

            layoutManager.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutConventionalWidescreenView)
            self.takeScreenshot("LoadingADICOMVolume-ConventionalWidescreen", "Conventional Widescreen Layout", -1)

            slicer.util.mainWindow().moduleSelector().selectModule("VolumeRendering")
            self.takeScreenshot("VolumeRendering-Module", "Volume Rendering", -1)

            volumeRenderingWidgetRep = slicer.modules.volumerendering.widgetRepresentation()
            abdomenVolume = slicer.mrmlScene.GetFirstNodeByName("6: CT_Thorax_Abdomen")
            volumeRenderingWidgetRep.setMRMLVolumeNode(abdomenVolume)
            self.takeScreenshot("VolumeRendering-SelectVolume", "Select the volume 6: CT_Thorax_Abdomen", -1)

            presetsScene = slicer.modules.volumerendering.logic().GetPresetsScene()
            ctCardiac3 = presetsScene.GetFirstNodeByName("CT-Cardiac3")
            volumeRenderingWidgetRep.applyPreset(ctCardiac3)
            self.takeScreenshot("VolumeRendering-SelectPreset", "Select the Preset CT-Cardiac-3")

            self.delayDisplay("Skipping: Select VTK CPU Ray Casting")

            volumeRenderingNode = slicer.mrmlScene.GetFirstNodeByName("VolumeRendering")
            volumeRenderingNode.SetVisibility(1)
            self.takeScreenshot("VolumeRendering-ViewRendering", "View Volume Rendering", -1)

            self.delayDisplay("Skipping Move the Shift slider")

            redWidget.sliceController().setSliceVisible(False)
            self.takeScreenshot("VolumeRendering-SlicesOff", "Turn off visibility of slices in 3D", -1)

            threeDView = layoutManager.threeDWidget(0).threeDView()
            self.clickAndDrag(threeDView)
            self.takeScreenshot("VolumeRendering-RotateVolumeRendering", "Rotate volume rendered image", -1)

            volumeRenderingNode.SetVisibility(0)
            self.takeScreenshot("VolumeRendering-TurnOffVolumeRendering", "Turn off volume rendered image", -1)

            volumeRenderingNode.SetCroppingEnabled(1)
            annotationROI = slicer.mrmlScene.GetFirstNodeByName("AnnotationROI")
            annotationROI.SetDisplayVisibility(1)
            self.takeScreenshot("VolumeRendering-DisplayROI", "Enable cropping and display ROI", -1)

            redWidget.sliceController().setSliceVisible(True)
            self.takeScreenshot("VolumeRendering-SlicesOn", "Turn on visibility of slices in 3D", -1)

            annotationROI.SetXYZ(-79.61, 154.16, -232.591)
            annotationROI.SetRadiusXYZ(43.4, 65.19, 70.5)
            self.takeScreenshot("VolumeRendering-SizedROI", "Position the ROI over a kidney", -1)

            volumeRenderingNode.SetVisibility(1)
            self.takeScreenshot("VolumeRendering-ROIRendering", "ROI volume rendered", -1)

            annotationROI.SetXYZ(15, 146, -186)
            annotationROI.SetRadiusXYZ(138, 57, 61)
            self.takeScreenshot("VolumeRendering-BothKidneys", "Rendered both kidneys", -1)

            self.delayDisplay("Test passed!")
        except Exception, e:
            import traceback

            traceback.print_exc()
            self.delayDisplay("Test caused exception!\n" + str(e))
Example #20
0
 def onHButtonClicked(self):
     i = ctk.ctkDICOMIndexer()
     i.addDirectory(slicer.dicomDatabase,
                    '/Users/Research/Documents/DICOM Files/TAC MONSERRAT')
     m = slicer.util.mainWindow()
     m.moduleSelector().selectModule('DICOM')
Example #21
0
 def importDICOM(self, dicomDatabase, dicomFilesDirectory):
     dicomWidget = slicer.modules.dicom.widgetRepresentation().self()
     indexer = ctk.ctkDICOMIndexer()
     indexer.addDirectory(dicomDatabase, dicomFilesDirectory, None)
     indexer.waitForImportFinished()
    def test_ReportingAIMRoundTrip(self):
        print ("CTEST_FULL_OUTPUT")
        """ Load the data using DICOM module
    """

        import os

        self.delayDisplay("Starting the DICOM test")
        #
        # first, get the data - a zip file of dicom data
        #
        import urllib

        downloads = (("http://slicer.kitware.com/midas3/download?items=10881", "JANCT-CT.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")

        reportingTempDir = slicer.app.temporaryPath + "/Reporting"
        print ("Temporary directory location: " + reportingTempDir)
        qt.QDir().mkpath(reportingTempDir)
        dicomFilesDirectory = reportingTempDir + "/dicomFiles"
        self.cleanupDir(dicomFilesDirectory)
        qt.QDir().mkpath(dicomFilesDirectory)
        slicer.app.applicationLogic().Unzip(filePath, dicomFilesDirectory)

        try:
            self.delayDisplay("Switching to temp database directory")
            tempDatabaseDirectory = reportingTempDir + "/tempDICOMDatbase"
            qt.QDir().mkpath(tempDatabaseDirectory)
            self.cleanupDir(tempDatabaseDirectory)
            if slicer.dicomDatabase:
                self.originalDatabaseDirectory = os.path.split(slicer.dicomDatabase.databaseFilename)[0]
            else:
                self.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")
            # dicomWidget.dicomApp.suspendModel()
            indexer = ctk.ctkDICOMIndexer()
            indexer.addDirectory(slicer.dicomDatabase, dicomFilesDirectory, None)
            indexer.waitForImportFinished()

            patient = slicer.dicomDatabase.patients()[0]
            studies = slicer.dicomDatabase.studiesForPatient(patient)
            series = [slicer.dicomDatabase.seriesForStudy(study) for study in studies]
            seriesUIDs = [uid for uidList in series for uid in uidList]
            dicomWidget.detailsPopup.offerLoadables(seriesUIDs, "SeriesUIDList")
            dicomWidget.detailsPopup.examineForLoading()

            loadablesByPlugin = dicomWidget.detailsPopup.loadablesByPlugin

            self.delayDisplay("Loading Selection")
            dicomWidget.detailsPopup.loadCheckedLoadables()

            # initialize the module with the report and volume

            volumes = slicer.util.getNodes("vtkMRMLScalarVolumeNode*")
            self.assertTrue(len(volumes) == 1)

            (name, volume) = volumes.items()[0]
            self.delayDisplay("Loaded volume name %s" % volume.GetName())

            self.delayDisplay("Configure Module")
            mainWindow = slicer.util.mainWindow()
            mainWindow.moduleSelector().selectModule("Reporting")

            reporting = slicer.modules.reporting.widgetRepresentation().self()

            report = slicer.mrmlScene.CreateNodeByClass("vtkMRMLReportingReportNode")
            report.SetReferenceCount(report.GetReferenceCount() - 1)
            slicer.mrmlScene.AddNode(report)
            report.SetFindingLabel(7)

            reporting.reportSelector.setCurrentNode(report)
            self.delayDisplay("Setting volume to %s" % volume.GetName())
            reporting.volumeSelector.setCurrentNode(volume)
            slicer.app.processEvents()

            # place some markups and add a segmentation label

            # add fiducial
            fidNode = slicer.vtkMRMLAnnotationFiducialNode()
            fidName = "AIM Round Trip Test Fiducial"
            fidNode.SetName(fidName)
            fidNode.SetSelected(1)
            fidNode.SetDisplayVisibility(1)
            fidNode.SetLocked(0)
            # TODO: ask Nicole where this is assigned in the regular workflow
            fidNode.SetAttribute("AssociatedNodeID", volume.GetID())
            print ("Calling set fid coords")
            startCoords = [15.8, 70.8, -126.7]
            fidNode.SetFiducialCoordinates(startCoords[0], startCoords[1], startCoords[2])
            print ("Starting fiducial coordinates: " + str(startCoords))
            slicer.mrmlScene.AddNode(fidNode)

            # add ruler
            rulerNode = slicer.vtkMRMLAnnotationRulerNode()
            rulerNode.SetName("Test Ruler")
            m = vtk.vtkMatrix4x4()
            volume.GetIJKToRASMatrix(m)
            ijk0 = [0, 0, 1, 1]
            ijk1 = [50, 50, 1, 1]
            ras0 = m.MultiplyPoint(ijk0)
            ras1 = m.MultiplyPoint(ijk1)
            rulerNode.SetPosition1(19.386751174926758, 68.528785705566406, -127.69000244140625)
            rulerNode.SetPosition2(132.72709655761719, -34.349384307861328, -127.69000244140625)
            rulerNode.SetAttribute("AssociatedNodeID", volume.GetID())
            slicer.mrmlScene.AddNode(rulerNode)
            slicer.app.processEvents()

            # add label node
            volumesLogic = slicer.modules.volumes.logic()
            labelNode = volumesLogic.CreateAndAddLabelVolume(slicer.mrmlScene, volume, "Segmentation")
            labelDisplayNode = labelNode.GetDisplayNode()
            labelDisplayNode.SetAndObserveColorNodeID("vtkMRMLColorTableNodeFileGenericAnatomyColors.txt")
            image = volume.GetImageData()
            thresh = vtk.vtkImageThreshold()
            if vtk.vtkVersion().GetVTKMajorVersion() < 6:
                thresh.SetInput(image)
            else:
                thresh.SetInputData(image)
            thresh.ThresholdBetween(10, 400)
            thresh.SetInValue(report.GetFindingLabel())
            thresh.SetOutValue(0)
            thresh.Update()
            labelNode.SetAndObserveImageData(thresh.GetOutput())
            reporting.segmentationSelector.setCurrentNode(labelNode)

            # Save the report

            exportDir = reportingTempDir + "/Output"
            qt.QDir().mkpath(exportDir)
            self.cleanupDir(exportDir)
            report.SetStorageDirectoryName(exportDir)
            reportingLogic = slicer.modules.reporting.logic()
            print ("Before saving report")
            reportingLogic.SaveReportToAIM(report)

            self.delayDisplay("Report saved")

            slicer.mrmlScene.Clear(0)

            # parse on patient level, find segmentation object, load and make sure
            # it matches the input
            # close the scene and load the report, check consistency

            # try to load back the saved AIM
            import glob

            print glob.glob(exportDir + "/*")
            xmlFiles = glob.glob(exportDir + "/*xml")
            print xmlFiles

            self.assertTrue(len(xmlFiles) == 1)
            reporting.importAIMFile = xmlFiles[0]
            reporting.onReportImport()

            self.delayDisplay("Report loaded from AIM! Test passed.")

            self.delayDisplay("Restoring original database directory")
            if self.originalDatabaseDirectory:
                dicomWidget.onDatabaseDirectoryChanged(self.originalDatabaseDirectory)

        except Exception, e:
            if self.originalDatabaseDirectory:
                dicomWidget.onDatabaseDirectoryChanged(self.originalDatabaseDirectory)
            import traceback

            traceback.print_exc()
            self.delayDisplay("Test caused exception!\n" + str(e))
            self.assertTrue(False)
Example #23
0
  def test_Part1DICOM(self):
    """ Test the DICOM part of the test using the head atlas
    """

    import os
    self.delayDisplay("Starting the DICOM test")
    #
    # first, get the data - a zip file of dicom data
    #
    import urllib
    downloads = (
        ('http://slicer.kitware.com/midas3/download?items=8610', 'dicom.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 + '/tempDICOMDatbase'
      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')
      dicomWidget.dicomApp.suspendModel()
      indexer = ctk.ctkDICOMIndexer()
      indexer.addDirectory(slicer.dicomDatabase, dicomFilesDirectory, None)
      indexer.waitForImportFinished()
      dicomWidget.dicomApp.resumeModel()
      dicomWidget.detailsPopup.open()
      # click on the first row of the tree
      index = dicomWidget.tree.indexAt(qt.QPoint(0,0))
      dicomWidget.onTreeClicked(index)

      self.delayDisplay('Loading Selection')
      dicomWidget.detailsPopup.loadCheckedLoadables()

      self.delayDisplay('Change Level')
      layoutManager = slicer.app.layoutManager()
      redWidget = layoutManager.sliceWidget('Red')
      self.clickAndDrag(redWidget,start=(10,10),end=(10,40))

      self.delayDisplay('Change Window')
      self.clickAndDrag(redWidget,start=(10,10),end=(40,10))

      self.delayDisplay('Change Layout')
      layoutManager = slicer.app.layoutManager()
      layoutManager.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutOneUpRedSliceView)

      self.delayDisplay('Zoom')
      self.clickAndDrag(redWidget,button='Right',start=(10,10),end=(10,40))

      self.delayDisplay('Pan')
      self.clickAndDrag(redWidget,button='Middle',start=(10,10),end=(40,40))

      self.delayDisplay('Center')
      redWidget.sliceController().fitSliceToBackground()

      self.delayDisplay('Lightbox')
      redWidget.sliceController().setLightboxTo6x6()

      self.delayDisplay('Conventional Layout')
      layoutManager.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutConventionalView)

      self.delayDisplay('No Lightbox')
      redWidget.sliceController().setLightboxTo1x1()

      self.delayDisplay('Four Up Layout')
      layoutManager.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutFourUpView)

      self.delayDisplay('Shift Mouse')
      self.clickAndDrag(redWidget,button='None',start=(100,100),end=(140,140),modifiers=['Shift'])

      self.delayDisplay('Conventional, Link, Slice Model')
      layoutManager.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutConventionalView)
      redWidget.sliceController().setSliceLink(True)
      redWidget.sliceController().setSliceVisible(True);

      self.delayDisplay('Rotate')
      threeDView = layoutManager.threeDWidget(0).threeDView()
      self.clickAndDrag(threeDView)

      self.delayDisplay('Zoom')
      threeDView = layoutManager.threeDWidget(0).threeDView()
      self.clickAndDrag(threeDView,button='Right')

      self.delayDisplay('Test passed!')
    except Exception, e:
      import traceback
      traceback.print_exc()
      self.delayDisplay('Test caused exception!\n' + str(e))
  def ImportStudy(self,dicomDataDir):
    indexer = ctk.ctkDICOMIndexer()

    # Import study to database
    indexer.addDirectory( slicer.dicomDatabase, dicomDataDir )
    indexer.waitForImportFinished()
def DoIt(inputDir, labelFile, outputDir, forceLabel, forceResample):

  dbDir1 = slicer.app.temporaryPath+'/LabelConverter'

  if not hasattr(slicer.modules, 'reporting'):
    print 'The Reporting module has not been loaded into Slicer, script cannot run!\n\tTry setting the --additional-module-path parameter.'
    sys.exit(1)

  reportingLogic = slicer.modules.reporting.logic()

  print('Temporary directory location: '+dbDir1)
  qt.QDir().mkpath(dbDir1)

  dbDir0 = None
  if slicer.dicomDatabase:
    dbDir0 = os.path.split(slicer.dicomDatabase.databaseFilename)[0]

  dicomWidget = slicer.modules.dicom.widgetRepresentation().self()
  dicomWidget.onDatabaseDirectoryChanged(dbDir1)

  # import DICOM study
  indexer = ctk.ctkDICOMIndexer()
  indexer.addDirectory(slicer.dicomDatabase, inputDir, None)
  indexer.waitForImportFinished()

  print('DICOM import finished!')

  #
  # Read the input DICOM series as a volume
  #
  dcmList = []
  for dcm in os.listdir(inputDir):
    if len(dcm)-dcm.rfind('.dcm') == 4:
      dcmList.append(inputDir+'/'+dcm)

  scalarVolumePlugin = slicer.modules.dicomPlugins['DICOMScalarVolumePlugin']()

  loadables = scalarVolumePlugin.examine([dcmList])

  if len(loadables) == 0:
    print 'Could not parse the DICOM Study!'
    sys.exit(1)

  inputVolume = scalarVolumePlugin.load(loadables[0])
  print 'Input volume loaded! ID = ', inputVolume.GetID()

  # read the label volume
  labelVolume = slicer.vtkMRMLLabelMapVolumeNode()
  sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
  sNode.SetFileName(labelFile)
  sNode.ReadData(labelVolume)

  if forceLabel>0:
    # print('Forcing label to '+str(forceLabel))
    labelImage = labelVolume.GetImageData()
    thresh = vtk.vtkImageThreshold()
    if vtk.vtkVersion().GetVTKMajorVersion() < 6:
      thresh.SetInput(labelImage)
    else:
      thresh.SetInputData(labelImage)
      thresh.ThresholdBetween(1, labelImage.GetScalarRange()[1])
      thresh.SetInValue(int(forceLabel))
      thresh.SetOutValue(0)
      thresh.ReplaceInOn()
      thresh.ReplaceOutOn()
      thresh.Update()
      labelImage = thresh.GetOutput()
      labelVolume.SetAndObserveImageData(labelImage)

  slicer.mrmlScene.AddNode(labelVolume)
  print 'Label volume added, id = ', labelVolume.GetID()

  # ensure that the label volume scalar type is unsigned short
  if labelVolume.GetImageData() != None:
    scalarType = labelVolume.GetImageData().GetScalarType()
    if scalarType != vtk.VTK_UNSIGNED_SHORT:
      print 'Label volume has pixel type of ',vtk.vtkImageScalarTypeNameMacro(scalarType),', casting to unsigned short'
      cast = vtk.vtkImageCast()
      cast.SetOutputScalarTypeToUnsignedShort()
      if vtk.vtkVersion().GetVTKMajorVersion() < 6:
        cast.SetInput(labelVolume.GetImageData())
        cast.Update()
        labelVolume.SetAndObserveImageData(cast.GetOutput())
      else:
        cast.SetInputConnection(labelVolume.GetImageDataConnection())
        cast.Update()
        labelVolume.SetImageDataConnection(cast.GetOutputPort())
      if labelVolume.GetImageData().GetScalarType() != vtk.VTK_UNSIGNED_SHORT:
        print 'Failed to cast label volume to unsigned short, type is ',  vtk.vtkImageScalarTypeNameMacro(labelVolume.GetImageData().GetScalarType())
        sys.exit(1)

  volumesLogic = slicer.modules.volumes.logic()
  geometryCheckString = volumesLogic.CheckForLabelVolumeValidity(inputVolume, labelVolume)
  if geometryCheckString != "":
    # has the user specified that forced resampling is okay?
    if forceResample == False:
      print 'Label volume mismatch with input volume:\n',geometryCheckString,'\nForced resample not specified, aborting. Re-run with --force option to ignore geometric inconsistencies'
      sys.exit(1)
    # resample label to the input volume raster
    resampledLabel = slicer.vtkMRMLLabelMapVolumeNode()
    slicer.mrmlScene.AddNode(resampledLabel)
    print 'Resampled label added, id = ', resampledLabel.GetID()
    resampledLabel = volumesLogic.ResampleVolumeToReferenceVolume(labelVolume, inputVolume)
    labelVolume = resampledLabel

  displayNode = slicer.vtkMRMLLabelMapVolumeDisplayNode()
  displayNode.SetAndObserveColorNodeID(reportingLogic.GetDefaultColorNode().GetID())
  slicer.mrmlScene.AddNode(displayNode)

  labelVolume.SetAttribute('AssociatedNodeID',inputVolume.GetID())
  labelVolume.SetAndObserveDisplayNodeID(displayNode.GetID())

  # initialize the DICOM DB for Reporting logic, save as DICOM SEG
  labelCollection = vtk.vtkCollection()
  labelCollection.AddItem(labelVolume)

  print('About to write DICOM SEG!')
  dbFileName = slicer.dicomDatabase.databaseFilename
  reportingLogic.InitializeDICOMDatabase(dbFileName)
  reportingLogic.DicomSegWrite(labelCollection, outputDir)

  dicomWidget.onDatabaseDirectoryChanged(dbDir0)

  exit()
def DoIt(inputDir, labelFile, outputDir, forceLabel):

  dbDir1 = slicer.app.temporaryPath+'/LabelConverter'
  reportingLogic = slicer.modules.reporting.logic()

  print('Temporary directory location: '+dbDir1)
  qt.QDir().mkpath(dbDir1)

  dbDir0 = None
  if slicer.dicomDatabase:
    dbDir0 = os.path.split(slicer.dicomDatabase.databaseFilename)[0]

  try:
    dicomWidget = slicer.modules.dicom.widgetRepresentation().self()
    dicomWidget.onDatabaseDirectoryChanged(dbDir1)
    
    # import DICOM study
    indexer = ctk.ctkDICOMIndexer()
    indexer.addDirectory(slicer.dicomDatabase, inputDir, None)
    indexer.waitForImportFinished()

    print('DICOM import finished!')

    #
    # Read the input DICOM series as a volume
    # 
    dcmList = []
    for dcm in os.listdir(inputDir):
      if len(dcm)-dcm.rfind('.dcm') == 4:
        dcmList.append(inputDir+'/'+dcm)

    scalarVolumePlugin = slicer.modules.dicomPlugins['DICOMScalarVolumePlugin']()

    loadables = scalarVolumePlugin.examine([dcmList])

    if len(loadables) == 0:
      print 'Could not parse the DICOM Study!'
      exit()
  
    inputVolume = scalarVolumePlugin.load(loadables[0])
    slicer.mrmlScene.AddNode(inputVolume)
    print('Input volume loaded!')

    # read the label volume
    labelVolume = slicer.vtkMRMLScalarVolumeNode()
    sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
    sNode.SetFileName(labelFile)
    sNode.ReadData(labelVolume)
    labelVolume.LabelMapOn()

    if forceLabel>0:
      print('Forcing label to '+str(forceLabel))
      labelImage = labelVolume.GetImageData()
      thresh = vtk.vtkImageThreshold()
      thresh.SetInput(labelImage)
      thresh.ThresholdBetween(1, labelImage.GetScalarRange()[1])
      thresh.SetInValue(int(forceLabel))
      thresh.SetOutValue(0)
      thresh.ReplaceInOn()
      thresh.ReplaceOutOn()
      thresh.Update()
      labelImage = thresh.GetOutput()
      labelVolume.SetAndObserveImageData(labelImage)

    slicer.mrmlScene.AddNode(labelVolume)
    
    # resample label to the input volume raster
    resampledLabel = slicer.vtkMRMLScalarVolumeNode()
    slicer.mrmlScene.AddNode(resampledLabel)
    eye = slicer.vtkMRMLLinearTransformNode()
    slicer.mrmlScene.AddNode(eye)
    parameters = {}
    parameters['inputVolume'] = labelVolume.GetID()
    parameters['referenceVolume'] = inputVolume.GetID()
    parameters['outputVolume'] = resampledLabel.GetID()
    parameters['warpTransform'] = eye.GetID()
    parameters['interpolationMode'] = 'NearestNeighbor'
    parameters['pixelType'] = 'ushort'
    cliNode = None
    cliNode = slicer.cli.run(slicer.modules.brainsresample, None, parameters, 1)
    labelVolume = resampledLabel

    displayNode = slicer.vtkMRMLLabelMapVolumeDisplayNode()
    displayNode.SetAndObserveColorNodeID(reportingLogic.GetDefaultColorNode().GetID())
    slicer.mrmlScene.AddNode(displayNode)

    labelVolume.SetAttribute('AssociatedNodeID',inputVolume.GetID())
    labelVolume.LabelMapOn()
    labelVolume.SetAndObserveDisplayNodeID(displayNode.GetID())
    
    # initialize the DICOM DB for Reporting logic, save as DICOM SEG
    labelCollection = vtk.vtkCollection()
    labelCollection.AddItem(labelVolume)

    print('About to write DICOM SEG!')
    dbFileName = slicer.dicomDatabase.databaseFilename
    reportingLogic.InitializeDICOMDatabase(dbFileName)
    reportingLogic.DicomSegWrite(labelCollection, outputDir)
  except:
    print('Error occurred!')

  dicomWidget.onDatabaseDirectoryChanged(dbDir0)

  exit()
  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.assertTrue( numOfFilesInDicomDataDirTest == self.expectedNumOfFilesInDicomDataDir )

      # Open test database and empty it
      qt.QDir().mkpath(self.dicomDatabaseDir)

      if slicer.dicomDatabase:
        self.originalDatabaseDirectory = os.path.split(slicer.dicomDatabase.databaseFilename)[0]
      else:
        self.originalDatabaseDirectory = None
        settings = qt.QSettings()
        settings.setValue('DatabaseDirectory', self.dicomDatabaseDir)

      dicomWidget = slicer.modules.dicom.widgetRepresentation().self()
      dicomWidget.onDatabaseDirectoryChanged(self.dicomDatabaseDir)
      self.assertTrue( slicer.dicomDatabase.isOpen )

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

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

      self.assertTrue( len(slicer.dicomDatabase.patients()) == 1 )
      self.assertTrue( slicer.dicomDatabase.patients()[0] )

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

      patient = slicer.dicomDatabase.patients()[0]
      studies = slicer.dicomDatabase.studiesForPatient(patient)
      series = [slicer.dicomDatabase.seriesForStudy(study) for study in studies]
      seriesUIDs = [uid for uidList in series for uid in uidList]
      dicomWidget.detailsPopup.offerLoadables(seriesUIDs, 'SeriesUIDList')
      dicomWidget.detailsPopup.loadCheckedLoadables()

      self.assertTrue( len( slicer.util.getNodes('vtkMRMLScalarVolumeNode*') ) == numOfScalarVolumeNodesBeforeLoad + 1 )
      self.assertTrue( 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 importDICOM(self, dicomDatabase, dicomFilesDirectory):
   dicomWidget = slicer.modules.dicom.widgetRepresentation().self()
   indexer = ctk.ctkDICOMIndexer()
   indexer.addDirectory(dicomDatabase, dicomFilesDirectory, None)
   indexer.waitForImportFinished()
  def test_ReportingAIMRoundTrip(self):
    print("CTEST_FULL_OUTPUT")
    """ Load the data using DICOM module
    """
 
    import os
    self.delayDisplay("Starting the DICOM test")
    #
    # first, get the data - a zip file of dicom data
    #
    import urllib
    downloads = (
        ('http://slicer.kitware.com/midas3/download?items=10881', 'JANCT-CT.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')

    reportingTempDir = slicer.app.temporaryPath+'/Reporting'
    print('Temporary directory location: '+reportingTempDir)
    qt.QDir().mkpath(reportingTempDir)
    dicomFilesDirectory = reportingTempDir + '/dicomFiles'
    self.cleanupDir(dicomFilesDirectory)
    qt.QDir().mkpath(dicomFilesDirectory)
    slicer.app.applicationLogic().Unzip(filePath, dicomFilesDirectory)

    try:
      self.delayDisplay("Switching to temp database directory")
      tempDatabaseDirectory = reportingTempDir + '/tempDICOMDatbase'
      qt.QDir().mkpath(tempDatabaseDirectory)
      self.cleanupDir(tempDatabaseDirectory)
      if slicer.dicomDatabase:
        self.originalDatabaseDirectory = os.path.split(slicer.dicomDatabase.databaseFilename)[0]
      else:
        self.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')
      #dicomWidget.dicomApp.suspendModel()
      indexer = ctk.ctkDICOMIndexer()
      indexer.addDirectory(slicer.dicomDatabase, dicomFilesDirectory, None)
      indexer.waitForImportFinished()

      patient = slicer.dicomDatabase.patients()[0]
      studies = slicer.dicomDatabase.studiesForPatient(patient)
      series = [slicer.dicomDatabase.seriesForStudy(study) for study in studies]
      seriesUIDs = [uid for uidList in series for uid in uidList]
      dicomWidget.detailsPopup.offerLoadables(seriesUIDs, 'SeriesUIDList')
      dicomWidget.detailsPopup.examineForLoading()

      loadablesByPlugin = dicomWidget.detailsPopup.loadablesByPlugin

      self.delayDisplay('Loading Selection')
      dicomWidget.detailsPopup.loadCheckedLoadables()

      # initialize the module with the report and volume
      
      volumes = slicer.util.getNodes('vtkMRMLScalarVolumeNode*')
      self.assertTrue(len(volumes) == 1)

      (name,volume) = volumes.items()[0]
      self.delayDisplay('Loaded volume name %s' % volume.GetName())

      self.delayDisplay('Configure Module')
      mainWindow = slicer.util.mainWindow()
      mainWindow.moduleSelector().selectModule('Reporting')
  
      reporting = slicer.modules.reporting.widgetRepresentation().self()

      report = slicer.mrmlScene.CreateNodeByClass('vtkMRMLReportingReportNode')
      report.SetReferenceCount(report.GetReferenceCount()-1)
      slicer.mrmlScene.AddNode(report)
      report.SetFindingLabel(7)
  
      reporting.reportSelector.setCurrentNode(report)
      self.delayDisplay('Setting volume to %s' % volume.GetName())
      reporting.volumeSelector.setCurrentNode(volume)
      slicer.app.processEvents()

      # place some markups and add a segmentation label

      # add fiducial
      fidNode = slicer.vtkMRMLAnnotationFiducialNode()
      fidName = "AIM Round Trip Test Fiducial"
      fidNode.SetName(fidName)
      fidNode.SetSelected(1)
      fidNode.SetDisplayVisibility(1)
      fidNode.SetLocked(0)
      # TODO: ask Nicole where this is assigned in the regular workflow
      fidNode.SetAttribute('AssociatedNodeID',volume.GetID())
      print("Calling set fid coords")
      startCoords = [15.8, 70.8, -126.7]    
      fidNode.SetFiducialCoordinates(startCoords[0],startCoords[1],startCoords[2])
      print("Starting fiducial coordinates: "+str(startCoords))
      slicer.mrmlScene.AddNode(fidNode)
  
      # add ruler
      rulerNode = slicer.vtkMRMLAnnotationRulerNode()
      rulerNode.SetName('Test Ruler')
      m = vtk.vtkMatrix4x4()
      volume.GetIJKToRASMatrix(m)
      ijk0 = [0,0,1,1]
      ijk1 = [50,50,1,1]
      ras0 = m.MultiplyPoint(ijk0)
      ras1 = m.MultiplyPoint(ijk1)
      rulerNode.SetPosition1(19.386751174926758, 68.528785705566406, -127.69000244140625)
      rulerNode.SetPosition2(132.72709655761719, -34.349384307861328, -127.69000244140625)
      rulerNode.SetAttribute('AssociatedNodeID',volume.GetID())
      slicer.mrmlScene.AddNode(rulerNode)
      slicer.app.processEvents()

      # add label node
      volumesLogic = slicer.modules.volumes.logic()
      labelNode = volumesLogic.CreateAndAddLabelVolume(slicer.mrmlScene, volume, "Segmentation")
      labelDisplayNode = labelNode.GetDisplayNode()
      labelDisplayNode.SetAndObserveColorNodeID('vtkMRMLColorTableNodeFileGenericAnatomyColors.txt')
      image = volume.GetImageData()
      thresh = vtk.vtkImageThreshold()
      if vtk.vtkVersion().GetVTKMajorVersion() < 6:
        thresh.SetInput(image)
      else:
        thresh.SetInputData(image)
      thresh.ThresholdBetween(10,400)
      thresh.SetInValue(report.GetFindingLabel())
      thresh.SetOutValue(0)
      thresh.Update()
      labelNode.SetAndObserveImageData(thresh.GetOutput())
      reporting.segmentationSelector.setCurrentNode(labelNode)

      # Save the report

      exportDir = reportingTempDir+'/Output'
      qt.QDir().mkpath(exportDir)
      self.cleanupDir(exportDir)
      report.SetStorageDirectoryName(exportDir)
      reportingLogic = slicer.modules.reporting.logic()
      print("Before saving report")
      reportingLogic.SaveReportToAIM(report)

      self.delayDisplay('Report saved')
      
      slicer.mrmlScene.Clear(0)


      # parse on patient level, find segmentation object, load and make sure
      # it matches the input
      # close the scene and load the report, check consistency

      # try to load back the saved AIM
      import glob
      print glob.glob(exportDir+'/*')      
      xmlFiles = glob.glob(exportDir+'/*xml')
      print xmlFiles

      self.assertTrue(len(xmlFiles) == 1)
      reporting.importAIMFile = xmlFiles[0]
      reporting.onReportImport()

      self.delayDisplay('Report loaded from AIM! Test passed.')
      
      self.delayDisplay("Restoring original database directory")
      if self.originalDatabaseDirectory:
        dicomWidget.onDatabaseDirectoryChanged(self.originalDatabaseDirectory)

    except Exception, e:
      if self.originalDatabaseDirectory:
        dicomWidget.onDatabaseDirectoryChanged(self.originalDatabaseDirectory)
      import traceback
      traceback.print_exc()
      self.delayDisplay('Test caused exception!\n' + str(e))
      self.assertTrue(False)
Example #30
0
    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.assertTrue(numOfFilesInDicomDataDirTest ==
                            self.expectedNumOfFilesInDicomDataDir)

            # Open test database and empty it
            qt.QDir().mkpath(self.dicomDatabaseDir)

            if slicer.dicomDatabase:
                self.originalDatabaseDirectory = os.path.split(
                    slicer.dicomDatabase.databaseFilename)[0]
            else:
                self.originalDatabaseDirectory = None
                settings = qt.QSettings()
                settings.setValue('DatabaseDirectory', self.dicomDatabaseDir)

            dicomWidget = slicer.modules.dicom.widgetRepresentation().self()
            dicomWidget.onDatabaseDirectoryChanged(self.dicomDatabaseDir)
            self.assertTrue(slicer.dicomDatabase.isOpen)

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

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

            self.assertTrue(len(slicer.dicomDatabase.patients()) == 1)
            self.assertTrue(slicer.dicomDatabase.patients()[0])

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

            patient = slicer.dicomDatabase.patients()[0]
            studies = slicer.dicomDatabase.studiesForPatient(patient)
            series = [
                slicer.dicomDatabase.seriesForStudy(study) for study in studies
            ]
            seriesUIDs = [uid for uidList in series for uid in uidList]
            dicomWidget.detailsPopup.offerLoadables(seriesUIDs,
                                                    'SeriesUIDList')
            dicomWidget.detailsPopup.loadCheckedLoadables()

            self.assertTrue(
                len(slicer.util.getNodes('vtkMRMLScalarVolumeNode*')) ==
                numOfScalarVolumeNodesBeforeLoad + 1)
            self.assertTrue(
                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)
Example #31
0
 def onHButtonClicked(self):
   i = ctk.ctkDICOMIndexer()
   i.addDirectory(slicer.dicomDatabase, '/Users/Research/Documents/DICOM Files/TAC MONSERRAT')
   m = slicer.util.mainWindow()
   m.moduleSelector().selectModule('DICOM')