Beispiel #1
0
 def onDatabaseDirectoryChanged(self,databaseDirectory):
   if not hasattr(slicer, 'dicomDatabase') or not slicer.dicomDatabase:
     slicer.dicomDatabase = ctk.ctkDICOMDatabase()
   DICOM.setDatabasePrecacheTags(self.dicomBrowser)
   databaseFilepath = databaseDirectory + "/ctkDICOM.sql"
   messages = ""
   if not os.path.exists(databaseDirectory):
     try:
       os.mkdir(databaseDirectory)
     except OSError:
       messages += "Directory does not exist and cannot be created. "
   else:
     if not os.access(databaseDirectory, os.W_OK):
       messages += "Directory not writable. "
     if not os.access(databaseDirectory, os.R_OK):
       messages += "Directory not readable. "
   if messages != "":
     self.messageBox('The database file path "%s" cannot be used.  %s\nPlease pick a different database directory using the LocalDatabase button in the DICOM Browser.' % (databaseFilepath,messages))
   else:
     slicer.dicomDatabase.openDatabase(databaseDirectory + "/ctkDICOM.sql", "SLICER")
     if not slicer.dicomDatabase.isOpen:
       self.messageBox('The database file path "%s" cannot be opened.\nPlease pick a different database directory using the LocalDatabase button in the DICOM Browser.' % databaseFilepath)
       self.dicomDatabase = None
     else:
       if self.dicomBrowser:
         if self.dicomBrowser.databaseDirectory != databaseDirectory:
           self.dicomBrowser.databaseDirectory = databaseDirectory
       else:
         settings = qt.QSettings()
         settings.setValue('DatabaseDirectory', databaseDirectory)
         settings.sync()
   if slicer.dicomDatabase:
     slicer.app.setDICOMDatabase(slicer.dicomDatabase)
Beispiel #2
0
 def onDatabaseDirectoryChanged(self, databaseDirectory):
     if not hasattr(slicer, 'dicomDatabase') or not slicer.dicomDatabase:
         slicer.dicomDatabase = ctk.ctkDICOMDatabase()
         self.setDatabasePrecacheTags()
     databaseFilepath = databaseDirectory + "/ctkDICOM.sql"
     messages = ""
     if not os.path.exists(databaseDirectory):
         messages += "Directory does not exist. "
     else:
         if not os.access(databaseDirectory, os.W_OK):
             messages += "Directory not writable. "
         if not os.access(databaseDirectory, os.R_OK):
             messages += "Directory not readable. "
     if messages != "":
         self.messageBox(
             'The database file path "%s" cannot be used.  %s\nPlease pick a different database directory using the LocalDatabase button in the DICOM Browser.'
             % (databaseFilepath, messages))
     else:
         slicer.dicomDatabase.openDatabase(
             databaseDirectory + "/ctkDICOM.sql", "SLICER")
         if not slicer.dicomDatabase.isOpen:
             self.messageBox(
                 'The database file path "%s" cannot be opened.\nPlease pick a different database directory using the LocalDatabase button in the DICOM Browser.'
                 % databaseFilepath)
             self.dicomDatabase = None
         else:
             if self.dicomApp:
                 if self.dicomApp.databaseDirectory != databaseDirectory:
                     self.dicomApp.databaseDirectory = databaseDirectory
             else:
                 settings = qt.QSettings()
                 settings.setValue('DatabaseDirectory', databaseDirectory)
                 settings.sync()
     if slicer.dicomDatabase:
         slicer.app.setDICOMDatabase(slicer.dicomDatabase)
Beispiel #3
0
  def __init__(self, parent):
    parent.title = "DICOM"
    parent.category = "Work in Progress"
    parent.contributor = "Steve Pieper"
    parent.helpText = """
The DICOM module is a place to experiment a bit with dicom classes from CTK (based on DCMTK).  It is a 'tent' because it is meant to be suitable for explorers, but may not be robust enough for civilized people.

Warning: all data directories are temporary and data may be gone next time you look!
    """
    parent.acknowledgementText = """
This work is supported by NA-MIC, NAC, BIRN, NCIGT, and the Slicer Community. See <a>http://www.slicer.org</a> for details.  Module implemented by Steve Pieper.  Based on work from CommonTK (http://www.commontk.org).
    """
    self.parent = parent

    if slicer.mrmlScene.GetTagByClassName( "vtkMRMLScriptedModuleNode" ) != 'ScriptedModule':
      slicer.mrmlScene.RegisterNodeClass(vtkMRMLScriptedModuleNode())

    # initialize the dicom infrastructure
    settings = qt.QSettings()
    # the dicom listener is also global, but only started on app start if 
    # the user so chooses
    if settings.contains('DICOM/RunListenerAtStart'):
      if bool(settings.value('DICOM/RunListenerAtStart')):
        # the dicom database is a global object for slicer
        databaseDirectory = settings.value('DatabaseDirectory')
        if databaseDirectory: 
          slicer.dicomDatabase = ctk.ctkDICOMDatabase()
          slicer.dicomDatabase.openDatabase(databaseDirectory + "/ctkDICOM.sql", "SLICER")
          if not hasattr(slicer, 'dicomListener'):
            try:
              slicer.dicomListener = DICOMLib.DICOMListener(slicer.dicomDatabase)
            except UserWarning as message:
              # TODO: how to put this into the error log?
              print ('Problem trying to start DICOMListener:\n %s' % message)
            slicer.dicomListener.start()
