示例#1
0
 def onSaveButtonClicked(self):
   bundle = EditUtil.EditUtil().getParameterNode().GetParameter('QuickTCGAEffect,erich')
   tran = json.loads(bundle)
   layers = []
   for key in tran:
     nn = tran[key]
     nn["file"] = key + '.tif'
     layers.append(tran[key])
   j = {}
   j['layers'] = layers
   j['username'] = self.setupUserName.text
   j['sourcetile'] = self.tilename
   j['generator'] = "3DSlicer-4.5.0 with SlicerPathology v1.0a"
   j['timestamp'] = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
   labelNodes = slicer.util.getNodes('vtkMRMLLabelMapVolumeNode*')
   savedMessage = 'Segmentations for the following series were saved:\n\n'
   for label in labelNodes.values():
     labelName = label.GetName()
     labelFileName = os.path.join(self.dataDirButton.directory, labelName + '.tif')
     print "labelFileName : "+labelFileName
     sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
     sNode.SetFileName(labelFileName)
     sNode.SetWriteFileFormat('tif')
     sNode.SetURI(None)
     success = sNode.WriteData(label)
     if success:
       print "successful writing "+labelFileName
     else:
       print "failed writing "+labelFileName
   jstr = json.dumps(j,sort_keys=True, indent=4, separators=(',', ': '))
   f = open(os.path.join(self.dataDirButton.directory, self.tilename + '.json'),'w')
   f.write(jstr)
   f.close()
示例#2
0
 def readFrame(self, file):
     sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
     sNode.ResetFileNameList()
     sNode.SetFileName(file)
     sNode.SetSingleFile(0)
     frame = slicer.vtkMRMLScalarVolumeNode()
     success = sNode.ReadData(frame)
     return (success, frame)
 def readFrame(self, file):
     sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
     sNode.ResetFileNameList()
     sNode.SetFileName(file)
     sNode.SetSingleFile(1)
     frame = slicer.vtkMRMLScalarVolumeNode()
     sNode.ReadData(frame)
     return frame
示例#4
0
    def loadFilesWithArchetype(self, files, name):
        """Load files in the traditional Slicer manner
    using the volume logic helper class
    and the vtkITK archetype helper code
    """
        sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
        vNode = slicer.vtkMRMLScalarVolumeNode()
        sNode.SetFileName(files[0])
        sNode.ResetFileNameList()
        for f in files:
            sNode.AddFileName(f)
        sNode.SetSingleFile(0)
        res = sNode.ReadData(vNode)

        if res == 1:
            vNode.SetScene(slicer.mrmlScene)
            vNode.SetName(name)
            slicer.mrmlScene.AddNode(vNode)
        else:
            vNode = None

        return vNode
