def captureSpatialsPositions(self,fidName ): saml = slicer.modules.annotations.logic() listNode = slicer.util.getNode("Tracker Points List") saml.SetActiveHierarchyNodeID(listNode.GetID()) StylusTipToReferenceNode = slicer.util.getNode("StylusTipToProbe") validTransformation = self.isValidTransformation("StylusTipToProbe") if validTransformation == True: #cfl = slicer.modules.collectfiducials.logic() #cfl.SetProbeTransformNode(StylusTipToReferenceNode) #cfl.AddFiducial() transformation = StylusTipToReferenceNode.GetMatrixTransformToParent() fidPos=[transformation.GetElement(0,3),transformation.GetElement(1,3),transformation.GetElement(2,3)] trackerNode=slicer.vtkMRMLAnnotationFiducialNode() trackerNode.SetFiducialWorldCoordinates(fidPos) trackerNode.SetName(fidName + '-Tracker') self.setActiveAnnotationsList("Tracker Points List") slicer.mrmlScene.AddNode(trackerNode) self.setActiveAnnotationsList("Fiducials List") fidPos=[0,0,0] fidNode=slicer.vtkMRMLAnnotationFiducialNode() fidNode.SetFiducialWorldCoordinates(fidPos) fidNode.SetName(fidName + '-Tracker') self.takeUSSnapshot2(fidName + '-Snapshot') snapshotNode=slicer.util.getNode(fidName + '-Snapshot') snapshotNode.SetDisplayVisibility(False) print("Tracker position recorded") else: print("Tracker position is invalid") return validTransformation
def readStylusTipPosition(self): tempFiducialsNode = self.stylusTrackerSelector.currentNode() xCoordinate = tempFiducialsNode.GetMatrixTransformToParent().GetElement(0,3) yCoordinate = tempFiducialsNode.GetMatrixTransformToParent().GetElement(1,3) zCoordinate = tempFiducialsNode.GetMatrixTransformToParent().GetElement(2,3) self.Coordinate = ([xCoordinate, yCoordinate, zCoordinate]) transformPositions = self.Coordinate self.fiducial = slicer.vtkMRMLAnnotationFiducialNode() if (self.iterationNo==0): self.pointCollectedButton01.setChecked(1) elif (self.iterationNo==1): self.pointCollectedButton02.setChecked(1) elif (self.iterationNo==2): self.pointCollectedButton03.setChecked(1) elif (self.iterationNo==3): self.pointCollectedButton04.setChecked(1) elif (self.iterationNo==4): self.pointCollectedButton05.setChecked(1) elif (self.iterationNo==5): self.pointCollectedButton06.setChecked(1) #print transformPositions return self.Coordinate
def __init__(self, slicerVersion): self.volume = slicer.vtkMRMLScalarVolumeNode() self.display = slicer.vtkMRMLScalarVolumeDisplayNode() if slicerVersion == 4: self.fiducialList = slicer.vtkMRMLAnnotationHierarchyNode() self.newFiducial = slicer.vtkMRMLAnnotationFiducialNode() else: self.fiducialList = slicer.vtkMRMLFiducialListNode() self.newFiducial = slicer.vtkMRMLFiducial()
def collect(self): fiducialsNode = self.readStylusTipPosition() #print "Getting the point..." fiducial = slicer.vtkMRMLAnnotationFiducialNode() fiducialName = "T" + str(self.iterationNo) fiducial.SetName(fiducialName) fiducial.SetFiducialCoordinates(fiducialsNode) fiducial.Initialize(slicer.mrmlScene) #fiducial.SetHideFromEditors() return fiducialsNode
def addFiducialsToTrackerList(self): saml = slicer.modules.annotations.logic() fnode=slicer.util.getNode("Tracker Points List") saml.SetActiveHierarchyNodeID(fnode.GetID()) f1=slicer.vtkMRMLAnnotationFiducialNode() f1.SetFiducialWorldCoordinates((10,0,5)) f1.SetName('Stylus Tip 1') slicer.mrmlScene.AddNode(f1) f2=slicer.vtkMRMLAnnotationFiducialNode() f2.SetFiducialWorldCoordinates((10,10,5)) f2.SetName('Stylus Tip 2') slicer.mrmlScene.AddNode(f2) f3=slicer.vtkMRMLAnnotationFiducialNode() f3.SetFiducialWorldCoordinates((20,10,5)) f3.SetName('Stylus Tip 3') slicer.mrmlScene.AddNode(f3) f4=slicer.vtkMRMLAnnotationFiducialNode() f4.SetFiducialWorldCoordinates((20,10,15)) f4.SetName('Stylus Tip 4') slicer.mrmlScene.AddNode(f4) print("Fiducials added to Tracker List")
def create_fiducials_list(seedList): saml = slicer.modules.annotations.logic() saml.SetActiveHierarchyNodeID(saml.GetTopLevelHierarchyNodeID()) saml.AddHierarchy() currentList = saml.GetActiveHierarchyNode() for seed in seedList: seedFN = slicer.vtkMRMLAnnotationFiducialNode() seedFN.SetFiducialWorldCoordinates(seed) seedFN.Initialize(slicer.mrmlScene) seedHN = slicer.vtkMRMLAnnotationHierarchyNode() seedHN.SetParentNodeID(currentList.GetID()) seedHN.SetAssociatedNodeID(seedFN.GetID()) return currentList
def onDrawNeedleButtonClicked(self): self.progress = qt.QProgressDialog(slicer.util.mainWindow()) self.progress.minimumDuration = 0 self.progress.show() self.progress.setValue(0) self.progress.setMaximum(0) self.progress.setCancelButton(0) self.progress.setWindowModality(2) self.progress.setLabelText('Creating Fiducials') slicer.app.processEvents(qt.QEventLoop.ExcludeUserInputEvents) self.progress.repaint() self.drawNeedleButton.enabled = False print 'Please wait drawing fiducials...' color = [random.randrange(50,100,1)/100,random.randrange(50,100,1)/100,random.randrange(50,100,1)/100] #color = [0,1,0] for i in xrange (len(self.trajectory)): fiducial = slicer.vtkMRMLAnnotationFiducialNode() fiducialName = self.status.text fiducialName = fiducialName fiducialLabel = self.status.text fiducial.SetName(fiducialName) fiducial.SetLocked(1) fiducial.SetFiducialLabel(fiducialLabel) fiducial.SetFiducialCoordinates(self.trajectory[i]) fiducial.Initialize(slicer.mrmlScene) displayNode=fiducial.GetDisplayNode() displayNode.SetGlyphScale(2) displayNode.SetColor(color) textNode=fiducial.GetAnnotationTextDisplayNode() textNode.SetTextScale(1) textNode.SetColor(color) self.progress.setValue(2) self.progress.repaint() slicer.app.processEvents(qt.QEventLoop.ExcludeUserInputEvents) self.progress.close() self.progress = None
def addFiducial(self,name,position=(0,0,0),associatedNode=None): """Add an instance of a fiducial to the scene for a given volume node""" annoLogic = slicer.modules.annotations.logic() originalActiveHierarchy = annoLogic.GetActiveHierarchyNodeID() slicer.mrmlScene.StartState(slicer.mrmlScene.BatchProcessState) # make the fiducial list if required listName = associatedNode.GetName() + "-landmarks" fidListHierarchyNode = slicer.util.getNode(listName) if not fidListHierarchyNode: fidListHierarchyNode = slicer.vtkMRMLAnnotationHierarchyNode() fidListHierarchyNode.HideFromEditorsOff() fidListHierarchyNode.SetName(listName) slicer.mrmlScene.AddNode(fidListHierarchyNode) # make it a child of the top level node fidListHierarchyNode.SetParentNodeID(annoLogic.GetTopLevelHierarchyNodeID()) # make this active so that the fids will be added to it annoLogic.SetActiveHierarchyNodeID(fidListHierarchyNode.GetID()) fiducialNode = slicer.vtkMRMLAnnotationFiducialNode() if associatedNode: fiducialNode.SetAttribute("AssociatedNodeID", associatedNode.GetID()) fiducialNode.SetName(name) fiducialNode.AddControlPoint(position, True, True) fiducialNode.SetSelected(False) fiducialNode.SetLocked(False) slicer.mrmlScene.AddNode(fiducialNode) fiducialNode.CreateAnnotationTextDisplayNode() fiducialNode.CreateAnnotationPointDisplayNode() # TODO: pick appropriate defaults # 135,135,84 fiducialNode.SetTextScale(3.) fiducialNode.GetAnnotationPointDisplayNode().SetGlyphScale(3.) fiducialNode.GetAnnotationPointDisplayNode().SetGlyphTypeFromString('StarBurst2D') fiducialNode.GetAnnotationPointDisplayNode().SetColor((1,1,0)) fiducialNode.GetAnnotationTextDisplayNode().SetColor((1,1,0)) fiducialNode.SetDisplayVisibility(True) annoLogic.SetActiveHierarchyNodeID(originalActiveHierarchy) slicer.mrmlScene.EndState(slicer.mrmlScene.BatchProcessState)
def convertTransformToFiducial(self): self.setUp scene = slicer.mrmlScene collection = scene.GetNodesByClass('vtkMRMLLinearTransformNode'); ntransforms = collection.GetNumberOfItems() collection.InitTraversal() n = 0 scene = slicer.mrmlScene while n < ntransforms: tnode = collection.GetNextItemAsObject() n = n + 1 m = vtk.vtkMatrix4x4() tnode.GetMatrixTransformToWorld(m) fnode = slicer.vtkMRMLAnnotationFiducialNode() pos = [m.GetElement(0,3), m.GetElement(1,3), m.GetElement(2,3)] fnode.SetFiducialCoordinates(pos[0], pos[1], pos[2]); scene.AddNode(fnode) fnode.CreateAnnotationTextDisplayNode(); fnode.CreateAnnotationPointDisplayNode(); name = '%s_Fiducial' % tnode.GetName() fnode.SetName(name)
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)
def test_ReportingAIMRoundTrip(self): print("CTEST_FULL_OUTPUT") """ Load the data using DICOM module """ import os self.delayDisplay("Starting the DICOM test") # # first, get the data - a zip file of dicom data # import urllib downloads = ( ('http://slicer.kitware.com/midas3/download?items=10881', 'JANCT-CT.zip'), ) self.delayDisplay("Downloading") for url,name in downloads: filePath = slicer.app.temporaryPath + '/' + name if not os.path.exists(filePath) or os.stat(filePath).st_size == 0: self.delayDisplay('Requesting download %s from %s...\n' % (name, url)) urllib.urlretrieve(url, filePath) self.delayDisplay('Finished with download\n') reportingTempDir = slicer.app.temporaryPath+'/Reporting' print('Temporary directory location: '+reportingTempDir) qt.QDir().mkpath(reportingTempDir) dicomFilesDirectory = reportingTempDir + '/dicomFiles' self.cleanupDir(dicomFilesDirectory) qt.QDir().mkpath(dicomFilesDirectory) slicer.app.applicationLogic().Unzip(filePath, dicomFilesDirectory) try: self.delayDisplay("Switching to temp database directory") tempDatabaseDirectory = reportingTempDir + '/tempDICOMDatbase' qt.QDir().mkpath(tempDatabaseDirectory) self.cleanupDir(tempDatabaseDirectory) if slicer.dicomDatabase: self.originalDatabaseDirectory = os.path.split(slicer.dicomDatabase.databaseFilename)[0] else: self.originalDatabaseDirectory = None settings = qt.QSettings() settings.setValue('DatabaseDirectory', tempDatabaseDirectory) dicomWidget = slicer.modules.dicom.widgetRepresentation().self() dicomWidget.onDatabaseDirectoryChanged(tempDatabaseDirectory) self.delayDisplay('Importing DICOM') mainWindow = slicer.util.mainWindow() mainWindow.moduleSelector().selectModule('DICOM') #dicomWidget.dicomApp.suspendModel() indexer = ctk.ctkDICOMIndexer() indexer.addDirectory(slicer.dicomDatabase, dicomFilesDirectory, None) indexer.waitForImportFinished() patient = slicer.dicomDatabase.patients()[0] studies = slicer.dicomDatabase.studiesForPatient(patient) series = [slicer.dicomDatabase.seriesForStudy(study) for study in studies] seriesUIDs = [uid for uidList in series for uid in uidList] dicomWidget.detailsPopup.offerLoadables(seriesUIDs, 'SeriesUIDList') dicomWidget.detailsPopup.examineForLoading() loadablesByPlugin = dicomWidget.detailsPopup.loadablesByPlugin self.delayDisplay('Loading Selection') dicomWidget.detailsPopup.loadCheckedLoadables() # initialize the module with the report and volume volumes = slicer.util.getNodes('vtkMRMLScalarVolumeNode*') self.assertTrue(len(volumes) == 1) (name,volume) = volumes.items()[0] self.delayDisplay('Loaded volume name %s' % volume.GetName()) self.delayDisplay('Configure Module') mainWindow = slicer.util.mainWindow() mainWindow.moduleSelector().selectModule('Reporting') reporting = slicer.modules.reporting.widgetRepresentation().self() report = slicer.mrmlScene.CreateNodeByClass('vtkMRMLReportingReportNode') report.SetReferenceCount(report.GetReferenceCount()-1) slicer.mrmlScene.AddNode(report) report.SetFindingLabel(7) reporting.reportSelector.setCurrentNode(report) self.delayDisplay('Setting volume to %s' % volume.GetName()) reporting.volumeSelector.setCurrentNode(volume) slicer.app.processEvents() # place some markups and add a segmentation label # add fiducial fidNode = slicer.vtkMRMLAnnotationFiducialNode() fidName = "AIM Round Trip Test Fiducial" fidNode.SetName(fidName) fidNode.SetSelected(1) fidNode.SetDisplayVisibility(1) fidNode.SetLocked(0) # TODO: ask Nicole where this is assigned in the regular workflow fidNode.SetAttribute('AssociatedNodeID',volume.GetID()) print("Calling set fid coords") startCoords = [15.8, 70.8, -126.7] fidNode.SetFiducialCoordinates(startCoords[0],startCoords[1],startCoords[2]) print("Starting fiducial coordinates: "+str(startCoords)) slicer.mrmlScene.AddNode(fidNode) # add ruler rulerNode = slicer.vtkMRMLAnnotationRulerNode() rulerNode.SetName('Test Ruler') m = vtk.vtkMatrix4x4() volume.GetIJKToRASMatrix(m) ijk0 = [0,0,1,1] ijk1 = [50,50,1,1] ras0 = m.MultiplyPoint(ijk0) ras1 = m.MultiplyPoint(ijk1) rulerNode.SetPosition1(19.386751174926758, 68.528785705566406, -127.69000244140625) rulerNode.SetPosition2(132.72709655761719, -34.349384307861328, -127.69000244140625) rulerNode.SetAttribute('AssociatedNodeID',volume.GetID()) slicer.mrmlScene.AddNode(rulerNode) slicer.app.processEvents() # add label node volumesLogic = slicer.modules.volumes.logic() labelNode = volumesLogic.CreateAndAddLabelVolume(slicer.mrmlScene, volume, "Segmentation") labelDisplayNode = labelNode.GetDisplayNode() labelDisplayNode.SetAndObserveColorNodeID('vtkMRMLColorTableNodeFileGenericAnatomyColors.txt') image = volume.GetImageData() thresh = vtk.vtkImageThreshold() if vtk.vtkVersion().GetVTKMajorVersion() < 6: thresh.SetInput(image) else: thresh.SetInputData(image) thresh.ThresholdBetween(10,400) thresh.SetInValue(report.GetFindingLabel()) thresh.SetOutValue(0) thresh.Update() labelNode.SetAndObserveImageData(thresh.GetOutput()) reporting.segmentationSelector.setCurrentNode(labelNode) # Save the report exportDir = reportingTempDir+'/Output' qt.QDir().mkpath(exportDir) self.cleanupDir(exportDir) report.SetStorageDirectoryName(exportDir) reportingLogic = slicer.modules.reporting.logic() print("Before saving report") reportingLogic.SaveReportToAIM(report) self.delayDisplay('Report saved') slicer.mrmlScene.Clear(0) # parse on patient level, find segmentation object, load and make sure # it matches the input # close the scene and load the report, check consistency # try to load back the saved AIM import glob print glob.glob(exportDir+'/*') xmlFiles = glob.glob(exportDir+'/*xml') print xmlFiles self.assertTrue(len(xmlFiles) == 1) reporting.importAIMFile = xmlFiles[0] reporting.onReportImport() self.delayDisplay('Report loaded from AIM! Test passed.') self.delayDisplay("Restoring original database directory") if self.originalDatabaseDirectory: dicomWidget.onDatabaseDirectoryChanged(self.originalDatabaseDirectory) except Exception, e: if self.originalDatabaseDirectory: dicomWidget.onDatabaseDirectoryChanged(self.originalDatabaseDirectory) import traceback traceback.print_exc() self.delayDisplay('Test caused exception!\n' + str(e)) self.assertTrue(False)
def test_ReportingAIMRoundTrip(self): print ("CTEST_FULL_OUTPUT") """ Load the data using DICOM module """ import os self.delayDisplay("Starting the DICOM test") # # first, get the data - a zip file of dicom data # import urllib downloads = (("http://slicer.kitware.com/midas3/download?items=10881", "JANCT-CT.zip"),) self.delayDisplay("Downloading") for url, name in downloads: filePath = slicer.app.temporaryPath + "/" + name if not os.path.exists(filePath) or os.stat(filePath).st_size == 0: self.delayDisplay("Requesting download %s from %s...\n" % (name, url)) urllib.urlretrieve(url, filePath) self.delayDisplay("Finished with download\n") reportingTempDir = slicer.app.temporaryPath + "/Reporting" print ("Temporary directory location: " + reportingTempDir) qt.QDir().mkpath(reportingTempDir) dicomFilesDirectory = reportingTempDir + "/dicomFiles" self.cleanupDir(dicomFilesDirectory) qt.QDir().mkpath(dicomFilesDirectory) slicer.app.applicationLogic().Unzip(filePath, dicomFilesDirectory) try: self.delayDisplay("Switching to temp database directory") tempDatabaseDirectory = reportingTempDir + "/tempDICOMDatbase" qt.QDir().mkpath(tempDatabaseDirectory) self.cleanupDir(tempDatabaseDirectory) if slicer.dicomDatabase: self.originalDatabaseDirectory = os.path.split(slicer.dicomDatabase.databaseFilename)[0] else: self.originalDatabaseDirectory = None settings = qt.QSettings() settings.setValue("DatabaseDirectory", tempDatabaseDirectory) dicomWidget = slicer.modules.dicom.widgetRepresentation().self() dicomWidget.onDatabaseDirectoryChanged(tempDatabaseDirectory) self.delayDisplay("Importing DICOM") mainWindow = slicer.util.mainWindow() mainWindow.moduleSelector().selectModule("DICOM") # dicomWidget.dicomApp.suspendModel() indexer = ctk.ctkDICOMIndexer() indexer.addDirectory(slicer.dicomDatabase, dicomFilesDirectory, None) indexer.waitForImportFinished() patient = slicer.dicomDatabase.patients()[0] studies = slicer.dicomDatabase.studiesForPatient(patient) series = [slicer.dicomDatabase.seriesForStudy(study) for study in studies] seriesUIDs = [uid for uidList in series for uid in uidList] dicomWidget.detailsPopup.offerLoadables(seriesUIDs, "SeriesUIDList") dicomWidget.detailsPopup.examineForLoading() loadablesByPlugin = dicomWidget.detailsPopup.loadablesByPlugin self.delayDisplay("Loading Selection") dicomWidget.detailsPopup.loadCheckedLoadables() # initialize the module with the report and volume volumes = slicer.util.getNodes("vtkMRMLScalarVolumeNode*") self.assertTrue(len(volumes) == 1) (name, volume) = volumes.items()[0] self.delayDisplay("Loaded volume name %s" % volume.GetName()) self.delayDisplay("Configure Module") mainWindow = slicer.util.mainWindow() mainWindow.moduleSelector().selectModule("Reporting") reporting = slicer.modules.reporting.widgetRepresentation().self() report = slicer.mrmlScene.CreateNodeByClass("vtkMRMLReportingReportNode") report.SetReferenceCount(report.GetReferenceCount() - 1) slicer.mrmlScene.AddNode(report) report.SetFindingLabel(7) reporting.reportSelector.setCurrentNode(report) self.delayDisplay("Setting volume to %s" % volume.GetName()) reporting.volumeSelector.setCurrentNode(volume) slicer.app.processEvents() # place some markups and add a segmentation label # add fiducial fidNode = slicer.vtkMRMLAnnotationFiducialNode() fidName = "AIM Round Trip Test Fiducial" fidNode.SetName(fidName) fidNode.SetSelected(1) fidNode.SetDisplayVisibility(1) fidNode.SetLocked(0) # TODO: ask Nicole where this is assigned in the regular workflow fidNode.SetAttribute("AssociatedNodeID", volume.GetID()) print ("Calling set fid coords") startCoords = [15.8, 70.8, -126.7] fidNode.SetFiducialCoordinates(startCoords[0], startCoords[1], startCoords[2]) print ("Starting fiducial coordinates: " + str(startCoords)) slicer.mrmlScene.AddNode(fidNode) # add ruler rulerNode = slicer.vtkMRMLAnnotationRulerNode() rulerNode.SetName("Test Ruler") m = vtk.vtkMatrix4x4() volume.GetIJKToRASMatrix(m) ijk0 = [0, 0, 1, 1] ijk1 = [50, 50, 1, 1] ras0 = m.MultiplyPoint(ijk0) ras1 = m.MultiplyPoint(ijk1) rulerNode.SetPosition1(19.386751174926758, 68.528785705566406, -127.69000244140625) rulerNode.SetPosition2(132.72709655761719, -34.349384307861328, -127.69000244140625) rulerNode.SetAttribute("AssociatedNodeID", volume.GetID()) slicer.mrmlScene.AddNode(rulerNode) slicer.app.processEvents() # add label node volumesLogic = slicer.modules.volumes.logic() labelNode = volumesLogic.CreateAndAddLabelVolume(slicer.mrmlScene, volume, "Segmentation") labelDisplayNode = labelNode.GetDisplayNode() labelDisplayNode.SetAndObserveColorNodeID("vtkMRMLColorTableNodeFileGenericAnatomyColors.txt") image = volume.GetImageData() thresh = vtk.vtkImageThreshold() if vtk.vtkVersion().GetVTKMajorVersion() < 6: thresh.SetInput(image) else: thresh.SetInputData(image) thresh.ThresholdBetween(10, 400) thresh.SetInValue(report.GetFindingLabel()) thresh.SetOutValue(0) thresh.Update() labelNode.SetAndObserveImageData(thresh.GetOutput()) reporting.segmentationSelector.setCurrentNode(labelNode) # Save the report exportDir = reportingTempDir + "/Output" qt.QDir().mkpath(exportDir) self.cleanupDir(exportDir) report.SetStorageDirectoryName(exportDir) reportingLogic = slicer.modules.reporting.logic() print ("Before saving report") reportingLogic.SaveReportToAIM(report) self.delayDisplay("Report saved") slicer.mrmlScene.Clear(0) # parse on patient level, find segmentation object, load and make sure # it matches the input # close the scene and load the report, check consistency # try to load back the saved AIM import glob print glob.glob(exportDir + "/*") xmlFiles = glob.glob(exportDir + "/*xml") print xmlFiles self.assertTrue(len(xmlFiles) == 1) reporting.importAIMFile = xmlFiles[0] reporting.onReportImport() self.delayDisplay("Report loaded from AIM! Test passed.") self.delayDisplay("Restoring original database directory") if self.originalDatabaseDirectory: dicomWidget.onDatabaseDirectoryChanged(self.originalDatabaseDirectory) except Exception, e: if self.originalDatabaseDirectory: dicomWidget.onDatabaseDirectoryChanged(self.originalDatabaseDirectory) import traceback traceback.print_exc() self.delayDisplay("Test caused exception!\n" + str(e)) self.assertTrue(False)
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())