Beispiel #4
0
 def onDatabaseDirectoryChanged(self, databaseDirectory):
     if not hasattr(slicer, 'dicomDatabase') or not slicer.dicomDatabase:
         slicer.dicomDatabase = ctk.ctkDICOMDatabase()
         self.setDatabasePrecacheTags()
     databaseFilepath = databaseDirectory + "/ctkDICOM.sql"
     if not (os.access(databaseDirectory, os.W_OK)
             and os.access(databaseDirectory, os.R_OK)):
         self.messageBox('The database file path "%s" cannot be opened.' %
                         databaseFilepath)
     else:
         slicer.dicomDatabase.openDatabase(
             databaseDirectory + "/ctkDICOM.sql", "SLICER")
         if not slicer.dicomDatabase.isOpen:
             self.messageBox(
                 'The database file path "%s" cannot be opened.' %
                 databaseFilepath)
             self.dicomDatabase = None
         else:
             if self.dicomApp:
                 if self.dicomApp.databaseDirectory != databaseDirectory:
                     self.dicomApp.databaseDirectory = databaseDirectory
             else:
                 settings = qt.QSettings()
                 settings.setValue('DatabaseDirectory', databaseDirectory)
                 settings.sync()
     if slicer.dicomDatabase:
         slicer.app.setDICOMDatabase(slicer.dicomDatabase)
Beispiel #5
0
    def __init__(self, parent):
        import string
        parent.title = "DICOM"
        parent.categories = ["", "Informatics"]  # top level module
        parent.contributors = ["Steve Pieper (Isomics)"]
        parent.helpText = string.Template("""
The DICOM module integrates DICOM classes from CTK (based on DCMTK).  See <a href=\"$a/Documentation/$b.$c/Modules/DICOM\">the documentaiton</a> for more information.
""").substitute({
            'a': parent.slicerWikiUrl,
            'b': slicer.app.majorVersion,
            'c': slicer.app.minorVersion
        })
        parent.acknowledgementText = """
This work is supported by NA-MIC, NAC, BIRN, NCIGT, and the Slicer Community. See <a href=http://www.slicer.org>http://www.slicer.org</a> for details.  Module implemented by Steve Pieper.  Based on work from CommonTK (http://www.commontk.org).
    """
        parent.icon = qt.QIcon(':Icons/Medium/SlicerLoadDICOM.png')
        self.parent = parent

        if slicer.mrmlScene.GetTagByClassName(
                "vtkMRMLScriptedModuleNode") != 'ScriptedModule':
            slicer.mrmlScene.RegisterNodeClass(vtkMRMLScriptedModuleNode())

        # initialize the dicom infrastructure
        slicer.dicomDatabase = None
        settings = qt.QSettings()
        # the dicom database is a global object for slicer
        if settings.contains('DatabaseDirectory'):
            databaseDirectory = settings.value('DatabaseDirectory')
            if databaseDirectory:
                slicer.dicomDatabase = ctk.ctkDICOMDatabase()
                slicer.dicomDatabase.openDatabase(
                    databaseDirectory + "/ctkDICOM.sql", "SLICER")
                if not slicer.dicomDatabase.isOpen:
                    # can't open the database, so prompt the user later if they enter module
                    slicer.dicomDatabase = None
                else:
                    # the dicom listener is also global, but only started on app start if
                    # the user so chooses
                    if settings.contains('DICOM/RunListenerAtStart'):
                        if settings.value(
                                'DICOM/RunListenerAtStart') == 'true':
                            if not hasattr(slicer, 'dicomListener'):
                                try:
                                    slicer.dicomListener = DICOMLib.DICOMListener(
                                        slicer.dicomDatabase)
                                    slicer.dicomListener.start()
                                except (UserWarning, OSError) as message:
                                    # TODO: how to put this into the error log?
                                    print(
                                        'Problem trying to start DICOMListener:\n %s'
                                        % message)
                if slicer.dicomDatabase:
                    slicer.app.setDICOMDatabase(slicer.dicomDatabase)

        # Trigger the menu to be added when application has started up
        if not slicer.app.commandOptions().noMainWindow:
            qt.QTimer.singleShot(0, self.addMenu)
        # set the dicom pre-cache tags once all plugin classes have been initialized
        qt.QTimer.singleShot(0, DICOM.setDatabasePrecacheTags)
Beispiel #6
0
 def onDatabaseDirectoryChanged(self,databaseDirectory):
   if not hasattr(slicer, 'dicomDatabase'):
     slicer.dicomDatabase = ctk.ctkDICOMDatabase()
   databaseFilepath = databaseDirectory + "/ctkDICOM.sql"
   if not (os.access(databaseDirectory, os.W_OK) and os.access(databaseDirectory, os.R_OK)):
     self.messageBox('The database file path "%s" cannot be opened.' % databaseFilepath)
     return
   slicer.dicomDatabase.openDatabase(databaseDirectory + "/ctkDICOM.sql", "SLICER")
   if not slicer.dicomDatabase.isOpen:
     self.messageBox('The database file path "%s" cannot be opened.' % databaseFilepath)