示例#5
0
    def loadFilesWithArchetype(self, files, name):
        """Load files in the traditional Slicer manner
    using the volume logic helper class
    and the vtkITK archetype helper code
    """
        sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
        vNode = slicer.vtkMRMLScalarVolumeNode()
        sNode.SetFileName(files[0])
        sNode.ResetFileNameList()
        for f in files:
            sNode.AddFileName(f)
        sNode.SetSingleFile(0)
        res = sNode.ReadData(vNode)

        if res == 1:
            vNode.SetScene(slicer.mrmlScene)
            vNode.SetName(name)
            slicer.mrmlScene.AddNode(vNode)
        else:
            vNode = None

        return vNode
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()
示例#7
0
  def load(self,loadable):
    """Load the selection as a MultiVolume, if multivolume attribute is
    present
    """

    mvNode = ''
    try:
      mvNode = loadable.multivolume
    except AttributeError:
      return

    nFrames = int(mvNode.GetAttribute('MultiVolume.NumberOfFrames'))
    files = string.split(mvNode.GetAttribute('MultiVolume.FrameFileList'),',')
    nFiles = len(files)
    filesPerFrame = nFiles/nFrames
    frames = []
    
    mvImage = vtk.vtkImageData()
    mvImageArray = None

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

    # read each frame into scalar volume
    for frameNumber in range(nFrames):
      
      sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
      sNode.ResetFileNameList();

      frameFileList = files[frameNumber*filesPerFrame:(frameNumber+1)*filesPerFrame]
      # sv plugin will sort the filenames by geometric order
      svLoadables = scalarVolumePlugin.examine([frameFileList])

      if len(svLoadables) == 0:
        return
      for f in svLoadables[0].files:
        sNode.AddFileName(f)

      sNode.SetFileName(frameFileList[0]) # only used when num files/frame = 1
      sNode.SetSingleFile(0)
      frame = slicer.vtkMRMLScalarVolumeNode()
      sNode.ReadData(frame)

      if frame == None:
        print('Failed to read a multivolume frame!')
        return False

      if frameNumber == 0:
        frameImage = frame.GetImageData()
        frameExtent = frameImage.GetExtent()
        frameSize = frameExtent[1]*frameExtent[3]*frameExtent[5]

        mvImage.SetExtent(frameExtent)
        mvImage.SetNumberOfScalarComponents(nFrames)

        mvImage.AllocateScalars()
        mvImageArray = vtk.util.numpy_support.vtk_to_numpy(mvImage.GetPointData().GetScalars())

        mvNode.SetScene(slicer.mrmlScene)

        mat = vtk.vtkMatrix4x4()
        frame.GetRASToIJKMatrix(mat)
        mvNode.SetRASToIJKMatrix(mat)
        frame.GetIJKToRASMatrix(mat)
        mvNode.SetIJKToRASMatrix(mat)

      frameImage = frame.GetImageData()
      frameImageArray = vtk.util.numpy_support.vtk_to_numpy(frameImage.GetPointData().GetScalars())

      mvImageArray.T[frameNumber] = frameImageArray

    mvDisplayNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLMultiVolumeDisplayNode')
    mvDisplayNode.SetReferenceCount(mvDisplayNode.GetReferenceCount()-1)
    mvDisplayNode.SetScene(slicer.mrmlScene)
    mvDisplayNode.SetDefaultColorMap()
    slicer.mrmlScene.AddNode(mvDisplayNode)

    mvNode.SetAndObserveDisplayNodeID(mvDisplayNode.GetID())
    mvNode.SetAndObserveImageData(mvImage)
    mvNode.SetNumberOfFrames(nFrames)
    slicer.mrmlScene.AddNode(mvNode)

    return True
  def LoadAIMFile(newReportID, fileName):
    dom = xml.dom.minidom.parse(fileName)

    SlicerReportingModuleWidgetHelper.Debug('Parsed AIM report:')
    SlicerReportingModuleWidgetHelper.Debug(dom.toxml())

    volumeList = []

    ddb = slicer.dicomDatabase
    volId = 1
    volume = None
  
    # get the annotation element and retrieve its name
    annotations = dom.getElementsByTagName('ImageAnnotation')
    if len(annotations) == 0:
      SlicerReportingModuleWidgetHelper.ErrorPopup('AIM file does not contain any annotations!')
      return
    ann = annotations[0]
    desc = ann.getAttribute('name')

    # get the anatomic entity element and initialize the report node based on
    # it
    anatomics = dom.getElementsByTagName('AnatomicEntity')
    if len(anatomics) != 1:
      SlicerReportingModuleWidgetHelper.ErrorPopup('AIM file does not contain any anatomic entities or contains more than one! This is not supported.')
      return
    anatomy = anatomics[0]

    labelValue = anatomy.getAttribute('codeValue')
    labelName = anatomy.getAttribute('codeMeaning')
    codingSchemeDesignator = anatomy.getAttribute('codingSchemeDesignator')
    if codingSchemeDesignator != '3DSlicer':
      SlicerReportingModuleWidgetHelper.WarningPopup('Code scheme designator '+codingSchemeDesignator+' is not supported. Default will be used instead.')
      labelValue = "1"

    newReport = slicer.mrmlScene.GetNodeByID(newReportID)
    newReport.SetFindingLabel(int(labelValue))


    # pull all the volumes that are referenced into the scene
    for node in dom.getElementsByTagName('ImageSeries'):
      instanceUID = node.getAttribute('instanceUID')
      filelist = ddb.filesForSeries(instanceUID)

      scalarVolumePlugin = slicer.modules.dicomPlugins['DICOMScalarVolumePlugin']()
      scalarVolumeLoadables = scalarVolumePlugin.examine([filelist])
      if len(scalarVolumeLoadables) == 0:
        SlicerReportingModuleWidgetHelper.ErrorPopup('Error loading AIM: Failed to load the volume node reference in the file')
     
      volumeName = scalarVolumeLoadables[0].name
      newReport.SetName('Report for Volume '+volumeName)

      volume = scalarVolumePlugin.load(scalarVolumeLoadables[0])
      volume.SetName(volumeName)

      if volume == None:
        SlicerReportingModuleWidgetHelper.Error('Failed to read series!')
        return

      if len(volumeList) != 0:
        SlicerReportingModuleWidgetHelper.ErrorPopup('Error importing AIM report: Report references more than one volume, which is not allowed!')
        return

      volumeList.append(volume)
      SlicerReportingModuleWidgetHelper.Debug('Volume read from AIM report:')

      slicer.modules.reporting.logic().AddVolumeToReport(volume)
      newReport.SetVolumeNodeID(volume.GetID())

    if len(volumeList) > 1:
      SlicerReportingModuleWidgetHelper.ErrorPopup('AIM does not allow to have more than one volume per file!')
      return

    if len(volumeList) == 0:
      SlicerReportingModuleWidgetHelper.ErrorPopup('AIM file you requested to load does not reference any volumes, cannot process it!')
      return

    #if volume != None:
    #  self.__volumeSelector.setCurrentNode(volume)

    instanceUIDs = volume.GetAttribute('DICOM.instanceUIDs')
    instanceUIDList = instanceUIDs.split()

    # AF: GeometricShape is inside geometricShapeCollection, but
    # there's no need to parse at that level, I think 
    # 
    # geometricShapeCollection
    #  |
    #  +-spatialCoordinateCollection
    #     |
    #     +-SpatialCoordinate
    #

    for node in dom.getElementsByTagName('GeometricShape'):

      ijCoordList = []
      rasPointList = []
      uidList = []
      elementType = node.getAttribute('xsi:type')
 
      for child in node.childNodes:
        if child.nodeName == 'spatialCoordinateCollection':
          for coord in child.childNodes:
            if coord.nodeName == 'SpatialCoordinate':
              ijCoordList.append(float(coord.getAttribute('x')))
              ijCoordList.append(float(coord.getAttribute('y')))
              uid = coord.getAttribute('imageReferenceUID')
              uidList.append(uid)
   
      SlicerReportingModuleWidgetHelper.Debug('Coordinate list: '+str(ijCoordList))

      ijk2ras = vtk.vtkMatrix4x4()
      volume.GetIJKToRASMatrix(ijk2ras)


      # convert each point from IJ to RAS
      for ij in range(len(uidList)):
        pointUID = uidList[ij]
        # locate the UID in the list assigned to the volume
        totalSlices = len(instanceUIDList)
        for k in range(len(instanceUIDList)):
          if pointUID == instanceUIDList[k]:
            break

        # print "k = ",k,", totalSlices = ",totalSlices 
        pointIJK = [ijCoordList[ij*2], ijCoordList[ij*2+1], k, 1.]
        pointRAS = ijk2ras.MultiplyPoint(pointIJK)
        SlicerReportingModuleWidgetHelper.Debug('Input point: '+str(pointIJK))
        SlicerReportingModuleWidgetHelper.Debug('Converted point: '+str(pointRAS))
        rasPointList.append(pointRAS[0:3])

      # instantiate the markup elements
      if elementType == 'Point':
        SlicerReportingModuleWidgetHelper.Debug("Importing a fiducial!")
        if len(ijCoordList) != 2:
          SlicerReportingModuleWidgetHelper.Error('Number of coordinates not good for a fiducial')
          return

        fiducial = slicer.mrmlScene.CreateNodeByClass('vtkMRMLAnnotationFiducialNode')
        fiducial.SetReferenceCount(fiducial.GetReferenceCount()-1)
        # associate it with the report
        fiducial.SetAttribute('ReportingReportNodeID', newReport.GetID())
        # associate it with the volume
        fiducial.SetAttribute('AssociatedNodeID', volume.GetID())
        # ??? Why the API is so inconsistent -- there's no SetPosition1() ???
        fiducial.SetFiducialCoordinates(rasPointList[0])
        fiducial.Initialize(slicer.mrmlScene)
        # adding to hierarchy is handled by the Reporting logic

      if elementType == 'MultiPoint':
        SlicerReportingModuleWidgetHelper.Debug("Importing a ruler!")
        if len(ijCoordList) != 4:
          SlicerReportingModuleWidgetHelper.Error('Number of coordinates not good for a ruler')
          return

        ruler = slicer.mrmlScene.CreateNodeByClass('vtkMRMLAnnotationRulerNode')
        ruler.SetReferenceCount(ruler.GetReferenceCount()-1)
        # associate it with the report
        ruler.SetAttribute('ReportingReportNodeID', newReport.GetID())
        # associate it with the volume
        ruler.SetAttribute('AssociatedNodeID', volume.GetID())
        SlicerReportingModuleWidgetHelper.Debug('Initializing with points '+str(rasPointList[0])+' and '+str(rasPointList[1]))
        ruler.SetPosition1(rasPointList[0])
        ruler.SetPosition2(rasPointList[1])
        ruler.Initialize(slicer.mrmlScene)
        # AF: Initialize() adds to the scene ...

    for node in dom.getElementsByTagName('Segmentation'):
      # read all labels that are available in the SEG object
      # check if the referenced volume is already in the scene
      #   if not, load it
      # initialize AssociatedNodeID for the label node to point to the
      # reference
      SlicerReportingModuleWidgetHelper.Debug('Importing a segmentation')
      labelNodes = vtk.vtkCollection()
      referenceNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLScalarVolumeNode')
      referenceNode.SetReferenceCount(referenceNode.GetReferenceCount()-1)

      uid = node.getAttribute('sopInstanceUID')

      res = False
      colorNode = slicer.mrmlScene.GetNodeByID(newReport.GetColorNodeID())
      res = slicer.modules.reporting.logic().DicomSegRead(labelNodes, uid, colorNode)
      SlicerReportingModuleWidgetHelper.Debug('Read this many labels from the seg object:'+str(labelNodes.GetNumberOfItems()))

      if labelNodes.GetNumberOfItems() == 0:
        print("Error loading segmentation object, have 0 labels")
      else:
        # read the reference node
        label0 = labelNodes.GetItemAsObject(0)

        referenceUIDs = label0.GetAttribute('DICOM.referenceInstanceUIDs')
        SlicerReportingModuleWidgetHelper.Debug('Seg object reference uids: '+referenceUIDs)

      for i in range(labelNodes.GetNumberOfItems()):
        displayNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLLabelMapVolumeDisplayNode')
        displayNode.SetReferenceCount(displayNode.GetReferenceCount()-1)
        displayNode.SetAndObserveColorNodeID(newReport.GetColorNodeID())
        slicer.mrmlScene.AddNode(displayNode)
        labelNode = labelNodes.GetItemAsObject(i)
        labelNode.SetAttribute('ReportingReportNodeID', newReport.GetID())
        labelNode.SetAttribute('AssociatedNodeID', volumeList[0].GetID())
        labelNode.SetAndObserveDisplayNodeID(displayNode.GetID())
        slicer.mrmlScene.AddNode(labelNode)

      # AF: this shuould not be necessary with the "proper" AIM input, since
      # only one volume should be present in the report, and only one item in
      # that volume should be annotated
      if 0:
      # if referenceUIDs != None:

        reader = slicer.vtkMRMLVolumeArchetypeStorageNode()
        reader.ResetFileNameList()

        for uid in string.split(referenceUIDs, ' '):

          fname = slicer.modules.reporting.logic().GetFileNameFromUID(uid)
          reader.AddFileName(fname)

        reader.SetFileName(string.split(referenceUIDs, ' ')[0])
        reader.SetSingleFile(0)
        
        referenceVolume = slicer.mrmlScene.CreateNodeByClass('vtkMRMLScalarVolumeNode')
        referenceVolumeUIDs = referenceVolume.GetAttribute('DICOM.instanceUIDs')
        reader.ReadData(referenceVolume)

        nodeToAdd = referenceVolume

        allVolumeNodes = slicer.mrmlScene.GetNodesByClass('vtkMRMLScalarVolumeNode')
        allVolumeNodes.SetReferenceCount(allVolumeNodes.GetReferenceCount()-1)
        for i in range(allVolumeNodes.GetNumberOfItems()):
          v = allVolumeNodes.GetItemAsObject(i)
          uids = v.GetAttribute('DICOM.instanceUIDs')
          if uids == referenceNodeUIDs:
            print('Referenced node is already in the scene!')
            nodeToAdd = None
            referenceNode = v
            break

        if nodeToAdd != None:
          slicer.mrmlScene.AddNode(nodeToAdd)

        slicer.modules.reporting.logic().AddVolumeToReport(referenceNode)

        for i in range(labelNodes.GetNumberOfItems()):
          displayNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLScalarVolumeDisplayNode')
          displayNode.SetReferenceCount(displayNode.GetReferenceCount()-1)
          displayNode.SetAndObserveColorNodeID(newReport.GetColorNodeID())
          slicer.mrmlScene.AddNode(displayNode)
          labelNode = labelNodes.GetItemAsObject(i)
          labelNode.SetAttribute('ReportingReportNodeID', newReport.GetID())
          labelNode.SetAttribute('AssociatedNodeID', referenceNode.GetID())
          labelNode.SetAndObserveDisplayNodeID(displayNode.GetID())
          slicer.mrmlScene.AddNode(labelNodes.GetItemAsObject(i))
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)
 def writeVolume(self,volume,name):
   path = slicer.app.temporaryPath + '/%s.nrrd' % name
   s = slicer.vtkMRMLVolumeArchetypeStorageNode()
   s.SetFileName(path)
   s.WriteData(volume)
   return path
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)
  def load(self,loadable):
    """Load the selection as a MultiVolume, if multivolume attribute is
    present
    """

    mvNode = ''
    try:
      mvNode = loadable.multivolume
    except AttributeError:
      return None

    nFrames = int(mvNode.GetAttribute('MultiVolume.NumberOfFrames'))
    files = string.split(mvNode.GetAttribute('MultiVolume.FrameFileList'),',')
    nFiles = len(files)
    filesPerFrame = nFiles/nFrames
    frames = []

    mvImage = vtk.vtkImageData()
    mvImageArray = None

    scalarVolumePlugin = slicer.modules.dicomPlugins['DICOMScalarVolumePlugin']()
    instanceUIDs = ""
    for file in files:
      uid = slicer.dicomDatabase.fileValue(file,self.tags['instanceUID'])
      if uid == "":
        uid = "Unknown"
      instanceUIDs += uid+" "
    instanceUIDs = instanceUIDs[:-1]
    mvNode.SetAttribute("DICOM.instanceUIDs", instanceUIDs)

    # read each frame into scalar volume
    for frameNumber in range(nFrames):

      sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
      sNode.ResetFileNameList();

      frameFileList = files[frameNumber*filesPerFrame:(frameNumber+1)*filesPerFrame]
      # sv plugin will sort the filenames by geometric order
      svLoadables = scalarVolumePlugin.examine([frameFileList])

      if len(svLoadables) == 0:
        return None
      for f in svLoadables[0].files:
        sNode.AddFileName(f)

      sNode.SetFileName(frameFileList[0]) # only used when num files/frame = 1
      sNode.SetSingleFile(0)
      frame = slicer.vtkMRMLScalarVolumeNode()
      sNode.ReadData(frame)

      if frame.GetImageData() == None:
        print('Failed to read a multivolume frame!')
        return None

      if frameNumber == 0:
        frameImage = frame.GetImageData()
        frameExtent = frameImage.GetExtent()
        frameSize = frameExtent[1]*frameExtent[3]*frameExtent[5]

        mvImage.SetExtent(frameExtent)
        if vtk.VTK_MAJOR_VERSION <= 5:
          mvImage.SetNumberOfScalarComponents(nFrames)
          mvImage.SetScalarType(frame.GetImageData().GetScalarType())
          mvImage.AllocateScalars()
        else:
          mvImage.AllocateScalars(frame.GetImageData().GetScalarType(), nFrames)

        mvImageArray = vtk.util.numpy_support.vtk_to_numpy(mvImage.GetPointData().GetScalars())

        mvNode.SetScene(slicer.mrmlScene)

        mat = vtk.vtkMatrix4x4()
        frame.GetRASToIJKMatrix(mat)
        mvNode.SetRASToIJKMatrix(mat)
        frame.GetIJKToRASMatrix(mat)
        mvNode.SetIJKToRASMatrix(mat)

      frameImage = frame.GetImageData()
      frameImageArray = vtk.util.numpy_support.vtk_to_numpy(frameImage.GetPointData().GetScalars())

      mvImageArray.T[frameNumber] = frameImageArray

    mvDisplayNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLMultiVolumeDisplayNode')
    mvDisplayNode.SetReferenceCount(mvDisplayNode.GetReferenceCount()-1)
    mvDisplayNode.SetScene(slicer.mrmlScene)
    mvDisplayNode.SetDefaultColorMap()
    slicer.mrmlScene.AddNode(mvDisplayNode)

    mvNode.SetAndObserveDisplayNodeID(mvDisplayNode.GetID())
    mvNode.SetAndObserveImageData(mvImage)
    mvNode.SetNumberOfFrames(nFrames)
    mvNode.SetName(loadable.name)
    slicer.mrmlScene.AddNode(mvNode)

    #
    # automatically select the volume to display
    #
    appLogic = slicer.app.applicationLogic()
    selNode = appLogic.GetSelectionNode()
    selNode.SetReferenceActiveVolumeID(mvNode.GetID())
    appLogic.PropagateVolumeSelection()

    # file list is no longer needed - remove the attribute
    mvNode.RemoveAttribute('MultiVolume.FrameFileList')

    return mvNode
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 writeVolume(self, volume, name):
     path = slicer.app.temporaryPath + '/%s.nrrd' % name
     s = slicer.vtkMRMLVolumeArchetypeStorageNode()
     s.SetFileName(path)
     s.WriteData(volume)
     return path
    def LoadAIMFile(newReportID, fileName):
        dom = xml.dom.minidom.parse(fileName)

        SlicerReportingModuleWidgetHelper.Debug('Parsed AIM report:')
        SlicerReportingModuleWidgetHelper.Debug(dom.toxml())

        volumeList = []

        ddb = slicer.dicomDatabase
        volId = 1
        volume = None

        # get the annotation element and retrieve its name
        annotations = dom.getElementsByTagName('ImageAnnotation')
        if len(annotations) == 0:
            SlicerReportingModuleWidgetHelper.ErrorPopup(
                'AIM file does not contain any annotations!')
            return
        ann = annotations[0]
        desc = ann.getAttribute('name')

        # get the anatomic entity element and initialize the report node based on
        # it
        anatomics = dom.getElementsByTagName('AnatomicEntity')
        if len(anatomics) != 1:
            SlicerReportingModuleWidgetHelper.ErrorPopup(
                'AIM file does not contain any anatomic entities or contains more than one! This is not supported.'
            )
            return
        anatomy = anatomics[0]

        labelValue = anatomy.getAttribute('codeValue')
        labelName = anatomy.getAttribute('codeMeaning')
        codeSchemeDesignator = anatomy.getAttribute('codeSchemeDesignator')
        if codeSchemeDesignator != '3DSlicer':
            SlicerReportingModuleWidgetHelper.WarningPopup(
                'Code scheme designator ' + codeSchemeDesignator +
                ' is not supported. Default will be used instead.')
            labelValue = "1"

        newReport = slicer.mrmlScene.GetNodeByID(newReportID)
        newReport.SetFindingLabel(int(labelValue))

        # pull all the volumes that are referenced into the scene
        for node in dom.getElementsByTagName('ImageSeries'):
            instanceUID = node.getAttribute('instanceUID')
            filelist = ddb.filesForSeries(instanceUID)

            scalarVolumePlugin = slicer.modules.dicomPlugins[
                'DICOMScalarVolumePlugin']()
            scalarVolumeLoadables = scalarVolumePlugin.examine([filelist])
            if len(scalarVolumeLoadables) == 0:
                SlicerReportingModuleWidgetHelper.ErrorPopup(
                    'Error loading AIM: Failed to load the volume node reference in the file'
                )

            volumeName = scalarVolumeLoadables[0].name
            newReport.SetName('Report for Volume ' + volumeName)

            volume = scalarVolumePlugin.load(scalarVolumeLoadables[0])
            volume.SetName(volumeName)

            if volume == None:
                SlicerReportingModuleWidgetHelper.Error(
                    'Failed to read series!')
                return

            if len(volumeList) != 0:
                SlicerReportingModuleWidgetHelper.ErrorPopup(
                    'Error importing AIM report: Report references more than one volume, which is not allowed!'
                )
                return

            volumeList.append(volume)
            SlicerReportingModuleWidgetHelper.Debug(
                'Volume read from AIM report:')

            slicer.modules.reporting.logic().InitializeHierarchyForVolume(
                volume)
            newReport.SetVolumeNodeID(volume.GetID())

        if len(volumeList) > 1:
            SlicerReportingModuleWidgetHelper.ErrorPopup(
                'AIM does not allow to have more than one volume per file!')
            return

        if len(volumeList) == 0:
            SlicerReportingModuleWidgetHelper.ErrorPopup(
                'AIM file you requested to load does not reference any volumes, cannot process it!'
            )
            return

        #if volume != None:
        #  self.__volumeSelector.setCurrentNode(volume)

        instanceUIDs = volume.GetAttribute('DICOM.instanceUIDs')
        instanceUIDList = instanceUIDs.split()

        # AF: GeometricShape is inside geometricShapeCollection, but
        # there's no need to parse at that level, I think
        #
        # geometricShapeCollection
        #  |
        #  +-spatialCoordinateCollection
        #     |
        #     +-SpatialCoordinate
        #

        for node in dom.getElementsByTagName('GeometricShape'):

            ijCoordList = []
            rasPointList = []
            uidList = []
            elementType = node.getAttribute('xsi:type')

            for child in node.childNodes:
                if child.nodeName == 'spatialCoordinateCollection':
                    for coord in child.childNodes:
                        if coord.nodeName == 'SpatialCoordinate':
                            ijCoordList.append(float(coord.getAttribute('x')))
                            ijCoordList.append(float(coord.getAttribute('y')))
                            uid = coord.getAttribute('imageReferenceUID')
                            uidList.append(uid)

            SlicerReportingModuleWidgetHelper.Debug('Coordinate list: ' +
                                                    str(ijCoordList))

            ijk2ras = vtk.vtkMatrix4x4()
            volume.GetIJKToRASMatrix(ijk2ras)

            # convert each point from IJ to RAS
            for ij in range(len(uidList)):
                pointUID = uidList[ij]
                # locate the UID in the list assigned to the volume
                totalSlices = len(instanceUIDList)
                for k in range(len(instanceUIDList)):
                    if pointUID == instanceUIDList[k]:
                        break

                # print "k = ",k,", totalSlices = ",totalSlices
                pointIJK = [
                    ijCoordList[ij * 2], ijCoordList[ij * 2 + 1], k, 1.
                ]
                pointRAS = ijk2ras.MultiplyPoint(pointIJK)
                SlicerReportingModuleWidgetHelper.Debug('Input point: ' +
                                                        str(pointIJK))
                SlicerReportingModuleWidgetHelper.Debug('Converted point: ' +
                                                        str(pointRAS))
                rasPointList.append(pointRAS[0:3])

            # instantiate the markup elements
            if elementType == 'Point':
                SlicerReportingModuleWidgetHelper.Debug(
                    "Importing a fiducial!")
                if len(ijCoordList) != 2:
                    SlicerReportingModuleWidgetHelper.Error(
                        'Number of coordinates not good for a fiducial')
                    return

                fiducial = slicer.mrmlScene.CreateNodeByClass(
                    'vtkMRMLAnnotationFiducialNode')
                fiducial.SetReferenceCount(fiducial.GetReferenceCount() - 1)
                # associate it with the volume
                fiducial.SetAttribute("AssociatedNodeID", volume.GetID())
                # ??? Why the API is so inconsistent -- there's no SetPosition1() ???
                fiducial.SetFiducialCoordinates(rasPointList[0])
                fiducial.Initialize(slicer.mrmlScene)
                # adding to hierarchy is handled by the Reporting logic

            if elementType == 'MultiPoint':
                SlicerReportingModuleWidgetHelper.Debug("Importing a ruler!")
                if len(ijCoordList) != 4:
                    SlicerReportingModuleWidgetHelper.Error(
                        'Number of coordinates not good for a ruler')
                    return

                ruler = slicer.mrmlScene.CreateNodeByClass(
                    'vtkMRMLAnnotationRulerNode')
                ruler.SetReferenceCount(ruler.GetReferenceCount() - 1)
                # associate it with the volume
                ruler.SetAttribute("AssociatedNodeID", volume.GetID())
                SlicerReportingModuleWidgetHelper.Debug(
                    'Initializing with points ' + str(rasPointList[0]) +
                    ' and ' + str(rasPointList[1]))
                ruler.SetPosition1(rasPointList[0])
                ruler.SetPosition2(rasPointList[1])
                ruler.Initialize(slicer.mrmlScene)
                # AF: Initialize() adds to the scene ...

        for node in dom.getElementsByTagName('Segmentation'):
            # read all labels that are available in the SEG object
            # check if the referenced volume is already in the scene
            #   if not, load it
            # initialize AssociatedNodeID for the label node to point to the
            # reference
            SlicerReportingModuleWidgetHelper.Debug('Importing a segmentation')
            labelNodes = vtk.vtkCollection()
            referenceNode = slicer.mrmlScene.CreateNodeByClass(
                'vtkMRMLScalarVolumeNode')
            referenceNode.SetReferenceCount(referenceNode.GetReferenceCount() -
                                            1)

            uid = node.getAttribute('sopInstanceUID')

            res = False
            colorNode = slicer.mrmlScene.GetNodeByID(
                newReport.GetColorNodeID())
            res = slicer.modules.reporting.logic().DicomSegRead(
                labelNodes, uid, colorNode)
            SlicerReportingModuleWidgetHelper.Debug(
                'Read this many labels from the seg object:' +
                str(labelNodes.GetNumberOfItems()))

            # read the reference node
            label0 = labelNodes.GetItemAsObject(0)

            referenceUIDs = label0.GetAttribute('DICOM.referenceInstanceUIDs')
            SlicerReportingModuleWidgetHelper.Debug(
                'Seg object reference uids: ' + referenceUIDs)

            for i in range(labelNodes.GetNumberOfItems()):
                displayNode = slicer.mrmlScene.CreateNodeByClass(
                    'vtkMRMLLabelMapVolumeDisplayNode')
                displayNode.SetReferenceCount(displayNode.GetReferenceCount() -
                                              1)
                displayNode.SetAndObserveColorNodeID(
                    newReport.GetColorNodeID())
                slicer.mrmlScene.AddNode(displayNode)
                labelNode = labelNodes.GetItemAsObject(i)
                labelNode.SetAttribute('AssociatedNodeID',
                                       volumeList[0].GetID())
                labelNode.SetAndObserveDisplayNodeID(displayNode.GetID())
                slicer.mrmlScene.AddNode(labelNode)

            # AF: this shuould not be necessary with the "proper" AIM input, since
            # only one volume should be present in the report, and only one item in
            # that volume should be annotated
            if 0:
                # if referenceUIDs != None:

                reader = slicer.vtkMRMLVolumeArchetypeStorageNode()
                reader.ResetFileNameList()

                for uid in string.split(referenceUIDs, ' '):

                    fname = slicer.modules.reporting.logic(
                    ).GetFileNameFromUID(uid)
                    reader.AddFileName(fname)

                reader.SetFileName(string.split(referenceUIDs, ' ')[0])
                reader.SetSingleFile(0)

                referenceVolume = slicer.mrmlScene.CreateNodeByClass(
                    'vtkMRMLScalarVolumeNode')
                referenceVolumeUIDs = referenceVolume.GetAttribute(
                    'DICOM.instanceUIDs')
                reader.ReadData(referenceVolume)

                nodeToAdd = referenceVolume

                allVolumeNodes = slicer.mrmlScene.GetNodesByClass(
                    'vtkMRMLScalarVolumeNode')
                allVolumeNodes.SetReferenceCount(
                    allVolumeNodes.GetReferenceCount() - 1)
                for i in range(allVolumeNodes.GetNumberOfItems()):
                    v = allVolumeNodes.GetItemAsObject(i)
                    uids = v.GetAttribute('DICOM.instanceUIDs')
                    if uids == referenceNodeUIDs:
                        print('Referenced node is already in the scene!')
                        nodeToAdd = None
                        referenceNode = v
                        break

                if nodeToAdd != None:
                    slicer.mrmlScene.AddNode(nodeToAdd)

                slicer.modules.reporting.logic().InitializeHierarchyForVolume(
                    referenceNode)

                for i in range(labelNodes.GetNumberOfItems()):
                    displayNode = slicer.mrmlScene.CreateNodeByClass(
                        'vtkMRMLScalarVolumeDisplayNode')
                    displayNode.SetReferenceCount(
                        displayNode.GetReferenceCount() - 1)
                    displayNode.SetAndObserveColorNodeID(
                        newReport.GetColorNodeID())
                    slicer.mrmlScene.AddNode(displayNode)
                    labelNode = labelNodes.GetItemAsObject(i)
                    labelNode.SetAttribute('AssociatedNodeID',
                                           referenceNode.GetID())
                    labelNode.SetAndObserveDisplayNodeID(displayNode.GetID())
                    slicer.mrmlScene.AddNode(labelNodes.GetItemAsObject(i))
