Example #1
0
 def setNewFiducial(self, newSceneNode):
     # Allow click to set the new fiducial to the list
     if self.fixed.fiducialList:
         self.fixed.fiducialList.RemoveObserver(
             vtk.vtkCommand.ModifiedEvent)
         self.fixed.fiducialList.AddObserver(vtk.vtkCommand.ModifiedEvent,
                                             self.onMRMLNodeAdded)
     self.fixed.fiducialList.UpdateScene(newSceneNode)
     collection = vtk.vtkCollection()
     self.fixed.fiducialList.GetDirectChildren(collection)
     print collection.GetNumberOfItems()
     ######
     #        create fiducial in volume labeled with fiducial list index
     #        add fiducial to appropriate list
     #    else:
     #        self.createNewFiducial() (i.e. ignore)
     #    if volume is not marked done:
     #        mark volume as done
     #    else:
     #        give warning
     #    if both are marked done:
     #        reset done flag
     #        quit
     #    else:
     #        self.createNewFiducial()
     # elif right-click:
     #    ignore
     # elif ESC:
     #    remove latest fiducial if lengths not equal (assumes ordered list!!!)
     #    reset done flags
     # elif RET:
     #    ignore (both fiducials need to be set (i.e. both flags need to == 'done'))
     # self.selector.AddNewAnnotationIDToList(self.fixed.newFiducial.GetID())
     print "Created a new fiducial node"
  def examineForImport(self,fileLists):
    """ Returns a list of qSlicerDICOMLoadable
    instances corresponding to ways of interpreting the 
    fileLists parameter.
    """    
    import vtkSlicerDicomRtImportExportModuleLogic

    # Create loadables for each file list
    loadables = []
    for fileList in fileLists: # Each file list corresponds to one series, so do loadables
      # Convert file list to VTK object to be able to pass it for examining
      # (VTK class cannot have Qt object as argument, otherwise it is not python wrapped)
      vtkFileList = vtk.vtkStringArray()
      for file in fileList:
        vtkFileList.InsertNextValue(file)

      # Examine files
      loadablesCollection = vtk.vtkCollection()
      slicer.modules.dicomrtimportexport.logic().ExamineForLoad(vtkFileList, loadablesCollection)

      for loadableIndex in xrange(0,loadablesCollection.GetNumberOfItems()):
        vtkLoadable = loadablesCollection.GetItemAsObject(loadableIndex)
        # Create Qt loadable if confidence is greater than 0
        if vtkLoadable.GetConfidence() > 0:
          # Convert to Qt loadable to pass it back
          qtLoadable = slicer.qSlicerDICOMLoadable()
          qtLoadable.copyFromVtkLoadable(vtkLoadable)
          qtLoadable.tooltip = 'Valid RT object in selection'
          qtLoadable.selected = True
          loadables.append(qtLoadable)

    return loadables
Example #3
0
 def setNewFiducial(self, newSceneNode):
     # Allow click to set the new fiducial to the list
     if self.fixed.fiducialList:
         self.fixed.fiducialList.RemoveObserver(vtk.vtkCommand.ModifiedEvent)
         self.fixed.fiducialList.AddObserver(vtk.vtkCommand.ModifiedEvent, self.onMRMLNodeAdded)
     self.fixed.fiducialList.UpdateScene(newSceneNode)
     collection = vtk.vtkCollection()
     self.fixed.fiducialList.GetDirectChildren(collection)
     print collection.GetNumberOfItems()
     ######
     #        create fiducial in volume labeled with fiducial list index
     #        add fiducial to appropriate list
     #    else:
     #        self.createNewFiducial() (i.e. ignore)
     #    if volume is not marked done:
     #        mark volume as done
     #    else:
     #        give warning
     #    if both are marked done:
     #        reset done flag
     #        quit
     #    else:
     #        self.createNewFiducial()
     # elif right-click:
     #    ignore
     # elif ESC:
     #    remove latest fiducial if lengths not equal (assumes ordered list!!!)
     #    reset done flags
     # elif RET:
     #    ignore (both fiducials need to be set (i.e. both flags need to == 'done'))
     # self.selector.AddNewAnnotationIDToList(self.fixed.newFiducial.GetID())
     print "Created a new fiducial node"
Example #4
0
 def convertFiducialHierarchyToVtkIdList(hierarchyNode,volumeNode):
     '''
     '''
     outputIds = vtk.vtkIdList()
     
     if not hierarchyNode or not volumeNode:
         return outputIds
     
     if isinstance(hierarchyNode,slicer.vtkMRMLAnnotationHierarchyNode) and isinstance(volumeNode,slicer.vtkMRMLScalarVolumeNode):
         
         childrenNodes = vtk.vtkCollection()
         
         image = volumeNode.GetImageData()
         hierarchyNode.GetChildrenDisplayableNodes(childrenNodes)     
         
         # now we have the children which are fiducialNodes - let's loop!
         for n in range(childrenNodes.GetNumberOfItems()):
             
             currentFiducial = childrenNodes.GetItemAsObject(n)
             currentCoordinatesRAS = [0,0,0]
             
             # grab the current coordinates
             currentFiducial.GetFiducialCoordinates(currentCoordinatesRAS)
             
             # convert the RAS to IJK
             currentCoordinatesIJK = Helper.ConvertRAStoIJK(volumeNode,currentCoordinatesRAS)
             
             # strip the last element since we need a 3based tupel
             currentCoordinatesIJKlist = (int(currentCoordinatesIJK[0]),int(currentCoordinatesIJK[1]),int(currentCoordinatesIJK[2]))
             outputIds.InsertNextId(int(image.ComputePointId(currentCoordinatesIJKlist)))
     
 
 
     # IdList was created, return it even if it might be empty
     return outputIds    
Example #5
0
    def getRulerNodeForVolumeAndStructure(self,
                                          volumeId,
                                          structureId,
                                          createIfNotExist=True,
                                          callbackWhenRulerModified=None):
        """ Search for the right ruler node to be created based on the volume and the selected
        structure (Aorta or PA).
        It also creates the necessary node hierarchy if it doesn't exist.
        :param volumeId:
        :param structureId: Aorta (1), PA (2)
        :param createIfNotExist: create the ruler node if it doesn't exist yet
        :param callbackWhenRulerModified: function to call when the ruler node is modified
        :return: node and a boolean indicating if the node has been created now
        """
        isNewNode = False
        if structureId == 0:  # none
            return None, isNewNode
        if structureId == self.AORTA:  # Aorta
            #nodeName = volumeId + '_paaRulers_aorta'
            nodeName = "A"
        elif structureId == self.PA:  # 'Pulmonary Arterial':
            #     nodeName = volumeId + '_paaRulers_pa'
            nodeName = "PA"
        # Get the node that contains all the rulers for this volume
        rulersListNode = self.getRulersListNode(
            volumeId, createIfNotExist=createIfNotExist)
        node = None
        if rulersListNode:
            # Search for the node
            for i in range(rulersListNode.GetNumberOfChildrenNodes()):
                nodeWrapper = rulersListNode.GetNthChildNode(i)
                # nodeWrapper is also a HierarchyNode. We need to look for its only child that will be the rulerNode
                col = vtk.vtkCollection()
                nodeWrapper.GetChildrenDisplayableNodes(col)
                rulerNode = col.GetItemAsObject(0)

                if rulerNode.GetName() == nodeName:
                    node = rulerNode
                    break

            if node is None and createIfNotExist:
                # Create the node
                # Set the active node, so that the new ruler is a child node
                annotationsLogic = slicer.modules.annotations.logic()
                annotationsLogic.SetActiveHierarchyNodeID(
                    rulersListNode.GetID())
                node = slicer.mrmlScene.CreateNodeByClass(
                    'vtkMRMLAnnotationRulerNode')
                node.SetName(nodeName)
                self.__changeColor__(node, self.defaultColor)
                slicer.mrmlScene.AddNode(node)
                isNewNode = True
                node.AddObserver(vtk.vtkCommand.ModifiedEvent,
                                 callbackWhenRulerModified)
                logging.debug("Created node " + nodeName + " for volume " +
                              volumeId)

        return node, isNewNode
def RemoveModels(modelHierarchyNode):
    collection = vtk.vtkCollection()
    modelHierarchyNode.GetAssociatedChildrenNodes(collection)
    if collection:
        nModels = collection.GetNumberOfItems()
        for i in range(nModels):
            model = collection.GetItemAsObject(i)
            slicer.mrmlScene.RemoveNode(model)
    return True
