def test_Part1Ruler(self, enableScreenshotsFlag=0, screenshotScaleFactor=1): """ Test using rulers """ logic = RSNAQuantTutorialLogic() logic.enableScreenshots = enableScreenshotsFlag logic.screenshotScaleFactor = screenshotScaleFactor self.delayDisplay("Starting the test") # # first, get some data # import SampleData tumor = SampleData.downloadSample('MRBrainTumor1') try: # four up view layoutManager = slicer.app.layoutManager() layoutManager.setLayout( slicer.vtkMRMLLayoutNode.SlicerLayoutFourUpView) # annotations module m = slicer.util.mainWindow() m.moduleSelector().selectModule('Annotations') # add ruler 1 rulerNode1 = slicer.vtkMRMLAnnotationRulerNode() rulerNode1.SetName("d1") rulerNode1.SetPosition1(-7.59519, 43.544, 28.6) rulerNode1.SetPosition2(-5.56987, 14.177, 28.6) rulerNode1.Initialize(slicer.mrmlScene) self.delayDisplay("Ruler 1") # add ruler 2 rulerNode2 = slicer.vtkMRMLAnnotationRulerNode() rulerNode2.SetName("d2") rulerNode2.SetPosition1(-3.54455, 27.656, 13.1646) rulerNode2.SetPosition2(-2.5319, 27.656, 47.5949) rulerNode2.Initialize(slicer.mrmlScene) self.delayDisplay("Ruler 2") # scroll annotLogic = slicer.modules.annotations.logic() annotLogic.JumpSlicesToAnnotationCoordinate(rulerNode1.GetID()) # show slices redWidget = layoutManager.sliceWidget('Red') redWidget.sliceController().setSliceLink(True) redWidget.sliceController().setSliceVisible(True) logic.takeScreenshot('Ruler', 'Ruler used to measure tumor diameter', -1) self.delayDisplay('Test passed!') except Exception as e: import traceback traceback.print_exc() self.delayDisplay('Test caused exception!\n' + str(e))
def test_Part1Ruler(self,enableScreenshotsFlag=0,screenshotScaleFactor=1): """ Test using rulers """ logic = RSNAQuantTutorialLogic() logic.enableScreenshots = enableScreenshotsFlag logic.screenshotScaleFactor = screenshotScaleFactor self.delayDisplay("Starting the test") # # first, get some data # import SampleData sampleDataLogic = SampleData.SampleDataLogic() tumor = sampleDataLogic.downloadMRBrainTumor1() try: # four up view layoutManager = slicer.app.layoutManager() layoutManager.setLayout(slicer.vtkMRMLLayoutNode.SlicerLayoutFourUpView) # annotations module m = slicer.util.mainWindow() m.moduleSelector().selectModule('Annotations') # add ruler 1 rulerNode1 = slicer.vtkMRMLAnnotationRulerNode() rulerNode1.SetName("d1") rulerNode1.SetPosition1(-7.59519,43.544,28.6) rulerNode1.SetPosition2(-5.56987,14.177,28.6) rulerNode1.Initialize(slicer.mrmlScene) self.delayDisplay("Ruler 1") # add ruler 2 rulerNode2 = slicer.vtkMRMLAnnotationRulerNode() rulerNode2.SetName("d2") rulerNode2.SetPosition1(-3.54455,27.656,13.1646) rulerNode2.SetPosition2(-2.5319,27.656,47.5949) rulerNode2.Initialize(slicer.mrmlScene) self.delayDisplay("Ruler 2") # scroll annotLogic = slicer.modules.annotations.logic() annotLogic.JumpSlicesToAnnotationCoordinate(rulerNode1.GetID()) # show slices redWidget = layoutManager.sliceWidget('Red') redWidget.sliceController().setSliceLink(True) redWidget.sliceController().setSliceVisible(True); logic.takeScreenshot('Ruler','Ruler used to measure tumor diameter',-1) self.delayDisplay('Test passed!') except Exception, e: import traceback traceback.print_exc() self.delayDisplay('Test caused exception!\n' + str(e))
def test_SlicerCreateRulerCrashIssue4199(self): """ Ideally you should have several levels of tests. At the lowest level tests should exercise the functionality of the logic with different inputs (both valid and invalid). At higher levels your tests should emulate the way the user would interact with your code and confirm that it still works the way you intended. One of the most important features of the tests is that it should alert other developers when their changes will have an impact on the behavior of your module. For example, if a developer removes a feature that you depend on, your test should break so they know that the feature is needed. """ logic = SlicerCreateRulerCrashIssue4199Logic() self.delayDisplay("Starting the test") slicer.util.selectModule('Welcome') # Add a ruler rulerNode = slicer.vtkMRMLAnnotationRulerNode() rulerNode.SetPosition1(0, 0, 0) rulerNode.SetPosition2(1, 1, 1) rulerNode.Initialize(slicer.mrmlScene) # Enter the Annotations module slicer.util.selectModule('Annotations') # If test reach this point without crashing it is a success self.delayDisplay('Test passed!')
def test_LineIntersityProfile1(self): """ Ideally you should have several levels of tests. At the lowest level tests should exercise the functionality of the logic with different inputs (both valid and invalid). At higher levels your tests should emulate the way the user would interact with your code and confirm that it still works the way you intended. One of the most important features of the tests is that it should alert other developers when their changes will have an impact on the behavior of your module. For example, if a developer removes a feature that you depend on, your test should break so they know that the feature is needed. """ self.delayDisplay("Starting the test") # # first, get some data # import urllib downloads = ( ('http://slicer.kitware.com/midas3/download?items=5767', 'FA.nrrd', slicer.util.loadVolume), ) for url, name, loader in downloads: filePath = slicer.app.temporaryPath + '/' + name if not os.path.exists(filePath) or os.stat(filePath).st_size == 0: logging.info( 'Requesting download %s from %s...\n' % (name, url)) urllib.urlretrieve(url, filePath) if loader: logging.info('Loading %s...' % (name,)) loader(filePath) self.delayDisplay('Finished with download and loading') volumeNode = slicer.util.getNode(pattern="FA") logic = LineIntersityProfileLogic() self.assertTrue(logic.hasImageData(volumeNode)) # self.delayDisplay('Test passed!') # Add Test # Initialise rule node in a know location rulerNode = slicer.vtkMRMLAnnotationRulerNode() slicer.mrmlScene.AddNode(rulerNode) rulerNode.SetPosition1(-65, 110, 60) rulerNode.SetPosition2(-15, 60, 60) rulerNode.SetName('Test') # Initialise input selectors moduleWidget = slicer.modules.LineIntersityProfileWidget # Note: the end has no "()", or a __init__ function required! moduleWidget.rulerSelector.setCurrentNode(rulerNode) moduleWidget.inputSelector1.setCurrentNode(volumeNode) moduleWidget.inputSelector2.setCurrentNode(volumeNode) self.delayDisplay("Inputs initialised!") # run the logic with the initialised inputs moduleWidget.onApplyButton() self.delayDisplay("if you see a ruler and a plot - test passed!")
def test_LineIntensityProfile1(self): """ Ideally you should have several levels of tests. At the lowest level tests should exercise the functionality of the logic with different inputs (both valid and invalid). At higher levels your tests should emulate the way the user would interact with your code and confirm that it still works the way you intended. One of the most important features of the tests is that it should alert other developers when their changes will have an impact on the behavior of your module. For example, if a developer removes a feature that you depend on, your test should break so they know that the feature is needed. """ self.delayDisplay("Starting the test") # # first, get some data # import urllib downloads = ( ('http://slicer.kitware.com/midas3/download?items=5767', 'FA.nrrd', slicer.util.loadVolume), ) for url,name,loader in downloads: filePath = slicer.app.temporaryPath + '/' + name if not os.path.exists(filePath) or os.stat(filePath).st_size == 0: logging.info('Requesting download %s from %s...\n' % (name, url)) urllib.urlretrieve(url, filePath) if loader: logging.info('Loading %s...' % (name,)) loader(filePath) self.delayDisplay('Finished with download and loading') volumeNode = slicer.util.getNode(pattern="FA") logic = LineIntensityProfileLogic() self.assertIsNotNone( logic.hasImageData(volumeNode) ) #initialize ruler in a known location rulerNode = slicer.vtkMRMLAnnotationRulerNode() slicer.mrmlScene.AddNode(rulerNode) rulerNode.SetPosition1(-65,110,60) rulerNode.SetPosition2(-15,60,60) rulerNode.SetName('Test') # initialize input selectors moduleWidget = slicer.modules.LineIntensityProfileWidget moduleWidget.rulerSelector.setCurrentNode(rulerNode) moduleWidget.inputSelector1.setCurrentNode(volumeNode) moduleWidget.inputSelector2.setCurrentNode(volumeNode) self.delayDisplay('inputs Initialized') #run the logic with initialized inputs moduleWidget.onApplyButton() self.delayDisplay('If you see a ruler and a plot - test passed')
def TestRulerAdd(renameFlag=1, visibilityFlag=1, numToAdd=20): print("numToAdd = ", numToAdd) if renameFlag > 0: print("Index\tTime to add ruler\tDelta between adds\tTime to rename ruler\tDelta between renames") print("%(index)04s\t" % {'index': "i"}, "t\tdt\tt\tdt") else: print("Index\tTime to add ruler\tDelta between adds") print("%(index)04s\t" % {'index': "i"}, "t\tdt") r1 = 0 a1 = 0 s1 = 0 r2 = 1 a2 = 1 s2 = 1 t1 = 0 t2 = 0 t3 = 0 t4 = 0 timeToAddThisRuler = 0 timeToAddLastRuler = 0 timeToRenameThisRuler = 0 timeToRenameLastRuler = 0 # iterate over the number of rulers to add for i in range(numToAdd): # print "i = ", i, "/", numToAdd, ", r = ", r, ", a = ", a, ", s = ", s rulerNode = slicer.vtkMRMLAnnotationRulerNode() rulerNode.SetPosition1(r1, a1, s1) rulerNode.SetPosition2(r2, a2, s2) t1 = time.process_time() rulerNode.Initialize(slicer.mrmlScene) t2 = time.process_time() timeToAddThisRuler = t2 - t1 dt = timeToAddThisRuler - timeToAddLastRuler if renameFlag > 0: t3 = time.process_time() rulerNode.SetName(str(i)) t4 = time.process_time() timeToRenameThisRuler = t4 - t3 dt2 = timeToRenameThisRuler - timeToRenameLastRuler print('%(index)04d\t' % {'index': i}, timeToAddThisRuler, "\t", dt, "\t", timeToRenameThisRuler, "\t", dt2) timeToRenameLastRuler = timeToRenameThisRuler else: print('%(index)04d\t' % {'index': i}, timeToAddThisRuler, "\t", dt) r1 = r1 + 1.0 a1 = a1 + 1.0 s1 = s1 + 1.0 r2 = r2 + 1.5 a2 = a2 + 1.5 s2 = s2 + 1.5 timeToAddLastRuler = timeToAddThisRuler
def findAxisOfMotion(self, origins): #Following guide from: http://sebastianraschka.com/Articles/2014_pca_step_by_step.html #scale factor for better display: scale = 100 #Calculate mean position meanVector = [0, 0 ,0] for i in range(3): meanVector[i] = np.mean(origins[i, :]) #Computing covariance matrix convMatrix = np.cov([origins[0, :], origins[1, :], origins[2, :]]) #Get eigenvectors eig_val, eig_vec = np.linalg.eig(convMatrix) # Make a list of (eigenvalue, eigenvector) tuples eig_pairs = [(np.abs(eig_val[i]), eig_vec[:,i]) for i in range(len(eig_val))] # Sort the (eigenvalue, eigenvector) tuples from high to low eig_pairs.sort() # eig_pairs.reverse() matrix_w = np.hstack((eig_pairs[0][1].reshape(3, 1), eig_pairs[1][1].reshape(3, 1), eig_pairs[2][1].reshape(3, 1))) print('Matrix W:\n', matrix_w) #Create linear transform for contour propagation vtkMatrix = vtk.vtkMatrix4x4() transform = slicer.vtkMRMLLinearTransformNode() slicer.mrmlScene.AddNode(transform) for i in range(3): for j in range(3): vtkMatrix.SetElement(j, i, matrix_w[i, j]) transform.SetAndObserveMatrixTransformFromParent(vtkMatrix) #Plot eigenvectors from mean position fiducials = slicer.vtkMRMLMarkupsFiducialNode() displayNode = slicer.vtkMRMLMarkupsDisplayNode() # vtkNew<vtkMRMLMarkupsFiducialStorageNode> wFStorageNode; slicer.mrmlScene.AddNode(displayNode) slicer.mrmlScene.AddNode(fiducials) fiducials.SetAndObserveDisplayNodeID(displayNode.GetID()) fiducials.AddFiducialFromArray(meanVector, "Mean Position") for i in range(len(eig_vec)): # fiducials.AddFiducialFromArray(meanVector + scale * eig_vec[i], " P " + str(i+1)) #Plot ruler ruler = slicer.vtkMRMLAnnotationRulerNode() displayRuler = slicer.vtkMRMLAnnotationLineDisplayNode() displayRuler.SetLabelVisibility(0) displayRuler.SetMaxTicks(0) displayRuler.SetLineWidth(5) slicer.mrmlScene.AddNode(displayRuler) slicer.mrmlScene.AddNode(ruler) ruler.SetAndObserveDisplayNodeID(displayRuler.GetID()) ruler.SetPosition1(meanVector) ruler.SetPosition2(meanVector + scale * eig_vec[i]) return matrix_w
def get3DEuclideanDistance(pos1, pos2): rulerNode = slicer.vtkMRMLAnnotationRulerNode() rulerNode.SetPosition1(pos1) rulerNode.SetPosition2(pos2) distance3D = rulerNode.GetDistanceMeasurement() return distance3D
def loadAdditionalMeasurements(self, srUID): """ Loads length measements as annotation rulers TODO: need to generalize to other report contents """ srFilePath = slicer.dicomDatabase.fileForInstance(srUID) sr = dicom.read_file(srFilePath) if not self.isConcept(sr, "imagingMeasurementReport"): return sr contents = {} measurements = [] contents['measurements'] = measurements for item in sr.ContentSequence: if self.isConcept(item, "personObserver"): contents['personObserver'] = item.PersonName if self.isConcept(item, "imagingMeasuremnts"): for contentItem in item.ContentSequence: if self.isConcept(contentItem, "measurementGroup"): measurement = {} for measurementItem in contentItem.ContentSequence: if self.isConcept(measurementItem, "trackingIdentifier"): measurement[ 'trackingIdentifier'] = measurementItem.TextValue if self.isConcept(measurementItem, "trackingUniqueIdentifier"): measurement[ 'trackingUniqueIdentifier'] = measurementItem.UID if self.isConcept(measurementItem, "findingSite"): measurement[ 'findingSite'] = measurementItem.ConceptCodeSequence[ 0].CodeMeaning if self.isConcept(measurementItem, "length"): for lengthItem in measurementItem.ContentSequence: measurement[ 'polyline'] = lengthItem.GraphicData for selectionItem in lengthItem.ContentSequence: if selectionItem.RelationshipType == "SELECTED FROM": for reference in selectionItem.ReferencedSOPSequence: measurement[ 'referencedSOPInstanceUID'] = reference.ReferencedSOPInstanceUID if hasattr( reference, "ReferencedFrameNumber" ) and reference.ReferencedFrameNumber != "1": print( 'Error - only single frame references supported' ) measurements.append(measurement) for measurement in contents['measurements']: rulerNode = slicer.vtkMRMLAnnotationRulerNode() rulerNode.SetLocked(True) rulerNode.SetName(contents['personObserver']) referenceFilePath = slicer.dicomDatabase.fileForInstance( measurement['referencedSOPInstanceUID']) reference = dicom.read_file(referenceFilePath) origin = numpy.array(reference.ImagePositionPatient) alongColumnVector = numpy.array( reference.ImageOrientationPatient[:3]) alongRowVector = numpy.array(reference.ImageOrientationPatient[3:]) alongColumnVector *= reference.PixelSpacing[1] alongRowVector *= reference.PixelSpacing[0] col1, row1, col2, row2 = measurement['polyline'] lpsToRAS = numpy.array([-1, -1, 1]) p1 = (origin + col1 * alongColumnVector + row1 * alongRowVector) * lpsToRAS p2 = (origin + col2 * alongColumnVector + row2 * alongRowVector) * lpsToRAS rulerNode.SetPosition1(*p1) rulerNode.SetPosition2(*p2) rulerNode.Initialize(slicer.mrmlScene) colorIndex = 1 + len( slicer.util.getNodesByClass('vtkMRMLAnnotationRulerNode')) colorNode = slicer.util.getNode("GenericAnatomyColors") color = [ 0, ] * 4 colorNode.GetColor(colorIndex, color) rulerNode.GetDisplayNode().SetColor(*color[:3]) rulerNode.GetAnnotationTextDisplayNode().SetColor(*color[:3]) rulerNode.GetAnnotationPointDisplayNode().SetColor(*color[:3]) rulerNode.GetAnnotationPointDisplayNode().SetGlyphScale(2) rulerNode.GetAnnotationLineDisplayNode().SetLabelPosition( random.random())