示例#16
0
    def load(self, loadable):
        """Load the selection as a MultiVolume, if multivolume attribute is
    present
    """

        mvNode = ''
        try:
            mvNode = loadable.multivolume
        except AttributeError:
            return None

        nFrames = int(mvNode.GetAttribute('MultiVolume.NumberOfFrames'))
        files = string.split(mvNode.GetAttribute('MultiVolume.FrameFileList'),
                             ',')
        nFiles = len(files)
        filesPerFrame = nFiles / nFrames
        frames = []

        mvImage = vtk.vtkImageData()
        mvImageArray = None

        scalarVolumePlugin = slicer.modules.dicomPlugins[
            'DICOMScalarVolumePlugin']()
        instanceUIDs = ""
        for file in files:
            uid = slicer.dicomDatabase.fileValue(file,
                                                 self.tags['instanceUID'])
            if uid == "":
                uid = "Unknown"
            instanceUIDs += uid + " "
        instanceUIDs = instanceUIDs[:-1]
        mvNode.SetAttribute("DICOM.instanceUIDs", instanceUIDs)

        # read each frame into scalar volume
        for frameNumber in range(nFrames):

            sNode = slicer.vtkMRMLVolumeArchetypeStorageNode()
            sNode.ResetFileNameList()

            frameFileList = files[frameNumber *
                                  filesPerFrame:(frameNumber + 1) *
                                  filesPerFrame]
            # sv plugin will sort the filenames by geometric order
            svLoadables = scalarVolumePlugin.examine([frameFileList])

            if len(svLoadables) == 0:
                return None
            for f in svLoadables[0].files:
                sNode.AddFileName(f)

            sNode.SetFileName(
                frameFileList[0])  # only used when num files/frame = 1
            sNode.SetSingleFile(0)
            frame = slicer.vtkMRMLScalarVolumeNode()
            sNode.ReadData(frame)

            if frame.GetImageData() == None:
                print('Failed to read a multivolume frame!')
                return None

            if frameNumber == 0:
                frameImage = frame.GetImageData()
                frameExtent = frameImage.GetExtent()
                frameSize = frameExtent[1] * frameExtent[3] * frameExtent[5]

                mvImage.SetExtent(frameExtent)
                if vtk.VTK_MAJOR_VERSION <= 5:
                    mvImage.SetNumberOfScalarComponents(nFrames)
                    mvImage.SetScalarType(frame.GetImageData().GetScalarType())
                    mvImage.AllocateScalars()
                else:
                    mvImage.AllocateScalars(
                        frame.GetImageData().GetScalarType(), nFrames)

                mvImageArray = vtk.util.numpy_support.vtk_to_numpy(
                    mvImage.GetPointData().GetScalars())

                mvNode.SetScene(slicer.mrmlScene)

                mat = vtk.vtkMatrix4x4()
                frame.GetRASToIJKMatrix(mat)
                mvNode.SetRASToIJKMatrix(mat)
                frame.GetIJKToRASMatrix(mat)
                mvNode.SetIJKToRASMatrix(mat)

            frameImage = frame.GetImageData()
            frameImageArray = vtk.util.numpy_support.vtk_to_numpy(
                frameImage.GetPointData().GetScalars())

            mvImageArray.T[frameNumber] = frameImageArray

        mvDisplayNode = slicer.mrmlScene.CreateNodeByClass(
            'vtkMRMLMultiVolumeDisplayNode')
        mvDisplayNode.SetReferenceCount(mvDisplayNode.GetReferenceCount() - 1)
        mvDisplayNode.SetScene(slicer.mrmlScene)
        mvDisplayNode.SetDefaultColorMap()
        slicer.mrmlScene.AddNode(mvDisplayNode)

        mvNode.SetAndObserveDisplayNodeID(mvDisplayNode.GetID())
        mvNode.SetAndObserveImageData(mvImage)
        mvNode.SetNumberOfFrames(nFrames)
        mvNode.SetName(loadable.name)
        slicer.mrmlScene.AddNode(mvNode)

        #
        # automatically select the volume to display
        #
        appLogic = slicer.app.applicationLogic()
        selNode = appLogic.GetSelectionNode()
        selNode.SetReferenceActiveVolumeID(mvNode.GetID())
        appLogic.PropagateVolumeSelection()

        # file list is no longer needed - remove the attribute
        mvNode.RemoveAttribute('MultiVolume.FrameFileList')

        return mvNode