Example #7
0
    def __init__(self, fiducialListNode, dl=0.5):
        import numpy

        self.dl = dl  # desired world space step size (in mm)
        self.dt = dl  # current guess of parametric stepsize
        self.fids = fiducialListNode

        # hermite interpolation functions
        self.h00 = lambda t: 2 * t ** 3 - 3 * t ** 2 + 1
        self.h10 = lambda t: t ** 3 - 2 * t ** 2 + t
        self.h01 = lambda t: -2 * t ** 3 + 3 * t ** 2
        self.h11 = lambda t: t ** 3 - t ** 2

        # n is the number of control points in the piecewise curve

        if self.fids.GetClassName() == "vtkMRMLAnnotationHierarchyNode":
            # slicer4 style hierarchy nodes
            collection = vtk.vtkCollection()
            self.fids.GetChildrenDisplayableNodes(collection)
            self.n = collection.GetNumberOfItems()
            if self.n == 0:
                return
            self.p = numpy.zeros((self.n, 3))
            for i in xrange(self.n):
                f = collection.GetItemAsObject(i)
                coords = [0, 0, 0]
                f.GetFiducialCoordinates(coords)
                self.p[i] = coords
        else:
            # slicer3 style fiducial lists
            self.n = self.fids.GetNumberOfFiducials()
            n = self.n
            if n == 0:
                return
            # get control point data
            # sets self.p
            self.p = numpy.zeros((n, 3))
            for i in xrange(n):
                self.p[i] = self.fids.GetNthFiducialXYZ(i)

        # calculate the tangent vectors
        # - fm is forward difference
        # - m is average of in and out vectors
        # - first tangent is out vector, last is in vector
        # - sets self.m
        n = self.n
        fm = numpy.zeros((n, 3))
        for i in xrange(0, n - 1):
            fm[i] = self.p[i + 1] - self.p[i]
        self.m = numpy.zeros((n, 3))
        for i in xrange(1, n - 1):
            self.m[i] = (fm[i - 1] + fm[i]) / 2.0
        self.m[0] = fm[0]
        self.m[n - 1] = fm[n - 2]

        self.path = [self.p[0]]
        self.calculatePath()
Example #8
0
    def __init__(self, fiducialListNode, dl=0.5):
        import numpy
        self.dl = dl  # desired world space step size (in mm)
        self.dt = dl  # current guess of parametric stepsize
        self.fids = fiducialListNode

        # hermite interpolation functions
        self.h00 = lambda t: 2 * t**3 - 3 * t**2 + 1
        self.h10 = lambda t: t**3 - 2 * t**2 + t
        self.h01 = lambda t: -2 * t**3 + 3 * t**2
        self.h11 = lambda t: t**3 - t**2

        # n is the number of control points in the piecewise curve

        if self.fids.GetClassName() == "vtkMRMLAnnotationHierarchyNode":
            # slicer4 style hierarchy nodes
            collection = vtk.vtkCollection()
            self.fids.GetChildrenDisplayableNodes(collection)
            self.n = collection.GetNumberOfItems()
            if self.n == 0:
                return
            self.p = numpy.zeros((self.n, 3))
            for i in xrange(self.n):
                f = collection.GetItemAsObject(i)
                coords = [0, 0, 0]
                f.GetFiducialCoordinates(coords)
                self.p[i] = coords
        else:
            # slicer3 style fiducial lists
            self.n = self.fids.GetNumberOfFiducials()
            n = self.n
            if n == 0:
                return
            # get control point data
            # sets self.p
            self.p = numpy.zeros((n, 3))
            for i in xrange(n):
                self.p[i] = self.fids.GetNthFiducialXYZ(i)

        # calculate the tangent vectors
        # - fm is forward difference
        # - m is average of in and out vectors
        # - first tangent is out vector, last is in vector
        # - sets self.m
        n = self.n
        fm = numpy.zeros((n, 3))
        for i in xrange(0, n - 1):
            fm[i] = self.p[i + 1] - self.p[i]
        self.m = numpy.zeros((n, 3))
        for i in xrange(1, n - 1):
            self.m[i] = (fm[i - 1] + fm[i]) / 2.
        self.m[0] = fm[0]
        self.m[n - 1] = fm[n - 2]

        self.path = [self.p[0]]
        self.calculatePath()
Example #9
0
 def __init__(self,pytripCube):
   self.name = pytripCube.patient_name
   self.pixel_size = pytripCube.pixel_size
   self.slice_distance = pytripCube.slice_distance
   self.dimx = pytripCube.dimx
   self.dimy = pytripCube.dimy
   self.dimz = pytripCube.dimz
   self.vois=[]
   self.vtkCollection = vtk.vtkCollection()    
   self.filePath=''
 def getFiducialSliceDisplayableManagerHelper(self,sliceName='Red'):
   sliceWidget = slicer.app.layoutManager().sliceWidget(sliceName)
   sliceView = sliceWidget.sliceView()
   collection = vtk.vtkCollection()
   sliceView.getDisplayableManagers(collection)
   for i in range(collection.GetNumberOfItems()):
    m = collection.GetItemAsObject(i)
    if m.GetClassName() == "vtkMRMLMarkupsFiducialDisplayableManager2D":
      return m.GetHelper()
   return None
Example #11
0
 def loadFile(self, title, fileType, nodeComboBox):
   manager = slicer.app.ioManager()
   loadedNodes = vtk.vtkCollection()
   properties = {}
   res = manager.openDialog(fileType, slicer.qSlicerFileDialog.Read, properties, loadedNodes)
   loadedNode = loadedNodes.GetItemAsObject(0)
   if res == True:
     nodeComboBox.setCurrentNode(loadedNode)
   self.reset3DViews()
   return loadedNode
 def getFiducialSliceDisplayableManagerHelper(self,sliceName='Red'):
   sliceWidget = slicer.app.layoutManager().sliceWidget(sliceName)
   sliceView = sliceWidget.sliceView()
   collection = vtk.vtkCollection()
   sliceView.getDisplayableManagers(collection)
   for i in range(collection.GetNumberOfItems()):
    m = collection.GetItemAsObject(i)
    if m.GetClassName() == "vtkMRMLMarkupsFiducialDisplayableManager2D":
      return m.GetHelper()
   return None
Example #13
0
 def loadFile(self, title, fileType, nodeComboBox):
     manager = slicer.app.ioManager()
     loadedNodes = vtk.vtkCollection()
     properties = {}
     res = manager.openDialog(fileType, slicer.qSlicerFileDialog.Read,
                              properties, loadedNodes)
     loadedNode = loadedNodes.GetItemAsObject(0)
     if res == True:
         nodeComboBox.setCurrentNode(loadedNode)
     self.reset3DViews()
     return loadedNode
  def makeModels(study, finding, colorTable):

    if (study == None) | (finding == None) | (colorTable == None):
      return    
     
    seg = finding.GetSegmentationMappedByStudyNodeID(study.GetID())
      
    if seg:
      labelVolume = seg.GetLabelVolumeNode()

      #create a temporary model hierarchy for generating models
      tempMH = slicer.vtkMRMLModelHierarchyNode()
      slicer.mrmlScene.AddNode(tempMH)
      
      if (labelVolume != None) & (tempMH != None):
        parameters = {}
        parameters['InputVolume'] = labelVolume.GetID()
        parameters['ColorTable'] = colorTable.GetID()
        parameters['ModelSceneFile'] = tempMH.GetID()
        parameters['GenerateAll'] = False
        parameters['StartLabel'] = finding.GetColorID()
        parameters['EndLabel'] = finding.GetColorID()
        parameters['Name'] = labelVolume.GetName() + "_" + finding.GetName()+"_M"

        cliModelMaker = None
        cliModelMaker = slicer.cli.run(slicer.modules.modelmaker, cliModelMaker, parameters, wait_for_completion = True)  
        genModelNodes = vtk.vtkCollection()
        tempMH.GetChildrenModelNodes(genModelNodes)

        if genModelNodes.GetNumberOfItems() > 0:
          modelNode = genModelNodes.GetItemAsObject(0)
          if modelNode:
            if modelNode.IsA('vtkMRMLModelNode'):
              hnode = slicer.vtkMRMLHierarchyNode.GetAssociatedHierarchyNode(modelNode.GetScene(), modelNode.GetID())
              if hnode:
                if seg.GetModelHierarchyNode():
                  SlicerLongitudinalPETCTModuleViewHelper.removeModelHierarchyAndChildModelNodesFromScene(seg.GetModelHierarchyNode())
                  
                  hnode.SetName(seg.GetName()+"_Model")
                  seg.SetAndObserveModelHierarchyNodeID(hnode.GetID())
                  modelNode.SetName(labelVolume.GetName() + "_" + finding.GetName()+"_M")
                  if modelNode.GetDisplayNode():
                    modelNode.GetDisplayNode().SetName(labelVolume.GetName() + "_" + finding.GetName()+"_D")
                    modelNode.GetDisplayNode().AddViewNodeID(SlicerLongitudinalPETCTModuleViewHelper.getStandardViewNode().GetID())
                  hnode.SetName(labelVolume.GetName() + "_" + finding.GetName()+"_H")
                  modelNode.SetHideFromEditors(False)
                else:
                  seg.SetAndObserveModelHierarchyNodeID("")
                  slicer.mrmlScene.RemoveNode(modelNode)   
                  slicer.mrmlScene.RemoveNode(hnode)
   
          slicer.mrmlScene.RemoveNode(tempMH.GetDisplayNode())
          slicer.mrmlScene.RemoveNode(tempMH)        
 def volumeFiducialsAsList(self,volumeNode):
   """return a list of annotation nodes that are
   children of the list associated with the given
   volume node"""
   children = []
   listName = volumeNode.GetName() + "-landmarks"
   fidListHierarchyNode = slicer.util.getNode(listName)
   if fidListHierarchyNode:
     childCollection = vtk.vtkCollection()
     fidListHierarchyNode.GetAllChildren(childCollection)
     for childIndex in range(childCollection.GetNumberOfItems()):
       children.append(childCollection.GetItemAsObject(childIndex))
   return children
