def test_Volume(self): """ Test the GetRASBounds & GetBounds method on a volume. """ #self.delayDisplay("Starting test_Volume") import SampleData sampleDataLogic = SampleData.SampleDataLogic() volumeNode = sampleDataLogic.downloadAbdominalCTVolume() bounds = range(6) volumeNode.GetRASBounds(bounds) untransformedBounds = [-165.68283081054688, 161.62185668945312, 7.542130470275879, 245.78431797027588, -347.62799072265625, -25.12799072265625] self.assertListAlmostEquals(bounds, untransformedBounds) volumeNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds) transform = vtk.vtkTransform() transform.Translate([-5.0, +42.0, -0.1]) transform.RotateWXYZ(41, 0.7, 0.6, 75) transform.Scale(2, 3, 10) transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode()) transformNode.ApplyTransform(transform) volumeNode.SetAndObserveTransformNodeID(transformNode.GetID()) transformedBounds = [-764.990027409413, 222.22539693955437, -157.26286179044325, 825.0196226274144, -3477.0246375801075, -244.4287311630153] volumeNode.GetRASBounds(bounds) self.assertListAlmostEquals(bounds, transformedBounds) volumeNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds)
def test_ROI(self): """ Test the GetRASBounds & GetBounds method on a ROI. """ #self.delayDisplay("Starting test_ROI") roiNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLAnnotationROINode()) roiNode.SetXYZ(100, 300, -0.689) roiNode.SetRadiusXYZ(700, 8, 45) bounds = range(6) roiNode.GetRASBounds(bounds) untransformedBounds = [-600, 800, 292, 308, -45.689, 44.311] self.assertListAlmostEquals(bounds, untransformedBounds) roiNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds) transform = vtk.vtkTransform() transform.Translate([-5.0, +42.0, -0.1]) transform.RotateWXYZ(41, 0.7, 0.6, 75) transform.Scale(2, 3, 10) transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode()) transformNode.ApplyTransform(transform) roiNode.SetAndObserveTransformNodeID(transformNode.GetID()) transformedBounds = [ -1520.2565880625004, 631.261028317266, -85.93765163061204, 1790.9115952348277, -454.6252695921299, 454.0147697244433 ] roiNode.GetRASBounds(bounds) self.assertListAlmostEquals(bounds, transformedBounds) roiNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds)
def test_Volume(self): """ Test the GetRASBounds & GetBounds method on a volume. """ #self.delayDisplay("Starting test_Volume") import SampleData volumeNode = SampleData.downloadSample('CTAAbdomenPanoramix') bounds = range(6) volumeNode.GetRASBounds(bounds) untransformedBounds = [ -165.68283081054688, 161.62185668945312, 7.542130470275879, 245.78431797027588, -347.62799072265625, -25.12799072265625 ] self.assertListAlmostEquals(bounds, untransformedBounds) volumeNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds) transform = vtk.vtkTransform() transform.Translate([-5.0, +42.0, -0.1]) transform.RotateWXYZ(41, 0.7, 0.6, 75) transform.Scale(2, 3, 10) transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode()) transformNode.ApplyTransform(transform) volumeNode.SetAndObserveTransformNodeID(transformNode.GetID()) transformedBounds = [ -764.990027409413, 222.22539693955437, -157.26286179044325, 825.0196226274144, -3477.0246375801075, -244.4287311630153 ] volumeNode.GetRASBounds(bounds) self.assertListAlmostEquals(bounds, transformedBounds) volumeNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds)
def apply_brains_rigid_registration(moving_node, pair, log_callback): transform_node = slicer.vtkMRMLTransformNode() transform_node.SetName(moving_node.GetName() + ' BRAINS transform') slicer.mrmlScene.AddNode(transform_node) # TODO use runSync slicer.cli.run( slicer.modules.brainsfit, None, { 'fixedVolume': pair.fixed.currentNode().GetID(), 'movingVolume': moving_node.GetID(), 'outputTransform': transform_node.GetID(), 'transformType': 'Rigid', 'samplingPercentage': 0.01, 'initialTransformMode': 'off', 'maskProcessingMode': 'NOMASK', # TODO double check Masking = NOMASK 'costMetric': 'NC', 'numberOfIterations': 1000, # TODO check if theres a max param 'minimumStepLength': 0.0000001, 'maximumStepLength': 0.001, 'skewScale': 1.0, 'reproportionScale': 1.0, 'relaxationFactor': 0.5, 'translationScale': 1.0 # aka transform scale }, wait_for_completion=True) print('TRANSFORM GENERATED: ') print(transform_node) moving_node.ApplyTransform(transform_node.GetTransformToParent()) moving_node.HardenTransform() moving_node.SetName(moving_node.GetName() + "_BRAINS") return moving_node
def onFiducialsModified2(self, observer, eventId): # matches which fiducial node to check against if self.probe2PathTransform == None: self.probe2PathTransform = slicer.vtkMRMLTransformNode() self.probe2PathTransform.SetName("Probe2PathTransform") slicer.mrmlScene.AddNode(self.probe2PathTransform) self.probe2PathTransform.SetMatrixTransformToParent(self.identity) if self.entryPose2Selector.currentNode() != None: display = self.entryPose2Selector.currentNode().GetDisplayNode() display.SetGlyphScale(1) if self.targetPose2Selector.currentNode() != None: display = self.targetPose2Selector.currentNode().GetDisplayNode() display.SetGlyphScale(1) if self.entryPose2Selector.currentNode( ) != None and self.targetPose2Selector.currentNode() != None: self.probe2PathTransform = self.logic.updateTransform( self.targetPose2Selector.currentNode(), self.entryPose2Selector.currentNode(), self.probe2PathTransform) else: pass
def test_Markup(self): """ Test the GetRASBounds & GetBounds method on a markup. """ #self.delayDisplay("Starting test_Markup") markupNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLMarkupsFiducialNode()) markupNode.AddFiducial(1.0, 0.0, 0.0) markupNode.AddFiducial(-45.0, -90.0, -180.0) markupNode.AddFiducial(-200.0, 500.0, -0.23) markupNode.AddFiducial(1.0, 1003.01, 0.0) bounds = range(6) markupNode.GetRASBounds(bounds) untransformedBounds = [-200, 1.0, -90, 1003.01, -180.0, 0.0] self.assertListAlmostEquals(bounds, untransformedBounds) markupNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds) transform = vtk.vtkTransform() transform.Translate([-5.0, +42.0, -0.1]) transform.RotateWXYZ(41, 0.7, 0.6, 75) transform.Scale(2, 3, 10) transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode()) transformNode.ApplyTransform(transform) markupNode.SetAndObserveTransformNodeID(transformNode.GetID()) transformedBounds = [-1977.3875985837567, 90.6250336838986, -213.3290140037272, 2314.3030541154367, -1801.9498682023534, 24.221433153858232] markupNode.GetRASBounds(bounds) self.assertListAlmostEquals(bounds, transformedBounds) markupNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds)
def test_ROI(self): """ Test the GetRASBounds & GetBounds method on a ROI. """ #self.delayDisplay("Starting test_ROI") roiNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLAnnotationROINode()) roiNode.SetXYZ(100, 300, -0.689) roiNode.SetRadiusXYZ(700, 8, 45) bounds = range(6) roiNode.GetRASBounds(bounds) untransformedBounds = [-600, 800, 292, 308, -45.689, 44.311] self.assertListAlmostEquals(bounds, untransformedBounds) roiNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds) transform = vtk.vtkTransform() transform.Translate([-5.0, +42.0, -0.1]) transform.RotateWXYZ(41, 0.7, 0.6, 75) transform.Scale(2, 3, 10) transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode()) transformNode.ApplyTransform(transform) roiNode.SetAndObserveTransformNodeID(transformNode.GetID()) transformedBounds = [-1520.2565880625004, 631.261028317266, -85.93765163061204, 1790.9115952348277, -454.6252695921299, 454.0147697244433] roiNode.GetRASBounds(bounds) self.assertListAlmostEquals(bounds, transformedBounds) roiNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds)
def onFiducialRegWizNode(self, observer, eventId): if self.FiducialRegWizNode.GetOutputTransformNode() == None: self.initialLandmarkTransform = slicer.vtkMRMLTransformNode() self.initialLandmarkTransform.SetName("FromPreopToIntraopInitialTransform") slicer.mrmlScene.AddNode(self.initialLandmarkTransform) self.FidRegWizRegResultComboBox.setCurrentNode(self.initialLandmarkTransform) else: self.initialLandmarkTransform = self.FiducialRegWizNode.GetOutputTransformNode()
def test_Segmentation(self): """ Test the GetRASBounds & GetBounds method on a segmentation. """ #self.delayDisplay("Starting test_Segmentation") cubeSource = vtk.vtkCubeSource() cubeSource.SetXLength(500) cubeSource.SetYLength(200) cubeSource.SetZLength(300) cubeSource.SetCenter(10, -85, 0.7) rotation = vtk.vtkTransform() rotation.RotateX(15.0) rotation.RotateZ(78) applyTransform = vtk.vtkTransformPolyDataFilter() applyTransform.SetTransform(rotation) applyTransform.SetInputConnection(cubeSource.GetOutputPort()) applyTransform.Update() modelNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLModelNode()) modelNode.SetPolyDataConnection(applyTransform.GetOutputPort()) segmentationNode = slicer.mrmlScene.AddNewNodeByClass( "vtkMRMLSegmentationNode") segmentationLogic = slicer.modules.segmentations.logic() segmentationLogic.ImportModelToSegmentationNode( modelNode, segmentationNode) # Testing bounds = list(range(6)) segmentationNode.GetRASBounds(bounds) untransformedBounds = [ -65.41641522206768, 237.23434621664228, -303.75878430165756, 289.7072339384945, -217.463212035832, 213.6873140360733 ] self.assertListAlmostEquals(bounds, untransformedBounds) segmentationNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds) transform = vtk.vtkTransform() transform.Translate([-5.0, +42.0, -0.1]) transform.RotateWXYZ(41, 0.7, 0.6, 75) transform.Scale(2, 3, 10) transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode()) transformNode.ApplyTransform(transform) segmentationNode.SetAndObserveTransformNodeID(transformNode.GetID()) transformedBounds = [ -690.2701685073093, 966.991271911892, -740.4842166018336, 1018.2608117218165, -2183.4229718546612, 2144.1077463008546 ] segmentationNode.GetRASBounds(bounds) self.assertListAlmostEquals(bounds, transformedBounds) segmentationNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds)
def flip(self, volumeNode, transformMatrix): transform = slicer.vtkMRMLTransformNode() transform.SetName('FlipTransformation') slicer.mrmlScene.AddNode(transform) transform.SetMatrixTransformFromParent(transformMatrix) volumeNode.SetAndObserveTransformNodeID(transform.GetID()) slicer.vtkSlicerTransformLogic().hardenTransform(volumeNode) slicer.mrmlScene.RemoveNode(transform)
def addTransform(self): """Create and add a transform node with a display node to the mrmlScene. Returns the transform node and its display node """ transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode()) transformDisplayNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformDisplayNode()) transformNode.SetAndObserveDisplayNodeID(transformDisplayNode.GetID()) return transformNode, transformDisplayNode
def addTransform(self): """Create and add a transform node with a display node to the mrmlScene. Returns the transform node and its display node """ transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode()) transformDisplayNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformDisplayNode()) transformNode.SetAndObserveDisplayNodeID(transformDisplayNode.GetID()) return transformNode, transformDisplayNode
def test_Segmentation(self): """ Test the GetRASBounds & GetBounds method on a segmentation. """ #self.delayDisplay("Starting test_Segmentation") cubeSource = vtk.vtkCubeSource() cubeSource.SetXLength(500) cubeSource.SetYLength(200) cubeSource.SetZLength(300) cubeSource.SetCenter(10, -85, 0.7) rotation = vtk.vtkTransform() rotation.RotateX(15.0) rotation.RotateZ(78) applyTransform = vtk.vtkTransformPolyDataFilter() applyTransform.SetTransform(rotation) applyTransform.SetInputConnection(cubeSource.GetOutputPort()) applyTransform.Update() modelNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLModelNode()) modelNode.SetPolyDataConnection(applyTransform.GetOutputPort()) segmentationNode = slicer.mrmlScene.AddNewNodeByClass( "vtkMRMLSegmentationNode") segmentationLogic = slicer.modules.segmentations.logic() segmentationLogic.ImportModelToSegmentationNode( modelNode, segmentationNode) # Testing bounds = range(6) segmentationNode.GetRASBounds(bounds) untransformedBounds = [ -65.4164152220677, 237.23434621664234, -305.4495706784099, 289.7072339384947, -217.46321203583187, 213.68731403607347 ] self.assertListAlmostEquals(bounds, untransformedBounds) segmentationNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds) transform = vtk.vtkTransform() transform.Translate([-5.0, +42.0, -0.1]) transform.RotateWXYZ(41, 0.7, 0.6, 75) transform.Scale(2, 3, 10) transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode()) transformNode.ApplyTransform(transform) segmentationNode.SetAndObserveTransformNodeID(transformNode.GetID()) transformedBounds = [ -690.2701685073098, 970.3186946284741, -744.3124542486084, 1018.260811721817, -2183.4639807718822, 2144.107746300856 ] segmentationNode.GetRASBounds(bounds) self.assertListAlmostEquals(bounds, transformedBounds) segmentationNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds)
def test_Model(self): """ Test the GetRASBounds & GetBounds method on a model. """ #self.delayDisplay("Starting test_Model") # Setup cubeSource = vtk.vtkCubeSource() cubeSource.SetXLength(500) cubeSource.SetYLength(200) cubeSource.SetZLength(300) cubeSource.SetCenter(10, -85, 0.7) rotation = vtk.vtkTransform() rotation.RotateX(15.0) rotation.RotateZ(78) applyTransform = vtk.vtkTransformPolyDataFilter() applyTransform.SetTransform(rotation) applyTransform.SetInputConnection(cubeSource.GetOutputPort()) applyTransform.Update() modelNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLModelNode()) modelNode.SetPolyDataConnection(applyTransform.GetOutputPort()) # Testing bounds = range(6) modelNode.GetRASBounds(bounds) untransformedBounds = [ -64.5710220336914, 235.01434326171875, -302.91339111328125, 287.3067932128906, -214.92703247070312, 212.1946258544922 ] self.assertListAlmostEquals(bounds, untransformedBounds) modelNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds) transform = vtk.vtkTransform() transform.Translate([-5.0, +42.0, -0.1]) transform.RotateWXYZ(41, 0.7, 0.6, 75) transform.Scale(2, 3, 10) transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode()) transformNode.ApplyTransform(transform) modelNode.SetAndObserveTransformNodeID(transformNode.GetID()) transformedBounds = [ -684.0789214975257, 961.8640451930095, -737.3987882515103, 1009.8075011032414, -2158.028473491281, 2129.118193451847 ] modelNode.GetRASBounds(bounds) self.assertListAlmostEquals(bounds, transformedBounds) modelNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds)
def test_Segmentation(self): """ Test the GetRASBounds & GetBounds method on a segmentation. """ #self.delayDisplay("Starting test_Segmentation") cubeSource = vtk.vtkCubeSource() cubeSource.SetXLength(500) cubeSource.SetYLength(200) cubeSource.SetZLength(300) cubeSource.SetCenter(10, -85, 0.7) rotation = vtk.vtkTransform() rotation.RotateX(15.0) rotation.RotateZ(78) applyTransform = vtk.vtkTransformPolyDataFilter() applyTransform.SetTransform(rotation) applyTransform.SetInputConnection(cubeSource.GetOutputPort()) applyTransform.Update() modelNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLModelNode()) modelNode.SetPolyDataConnection(applyTransform.GetOutputPort()) segmentationNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLSegmentationNode()) segmentationLogic = slicer.modules.segmentations.logic() segmentationLogic.ImportModelToSegmentationNode(modelNode, segmentationNode) # Testing bounds = range(6) segmentationNode.GetRASBounds(bounds) untransformedBounds = [-65.0710220336914, 235.9289779663086, -304.413391113281, 288.586608886719, -216.427032470703, 213.572967529297] self.assertListAlmostEquals(bounds, untransformedBounds) segmentationNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds) transform = vtk.vtkTransform() transform.Translate([-5.0, +42.0, -0.1]) transform.RotateWXYZ(41, 0.7, 0.6, 75) transform.Scale(2, 3, 10) transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode()) transformNode.ApplyTransform(transform) segmentationNode.SetAndObserveTransformNodeID(transformNode.GetID()) transformedBounds = [-687.4653523284665, 966.3004987004498, -741.50842882335, 1013.9676912857693, -2173.06971199151, 2142.935099515583] segmentationNode.GetRASBounds(bounds) self.assertListAlmostEquals(bounds, transformedBounds) segmentationNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds)
def test_Segmentation(self): """ Test the GetRASBounds & GetBounds method on a segmentation. """ #self.delayDisplay("Starting test_Segmentation") cubeSource = vtk.vtkCubeSource() cubeSource.SetXLength(500) cubeSource.SetYLength(200) cubeSource.SetZLength(300) cubeSource.SetCenter(10, -85, 0.7) rotation = vtk.vtkTransform() rotation.RotateX(15.0) rotation.RotateZ(78) applyTransform = vtk.vtkTransformPolyDataFilter() applyTransform.SetTransform(rotation) applyTransform.SetInputConnection(cubeSource.GetOutputPort()) applyTransform.Update() modelNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLModelNode()) modelNode.SetPolyDataConnection(applyTransform.GetOutputPort()) segmentationNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLSegmentationNode()) segmentationLogic = slicer.modules.segmentations.logic() segmentationLogic.ImportModelToSegmentationNode(modelNode, segmentationNode) # Testing bounds = range(6) segmentationNode.GetRASBounds(bounds) untransformedBounds = [-65.4164152220677, 237.23434621664234, -305.4495706784099, 289.7072339384947, -217.46321203583187, 213.68731403607347] self.assertListAlmostEquals(bounds, untransformedBounds) segmentationNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds) transform = vtk.vtkTransform() transform.Translate([-5.0, +42.0, -0.1]) transform.RotateWXYZ(41, 0.7, 0.6, 75) transform.Scale(2, 3, 10) transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode()) transformNode.ApplyTransform(transform) segmentationNode.SetAndObserveTransformNodeID(transformNode.GetID()) transformedBounds = [-690.2701685073098, 970.3186946284741, -744.3124542486084, 1018.260811721817, -2183.4639807718822, 2144.107746300856] segmentationNode.GetRASBounds(bounds) self.assertListAlmostEquals(bounds, transformedBounds) segmentationNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds)
def test_Segmentation(self): """ Test the GetRASBounds & GetBounds method on a segmentation. """ #self.delayDisplay("Starting test_Segmentation") cubeSource = vtk.vtkCubeSource() cubeSource.SetXLength(500) cubeSource.SetYLength(200) cubeSource.SetZLength(300) cubeSource.SetCenter(10, -85, 0.7) rotation = vtk.vtkTransform() rotation.RotateX(15.0) rotation.RotateZ(78) applyTransform = vtk.vtkTransformPolyDataFilter() applyTransform.SetTransform(rotation) applyTransform.SetInputConnection(cubeSource.GetOutputPort()) applyTransform.Update() modelNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLModelNode()) modelNode.SetPolyDataConnection(applyTransform.GetOutputPort()) segmentationNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLSegmentationNode()) segmentationLogic = slicer.modules.segmentations.logic() segmentationLogic.ImportModelToSegmentationNode(modelNode, segmentationNode) # Testing bounds = range(6) segmentationNode.GetRASBounds(bounds) untransformedBounds = [-65.0710220336914, 235.9289779663086, -304.413391113281, 288.586608886719, -216.427032470703, 213.572967529297] self.assertListAlmostEquals(bounds, untransformedBounds) segmentationNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds) transform = vtk.vtkTransform() transform.Translate([-5.0, +42.0, -0.1]) transform.RotateWXYZ(41, 0.7, 0.6, 75) transform.Scale(2, 3, 10) transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode()) transformNode.ApplyTransform(transform) segmentationNode.SetAndObserveTransformNodeID(transformNode.GetID()) transformedBounds = [-200.70776329131795, 479.54290966330126, -723.6172978253361, 996.0765602877555, -2171.2883672792996, 2141.1537548033725] segmentationNode.GetRASBounds(bounds) self.assertListAlmostEquals(bounds, transformedBounds) segmentationNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds)
def __init__(self, transform_name, mesh_filename): """INPUT: transform_name [str] - name assigned to node in Slicer. (If using IGTL be sure this matches) mesh_filename [str] - filename with given mesh - accepts .stl and .dae """ self.transform_name = transform_name self.mesh_filename = mesh_filename _, self.mesh_model_node = slicer.util.loadModel( mesh_filename, returnNode=True) # TODO: [May become deprecated] self.mesh_nodeID = self.mesh_model_node.GetID() self.transform_node = slicer.vtkMRMLTransformNode() self.transform_node.SetName(transform_name) slicer.mrmlScene.AddNode(self.transform_node) self.transform_nodeID = self.transform_node.GetID() self.display_node = self.mesh_model_node.GetDisplayNode() self.mesh_model_node.SetAndObserveTransformNodeID( self.transform_nodeID)
def test_Model(self): """ Test the GetRASBounds & GetBounds method on a model. """ #self.delayDisplay("Starting test_Model") # Setup cubeSource = vtk.vtkCubeSource() cubeSource.SetXLength(500) cubeSource.SetYLength(200) cubeSource.SetZLength(300) cubeSource.SetCenter(10, -85, 0.7) rotation = vtk.vtkTransform() rotation.RotateX(15.0) rotation.RotateZ(78) applyTransform = vtk.vtkTransformPolyDataFilter() applyTransform.SetTransform(rotation) applyTransform.SetInputConnection(cubeSource.GetOutputPort()) applyTransform.Update() modelNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLModelNode()) modelNode.SetPolyDataConnection(applyTransform.GetOutputPort()) # Testing bounds = range(6) modelNode.GetRASBounds(bounds) untransformedBounds = [-64.5710220336914, 235.01434326171875, -302.91339111328125, 287.3067932128906, -214.92703247070312, 212.1946258544922] self.assertListAlmostEquals(bounds, untransformedBounds) modelNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds) transform = vtk.vtkTransform() transform.Translate([-5.0, +42.0, -0.1]) transform.RotateWXYZ(41, 0.7, 0.6, 75) transform.Scale(2, 3, 10) transformNode = slicer.mrmlScene.AddNode(slicer.vtkMRMLTransformNode()) transformNode.ApplyTransform(transform) modelNode.SetAndObserveTransformNodeID(transformNode.GetID()) transformedBounds = [-684.0789214975257, 961.8640451930095, -737.3987882515103, 1009.8075011032414, -2158.028473491281, 2129.118193451847] modelNode.GetRASBounds(bounds) self.assertListAlmostEquals(bounds, transformedBounds) modelNode.GetBounds(bounds) self.assertListAlmostEquals(bounds, untransformedBounds)
def onAlignButtonTB(self): self.RWButton.enabled = False self.alignButtonTB.enabled = False self.landmarkTransform = slicer.vtkMRMLTransformNode() slicer.mrmlScene.AddNode(self.landmarkTransform) logic = AlignCrop3DSlicerModuleLogic() if(self.movingFiducialNode.GetNumberOfFiducials() > 2): logic.runAlignmentRegistration(self.landmarkTransform, self.templateFidTB, self.movingFiducialNode, self.placementListTB) else: slicer.util.infoDisplay("At least 3 fiducials required for registration to proceed") #Apply Landmark transform on input Volume & Fiducials and Harden self.inputVolumeTB.SetAndObserveTransformNodeID(self.landmarkTransform.GetID()) slicer.vtkSlicerTransformLogic().hardenTransform(self.inputVolumeTB) self.movingFiducialNode.SetAndObserveTransformNodeID(self.landmarkTransform.GetID()) slicer.vtkSlicerTransformLogic().hardenTransform(self.movingFiducialNode) #TODO - Align output is incorrect!! Investigate (Jan 17th - 2018) #Set template to foreground in Slice Views applicationLogic = slicer.app.applicationLogic() selectionNode = applicationLogic.GetSelectionNode() selectionNode.SetSecondaryVolumeID(self.templateVolumeTB.GetID()) applicationLogic.PropagateForegroundVolumeSelection(0) #set overlap of foreground & background in slice view sliceLayout = slicer.app.layoutManager() sliceLogicR = sliceLayout.sliceWidget('Red').sliceLogic() compositeNodeR = sliceLogicR.GetSliceCompositeNode() compositeNodeR.SetForegroundOpacity(0.5) sliceLogicY = sliceLayout.sliceWidget('Yellow').sliceLogic() compositeNodeY = sliceLogicY.GetSliceCompositeNode() compositeNodeY.SetForegroundOpacity(0.5) sliceLogicG = sliceLayout.sliceWidget('Green').sliceLogic() compositeNodeG = sliceLogicG.GetSliceCompositeNode() compositeNodeG.SetForegroundOpacity(0.5) #centre slice viewer on image slicer.app.applicationLogic().FitSliceToAll() #Make Atlas Fidcials visible self.templateFidTB.SetDisplayVisibility(1)
def applySkyscanTransform(self, volumeNode): #set up transform node transformNode = slicer.vtkMRMLTransformNode() slicer.mrmlScene.AddNode(transformNode) volumeNode.SetAndObserveTransformNodeID(transformNode.GetID()) #set up Skyscan transform transformMatrixNp = np.array([[1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1]]) transformMatrixVTK = vtk.vtkMatrix4x4() for row in range(4): for col in range(4): transformMatrixVTK.SetElement(row, col, transformMatrixNp[row,col]) transformNode.SetMatrixTransformToParent(transformMatrixVTK) #harden and clean up slicer.vtkSlicerTransformLogic().hardenTransform(volumeNode) slicer.mrmlScene.RemoveNode(transformNode)
def onAlignButton(self): self.RWButton.enabled = False #Create Landmark transform placeholder self.LandmarkTrans = slicer.vtkMRMLTransformNode() slicer.mrmlScene.AddNode(self.LandmarkTrans) logic = AValue3DSlicerModuleLogic() #Run fiducial registration if(self.placedLandmarkNode.GetNumberOfFiducials() == 4): logic.runFiducialRegistration(self.rightAtlas.isChecked(), self.LandmarkTrans, self.placedLandmarkNode) else: slicer.util.infoDisplay("4 Fiducials required for registration") #TODO - add appropriate information to help user! #Apply Landmark transform on Atlas Volume then Harden self.atlasVolume.SetAndObserveTransformNodeID(self.LandmarkTrans.GetID()) slicer.vtkSlicerTransformLogic().hardenTransform(self.atlasVolume) #Apply Landmark transform on Fiduicals then Harden self.atlasFid.SetAndObserveTransformNodeID(self.LandmarkTrans.GetID()) slicer.vtkSlicerTransformLogic().hardenTransform(self.atlasFid) #Set Atlas to foreground in Slice Views applicationLogic = slicer.app.applicationLogic() selectionNode = applicationLogic.GetSelectionNode() selectionNode.SetSecondaryVolumeID(self.atlasVolume.GetID()) applicationLogic.PropagateForegroundVolumeSelection(0) #set overlap of foreground & background in slice view sliceLayout = slicer.app.layoutManager() sliceLogicR = sliceLayout.sliceWidget('Red').sliceLogic() compositeNodeR = sliceLogicR.GetSliceCompositeNode() compositeNodeR.SetForegroundOpacity(0.4) sliceLogicY = sliceLayout.sliceWidget('Yellow').sliceLogic() compositeNodeY = sliceLogicY.GetSliceCompositeNode() compositeNodeY.SetForegroundOpacity(0.4) sliceLogicG = sliceLayout.sliceWidget('Green').sliceLogic() compositeNodeG = sliceLogicG.GetSliceCompositeNode() compositeNodeG.SetForegroundOpacity(0.4) self.defineCropButton.enabled = True # enabled next step "Defining Crop region of interest" self.placedLandmarkNode.SetDisplayVisibility(0) #turn off display of placed landmarks -TODO - Is this needed
def viewAlignedMeshWithinSlicer(viewMeshFolder, viewLmkFolder): slicer.mrmlScene.Clear(0) modelDir = viewMeshFolder modelFileExt = "ply" numberOfColumns = 4 modelFiles = list(f for f in os.listdir(modelDir) if f.endswith('.' + modelFileExt)) markupDir = viewLmkFolder markupFileExt = "fcsv" # Create a custom layout numberOfRows = min(int(math.ceil(len(modelFiles) / numberOfColumns)), 4) customLayoutId = 3311 # we pick a random id that is not used by others slicer.app.setRenderPaused(True) customLayout = '<layout type="vertical">' viewIndex = 0 for rowIndex in range(numberOfRows): customLayout += '<item><layout type="horizontal">' for colIndex in range(numberOfColumns): name = os.path.basename( modelFiles[viewIndex]) if viewIndex < len( modelFiles) else "compare " + str(viewIndex) customLayout += '<item><view class="vtkMRMLViewNode" singletontag="' + name customLayout += '"><property name="viewlabel" action="default">' + name + '</property></view></item>' viewIndex += 1 customLayout += '</layout></item>' customLayout += '</layout>' if not slicer.app.layoutManager().layoutLogic().GetLayoutNode( ).SetLayoutDescription(customLayoutId, customLayout): slicer.app.layoutManager().layoutLogic().GetLayoutNode( ).AddLayoutDescription(customLayoutId, customLayout) slicer.app.layoutManager().setLayout(customLayoutId) # Add a transform node c = 2000 transformNode = slicer.vtkMRMLTransformNode() slicer.mrmlScene.AddNode(transformNode) transformMatrixNP = np.array([[c, 0, 0, 0], [0, c, 0, 0], [0, 0, c, 0], [0, 0, 0, 1]]) transformNode.SetAndObserveMatrixTransformToParent( slicer.util.vtkMatrixFromArray(transformMatrixNP)) # Load and show each model in a view for modelIndex, modelFile in enumerate(modelFiles): if modelIndex < numberOfColumns * numberOfRows: # set a viewNode name = os.path.basename(modelFile) viewNode = slicer.mrmlScene.GetSingletonNode( name, "vtkMRMLViewNode") viewNode.LinkedControlOn() # set a modelNode modelNode = slicer.util.loadModel(modelDir + "/" + modelFile) modelNode.SetAndObserveTransformNodeID(transformNode.GetID()) modelNode.GetDisplayNode().AddViewNodeID(viewNode.GetID()) # Show only one set of landmark in each view markupFile = os.path.splitext( modelFile)[0] + '.' + markupFileExt markupNode = slicer.util.loadMarkupsFiducialList(markupDir + "/" + markupFile)[1] markupNode.SetAndObserveTransformNodeID(transformNode.GetID()) mDisplayNode = markupNode.GetDisplayNode() mDisplayNode.SetTextScale(0) mDisplayNode.SetGlyphScale(4) mDisplayNode.AddViewNodeID(viewNode.GetID()) slicer.app.setRenderPaused(False)
def autoAlign(self, markupsList, inputVolume): if markupsList.GetNumberOfFiducials() is not 3: raise ValueError( "Orientation markup must contain exactly 3 fiducials") coordinateList = [] for i in range(3): x = [0, 0, 0, 0] markupsList.GetNthFiducialWorldCoordinates(i, x) del x[3] coordinateList.append(x) # create two vectors that define a plane between the three specified points vectorA = [ coordinateList[1][dim] - coordinateList[0][dim] for dim in range(3) ] vectorB = [ coordinateList[2][dim] - coordinateList[0][dim] for dim in range(3) ] # calculate the normal vector to the plane and dvide it by its length to create a unit vector vectorNorm = np.cross(vectorA, vectorB) length = np.sum(np.power(dim, 2) for dim in vectorNorm) length = np.sqrt(length) vectorNorm /= length v = np.cross(vectorNorm, [0, 0, 1]) # v represents the skew-symmetric cross product of the normal vector and the vertical unit vector v = [[0, -v[2], v[1]], [v[2], 0, -v[0]], [-v[1], v[0], 0]] x = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] n = np.add(x, v) # c represents the cosine of the angle between the given normal and the vertical unit vector c = (vectorNorm[2] / np.sqrt(np.sum(np.power(dim, 2) for dim in vectorNorm))) m = np.linalg.matrix_power(v, 2) * (1 / (1 + c)) r = np.add(n, m) # find offset between horzontally aligned points point = [] point.append(np.dot(r, coordinateList[0])) point.append(np.dot(r, coordinateList[2])) xOffset = point[0][0] - point[1][0] yOffset = point[1][1] - point[0][1] # find angle between points angle = np.arctan2(yOffset, xOffset) # create rotation matrix based on that angle x = [[np.cos(angle), -np.sin(angle), 0], [np.sin(angle), np.cos(angle), 0], [0, 0, 1]] # find product of transformation and rotation matricies r = np.dot(x, r) # add fourth row/column to make 4x4 shape r2 = np.c_[r, np.zeros(3)] rotMatrix = np.r_[r2, [[0, 0, 0, 1]]] # apply transformation to volume and points vtkRotMatrix = vtk.vtkMatrix4x4() [[ vtkRotMatrix.SetElement(row, col, rotMatrix[row, col]) for row in range(4) ] for col in range(4)] transform = slicer.vtkMRMLTransformNode() transform.SetMatrixTransformToParent(vtkRotMatrix) slicer.mrmlScene.AddNode(transform) inputVolume.SetAndObserveTransformNodeID(transform.GetID()) markupsList.SetAndObserveTransformNodeID(transform.GetID())
def run(self, inputVolume, inputMRIVolume, Thresholdvalue, enableScreenshots=0): """ Run the actual algorithm """ #if not self.isValidInputOutputData(inputVolume, inputMRIVolume, outputVolume): #slicer.util.errorDisplay('Input volume is the same as output volume. Choose a different output volume.') # return False logging.info('Processing started') ###################################################################################################################### #os.path.abspath(__file__) #os.path.dirname(os.path.abspath(__file__)) now = datetime.now() distinctsubpathname = str(now.strftime("%m%d%Y_%H%M%S")) #Remove Directories if os.path.exists(os.path.dirname(__file__) + "/Tmp"): self.remove(os.path.dirname(__file__) + "/Tmp") os.mkdir(os.path.dirname(__file__) + "/Tmp") os.mkdir(os.path.dirname(__file__) + "/Tmp/"+distinctsubpathname) os.mkdir(os.path.dirname(__file__) + "/Tmp/"+distinctsubpathname+"/transform") os.mkdir(os.path.dirname(__file__) + "/Tmp/"+distinctsubpathname+"/result") self.ElastixExecutable = os.path.dirname(__file__)+"/Elastix/bin/elastix" self.TransformixExecutable = os.path.dirname(__file__)+"/Elastix/bin/transformix" self.fixedInputFile = os.path.dirname(__file__) + "/Tmp/"+distinctsubpathname+"/fixedtmp.nii" self.movingInputFile = os.path.dirname(__file__) + "/Tmp/"+distinctsubpathname+"/movingtmp.nii" self.transformpath = os.path.dirname(__file__) + "/Tmp/"+distinctsubpathname+"/transform" self.resultelastixpath = os.path.dirname(__file__) + "/Tmp/"+distinctsubpathname+"/result" self.parameterfile = os.path.dirname(__file__) + "/Resources/Parameters_Rigid.txt" self.transformparameterfile = self.transformpath + "/TransformParameters.0.txt" self.resourcespath = os.path.dirname(__file__) + "/Resources" self.electrodefilepath = os.path.dirname(__file__) + "/Tmp/"+distinctsubpathname volumesLogic = slicer.modules.volumes.logic() if inputMRIVolume is None: namemriaux= "MRI_ATLAS_"+str(now.strftime("%m%d%Y_%H%M%S")) slicer.util.loadVolume(self.resourcespath+"/atlasImage.mha", {'name': namemriaux}) self.parameterfile2 = os.path.dirname(__file__) + "/Resources/Parameters_BSpline.txt" self.transformparameterfile = self.transformpath + "/TransformParameters.1.txt" properties = {'useCompression': 0} slicer.util.saveNode(inputVolume, self.fixedInputFile, properties) slicer.util.saveNode(slicer.util.getNode(namemriaux), self.movingInputFile, properties) subprocess.call(r'"'+self.ElastixExecutable+'" -f "'+self.fixedInputFile+'" -m "'+self.movingInputFile+'" -out "'+self.transformpath+'" -p "'+self.parameterfile+'" -p "'+self.parameterfile2+'"', shell=True) subprocess.call(r'"'+self.TransformixExecutable+'" -tp "'+self.transformparameterfile+'" -out "'+self.resultelastixpath+'" -in "'+self.movingInputFile+'" -def all', shell=True) else: properties = {'useCompression': 0} slicer.util.saveNode(inputVolume, self.fixedInputFile, properties) slicer.util.saveNode(inputMRIVolume, self.movingInputFile, properties) subprocess.call(r'"'+self.ElastixExecutable+'" -f "'+self.fixedInputFile+'" -m "'+self.movingInputFile+'" -out "'+self.transformpath+'" -p "'+self.parameterfile+'"', shell=True) subprocess.call(r'"'+self.TransformixExecutable+'" -tp "'+self.transformparameterfile+'" -out "'+self.resultelastixpath+'" -in "'+self.movingInputFile+'"', shell=True) #slicer.mrmlScene.RemoveNode(inputVolume) #slicer.mrmlScene.RemoveNode(inputMRIVolume) outputTransformNode = slicer.vtkMRMLTransformNode() outputTransformNode.SetName("transform_"+str(now.strftime("%m%d%Y_%H%M%S"))) slicer.mrmlScene.AddNode(outputTransformNode) outputTransformPath = os.path.join(self.resultelastixpath, "deformationField.mhd") [success, loadedOutputTransformNode] = slicer.util.loadTransform(outputTransformPath, returnNode = True) if success: if loadedOutputTransformNode.GetReadAsTransformToParent(): outputTransformNode.SetAndObserveTransformToParent(loadedOutputTransformNode.GetTransformToParent()) else: outputTransformNode.SetAndObserveTransformFromParent(loadedOutputTransformNode.GetTransformFromParent()) #slicer.mrmlScene.RemoveNode(loadedOutputTransformNode) nameaux= "Brain_Reg_"+str(now.strftime("%m%d%Y_%H%M%S")) slicer.util.loadVolume(self.resultelastixpath+"/result.mhd", {'name': nameaux}) outputVolume = volumesLogic.CloneVolume(slicer.mrmlScene, inputVolume, "Aux_Crop_"+str(now.strftime("%m%d%Y_%H%M%S"))) brainmask = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, inputVolume, "brainmask" ) path2files = os.path.dirname(__file__) cliParams={} cliParams["inputVolume"] = slicer.util.getNode(nameaux).GetID() cliParams["outputVolume"] = outputVolume.GetID() cliParams["brainMask"] = brainmask.GetID() if platform.system() is "Windows": cliParams["datPath"] = path2files + '\\Resources\\dat\\' cliParams["refVolsPath"] = path2files + '\\Resources\\ref_vols' else: cliParams["datPath"] = path2files + '/Resources/dat/' cliParams["refVolsPath"] = path2files + '/Resources/ref_vols' slicer.cli.run(slicer.modules.robexbrainextractioncore, None, cliParams, wait_for_completion=True) BrainCropVolume = volumesLogic.CloneVolume(slicer.mrmlScene, inputVolume, "Brain_Crop_"+str(now.strftime("%m%d%Y_%H%M%S"))) cliParams={} cliParams["InputVolume"] = outputVolume.GetID() cliParams["OutputVolume"] = BrainCropVolume.GetID() slicer.cli.run(slicer.modules.castscalarvolume, None, cliParams, wait_for_completion=True) #slicer.mrmlScene.RemoveNode(slicer.util.getNode("Aux_Crop_"+str(now.strftime("%m%d%Y_%H%M%S")))) PreprocessesCT = volumesLogic.CloneVolume(slicer.mrmlScene, inputVolume, "Preprocessed_CT_"+str(now.strftime("%m%d%Y_%H%M%S"))) cliParams = {'InputVolume': inputVolume.GetID(), 'MaskVolume': brainmask.GetID(), 'OutputVolume': PreprocessesCT.GetID()} cliNode = slicer.cli.run(slicer.modules.maskscalarvolume, None, cliParams, wait_for_completion=True) electrodeslabelimage = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, inputVolume, "electrodes" ) cliParams = {'inputVolume': PreprocessesCT.GetID(), 'outputVolume': electrodeslabelimage.GetID(),'threshold' : Thresholdvalue,'datPath' : self.electrodefilepath} cliNode = slicer.cli.run(slicer.modules.fastelectrodesegmentor, None, cliParams, wait_for_completion=True) Brain3D = volumesLogic.CreateAndAddLabelVolume( slicer.mrmlScene, BrainCropVolume, "Brain3D" ) cliParams = {'inputVolume': BrainCropVolume.GetID(), 'outputVolume': Brain3D.GetID()} cliNode = slicer.cli.run(slicer.modules.modifiedqentropysegmentation, None, cliParams, wait_for_completion=True) #Rendering Electrodes self.makeModel(Brain3D, "1,2,3", 5,"BRAIN") with open(self.electrodefilepath+"/electrodescordinatesFile.txt", 'r') as filehandle: columnarray = [] rowarray = [] slicenumarray = [] electrodes = [] for line in filehandle: currentPlace = line[:-1] if len(currentPlace.strip()) != 0: aux =currentPlace.split(",") columnarray.append(int(aux[0])) rowarray.append(int(aux[1])) slicenumarray.append(int(aux[2])) if len(currentPlace.strip()) == 0: targetarray = ([round(np.median(columnarray)),round(np.median(rowarray)),round(np.median(slicenumarray))]) if (self.checkifelectrodeexists(electrodes,targetarray)==False): electrodes.append(targetarray) columnarray=[] rowarray=[] slicenumarray=[] filehandle.close() nameelectrodesfiducial= "Electrodes_"+str(now.strftime("%m%d%Y_%H%M%S")) mlogic = slicer.modules.markups.logic() fidNode = slicer.util.getNode(mlogic.AddNewFiducialNode(nameelectrodesfiducial)) volumeNode = inputVolume electrodenum = 0 for electrode in electrodes: electrodenum = electrodenum+1 # Get position of highest voxel value point_Ijk = [electrode[0], electrode[1], electrode[2]] # Get physical coordinates from voxel coordinates volumeIjkToRas = vtk.vtkMatrix4x4() volumeNode.GetIJKToRASMatrix(volumeIjkToRas) point_VolumeRas = [0, 0, 0, 1] volumeIjkToRas.MultiplyPoint(np.append(point_Ijk,1.0), point_VolumeRas) # If volume node is transformed, apply that transform to get volume's RAS coordinates transformVolumeRasToRas = vtk.vtkGeneralTransform() slicer.vtkMRMLTransformNode.GetTransformBetweenNodes(volumeNode.GetParentTransformNode(), None, transformVolumeRasToRas) point_Ras = transformVolumeRasToRas.TransformPoint(point_VolumeRas[0:3]) # Add a markup at the computed position and print its coordinates fidNode.AddFiducial(point_Ras[0], point_Ras[1], point_Ras[2], "Contact_"+str(electrodenum)) logging.info('Processing completed') return True
def run(self, inputVolume, outputVolume, atlasVolume, initialTrans, outputTrans, atlasFid): """ Run the actual algorithm """ #check appropriate volume is selected if not self.isValidInputOutputData(inputVolume, outputVolume): slicer.util.errorDisplay('Input volume is the same as output volume. Choose a different output volume.') return False logging.info('.....Printing Initial Transform....') logging.info(initialTrans) #Create intermediate linear transform node self.linearTrans = slicer.vtkMRMLTransformNode() slicer.mrmlScene.AddNode(self.linearTrans) #Set parameters and run affine registration Step 1 cliParamsAffine = { 'fixedVolume' : inputVolume.GetID(), 'movingVolume' : atlasVolume.GetID(), 'linearTransform' : self.linearTrans.GetID() } cliParamsAffine.update({'samplingPercentage' : 1, 'initialTransformMode' : 'off', 'transformType' : 'Affine'}) cliParamsAffine.update({'numberOfIterations' : 3000, 'minimumStepLength' : 0.00001, 'maximumStepLength' : 0.05}) cliAffineTransREG = slicer.cli.run(slicer.modules.brainsfit, None, cliParamsAffine, wait_for_completion=True) logging.info('....Printing Affine Transform....') logging.info(self.linearTrans) #Apply linear transform result from step 1 on Atlas Volume atlasVolume.SetAndObserveTransformNodeID(self.linearTrans.GetID()) slicer.vtkSlicerTransformLogic().hardenTransform(atlasVolume) # Set parameters and run BSpline registration Step 2 cliParams = { 'fixedVolume' : inputVolume.GetID(), 'movingVolume' : atlasVolume.GetID(), 'bsplineTransform' : outputTrans.GetID() } #'initialTransform' : self.linearTrans.GetID() cliParams.update({ 'samplingPercentage' : 1, 'initialTransfomMode' : 'off' }) cliParams.update({ 'transformType' : 'BSpline', 'splineGridSize': '3,3,3'}) cliParams.update({ 'numberOfIterations' : 3000, 'minimumStepLength' : 0.00001, 'maximumStepLength' : 0.05}) cliParams.update({'costMetric' : 'NC' }) cliBSplineREG = slicer.cli.run(slicer.modules.brainsfit, None, cliParams, wait_for_completion=True) logging.info('....Printing BSpline Transform....') logging.info(outputTrans) #Apply BSpline transform on A-Value Fiducials atlasFid.SetAndObserveTransformNodeID(outputTrans.GetID()) slicer.vtkSlicerTransformLogic().hardenTransform(atlasFid) #Calculate New A-Value numOfFids = atlasFid.GetNumberOfFiducials() fidXYZ_RW = [0,0,0] #Round Window placeholder fidXYZ_LW = [0,0,0] #Lateral Wall placeholder print numOfFids for index in range(numOfFids): if index == 0: atlasFid.GetNthFiducialPosition(index, fidXYZ_RW) print fidXYZ_RW else: atlasFid.GetNthFiducialPosition(index, fidXYZ_LW) print fidXYZ_LW newAValue = math.sqrt( ((fidXYZ_RW[0] - fidXYZ_LW[0])**2) + \ ((fidXYZ_RW[1] - fidXYZ_LW[1])**2) + \ ((fidXYZ_LW[2] - fidXYZ_RW[2])**2) ) #Calculating CDL Estimates AlexiadesCDLoc = 4.16 * newAValue - 4 #CDL estimate from Alexiades et al. (2015) KochCDLoc = 4.16 * newAValue - 5.05 #CDL estimate from Koch et al. (2017) KochCDLlw = 3.86 * newAValue + 4.99 #CDL estimtae from Koch et al. (2017) #Display Patient ID and Estimated A Valuee outputDisp = "Patient ID:\n" + inputVolume.GetName() + \ "\n\nEstimated A Value:\n" + format(newAValue, '0.1f') + 'mm\n\n' + \ "Estimated CDL Values\n" + "CDL(oc)-1: " + format(AlexiadesCDLoc, '0.1f') + 'mm\n' + \ "CDL(oc)-2: " + format(KochCDLoc, '0.1f') + "mm\n" + \ "CDL(lw)-1: " + format(KochCDLlw, '0.1f') + "mm\n" slicer.util.infoDisplay(outputDisp) logging.info('Processing completed') #TODO - Deal with output Volume!! return True