Beispiel #7
0
  def __init__(self, parent):
    ScriptedLoadableModule.__init__(self, parent)
    import string
    self.parent.title = "DICOM"
    self.parent.categories = ["", "Informatics"] # top level module
    self.parent.contributors = ["Steve Pieper (Isomics)"]
    self.parent.helpText = string.Template("""
The DICOM module integrates DICOM classes from CTK (based on DCMTK).  See <a href=\"$a/Documentation/$b.$c/Modules/DICOM\">the documentaiton</a> for more information.
""").substitute({ 'a':parent.slicerWikiUrl, 'b':slicer.app.majorVersion, 'c':slicer.app.minorVersion })
    self.parent.acknowledgementText = """
This work is supported by NA-MIC, NAC, BIRN, NCIGT, and the Slicer Community. See <a href=http://www.slicer.org>http://www.slicer.org</a> for details.  Module implemented by Steve Pieper.  Based on work from CommonTK (http://www.commontk.org).
    """
    self.parent.icon = qt.QIcon(':Icons/Medium/SlicerLoadDICOM.png')
    self.parent.dependencies = ["SubjectHierarchy"]

    if slicer.mrmlScene.GetTagByClassName( "vtkMRMLScriptedModuleNode" ) != 'ScriptedModule':
      slicer.mrmlScene.RegisterNodeClass(vtkMRMLScriptedModuleNode())

    # initialize the dicom infrastructure
    slicer.dicomDatabase = None
    settings = qt.QSettings()
    # the dicom database is a global object for slicer
    if settings.contains('DatabaseDirectory'):
      databaseDirectory = settings.value('DatabaseDirectory')
      if databaseDirectory:
        slicer.dicomDatabase = ctk.ctkDICOMDatabase()
        slicer.dicomDatabase.openDatabase(databaseDirectory + "/ctkDICOM.sql", "SLICER")
        if not slicer.dicomDatabase.isOpen:
          # can't open the database, so prompt the user later if they enter module
          slicer.dicomDatabase = None
        else:
          # the dicom listener is also global, but only started on app start if
          # the user so chooses
          if settings.contains('DICOM/RunListenerAtStart'):
            if settings.value('DICOM/RunListenerAtStart') == 'true':
              if not hasattr(slicer, 'dicomListener'):
                try:
                  slicer.dicomListener = DICOMLib.DICOMListener(slicer.dicomDatabase)
                  slicer.dicomListener.start()
                except (UserWarning,OSError) as message:
                  # TODO: how to put this into the error log?
                  print ('Problem trying to start DICOMListener:\n %s' % message)
        if slicer.dicomDatabase:
          slicer.app.setDICOMDatabase(slicer.dicomDatabase)

    # Trigger the menu to be added when application has started up
    if not slicer.app.commandOptions().noMainWindow :
      qt.QTimer.singleShot(0, self.addMenu)
    # set the dicom pre-cache tags once all plugin classes have been initialized
    qt.QTimer.singleShot(0, DICOM.setDatabasePrecacheTags)
Beispiel #8
0
 def onDatabaseDirectoryChanged(self, databaseDirectory):
     if not hasattr(slicer, 'dicomDatabase'):
         slicer.dicomDatabase = ctk.ctkDICOMDatabase()
     databaseFilepath = databaseDirectory + "/ctkDICOM.sql"
     if not (os.access(databaseDirectory, os.W_OK)
             and os.access(databaseDirectory, os.R_OK)):
         self.messageBox('The database file path "%s" cannot be opened.' %
                         databaseFilepath)
         return
     slicer.dicomDatabase.openDatabase(databaseDirectory + "/ctkDICOM.sql",
                                       "SLICER")
     if not slicer.dicomDatabase.isOpen:
         self.messageBox('The database file path "%s" cannot be opened.' %
                         databaseFilepath)
Beispiel #9
0
    def __init__(self, parent):
        import string

        parent.title = "DICOM"
        parent.categories = ["", "Informatics"]  # top level module
        parent.contributors = ["Steve Pieper (Isomics)"]
        parent.helpText = string.Template(
            """
The DICOM module integrates DICOM classes from CTK (based on DCMTK).  See <a href=\"$a/Documentation/$b.$c/Modules/DICOM\">$a/Documentation/$b.$c/Modules/DICOM</a> for more information.
"""
        ).substitute({"a": parent.slicerWikiUrl, "b": slicer.app.majorVersion, "c": slicer.app.minorVersion})
        parent.acknowledgementText = """
This work is supported by NA-MIC, NAC, BIRN, NCIGT, and the Slicer Community. See <a>http://www.slicer.org</a> for details.  Module implemented by Steve Pieper.  Based on work from CommonTK (http://www.commontk.org).
    """
        parent.icon = qt.QIcon(":Icons/Medium/SlicerLoadDICOM.png")
        self.parent = parent

        if slicer.mrmlScene.GetTagByClassName("vtkMRMLScriptedModuleNode") != "ScriptedModule":
            slicer.mrmlScene.RegisterNodeClass(vtkMRMLScriptedModuleNode())

        # initialize the dicom infrastructure
        settings = qt.QSettings()
        # the dicom database is a global object for slicer
        if settings.contains("DatabaseDirectory"):
            databaseDirectory = settings.value("DatabaseDirectory")
            if databaseDirectory:
                slicer.dicomDatabase = ctk.ctkDICOMDatabase()
                slicer.dicomDatabase.openDatabase(databaseDirectory + "/ctkDICOM.sql", "SLICER")
                # the dicom listener is also global, but only started on app start if
                # the user so chooses
                if settings.contains("DICOM/RunListenerAtStart"):
                    if bool(settings.value("DICOM/RunListenerAtStart")):
                        if not hasattr(slicer, "dicomListener"):
                            try:
                                slicer.dicomListener = DICOMLib.DICOMListener(slicer.dicomDatabase)
                                slicer.dicomListener.start()
                            except (UserWarning, OSError) as message:
                                # TODO: how to put this into the error log?
                                print("Problem trying to start DICOMListener:\n %s" % message)
        else:
            slicer.dicomDatabase = None

        # Trigger the menu to be added when application has started up
        if not slicer.app.commandOptions().noMainWindow:
            qt.QTimer.singleShot(0, self.addMenu)