Example #16
0
 def widgetVisible(self, fidNode, viewNodeID):
   lm = slicer.app.layoutManager()
   for v in range(lm.threeDViewCount):
    td = lm.threeDWidget(v)
    ms = vtk.vtkCollection()
    td.getDisplayableManagers(ms)
    for i in range(ms.GetNumberOfItems()):
     m = ms.GetItemAsObject(i)
     if m.GetClassName() == "vtkMRMLMarkupsFiducialDisplayableManager3D" and m.GetMRMLViewNode().GetID() == viewNodeID:
       h = m.GetHelper()
       seedWidget = h.GetWidget(fidNode)
       return seedWidget.GetEnabled()
   return 0
 def removeModelHierarchyAndChildModelNodesFromScene(modelHierarchyNode):
   if modelHierarchyNode:
     cmn = vtk.vtkCollection()
     
     modelHierarchyNode.GetChildrenModelNodes(cmn)
     
     for i in range(cmn.GetNumberOfItems()):
       model = cmn.GetItemAsObject(i)
       
       if model.IsA('vtkMRMLModelNode'):
         slicer.mrmlScene.RemoveNode(model)
         
     slicer.mrmlScene.RemoveNode(modelHierarchyNode)       
Example #18
0
    def getRulerNodeForVolumeAndStructure(
        self, volumeId, structureId, createIfNotExist=True, callbackWhenRulerModified=None
    ):
        """ Search for the right ruler node to be created based on the volume and the selected
        structure (Aorta or PA).
        It also creates the necessary node hierarchy if it doesn't exist.
        :param volumeId:
        :param structureId: Aorta (1), PA (2)
        :param createIfNotExist: create the ruler node if it doesn't exist yet
        :param callbackWhenRulerModified: function to call when the ruler node is modified
        :return: node and a boolean indicating if the node has been created now
        """
        isNewNode = False
        if structureId == 0:  # none
            return None, isNewNode
        if structureId == self.AORTA:  # Aorta
            # nodeName = volumeId + '_paaRulers_aorta'
            nodeName = "A"
        elif structureId == self.PA:  # 'Pulmonary Arterial':
            #     nodeName = volumeId + '_paaRulers_pa'
            nodeName = "PA"
        # Get the node that contains all the rulers for this volume
        rulersListNode = self.getRulersListNode(volumeId, createIfNotExist=createIfNotExist)
        node = None
        if rulersListNode:
            # Search for the node
            for i in range(rulersListNode.GetNumberOfChildrenNodes()):
                nodeWrapper = rulersListNode.GetNthChildNode(i)
                # nodeWrapper is also a HierarchyNode. We need to look for its only child that will be the rulerNode
                col = vtk.vtkCollection()
                nodeWrapper.GetChildrenDisplayableNodes(col)
                rulerNode = col.GetItemAsObject(0)

                if rulerNode.GetName() == nodeName:
                    node = rulerNode
                    break

            if node is None and createIfNotExist:
                # Create the node
                # Set the active node, so that the new ruler is a child node
                annotationsLogic = slicer.modules.annotations.logic()
                annotationsLogic.SetActiveHierarchyNodeID(rulersListNode.GetID())
                node = slicer.mrmlScene.CreateNodeByClass("vtkMRMLAnnotationRulerNode")
                node.SetName(nodeName)
                self.__changeColor__(node, self.defaultColor)
                slicer.mrmlScene.AddNode(node)
                isNewNode = True
                node.AddObserver(vtk.vtkCommand.ModifiedEvent, callbackWhenRulerModified)
                logging.debug("Created node " + nodeName + " for volume " + volumeId)

        return node, isNewNode
Example #19
0
 def onAnnotationsFontSizeChanged(self, size):
     lm = slicer.app.layoutManager()
     for sliceName in lm.sliceViewNames():
         sWidget = lm.sliceWidget(sliceName)
         sView = sWidget.sliceView()
         DisplayableManagersCollection = vtk.vtkCollection()
         sView.getDisplayableManagers(DisplayableManagersCollection)
         for DisplayableManagersIndex in range(
                 DisplayableManagersCollection.GetNumberOfItems()):
             AstroDisplayableManager = DisplayableManagersCollection.GetItemAsObject(
                 DisplayableManagersIndex)
             if AstroDisplayableManager.GetClassName(
             ) == "vtkMRMLAstroTwoDAxesDisplayableManager":
                 AstroDisplayableManager.SetAnnotationsFontSize(size)
  def export(self,exportables):
    import vtkSlicerDicomRtImportExportModuleLogic
    from vtkSlicerDICOMLibModuleLogicPython import vtkSlicerDICOMExportable
    
    # Convert Qt loadables to VTK ones for the RT export logic
    exportablesCollection = vtk.vtkCollection()
    for exportable in exportables:
      vtkExportable = slicer.vtkSlicerDICOMExportable()
      exportable.copyToVtkExportable(vtkExportable)
      exportablesCollection.AddItem(vtkExportable)

    # Export RT study
    message = slicer.modules.dicomrtimportexport.logic().ExportDicomRTStudy(exportablesCollection)    
    return message
Example #21
0
 def widgetVisibleOnSlice(self, fidNode, sliceNodeID):
   lm = slicer.app.layoutManager()
   sliceNames = lm.sliceViewNames()
   for sliceName in sliceNames:
     sliceWidget = lm.sliceWidget(sliceName)
     sliceView = sliceWidget.sliceView()
     ms = vtk.vtkCollection()
     sliceView.getDisplayableManagers(ms)
     for i in range(ms.GetNumberOfItems()):
       m = ms.GetItemAsObject(i)
       if m.GetClassName() == 'vtkMRMLMarkupsFiducialDisplayableManager2D' and m.GetSliceNode().GetID() == sliceNodeID:
         h = m.GetHelper()
         seedWidget = h.GetWidget(fidNode)
         return seedWidget.GetEnabled()
   return 0
def TransformModelHierarchy(modelHierarchyNode, transformNode):
    if not transformNode:
        return False

    # modelLabelNode.SetAndObserveTransformNodeID(transformNode.GetID())
    # slicer.vtkSlicerTransformLogic.hardenTransform(modelLabelNode)
    collection = vtk.vtkCollection()
    modelHierarchyNode.GetAssociatedChildrenNodes(collection)
    if collection:
        nModels = collection.GetNumberOfItems()
        for i in range(nModels):
            model = collection.GetItemAsObject(i)
            model.SetAndObserveTransformNodeID(transformNode.GetID())
            slicer.vtkSlicerTransformLogic.hardenTransform(model)
    return True
 def volumeFiducialsByName(self,volumeNode):
   """return a dictionary of annotation nodes that are
   children of the list associated with the given
   volume node, where the keys are fiducial names
   and the values are fiducial nodes"""
   fiducialsByName = {}
   listName = volumeNode.GetName() + "-landmarks"
   fidListHierarchyNode = slicer.util.getNode(listName)
   if fidListHierarchyNode:
     childCollection = vtk.vtkCollection()
     fidListHierarchyNode.GetAllChildren(childCollection)
     for childIndex in range(childCollection.GetNumberOfItems()):
       fiducialNode = childCollection.GetItemAsObject(childIndex)
       fiducialsByName[fiducialNode.GetName()] = fiducialNode
   return fiducialsByName
 def UpdateSelfAndChildMetrics( allMetrics, transformName, absTime, metricsTable ):
   if ( PythonMetricsCalculatorLogic.GetMRMLScene() == None or PythonMetricsCalculatorLogic.GetPerkEvaluatorLogic() == None ):
     return
 
   # Get the recorded transform node
   updatedTransformNode = PythonMetricsCalculatorLogic.GetMRMLScene().GetFirstNode( transformName, "vtkMRMLLinearTransformNode", [ False ] ) # TODO: Is there an error in this function?
   
   # Get all transforms in the scene
   transformCollection = vtk.vtkCollection()
   PythonMetricsCalculatorLogic.GetPerkEvaluatorLogic().GetSceneVisibleTransformNodes( transformCollection )
   
   # Update all metrics associated with children of the recorded transform
   for i in range( transformCollection.GetNumberOfItems() ):
     currentTransformNode = transformCollection.GetItemAsObject( i )
     if ( PythonMetricsCalculatorLogic.GetPerkEvaluatorLogic().IsSelfOrDescendentTransformNode( updatedTransformNode, currentTransformNode ) ):
       PythonMetricsCalculatorLogic.UpdateMetrics( allMetrics, currentTransformNode, absTime, metricsTable )
Example #25
0
 def onAnnotationsColorChanged(self, color):
     lm = slicer.app.layoutManager()
     for sliceName in lm.sliceViewNames():
         sWidget = lm.sliceWidget(sliceName)
         sView = sWidget.sliceView()
         DisplayableManagersCollection = vtk.vtkCollection()
         sView.getDisplayableManagers(DisplayableManagersCollection)
         for DisplayableManagersIndex in range(
                 DisplayableManagersCollection.GetNumberOfItems()):
             AstroDisplayableManager = DisplayableManagersCollection.GetItemAsObject(
                 DisplayableManagersIndex)
             if AstroDisplayableManager.GetClassName() == "vtkMRMLAstroTwoDAxesDisplayableManager" or \
                AstroDisplayableManager.GetClassName() == "vtkMRMLAstroBeamDisplayableManager" :
                 AstroDisplayableManager.SetAnnotationsColor(
                     color.red() / 255.,
                     color.green() / 255.,
                     color.blue() / 255.)
Example #26
0
    def populateRulers(self, annotationHierarchy, verterbraeNames):
        completeVerterbraeNames = []
        for verterbraeName in verterbraeNames:
            completeVerterbraeNames.append(verterbraeName + "-s")
            completeVerterbraeNames.append(verterbraeName + "-i")

        if annotationHierarchy != None:
            rulerNodes = vtk.vtkCollection()
            annotationHierarchy.GetDirectChildren(rulerNodes)

            rulerNodeNames = []
            for nodeIndex in range(rulerNodes.GetNumberOfItems()):
                if rulerNodes.GetItemAsObject(nodeIndex).GetClassName(
                ) == "vtkMRMLAnnotationRulerNode":
                    rulerNodeNames.append(
                        rulerNodes.GetItemAsObject(nodeIndex).GetName())

            addedRulerNodesList = []
            addedVerterbrae = 200
            for completeVerterbraeName in completeVerterbraeNames:
                if completeVerterbraeName not in rulerNodeNames:
                    newRulerNode = slicer.vtkMRMLAnnotationRulerNode()
                    newRulerNode.SetName(completeVerterbraeName)
                    newRulerNode.SetPosition1(0, addedVerterbrae, 0)
                    newRulerNode.SetPosition2(-300, addedVerterbrae, 0)
                    newRulerNode.SetPointColour([0, 0, 1])
                    newRulerNode.Initialize(slicer.mrmlScene)
                    annotationHierarchy.SetAndObserveDisplayNodeID(
                        newRulerNode.GetDisplayNodeID())
                    addedVerterbrae -= 50
                    addedRulerNodesList.append(newRulerNode)

        else:
            addedVerterbrae = 200
            for completeVerterbraeName in completeVerterbraeNames:
                newRulerNode = slicer.vtkMRMLAnnotationRulerNode()
                newRulerNode.SetName(completeVerterbraeName)
                newRulerNode.SetPosition1(0, addedVerterbrae, 0)
                newRulerNode.SetPosition2(-300, addedVerterbrae, 0)
                newRulerNode.Initialize(slicer.mrmlScene)
                annotationHierarchy.SetAndObserveDisplayNodeID(
                    newRulerNode.GetDisplayNodeID())
                addedVerterbrae -= 50

        return addedRulerNodesList
  def load(self,loadable):
    """ Call Reporting logic to load the DICOM SEG object
    """
    print('DICOM SEG load()')
    labelNodes = vtk.vtkCollection()

    uid = None

    try:
      reportingLogic = slicer.modules.reporting.logic()
      uid = loadable.uid
      print 'in load(): uid = ', uid
    except AttributeError:
      return False

    res = False
    # default color node will be used
    res = reportingLogic.DicomSegRead(labelNodes, uid)
    print 'Read this many labels:',labelNodes.GetNumberOfItems()

    defaultColorNode = reportingLogic.GetDefaultColorNode()
    for i in range(labelNodes.GetNumberOfItems()):
      # create and initialize the display node to use default color node
      displayNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLLabelMapVolumeDisplayNode')
      displayNode.SetReferenceCount(displayNode.GetReferenceCount()-1)
      displayNode.SetAndObserveColorNodeID(defaultColorNode.GetID())
      slicer.mrmlScene.AddNode(displayNode)

      # assign it to the label node
      # this is done here as opposed to Reporting logic to minimize the
      # dependencies of the DICOM SEG functionality in the Slicer internals
      labelNode = labelNodes.GetItemAsObject(i)
      labelNode.SetAndObserveDisplayNodeID(displayNode.GetID())
      slicer.mrmlScene.AddNode(labelNode)

      # create Subject hierarchy nodes for the loaded series
      self.addSeriesInSubjectHierarchy(loadable, labelNode)

    return True