Beispiel #10
0
  def __init__(self, parent=None):
    self.testingServer = None
    self.dicomDatabase = ctk.ctkDICOMDatabase()

    # TODO: are these wrapped so we can avoid magic numbers?
    self.dicomModelUIDRole = 32
    self.dicomModelTypeRole = self.dicomModelUIDRole + 1
    self.dicomModelTypes = ('Root', 'Patient', 'Study', 'Series', 'Image')

    if not parent:
      self.parent = slicer.qMRMLWidget()
      self.parent.setLayout(qt.QVBoxLayout())
      self.parent.setMRMLScene(slicer.mrmlScene)
      self.layout = self.parent.layout()
      self.setup()
      self.parent.show()
    else:
      self.parent = parent
      self.layout = parent.layout()
Beispiel #11
0
 def onDatabaseDirectoryChanged(self,databaseDirectory):
   if not hasattr(slicer, 'dicomDatabase') or not slicer.dicomDatabase:
     slicer.dicomDatabase = ctk.ctkDICOMDatabase()
     self.setDatabasePrecacheTags()
   databaseFilepath = databaseDirectory + "/ctkDICOM.sql"
   if not (os.access(databaseDirectory, os.W_OK) and os.access(databaseDirectory, os.R_OK)):
     self.messageBox('The database file path "%s" cannot be opened.' % databaseFilepath)
     return
   slicer.dicomDatabase.openDatabase(databaseDirectory + "/ctkDICOM.sql", "SLICER")
   if not slicer.dicomDatabase.isOpen:
     self.messageBox('The database file path "%s" cannot be opened.' % databaseFilepath)
     self.dicomDatabase = None
     return
   if self.dicomApp:
     if self.dicomApp.databaseDirectory != databaseDirectory:
       self.dicomApp.databaseDirectory = databaseDirectory
   else:
     settings = qt.QSettings()
     settings.setValue('DatabaseDirectory', databaseDirectory)
     settings.sync()
Beispiel #12
0
    def __init__(self, parent):
        parent.title = "DICOM"
        parent.category = ""  # top level module
        parent.contributor = "Steve Pieper"
        parent.helpText = """
The DICOM module is a place to experiment a bit with dicom classes from CTK (based on DCMTK).  It is a 'tent' because it is meant to be suitable for explorers, but may not be robust enough for civilized people.

Warning: all data directories are temporary and data may be gone next time you look!
    """
        parent.acknowledgementText = """
This work is supported by NA-MIC, NAC, BIRN, NCIGT, and the Slicer Community. See <a>http://www.slicer.org</a> for details.  Module implemented by Steve Pieper.  Based on work from CommonTK (http://www.commontk.org).
    """
        self.parent = parent

        if slicer.mrmlScene.GetTagByClassName(
                "vtkMRMLScriptedModuleNode") != 'ScriptedModule':
            slicer.mrmlScene.RegisterNodeClass(vtkMRMLScriptedModuleNode())

        # initialize the dicom infrastructure
        settings = qt.QSettings()
        # the dicom database is a global object for slicer
        databaseDirectory = settings.value('DatabaseDirectory')
        if databaseDirectory:
            slicer.dicomDatabase = ctk.ctkDICOMDatabase()
            slicer.dicomDatabase.openDatabase(
                databaseDirectory + "/ctkDICOM.sql", "SLICER")
            # the dicom listener is also global, but only started on app start if
            # the user so chooses
            if settings.contains('DICOM/RunListenerAtStart'):
                if bool(settings.value('DICOM/RunListenerAtStart')):
                    if not hasattr(slicer, 'dicomListener'):
                        try:
                            slicer.dicomListener = DICOMLib.DICOMListener(
                                slicer.dicomDatabase)
                        except UserWarning as message:
                            # TODO: how to put this into the error log?
                            print(
                                'Problem trying to start DICOMListener:\n %s' %
                                message)
                        slicer.dicomListener.start()