Example #28
0
    def convertFiducialHierarchyToVtkIdList(hierarchyNode, volumeNode):
        '''
        '''
        outputIds = vtk.vtkIdList()

        if not hierarchyNode or not volumeNode:
            return outputIds

        if isinstance(hierarchyNode,
                      slicer.vtkMRMLAnnotationHierarchyNode) and isinstance(
                          volumeNode, slicer.vtkMRMLScalarVolumeNode):

            childrenNodes = vtk.vtkCollection()

            image = volumeNode.GetImageData()
            hierarchyNode.GetChildrenDisplayableNodes(childrenNodes)

            # now we have the children which are fiducialNodes - let's loop!
            for n in range(childrenNodes.GetNumberOfItems()):

                currentFiducial = childrenNodes.GetItemAsObject(n)
                currentCoordinatesRAS = [0, 0, 0]

                # grab the current coordinates
                currentFiducial.GetFiducialCoordinates(currentCoordinatesRAS)

                # convert the RAS to IJK
                currentCoordinatesIJK = Helper.ConvertRAStoIJK(
                    volumeNode, currentCoordinatesRAS)

                # strip the last element since we need a 3based tupel
                currentCoordinatesIJKlist = (int(currentCoordinatesIJK[0]),
                                             int(currentCoordinatesIJK[1]),
                                             int(currentCoordinatesIJK[2]))
                outputIds.InsertNextId(
                    int(image.ComputePointId(currentCoordinatesIJKlist)))

        # IdList was created, return it even if it might be empty
        return outputIds
  def onLabelExport(self):
    '''
    TODO: add a check that the selected label is associated with a volume that
    has DICOM.instanceUIDs attribute set
    '''
    
    label = self.segmentationSelector.currentNode()
    scalar = self.volumeSelector.currentNode()

    # assuming here the user does the 
    if label == None or scalar == None:
      self.exportButton.enabled = 0
      return
    
    labelImage = label.GetImageData()
    scalarImage = label.GetImageData()
    lDim = labelImage.GetDimensions()
    sDim = scalarImage.GetDimensions()
    if lDim[0]!=sDim[0] or lDim[1]!=sDim[1] or lDim[2]!=sDim[2]:
      self.__helpLabel.text = 'Geometries do not match'
      return

    label = self.segmentationSelector.currentNode()
    scalar = self.volumeSelector.currentNode()
 
    # need to set up the associated node ID
    label.SetAttribute('AssociatedNodeID', scalar.GetID())

    labelCollection = vtk.vtkCollection()
    labelCollection.AddItem(label)
    reportingLogic = slicer.modules.reporting.logic()
    dirName = self.outputDir
    fileName = reportingLogic.DicomSegWrite(labelCollection, dirName)

    if fileName == '':
      self.__helpLabel.text = 'Error!'
    else:
      self.__helpLabel.text = 'Exported to '+fileName.split('/')[-1]
    def onLabelExport(self):
        '''
    TODO: add a check that the selected label is associated with a volume that
    has DICOM.instanceUIDs attribute set
    '''

        label = self.segmentationSelector.currentNode()
        scalar = self.volumeSelector.currentNode()

        # assuming here the user does the
        if label == None or scalar == None:
            self.exportButton.enabled = 0
            return

        labelImage = label.GetImageData()
        scalarImage = label.GetImageData()
        lDim = labelImage.GetDimensions()
        sDim = scalarImage.GetDimensions()
        if lDim[0] != sDim[0] or lDim[1] != sDim[1] or lDim[2] != sDim[2]:
            self.__helpLabel.text = 'Geometries do not match'
            return

        label = self.segmentationSelector.currentNode()
        scalar = self.volumeSelector.currentNode()

        # need to set up the associated node ID
        label.SetAttribute('AssociatedNodeID', scalar.GetID())

        labelCollection = vtk.vtkCollection()
        labelCollection.AddItem(label)
        reportingLogic = slicer.modules.reporting.logic()
        dirName = self.outputDir
        fileName = reportingLogic.DicomSegWrite(labelCollection, dirName)

        if fileName == '':
            self.__helpLabel.text = 'Error!'
        else:
            self.__helpLabel.text = 'Exported to ' + fileName.split('/')[-1]
  def createFiducialMatrix(self):
    self.fiducialMatrixStatus = True
 
    # extracting the effects of transform parameters
    transformNode1 = self.templateSelector.currentNode().GetParentTransformNode()
    #print transformNode1
    shiftTransform1 = [0 , 0, 0]
    rotationTransform1 = [[1, 0,0],[0,1,0],[0,0,1]]
    #shiftTransform2 = [0, 0, 0]
    #rotationTransform2 = [1, 0,0],[0,1,0],[0,0,1]]
    if transformNode1 != None:
      m = vtk.vtkMatrix4x4()
      transformNode1.GetMatrixTransformToWorld(m)
      shiftTransform1 = [ m.GetElement(0,3), m.GetElement(1,3), m.GetElement(2,3) ]
      rotationTransform1 = [[m.GetElement(0,0), m.GetElement(0,1),m.GetElement(0,2)],[m.GetElement(1,0), m.GetElement(1,1),m.GetElement(1,2)],[m.GetElement(2,0), m.GetElement(2,1),m.GetElement(2,2)]]

    self.fids = self.inputFiducialsNodeSelector.currentNode();
    if self.fids.GetClassName() == "vtkMRMLAnnotationHierarchyNode":
    # slicer4 style hierarchy nodes
      collection = vtk.vtkCollection()
      self.fids.GetChildrenDisplayableNodes(collection)
      self.n = collection.GetNumberOfItems()

      if self.n == 0: 
        return
      self.p = numpy.zeros((self.n,3))
      for i in xrange(self.n):
        f = collection.GetItemAsObject(i)
        coords = [0,0,0]
        # Need to change to consider the transform that is applied to the points
        # offset for template width, moving the needle holes in z direction
        f.GetFiducialCoordinates(coords)
        print coords
        coords = numpy.add(coords,[ 0, 0, self.templateWidth]) 
        print coords
        self.p[i] = numpy.add(numpy.dot(rotationTransform1,coords),shiftTransform1) 
  def load(self,loadable):
    """ Call Reporting logic to load the DICOM SEG object
    """
    print('DICOM SEG load()')
    labelNodes = vtk.vtkCollection()

    uid = None

    try:
      reportingLogic = slicer.modules.reporting.logic()
      uid = loadable.uid
      print 'in load(): uid = ', uid
    except AttributeError:
      return False

    res = False
    # default color node will be used
    res = reportingLogic.DicomSegRead(labelNodes, uid)
    print 'Read this many labels:',labelNodes.GetNumberOfItems()

    defaultColorNode = reportingLogic.GetDefaultColorNode()
    for i in range(labelNodes.GetNumberOfItems()):
      # create and initialize the display node to use default color node
      displayNode = slicer.mrmlScene.CreateNodeByClass('vtkMRMLLabelMapVolumeDisplayNode')
      displayNode.SetReferenceCount(displayNode.GetReferenceCount()-1)
      displayNode.SetAndObserveColorNodeID(defaultColorNode.GetID())
      slicer.mrmlScene.AddNode(displayNode)

      # assign it to the label node
      # this is done here as opposed to Reporting logic to minimize the
      # dependencies of the DICOM SEG functionality in the Slicer internals
      labelNode = labelNodes.GetItemAsObject(i)
      labelNode.SetAndObserveDisplayNodeID(displayNode.GetID())
      slicer.mrmlScene.AddNode(labelNode)

    return True
    def start(self, preview=False):
        '''
    '''
        SlicerVmtkCommonLib.Helper.Debug("Starting Level Set Segmentation..")

        # first we need the nodes
        currentVolumeNode = self.__inputVolumeNodeSelector.currentNode()
        currentSeedsNode = self.__seedFiducialsNodeSelector.currentNode()
        currentVesselnessNode = self.__vesselnessVolumeNodeSelector.currentNode(
        )
        currentStoppersNode = self.__stopperFiducialsNodeSelector.currentNode()
        currentLabelMapNode = self.__outputVolumeNodeSelector.currentNode()
        currentModelNode = self.__outputModelNodeSelector.currentNode()

        if not currentVolumeNode:
            # we need a input volume node
            return 0

        if not currentSeedsNode:
            # we need a seeds node
            return 0

        if not currentStoppersNode or currentStoppersNode.GetID(
        ) == currentSeedsNode.GetID():
            # we need a current stopper node
            # self.__stopperFiducialsNodeSelector.addNode()
            pass

        if not currentLabelMapNode or currentLabelMapNode.GetID(
        ) == currentVolumeNode.GetID():
            # we need a current labelMap node
            newLabelMapDisplayNode = slicer.mrmlScene.CreateNodeByClass(
                "vtkMRMLLabelMapVolumeDisplayNode")
            newLabelMapDisplayNode.SetScene(slicer.mrmlScene)
            newLabelMapDisplayNode.SetDefaultColorMap()
            slicer.mrmlScene.AddNode(newLabelMapDisplayNode)

            newLabelMapNode = slicer.mrmlScene.CreateNodeByClass(
                "vtkMRMLScalarVolumeNode")
            newLabelMapNode.CopyOrientation(currentVolumeNode)
            newLabelMapNode.SetScene(slicer.mrmlScene)
            newLabelMapNode.SetName(
                slicer.mrmlScene.GetUniqueNameByString(
                    self.__outputVolumeNodeSelector.baseName))
            newLabelMapNode.LabelMapOn()
            newLabelMapNode.SetAndObserveDisplayNodeID(
                newLabelMapDisplayNode.GetID())
            slicer.mrmlScene.AddNode(newLabelMapNode)
            currentLabelMapNode = newLabelMapNode
            self.__outputVolumeNodeSelector.setCurrentNode(currentLabelMapNode)

        if not currentModelNode:
            # we need a current model node, the display node is created later
            newModelNode = slicer.mrmlScene.CreateNodeByClass(
                "vtkMRMLModelNode")
            newModelNode.SetScene(slicer.mrmlScene)
            newModelNode.SetName(
                slicer.mrmlScene.GetUniqueNameByString(
                    self.__outputModelNodeSelector.baseName))
            slicer.mrmlScene.AddNode(newModelNode)
            currentModelNode = newModelNode

            self.__outputModelNodeSelector.setCurrentNode(currentModelNode)

        # now we need to convert the fiducials to vtkIdLists
        seeds = SlicerVmtkCommonLib.Helper.convertFiducialHierarchyToVtkIdList(
            currentSeedsNode, currentVolumeNode)
        # stoppers = SlicerVmtkCommonLib.Helper.convertFiducialHierarchyToVtkIdList(currentStoppersNode, currentVolumeNode)
        stoppers = vtk.vtkIdList()  # TODO

        # the input image for the initialization
        inputImage = vtk.vtkImageData()

        # check if we have a vesselnessNode - this will be our input for the initialization then
        if currentVesselnessNode:
            # yes, there is one
            inputImage.DeepCopy(currentVesselnessNode.GetImageData())
        else:
            # no, there is none - we use the original image
            inputImage.DeepCopy(currentVolumeNode.GetImageData())

        inputImage.Update()

        # initialization
        initImageData = vtk.vtkImageData()

        # evolution
        evolImageData = vtk.vtkImageData()

        # perform the initialization
        initImageData.DeepCopy(self.GetLogic().performInitialization(
            inputImage, self.__thresholdSlider.minimumValue,
            self.__thresholdSlider.maximumValue, seeds, stoppers,
            0))  # TODO sidebranch ignore feature
        initImageData.Update()

        if not initImageData.GetPointData().GetScalars():
            # something went wrong, the image is empty
            SlicerVmtkCommonLib.Helper.Info(
                "Segmentation failed - the output was empty..")
            return -1

        # check if it is a preview call
        if preview:

            # if this is a preview call, we want to skip the evolution
            evolImageData.DeepCopy(initImageData)

        else:

            # no preview, run the whole thing! we never use the vesselness node here, just the original one
            evolImageData.DeepCopy(self.GetLogic().performEvolution(
                currentVolumeNode.GetImageData(), initImageData,
                self.__iterationSpinBox.value, self.__inflationSlider.value,
                self.__curvatureSlider.value, self.__attractionSlider.value,
                'geodesic'))

        evolImageData.Update()

        # create segmentation labelMap
        labelMap = vtk.vtkImageData()
        labelMap.DeepCopy(self.GetLogic().buildSimpleLabelMap(
            evolImageData, 0, 5))
        labelMap.Update()

        currentLabelMapNode.CopyOrientation(currentVolumeNode)

        # propagate the label map to the node
        currentLabelMapNode.SetAndObserveImageData(labelMap)
        currentLabelMapNode.Modified()

        # deactivate the threshold in the GUI
        self.resetThresholdOnDisplayNode()
        # self.onInputVolumeChanged()

        # show the segmentation results in the GUI
        selectionNode = slicer.app.applicationLogic().GetSelectionNode()

        if preview and currentVesselnessNode:
            # if preview and a vesselnessNode was configured, show it
            selectionNode.SetReferenceActiveVolumeID(
                currentVesselnessNode.GetID())
        else:
            # if not preview, show the original volume
            if currentVesselnessNode:
                selectionNode.SetReferenceSecondaryVolumeID(
                    currentVesselnessNode.GetID())
            selectionNode.SetReferenceActiveVolumeID(currentVolumeNode.GetID())
        selectionNode.SetReferenceActiveLabelVolumeID(
            currentLabelMapNode.GetID())
        slicer.app.applicationLogic().PropagateVolumeSelection()

        # generate 3D model
        model = vtk.vtkPolyData()

        # we need the ijkToRas transform for the marching cubes call
        ijkToRasMatrix = vtk.vtkMatrix4x4()
        currentLabelMapNode.GetIJKToRASMatrix(ijkToRasMatrix)

        # call marching cubes
        model.DeepCopy(self.GetLogic().marchingCubes(evolImageData,
                                                     ijkToRasMatrix, 0.0))
        model.Update()

        # propagate model to nodes
        currentModelNode.SetAndObservePolyData(model)
        currentModelNode.Modified()

        currentModelDisplayNode = currentModelNode.GetDisplayNode()

        if not currentModelDisplayNode:

            # create new displayNode
            currentModelDisplayNode = slicer.mrmlScene.CreateNodeByClass(
                "vtkMRMLModelDisplayNode")
            slicer.mrmlScene.AddNode(currentModelDisplayNode)

        # always configure the displayNode to show the model
        currentModelDisplayNode.SetInputPolyData(
            currentModelNode.GetPolyData())
        currentModelDisplayNode.SetColor(1.0, 0.55, 0.4)  # red
        currentModelDisplayNode.SetBackfaceCulling(0)
        currentModelDisplayNode.SetSliceIntersectionVisibility(0)
        currentModelDisplayNode.SetVisibility(1)
        currentModelDisplayNode.SetOpacity(1.0)
        currentModelDisplayNode.Modified()

        # update the reference between model node and it's display node
        currentModelNode.SetAndObserveDisplayNodeID(
            currentModelDisplayNode.GetID())
        currentModelNode.Modified()

        # fit slice to all sliceviewers
        slicer.app.applicationLogic().FitSliceToAll()

        # jump all sliceViewers to the first fiducial point, if one was used
        if currentSeedsNode:

            currentCoordinatesRAS = [0, 0, 0]

            if isinstance(currentSeedsNode,
                          slicer.vtkMRMLAnnotationHierarchyNode):

                childrenNodes = vtk.vtkCollection()

                currentSeedsNode.GetChildrenDisplayableNodes(childrenNodes)

                # now we have the children, let's get the first one
                currentFiducial = childrenNodes.GetItemAsObject(0)

                # grab the current coordinates
                currentFiducial.GetFiducialCoordinates(currentCoordinatesRAS)

            elif isinstance(currentSeedsNode,
                            slicer.vtkMRMLAnnotationFiducialNode):

                # grab the current coordinates
                currentSeedsNode.GetFiducialCoordinates(currentCoordinatesRAS)

            numberOfSliceNodes = slicer.mrmlScene.GetNumberOfNodesByClass(
                'vtkMRMLSliceNode')
            for n in xrange(numberOfSliceNodes):
                sliceNode = slicer.mrmlScene.GetNthNodeByClass(
                    n, "vtkMRMLSliceNode")
                if sliceNode:
                    sliceNode.JumpSliceByOffsetting(currentCoordinatesRAS[0],
                                                    currentCoordinatesRAS[1],
                                                    currentCoordinatesRAS[2])

        # center 3D view(s) on the new model
        if currentCoordinatesRAS:
            for d in range(slicer.app.layoutManager().threeDViewCount):

                threeDView = slicer.app.layoutManager().threeDWidget(
                    d).threeDView()

                # reset the focal point
                threeDView.resetFocalPoint()

                # and fly to our seed point
                interactor = threeDView.interactor()
                renderer = threeDView.renderWindow().GetRenderers(
                ).GetItemAsObject(0)
                interactor.FlyTo(renderer, currentCoordinatesRAS[0],
                                 currentCoordinatesRAS[1],
                                 currentCoordinatesRAS[2])

        SlicerVmtkCommonLib.Helper.Debug("End of Level Set Segmentation..")
  def start( self, preview=False ):
    '''
    '''
    SlicerVmtkCommonLib.Helper.Debug( "Starting Level Set Segmentation.." )

    # first we need the nodes
    currentVolumeNode = self.__inputVolumeNodeSelector.currentNode()
    currentSeedsNode = self.__seedFiducialsNodeSelector.currentNode()
    currentVesselnessNode = self.__vesselnessVolumeNodeSelector.currentNode()
    currentStoppersNode = self.__stopperFiducialsNodeSelector.currentNode()
    currentLabelMapNode = self.__outputVolumeNodeSelector.currentNode()
    currentModelNode = self.__outputModelNodeSelector.currentNode()

    if not currentVolumeNode:
        # we need a input volume node
        return 0

    if not currentSeedsNode:
        # we need a seeds node
        return 0

    if not currentStoppersNode or currentStoppersNode.GetID() == currentSeedsNode.GetID():
        # we need a current stopper node
        # self.__stopperFiducialsNodeSelector.addNode()
        pass

    if not currentLabelMapNode or currentLabelMapNode.GetID() == currentVolumeNode.GetID():
        # we need a current labelMap node
        newLabelMapDisplayNode = slicer.mrmlScene.CreateNodeByClass( "vtkMRMLLabelMapVolumeDisplayNode" )
        newLabelMapDisplayNode.SetScene( slicer.mrmlScene )
        newLabelMapDisplayNode.SetDefaultColorMap()
        slicer.mrmlScene.AddNode( newLabelMapDisplayNode )

        newLabelMapNode = slicer.mrmlScene.CreateNodeByClass( "vtkMRMLScalarVolumeNode" )
        newLabelMapNode.CopyOrientation( currentVolumeNode )
        newLabelMapNode.SetScene( slicer.mrmlScene )
        newLabelMapNode.SetName( slicer.mrmlScene.GetUniqueNameByString( self.__outputVolumeNodeSelector.baseName ) )
        newLabelMapNode.LabelMapOn()
        newLabelMapNode.SetAndObserveDisplayNodeID( newLabelMapDisplayNode.GetID() )
        slicer.mrmlScene.AddNode( newLabelMapNode )
        currentLabelMapNode = newLabelMapNode
        self.__outputVolumeNodeSelector.setCurrentNode( currentLabelMapNode )

    if not currentModelNode:
        # we need a current model node, the display node is created later
        newModelNode = slicer.mrmlScene.CreateNodeByClass( "vtkMRMLModelNode" )
        newModelNode.SetScene( slicer.mrmlScene )
        newModelNode.SetName( slicer.mrmlScene.GetUniqueNameByString( self.__outputModelNodeSelector.baseName ) )
        slicer.mrmlScene.AddNode( newModelNode )
        currentModelNode = newModelNode

        self.__outputModelNodeSelector.setCurrentNode( currentModelNode )

    # now we need to convert the fiducials to vtkIdLists
    seeds = SlicerVmtkCommonLib.Helper.convertFiducialHierarchyToVtkIdList( currentSeedsNode, currentVolumeNode )
    # stoppers = SlicerVmtkCommonLib.Helper.convertFiducialHierarchyToVtkIdList(currentStoppersNode, currentVolumeNode)
    stoppers = vtk.vtkIdList()  # TODO

    # the input image for the initialization
    inputImage = vtk.vtkImageData()

    # check if we have a vesselnessNode - this will be our input for the initialization then
    if currentVesselnessNode:
        # yes, there is one
        inputImage.DeepCopy( currentVesselnessNode.GetImageData() )
    else:
        # no, there is none - we use the original image
        inputImage.DeepCopy( currentVolumeNode.GetImageData() )

    inputImage.Update()

    # initialization
    initImageData = vtk.vtkImageData()

    # evolution
    evolImageData = vtk.vtkImageData()

    # perform the initialization
    initImageData.DeepCopy( self.GetLogic().performInitialization( inputImage,
                                                                 self.__thresholdSlider.minimumValue,
                                                                 self.__thresholdSlider.maximumValue,
                                                                 seeds,
                                                                 stoppers,
                                                                 0 ) )  # TODO sidebranch ignore feature
    initImageData.Update()

    if not initImageData.GetPointData().GetScalars():
        # something went wrong, the image is empty
        SlicerVmtkCommonLib.Helper.Info( "Segmentation failed - the output was empty.." )
        return -1

    # check if it is a preview call
    if preview:

        # if this is a preview call, we want to skip the evolution
        evolImageData.DeepCopy( initImageData )

    else:

        # no preview, run the whole thing! we never use the vesselness node here, just the original one
        evolImageData.DeepCopy( self.GetLogic().performEvolution( currentVolumeNode.GetImageData(),
                                                                initImageData,
                                                                self.__iterationSpinBox.value,
                                                                self.__inflationSlider.value,
                                                                self.__curvatureSlider.value,
                                                                self.__attractionSlider.value,
                                                                'geodesic' ) )

    evolImageData.Update()

    # create segmentation labelMap
    labelMap = vtk.vtkImageData()
    labelMap.DeepCopy( self.GetLogic().buildSimpleLabelMap( evolImageData, 0, 5 ) )
    labelMap.Update()

    currentLabelMapNode.CopyOrientation( currentVolumeNode )

    # propagate the label map to the node
    currentLabelMapNode.SetAndObserveImageData( labelMap )
    currentLabelMapNode.Modified()

    # deactivate the threshold in the GUI
    self.resetThresholdOnDisplayNode()
    # self.onInputVolumeChanged()

    # show the segmentation results in the GUI
    selectionNode = slicer.app.applicationLogic().GetSelectionNode()

    if preview and currentVesselnessNode:
        # if preview and a vesselnessNode was configured, show it
        selectionNode.SetReferenceActiveVolumeID( currentVesselnessNode.GetID() )
    else:
        # if not preview, show the original volume
        if currentVesselnessNode:
            selectionNode.SetReferenceSecondaryVolumeID( currentVesselnessNode.GetID() )
        selectionNode.SetReferenceActiveVolumeID( currentVolumeNode.GetID() )
    selectionNode.SetReferenceActiveLabelVolumeID( currentLabelMapNode.GetID() )
    slicer.app.applicationLogic().PropagateVolumeSelection()

    # generate 3D model
    model = vtk.vtkPolyData()

    # we need the ijkToRas transform for the marching cubes call
    ijkToRasMatrix = vtk.vtkMatrix4x4()
    currentLabelMapNode.GetIJKToRASMatrix( ijkToRasMatrix )

    # call marching cubes
    model.DeepCopy( self.GetLogic().marchingCubes( evolImageData, ijkToRasMatrix, 0.0 ) )
    model.Update()

    # propagate model to nodes
    currentModelNode.SetAndObservePolyData( model )
    currentModelNode.Modified()

    currentModelDisplayNode = currentModelNode.GetDisplayNode()

    if not currentModelDisplayNode:

        # create new displayNode
        currentModelDisplayNode = slicer.mrmlScene.CreateNodeByClass( "vtkMRMLModelDisplayNode" )
        slicer.mrmlScene.AddNode( currentModelDisplayNode )

    # always configure the displayNode to show the model
    currentModelDisplayNode.SetInputPolyData( currentModelNode.GetPolyData() )
    currentModelDisplayNode.SetColor( 1.0, 0.55, 0.4 )  # red
    currentModelDisplayNode.SetBackfaceCulling( 0 )
    currentModelDisplayNode.SetSliceIntersectionVisibility( 0 )
    currentModelDisplayNode.SetVisibility( 1 )
    currentModelDisplayNode.SetOpacity( 1.0 )
    currentModelDisplayNode.Modified()

    # update the reference between model node and it's display node
    currentModelNode.SetAndObserveDisplayNodeID( currentModelDisplayNode.GetID() )
    currentModelNode.Modified()

    # fit slice to all sliceviewers
    slicer.app.applicationLogic().FitSliceToAll()

    # jump all sliceViewers to the first fiducial point, if one was used
    if currentSeedsNode:

        currentCoordinatesRAS = [0, 0, 0]

        if isinstance( currentSeedsNode, slicer.vtkMRMLAnnotationHierarchyNode ):

            childrenNodes = vtk.vtkCollection()

            currentSeedsNode.GetChildrenDisplayableNodes( childrenNodes )

            # now we have the children, let's get the first one
            currentFiducial = childrenNodes.GetItemAsObject( 0 )

            # grab the current coordinates
            currentFiducial.GetFiducialCoordinates( currentCoordinatesRAS )

        elif isinstance( currentSeedsNode, slicer.vtkMRMLAnnotationFiducialNode ):

            # grab the current coordinates
            currentSeedsNode.GetFiducialCoordinates( currentCoordinatesRAS )

        numberOfSliceNodes = slicer.mrmlScene.GetNumberOfNodesByClass( 'vtkMRMLSliceNode' )
        for n in xrange( numberOfSliceNodes ):
            sliceNode = slicer.mrmlScene.GetNthNodeByClass( n, "vtkMRMLSliceNode" )
            if sliceNode:
                sliceNode.JumpSliceByOffsetting( currentCoordinatesRAS[0], currentCoordinatesRAS[1], currentCoordinatesRAS[2] )


    # center 3D view(s) on the new model
    if currentCoordinatesRAS:
        for d in range( slicer.app.layoutManager().threeDViewCount ):

            threeDView = slicer.app.layoutManager().threeDWidget( d ).threeDView()

            # reset the focal point
            threeDView.resetFocalPoint()

            # and fly to our seed point
            interactor = threeDView.interactor()
            renderer = threeDView.renderWindow().GetRenderers().GetItemAsObject( 0 )
            interactor.FlyTo( renderer, currentCoordinatesRAS[0], currentCoordinatesRAS[1], currentCoordinatesRAS[2] )

    SlicerVmtkCommonLib.Helper.Debug( "End of Level Set Segmentation.." )
  def onRegistrationButtonClicked(self):
    print "Hello Registration :) "
    self.referenceAttachmentCollapsibleButton.enabled = True
    
    linearTransformExistence = False
    linearTransformNodes = slicer.util.getNodes('vtkMRMLlinearTransformNode*')
    for linearTransformNode in linearTransformNodes.keys():
      if linearTransformNode=='ModelToTemplateTransform':
        linearTransformExistence = True
    if linearTransformExistence == False:
      followupTransform = slicer.vtkMRMLLinearTransformNode()
      followupTransform.SetName('ModelToTemplateTransform')
      followupTransform.SetScene(slicer.mrmlScene)
      slicer.mrmlScene.AddNode(followupTransform)
      self.followupTransform = followupTransform

    self.fiducialListNode = slicer.util.getNode('Template Fiducials')
    movingLandmarksListID = self.fiducialListNode.GetID()
    
    

    modelFiducials = self.modelFiducialSelector.currentNode()
    
    
    
    # extracting the effects of transform parameters
    transformNode1 = self.templateSelector.currentNode().GetParentTransformNode()
    #print transformNode1
    shiftTransform1 = [0 , 0, 0]
    rotationTransform1 = [[1, 0,0],[0,1,0],[0,0,1]]
    #shiftTransform2 = [0, 0, 0]
    #rotationTransform2 = [1, 0,0],[0,1,0],[0,0,1]]
    if transformNode1 != None:
      m = vtk.vtkMatrix4x4()
      transformNode1.GetMatrixTransformToWorld(m)
      shiftTransform1 = [ m.GetElement(0,3), m.GetElement(1,3), m.GetElement(2,3) ]
      rotationTransform1 = [[m.GetElement(0,0), m.GetElement(0,1),m.GetElement(0,2)],[m.GetElement(1,0), m.GetElement(1,1),m.GetElement(1,2)],[m.GetElement(2,0), m.GetElement(2,1),m.GetElement(2,2)]]
      #transformNode2 = transformNode1.GetParentTransformNode()
      #if transformNode2 != None:
        #transformNode2.GetMatrixTransformToWorld(m)
        #shiftTransform2 = [ m.GetElement(0,3), m.GetElement(1,3), m.GetElement(2,3) ]
        #rotationTransform2 = [[m.GetElement(0,0), m.GetElement(0,1),m.GetElement(0,2)],[m.GetElement(1,0), m.GetElement(1,1),m.GetElement(1,2)],[m.GetElement(2,0), m.GetElement(2,1),m.GetElement(2,2)]
    #shiftTransform = numpy.add(shiftTransform1,shiftTransform2)

    
    
    # Changing the fiducial coordinates according to the transform
    
    if modelFiducials.GetClassName() == "vtkMRMLAnnotationHierarchyNode":
    # slicer4 style hierarchy nodes
      collection = vtk.vtkCollection()
      modelFiducials.GetChildrenDisplayableNodes(collection)
      n = collection.GetNumberOfItems()
    
    
    if n != 6: 
        return
      # output an error and ask user to select a fiducial with 6 points
    listExitence = False
    hierarchyNodes = slicer.util.getNodes('vtkMRMLAnnotationHierarchyNode*')
    for hierarchyNode in hierarchyNodes.keys():
      if hierarchyNode=='New Model Fiducials':
        listExitence = True
        self.newModelFiducialAnnotationList.RemoveAllChildrenNodes()
    if listExitence == False:
      newModelFiducialAnnotationList = slicer.vtkMRMLAnnotationHierarchyNode()
      newModelFiducialAnnotationList.SetName('New Model Fiducials')
      # hide the fiducial list from the scene
      newModelFiducialAnnotationList.SetHideFromEditors(1)
      newModelFiducialAnnotationList.SetScene(self.scene)
      self.scene.AddNode(newModelFiducialAnnotationList)
      self.newModelFiducialAnnotationList = newModelFiducialAnnotationList

    self.logic.SetActiveHierarchyNodeID(self.newModelFiducialAnnotationList.GetID())



    #self.logic.AddHierarchy
    #a=self.logic.GetActiveHierarchyNode()
    #a.SetName('New Model Fiducials')
    
    p = numpy.zeros((n,3))
    for i in xrange(n):
      f = collection.GetItemAsObject(i)
      coords = [0,0,0]
      # Need to change to consider the transform that is applied to the points
      f.GetFiducialCoordinates(coords)
      newCoords = numpy.add(numpy.dot(rotationTransform1,coords),shiftTransform1)
      newfid = slicer.vtkMRMLAnnotationFiducialNode()
      newfid.SetFiducialCoordinates(newCoords)
      newfid.SetHideFromEditors(0)
      newfid.SetName(str(i))
      self.scene.AddNode(newfid)

    fixedLandmarksListID = self.newModelFiducialAnnotationList.GetID() 

    self.OutputMessage = ""
    parameters = {}
    parameters["fixedLandmarks"] = fixedLandmarksListID 
    parameters["movingLandmarks"] = movingLandmarksListID
   
    parameters["saveTransform"] = self.followupTransform
    parameters["transformType"] = "Rigid"
    parameters["rms"] = self.RMS
    parameters["outputMessage"] = self.OutputMessage
    
    fidreg = slicer.modules.fiducialregistration
    self.__cliNode = None
    self.__cliNode = slicer.cli.run(fidreg, self.__cliNode, parameters)
    print "RMS is", self.RMS
    #self.__cliObserverTag = self.__cliNode.AddObserver('ModifiedEvent', self.processRegistrationCompletion)
    #self.__registrationStatus.setText('Wait ...')
    #self.firstRegButton.setEnabled(0)

    stylusNode = self.stylusTrackerSelector.currentNode() 
    stylusNode.SetAndObserveTransformNodeID(self.followupTransform.GetID())