Beispiel #13
0
    def test_RoundTrip(self):
        """
    Test fiducial round trip to and from AIM XML file on disk
    """

        print("ctest, please don't truncate my output: CTEST_FULL_OUTPUT")

        # enter the module
        mainWindow = slicer.util.mainWindow()
        mainWindow.moduleSelector().selectModule('Reporting')

        # l = slicer.modulelogic.vtkSlicerReportingModuleLogic()
        l = slicer.modules.reporting.logic()
        l.GUIHiddenOff()

        # testDataPath = os.path.normpath(os.path.join(os.path.realpath(__file__), "..", "..", "Prototype/TestData/DICOM.CT/")
        print("Reporting round trip test, current working directory = " +
              os.getcwd())
        testDataPath = os.path.join(os.getcwd(),
                                    "../../Testing/Temporary/DICOM.CT")
        # testDataPath = "/projects/birn/nicole/Slicer4/Reporting/Prototype/TestData/DICOM.CT"
        print("test data path = " + testDataPath)

        # set up a new DICOM database
        print("Creating a dicomDatabase!")
        ddb = ctk.ctkDICOMDatabase()
        if not ddb:
            print("ERROR: failed to create a new dicom database!")
            return
        dbpath = slicer.app.slicerHome + '/Testing/Temporary/TestingDCMDB/ctkDICOM.sql'
        print('database path set to ' + dbpath)
        if not os.path.exists(os.path.dirname(dbpath)):
            print('Creating dir ' + os.path.dirname(dbpath))
            os.makedirs(os.path.dirname(dbpath))
        ddb.openDatabase(dbpath, "ReportingTesting")
        if not ddb.isOpen:
            print("ERROR: failed to open a new dicom database at path " +
                  dbpath)
            return
        retval = ddb.initializeDatabase()
        if not retval:
            print("ERROR: failed to init database")
            return

        l.InitializeDICOMDatabase(dbpath)

        testFileNames = []
        for n in [487, 488, 489]:
            filename = os.path.join(testDataPath,
                                    "instance_" + str(n) + ".dcm")
            print("Adding file " + filename)
            testFileNames.append(filename)

        # check to see if the test data is already in it
        patients = ddb.patients()
        if len(patients) == 0:
            # add the files
            for filename in testFileNames:
                print("Inserting file " + filename)
                retval = ddb.insert(filename)
            patients = ddb.patients()
            if len(patients) == 0:
                print("ERROR: unable to add test files to database!")
                print(str(testFileNames))
                return

        # get the UID for the series
        study = ddb.studiesForPatient(patients[0])
        series = ddb.seriesForStudy(study[0])
        seriesUID = series[0]

        # seriesUID = "1.2.392.200103.20080913.113635.2.2009.6.22.21.43.10.23432.1"
        # seriesUID = "2.16.840.1.114362.1.759508.1251415878280.192"
        # seriesUID = "1.3.12.2.1107.5.1.4.53031.30000011032906120157800000219"
        print("For test, using the AIM sample volume with series UID of " +
              seriesUID)
        fileList = ddb.filesForSeries(seriesUID)
        print("fileList = " + str(fileList))
        if not fileList:
            print("ERROR: sample series with id " + seriesUID +
                  " not found in database!")
            return

        # add a parameter node
        parameterNode = slicer.vtkMRMLScriptedModuleNode()
        parameterNode.SetModuleName('Reporting')
        slicer.mrmlScene.AddNode(parameterNode)
        # set it to be the active parameter node
        l.SetActiveParameterNodeID(parameterNode.GetID())

        #
        # create a new report, make it the report in the parameter node, set up hierarchy
        #
        reportNode = slicer.mrmlScene.CreateNodeByClass(
            "vtkMRMLReportingReportNode")
        reportNode.SetReferenceCount(reportNode.GetReferenceCount() - 1)

        # set the color id
        colorID = 'vtkMRMLColorTableNodeFileGenericAnatomyColors.txt'
        reportNode.SetColorNodeID(colorID)
        reportNode.SetDICOMDatabaseFileName(dbpath)

        slicer.mrmlScene.AddNode(reportNode)
        parameterNode.SetParameter("reportID", reportNode.GetID())
        print(
            "Init hierarchy for report node, set parameter node to report id of "
            + reportNode.GetID())
        l.InitializeHierarchyForReport(reportNode)

        #
        # get some sample data from the database
        #
        volId = 1
        volumeNode = None
        volName = 'AIM volume ' + str(volId)

        print("Dicom data base = " + ddb)

        slicer.dicomDatabase = ddb
        scalarVolumePlugin = slicer.modules.dicomPlugins[
            'DICOMScalarVolumePlugin']()
        scalarVolumeLoadables = scalarVolumePlugin.examine([filelist])
        volumeNode = scalarVolumePlugin.load(scalarVolumeLoadables[0])
        volumeNode.SetName(volName)
        # print "volumeNode = ",volumeNode

        print("Initialize Hierarchy For Volume with id " + volumeNode.GetID())
        l.InitializeHierarchyForVolume(volumeNode)
        print("---Now active mark up is " + l.GetActiveMarkupHierarchyID())
        print("adding a fiducial")

        #
        # define a fiducial
        #
        fidNode = slicer.vtkMRMLAnnotationFiducialNode()
        fidName = "AIM Round Trip Test Fiducial"
        fidNode.SetName(fidName)
        fidNode.SetSelected(1)
        fidNode.SetVisible(1)
        fidNode.SetLocked(0)
        print("Calling set fid coords")
        startCoords = [15.8, 70.8, -126.7]
        fidNode.SetFiducialCoordinates(startCoords[0], startCoords[1],
                                       startCoords[2])
        print("Starting fiducial coordinates: " + str(startCoords))
        # point it to the volume
        fidNode.SetAttribute("AssociatedNodeID", volumeNode.GetID())
        fidNode.SetScene(slicer.mrmlScene)
        print("Adding text disp node")
        fidNode.CreateAnnotationTextDisplayNode()
        print("Adding point display node")
        fidNode.CreateAnnotationPointDisplayNode()

        print("add node:")
        # slicer.mrmlScene.DebugOn()
        # l.DebugOn()
        slicer.mrmlScene.AddNode(fidNode)

        print("getting slice uid")
        uid = l.GetSliceUIDFromMarkUp(fidNode)
        print("fidNode uid = " + uid)

        #
        # create a label volume
        #
        volumesLogic = slicer.modules.volumes.logic()
        labelNode = volumesLogic.CreateLabelVolume(slicer.mrmlScene,
                                                   volumeNode, "Segmentation")
        labelDisplayNode = labelNode.GetDisplayNode()
        labelDisplayNode.SetAndObserveColorNodeID(
            'vtkMRMLColorTableNodeFileGenericAnatomyColors.txt')
        l.AddNodeToReport(labelNode)

        # initialize image content
        labelImage = labelNode.GetImageData()
        extent = labelImage.GetExtent()
        pixelCounter = 0
        for k in range(extent[5]):
            for j in range(extent[3]):
                for i in range(extent[1]):
                    if pixelCounter in initializedSegmentationVoxels:
                        labelImage.SetScalarComponentFromFloat(i, j, k, 0, 1)
                    else:
                        labelImage.SetScalarComponentFromFloat(i, j, k, 0, 0)
                    pixelCounter = pixelCounter + 1

        # test save to mrml
        # slicer.mrmlScene.SetURL('/spl/tmp/nicole/Testing/aim/RoundTripTest.mrml')
        # slicer.mrmlScene.Commit()

        #
        # output AIM XML
        #
        dirName = slicer.app.slicerHome + '/Testing/Temporary/'
        reportNode.SetStorageDirectoryName(dirName)

        print("Saving report to " + dirName)
        retval = l.SaveReportToAIM(reportNode)

        if (retval != 0):
            print("ERROR: unable to save report to aim file " + dirName +
                  ", retval=" + retval)
        else:
            print("Saved report to " + dirName)

        self.assertEqual(retval, 0)

        print("\n\n\nReloading aim file...")

        #
        # now clear the scene so can read in
        #
        # TBD: this causes a crash
        # slicer.mrmlScene.Clear(0)

        #
        # load in the aim file
        #
        newReport = slicer.mrmlScene.CreateNodeByClass(
            "vtkMRMLReportingReportNode")
        newReport.SetReferenceCount(newReport.GetReferenceCount() - 1)
        # set the default color map
        newReport.SetColorNodeID(colorID)
        newReport.SetDICOMDatabaseFileName(dbpath)
        slicer.mrmlScene.AddNode(newReport)
        parameterNode.SetParameter("reportID", newReport.GetID())

        Helper.LoadAIMFile(newReport.GetID(), aimFileName)

        # check the fiducial
        endCoords = [0, 0, 0]
        col = slicer.mrmlScene.GetNodesByClass("vtkMRMLAnnotationFiducialNode")
        col.SetReferenceCount(col.GetReferenceCount() - 1)

        # if the scene is not cleared, we should have 2 fiducials
        nFiducials = col.GetNumberOfItems()

        if nFiducials != 2:
            print("Failed to read fiducial form the saved report!")
            self.assertTrue(False)

        f = col.GetItemAsObject(1)
        f.GetFiducialCoordinates(endCoords)

        print("Start Coords = " + str(startCoords[0]) + "," +
              str(startCoords[1]) + "," + str(startCoords[2]))
        print("End Coords = " + str(endCoords))

        xdiff = endCoords[0] - startCoords[0]
        ydiff = endCoords[1] - startCoords[1]
        zdiff = endCoords[2] - startCoords[2]
        diffTotal = xdiff + ydiff + zdiff

        print(
            "Difference between coordinates after loaded the aim file and value from before stored the aim file: "
            + str(xdiff) + "," + str(ydiff) + "," + str(zdiff) +
            ". Total difference = " + str(diffTotal))

        if diffTotal > 0.1:
            print("Fiducial coordinates error exceeds the allowed bounds")
            self.assertTrue(False)

        # check the label node
        sceneVolumes = slicer.mrmlScene.GetNodesByClass(
            "vtkMRMLScalarVolumeNode")
        sceneVolumes.SetReferenceCount(sceneVolumes.GetReferenceCount() - 1)

        sceneLabels = []

        for i in range(sceneVolumes.GetNumberOfItems()):
            vol = sceneVolumes.GetItemAsObject(i)
            if vol.GetLabelMap():
                sceneLabels.append(vol)

        if len(sceneLabels) != 2:
            print(
                "Scene does not have two label nodes after reloading from AIM!"
            )
            self.assertTrue(False)

        newLabelNode = sceneLabels[1]
        newLabelImage = newLabelNode.GetImageData()
        extent = newLabelImage.GetExtent()
        pixelCounter = 0
        for k in range(extent[5]):
            for j in range(extent[3]):
                for i in range(extent[1]):
                    pixel = newLabelImage.GetScalarComponentAsFloat(i, j, k, 0)
                    if ((pixelCounter in initializedSegmentationVoxels)
                            and pixel != 1) or (not (
                                pixelCounter in initializedSegmentationVoxels)
                                                and pixel != 0):
                        print("Segmentation content not recovered correctly!")
                        print("Pixel counter " + str(pixelCounter) +
                              " is set to " + str(pixel))
                        self.assertTrue(False)
                    pixelCounter = pixelCounter + 1

        self.assertTrue(True)
  def test_RoundTrip(self):
    """
    Test fiducial round trip to and from AIM XML file on disk
    """

    print("ctest, please don't truncate my output: CTEST_FULL_OUTPUT")

    # enter the module
    mainWindow = slicer.util.mainWindow()
    mainWindow.moduleSelector().selectModule('Reporting')

    # l = slicer.modulelogic.vtkSlicerReportingModuleLogic()
    l = slicer.modules.reporting.logic() 
    l.GUIHiddenOff()

    # testDataPath = os.path.normpath(os.path.join(os.path.realpath(__file__), "..", "..", "Prototype/TestData/DICOM.CT/")   
    print("Reporting round trip test, current working directory = "+os.getcwd())
    testDataPath = os.path.join(os.getcwd(),"../../Testing/Temporary/DICOM.CT")
    # testDataPath = "/projects/birn/nicole/Slicer4/Reporting/Prototype/TestData/DICOM.CT"
    print("test data path = "+testDataPath)
 
    # set up a new DICOM database
    print("Creating a dicomDatabase!")
    ddb = ctk.ctkDICOMDatabase()
    if not ddb:
      print("ERROR: failed to create a new dicom database!")
      return   
    dbpath = slicer.app.slicerHome + '/Testing/Temporary/TestingDCMDB/ctkDICOM.sql'
    print('database path set to '+dbpath)
    if not os.path.exists(os.path.dirname(dbpath)):
      print('Creating dir '+os.path.dirname(dbpath))
      os.makedirs(os.path.dirname(dbpath))
    ddb.openDatabase(dbpath,"ReportingTesting")
    if not ddb.isOpen:
      print("ERROR: failed to open a new dicom database at path "+dbpath)
      return
    retval = ddb.initializeDatabase()
    if not retval:
      print("ERROR: failed to init database")
      return

    l.InitializeDICOMDatabase(dbpath)

    testFileNames = []
    for n in [487, 488, 489]:
      filename = os.path.join(testDataPath, "instance_" + str(n) + ".dcm")
      print("Adding file "+filename)
      testFileNames.append(filename)

    # check to see if the test data is already in it
    patients = ddb.patients()
    if len(patients) == 0:
      # add the files
      for filename in testFileNames:
        print("Inserting file "+filename)
        retval = ddb.insert(filename)
      patients = ddb.patients()
      if len(patients) == 0:
        print("ERROR: unable to add test files to database!")
        print(str(testFileNames))
        return

    # get the UID for the series
    study = ddb.studiesForPatient(patients[0])
    series = ddb.seriesForStudy(study[0])
    seriesUID = series[0]
        
    # seriesUID = "1.2.392.200103.20080913.113635.2.2009.6.22.21.43.10.23432.1"
    # seriesUID = "2.16.840.1.114362.1.759508.1251415878280.192"
    # seriesUID = "1.3.12.2.1107.5.1.4.53031.30000011032906120157800000219"
    print("For test, using the AIM sample volume with series UID of "+seriesUID)
    fileList = ddb.filesForSeries(seriesUID)
    print("fileList = "+str(fileList))
    if not fileList:
      print("ERROR: sample series with id "+seriesUID+" not found in database!")
      return

    # add a parameter node
    parameterNode = slicer.vtkMRMLScriptedModuleNode()
    parameterNode.SetModuleName('Reporting')
    slicer.mrmlScene.AddNode(parameterNode)
    # set it to be the active parameter node
    l.SetActiveParameterNodeID(parameterNode.GetID())

    #
    # create a new report, make it the report in the parameter node, set up hierarchy
    #
    reportNode = slicer.mrmlScene.CreateNodeByClass("vtkMRMLReportingReportNode")
    reportNode.SetReferenceCount(reportNode.GetReferenceCount() - 1)
    
    # set the color id
    colorID = 'vtkMRMLColorTableNodeFileGenericAnatomyColors.txt'
    reportNode.SetColorNodeID(colorID)
    reportNode.SetDICOMDatabaseFileName(dbpath)

    slicer.mrmlScene.AddNode(reportNode)
    parameterNode.SetParameter("reportID", reportNode.GetID())

    #
    # get some sample data from the database
    #
    volId = 1
    volumeNode = None
    volName = 'AIM volume '+str(volId)

    # print("Dicom data base = "+ddb)

    slicer.dicomDatabase = ddb
    scalarVolumePlugin = slicer.modules.dicomPlugins['DICOMScalarVolumePlugin']()
    scalarVolumeLoadables = scalarVolumePlugin.examine([fileList])
    volumeNode = scalarVolumePlugin.load(scalarVolumeLoadables[0])
    volumeNode.SetName(volName)
    # print "volumeNode = ",volumeNode

    print("Adding to Report: Volume with id "+volumeNode.GetID())
    l.AddVolumeToReport(volumeNode)
    # set it on the report
    reportNode.SetVolumeNodeID(volumeNode.GetID())

    print("adding a fiducial")

    #
    # define a fiducial
    #
    fidNode = slicer.vtkMRMLAnnotationFiducialNode()
    fidName = "AIM Round Trip Test Fiducial"
    fidNode.SetName(fidName)
    fidNode.SetSelected(1)
    fidNode.SetDisplayVisibility(1)
    fidNode.SetLocked(0)
    print("Calling set fid coords")
    startCoords = [15.8, 70.8, -126.7]    
    fidNode.SetFiducialCoordinates(startCoords[0],startCoords[1],startCoords[2])
    print("Starting fiducial coordinates: "+str(startCoords))
    # point it to the volume
    fidNode.SetAttribute("AssociatedNodeID", volumeNode.GetID())
    # point it to the report
    fidNode.SetAttribute("ReportingReportNodeID", reportNode.GetID())
    fidNode.SetScene(slicer.mrmlScene)
    print("Adding text disp node")
    fidNode.CreateAnnotationTextDisplayNode()
    print("Adding point display node")
    fidNode.CreateAnnotationPointDisplayNode()

    print("add node:")
    # slicer.mrmlScene.DebugOn()
    # l.DebugOn()
    slicer.mrmlScene.AddNode(fidNode) 
   
    print("getting slice uid")
    uid = l.GetSliceUIDFromMarkUp(fidNode)
    print("fidNode uid = "+uid)

    #
    # create a label volume
    #
    volumesLogic = slicer.modules.volumes.logic()
    labelNode = volumesLogic.CreateAndAddLabelVolume(slicer.mrmlScene, volumeNode, "Segmentation")
    labelDisplayNode = labelNode.GetDisplayNode()
    labelDisplayNode.SetAndObserveColorNodeID('vtkMRMLColorTableNodeFileGenericAnatomyColors.txt')
    l.AddNodeToReport(labelNode)

    # initialize image content
    labelImage = labelNode.GetImageData()
    extent = labelImage.GetExtent()
    pixelCounter = 0
    for k in range(extent[5]):
      for j in range(extent[3]):
        for i in range(extent[1]):
          if pixelCounter in initializedSegmentationVoxels:
            labelImage.SetScalarComponentFromFloat(i,j,k,0,1)
          else:
            labelImage.SetScalarComponentFromFloat(i,j,k,0,0)
          pixelCounter = pixelCounter + 1


    # test save to mrml
    # slicer.mrmlScene.SetURL('/spl/tmp/nicole/Testing/aim/RoundTripTest.mrml')
    # slicer.mrmlScene.Commit()

    #
    # output AIM XML
    #
    dirName = slicer.app.slicerHome + '/Testing/Temporary/'
    reportNode.SetStorageDirectoryName(dirName)

    print("Saving report to "+dirName)
    retval = l.SaveReportToAIM(reportNode)

    if (retval != 0):
      print("ERROR: unable to save report to aim file "+dirName+", retval="+retval)
    else:
      print("Saved report to "+dirName+" in file "+reportNode.GetAIMFileName())

    self.assertEqual(retval, 0)

    print("\n\n\nReloading aim file"+reportNode.GetAIMFileName())

    #
    # now clear the scene so can read in
    #
    # TBD: this causes a crash
    # slicer.mrmlScene.Clear(0)

    #
    # load in the aim file
    #
    newReport = slicer.mrmlScene.CreateNodeByClass("vtkMRMLReportingReportNode")
    newReport.SetReferenceCount(newReport.GetReferenceCount()-1)
    # set the default color map
    newReport.SetColorNodeID(colorID)
    newReport.SetDICOMDatabaseFileName(dbpath)
    slicer.mrmlScene.AddNode(newReport)
    parameterNode.SetParameter("reportID", newReport.GetID())

    Helper.LoadAIMFile(newReport.GetID(),reportNode.GetAIMFileName())

    # check the fiducial
    endCoords = [0,0,0]
    col = slicer.mrmlScene.GetNodesByClass("vtkMRMLAnnotationFiducialNode")
    col.SetReferenceCount(col.GetReferenceCount() - 1)

    # if the scene is not cleared, we should have 2 fiducials
    nFiducials = col.GetNumberOfItems()

    if nFiducials != 2:
      print("Failed to read a fiducial from the saved report! Expect 2 in the non cleared scene, have " + str(nFiducials))
      self.assertTrue(False)
    
    f = col.GetItemAsObject(1)
    f.GetFiducialCoordinates(endCoords)

    print("Start Coords = "+str(startCoords[0])+","+str(startCoords[1])+","+str(startCoords[2]))
    print("End Coords = "+str(endCoords))

    xdiff = endCoords[0] - startCoords[0]
    ydiff = endCoords[1] - startCoords[1]
    zdiff = endCoords[2] - startCoords[2]
    diffTotal = xdiff + ydiff + zdiff

    print("Difference between coordinates after loaded the aim file and value from before stored the aim file: "+str(xdiff)+","+str(ydiff)+","+str(zdiff)+". Total difference = "+str(diffTotal))

    if diffTotal > 0.1:
      print("Fiducial coordinates error exceeds the allowed bounds")
      self.assertTrue(False)


    # check the label node
    sceneVolumes = slicer.mrmlScene.GetNodesByClass("vtkMRMLScalarVolumeNode")
    sceneVolumes.SetReferenceCount(sceneVolumes.GetReferenceCount() - 1)

    sceneLabels = []

    for i in range(sceneVolumes.GetNumberOfItems()):
      vol = sceneVolumes.GetItemAsObject(i)
      if vol.GetLabelMap():
        sceneLabels.append(vol)

    if len(sceneLabels) != 2:
      print("Scene does not have two label nodes after reloading from AIM!")
      self.assertTrue(False)

    newLabelNode = sceneLabels[1]
    newLabelImage = newLabelNode.GetImageData()
    extent = newLabelImage.GetExtent()
    pixelCounter = 0
    for k in range(extent[5]):
      for j in range(extent[3]):
        for i in range(extent[1]):
          pixel = newLabelImage.GetScalarComponentAsFloat(i,j,k,0)
          if ((pixelCounter in initializedSegmentationVoxels) and pixel != 1) or (not(pixelCounter in initializedSegmentationVoxels) and pixel != 0):
            print("Segmentation content not recovered correctly!")
            print("Pixel counter "+str(pixelCounter)+" is set to "+str(pixel))
            self.assertTrue(False)
          pixelCounter = pixelCounter + 1

    self.assertTrue(True)