Example #36
0
    def onCalculateButton(self):
        logic = SpinalCurvatureMeasurementLogic()
        (self.superiorAnglesList,
         self.inferiorAnglesList) = logic.calculateAngles(
             self.inputSelector.currentNode(),
             self.projectionPlaneBox.currentText)

        superiorAnglesListCount = 0
        for superiorAngle in self.superiorAnglesList:
            self.angleTable.item(superiorAnglesListCount,
                                 1).setText(str(superiorAngle))
            superiorAnglesListCount += 1

        inferiorAnglesListCount = 0
        for inferiorAngle in self.inferiorAnglesList:
            self.angleTable.item(inferiorAnglesListCount,
                                 2).setText(str(inferiorAngle))
            inferiorAnglesListCount += 1

        # Refresh observers
        for rulerNode, tag in self.observerTags:
            rulerNode.RemoveObserver(tag)

        rulerNodes = vtk.vtkCollection()
        self.inputSelector.currentNode().GetDirectChildren(rulerNodes)

        rulerNodesList = []
        for nodeIndex in range(rulerNodes.GetNumberOfItems()):
            if rulerNodes.GetItemAsObject(
                    nodeIndex).GetClassName() == "vtkMRMLAnnotationRulerNode":
                rulerNodesList.append(rulerNodes.GetItemAsObject(nodeIndex))

        for rulerNode in rulerNodesList:

            def update(caller, ev):
                import re
                angle = logic.updateAngle(caller,
                                          self.projectionPlaneBox.currentText)

                rulerName = caller.GetName()
                #nameSearch.group(1) - Region (C, T, or L)
                #nameSearch.group(2) - Number (1, 2, 3, etc.)
                #nameSearch.group(3) - Superior or Inferior (s or i)
                nameSearch = re.search(r"^([CTL])(\d+)-([si])$", rulerName)
                if nameSearch != None:
                    if nameSearch.group(1) == "C":
                        index = int(nameSearch.group(2)) - 1
                    elif nameSearch.group(1) == "T":
                        index = int(nameSearch.group(
                            2)) + self.CONST_NUMBER_OF_CERVICAL_VERTERBRAE - 1
                    elif nameSearch.group(1) == "L":
                        index = int(
                            nameSearch.group(2)
                        ) + self.CONST_NUMBER_OF_CERVICAL_VERTERBRAE + self.CONST_NUMBER_OF_THORACIC_VERTERBRAE - 1

                    if nameSearch.group(3) == "s":
                        self.angleTable.item(index, 1).setText(str(angle))
                    elif nameSearch.group(3) == "i":
                        self.angleTable.item(index, 2).setText(str(angle))

            tag = rulerNode.AddObserver(rulerNode.ControlPointModifiedEvent,
                                        update)
            self.observerTags.append([rulerNode, tag])
Example #37
0
    def calculateAngles(self, annotationHierarchy, planeOrientation):
        import re, math

        superiorCervicalAngles = [None
                                  ] * self.CONST_NUMBER_OF_CERVICAL_VERTERBRAE
        superiorThoracicAngles = [None
                                  ] * self.CONST_NUMBER_OF_THORACIC_VERTERBRAE
        superiorLumbarAngles = [None] * self.CONST_NUMBER_OF_LUMBAR_VERTERBRAE

        inferiorCervicalAngles = [None
                                  ] * self.CONST_NUMBER_OF_CERVICAL_VERTERBRAE
        inferiorThoracicAngles = [None
                                  ] * self.CONST_NUMBER_OF_THORACIC_VERTERBRAE
        inferiorLumbarAngles = [None] * self.CONST_NUMBER_OF_LUMBAR_VERTERBRAE

        if planeOrientation == "Coronal":
            planeNormal = [0, 1, 0]
            baseAngleVector = [1, 0, 0]
        elif planeOrientation == "Axial":
            planeNormal = [0, 0, 1]
            baseAngleVector = [1, 0, 0]
        else:
            planeNormal = [1, 0, 0]
            baseAngleVector = [0, 1, 0]

        rulerNodes = vtk.vtkCollection()
        annotationHierarchy.GetDirectChildren(rulerNodes)

        rulerNodesList = []
        for nodeIndex in range(rulerNodes.GetNumberOfItems()):
            if rulerNodes.GetItemAsObject(
                    nodeIndex).GetClassName() == "vtkMRMLAnnotationRulerNode":
                rulerNodesList.append(rulerNodes.GetItemAsObject(nodeIndex))

        for ruler in rulerNodesList:
            angle = self.updateAngle(ruler, planeOrientation)

            rulerName = ruler.GetName()
            #nameSearch.group(1) - Region (C, T, or L)
            #nameSearch.group(2) - Number (1, 2, 3, etc.)
            #nameSearch.group(3) - Superior or Inferior (s or i)
            nameSearch = re.search(r"^([CTL])(\d+)-([si])$", rulerName)
            if nameSearch != None:
                if nameSearch.group(1) == "C":
                    if nameSearch.group(3) == "s":
                        superiorCervicalAngles[int(nameSearch.group(2)) -
                                               1] = angle
                    elif nameSearch.group(3) == "i":
                        inferiorCervicalAngles[int(nameSearch.group(2)) -
                                               1] = angle
                elif nameSearch.group(1) == "T":
                    if nameSearch.group(3) == "s":
                        superiorThoracicAngles[int(nameSearch.group(2)) -
                                               1] = angle
                    elif nameSearch.group(3) == "i":
                        inferiorThoracicAngles[int(nameSearch.group(2)) -
                                               1] = angle
                elif nameSearch.group(1) == "L":
                    if nameSearch.group(3) == "s":
                        superiorLumbarAngles[int(nameSearch.group(2)) -
                                             1] = angle
                    elif nameSearch.group(3) == "i":
                        inferiorLumbarAngles[int(nameSearch.group(2)) -
                                             1] = angle

        return (superiorCervicalAngles + superiorThoracicAngles +
                superiorLumbarAngles, inferiorCervicalAngles +
                inferiorThoracicAngles + inferiorLumbarAngles)
Example #38
0
    def __init__(self, markersFiducialsNode, targetFiducialNode, entryFiducialNode):
        
        self.fids = [markersFiducialsNode, targetFiducialNode, entryFiducialNode]

        # Get the point's coordinates in the markers, target and entry fiducials
        self.position = [] #save the points' position
        for i in range(len(self.fids)):
            if self.fids[i].GetClassName() == "vtkMRMLAnnotationHierarchyNode":
                # slicer4 style hierarchy nodes
                collection = vtk.vtkCollection()
                self.fids[i].GetChildrenDisplayableNodes(collection)
                self.n =  collection.GetNumberOfItems()
                if self.n == 0:
                    return
                self.p = numpy.zeros((self.n,3))
                for j in xrange(self.n):
                    f = collection.GetItemAsObject(j)
                    coords = [0,0,0]
                    f.GetFiducialCoordinates(coords)
                    self.p[j] = coords
            elif self.fids[i].GetClassName() == 'vtkMRMLMarkupsFiducialNode':
                # slicer4 Markups node
                self.n = self.fids[i].GetNumberOfFiducials()
                n = self.n
                if n == 0:
                    return
                # get fiducial positions
                # sets self.p
                self.p = numpy.zeros((n,3))
                for j in xrange(n):
                    coord = [0.0, 0.0, 0.0]
                    self.fids[i].GetNthFiducialPosition(j, coord)
                    self.p[j] = coord
            else:
                # slicer3 style fiducial lists
                self.n = self.fids[i].GetNumberOfFiducials()
                n = self.n
                if n == 0:
                    return
                #sets self.p
                self.p = numpy.zeros((n,3))
                for j in xrange(n):
                    self.p[j] = self.fids[i].GetNthFiducialXYZ(j)
            self.position.append(self.p)

        #Vectors of the points and the normals of the reference plane
        vector1 = self.position[0][0] - self.position[0][1] #a vector in the plane red
        vector2 = self.position[0][0] - self.position[0][2] #a vector in the plane red
        normalRed = numpy.cross(vector1,vector2) #normal of the plane red using the 'numpy.cross()' to calculate the cross product of two vector
        vector3 = self.position[0][3] - self.position[0][4] #a vector in the plane green
        normalGreen = numpy.cross(vector3, normalRed) #normal of the plane green
        normalBlue = numpy.cross(normalRed, normalGreen)#normal of the plane blue

        #Vector of the target and entry point
        vectorTargetEntry = self.position[1][0] - self.position[2][0]# the vector the target and entry point

        #Distance between target and entry point
        distance = round(numpy.linalg.norm(vectorTargetEntry), 1)

        #Angles between the puncture path and the reference plane
        sinAngleRed = numpy.abs(numpy.dot(vectorTargetEntry, normalRed)) / (numpy.linalg.norm(normalRed)*numpy.linalg.norm(vectorTargetEntry)) 
        sinAngleGreen = numpy.abs(numpy.dot(vectorTargetEntry, normalGreen)) / (numpy.linalg.norm(normalGreen)*numpy.linalg.norm(vectorTargetEntry)) 
        sinAngleBlue = numpy.abs(numpy.dot(vectorTargetEntry, normalBlue)) / (numpy.linalg.norm(normalBlue)*numpy.linalg.norm(vectorTargetEntry))

        angleRed = round(numpy.arcsin(sinAngleRed) / numpy.pi * 180.0, 1) # angle of the puncture path relative to the plane red
        angleGreen = round(numpy.arcsin(sinAngleGreen) / numpy.pi * 180.0, 1) # angle of the puncture path relative to the plane green
        angleBlue = round(numpy.arcsin(sinAngleBlue) / numpy.pi * 180.0, 1) # angle of the puncture path relative to the plane blue

        self.normalRed = normalRed
        self.normalGreen = normalGreen
        self.normalBlue = normalBlue
        
        self.angleRed = angleRed
        self.angleGreen = angleGreen
        self.angleBlue = angleBlue
        self.distance = distance
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 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 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))
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 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()