Hi. I am an interventional cardiologist. Currently I am interested in pre-planning for my intervention. In detail, I want to determine the optimal angles for setting the X-ray views.
Is there any extension, or Python codes for displaying these parameter (as I show in the following image).
There isn’t a dedicated planning tool that I’m aware of. You may want to just use Markups Angles to design your imaging plan and then match the device as best you can.
You can copy-paste this code snippet to the Python console to show the anatomical angles (LAO/RAO, CRA/CAU) of the C-arm in the corner of a 3D view:
threeDViewIndex = 0 # change this to show angles in a different 3D view
def positionerAngleFromViewNormal(viewNormal):
# According to https://www5.informatik.uni-erlangen.de/Forschung/Publikationen/2014/Koch14-OVA.pdf
nx = -viewNormal[0] # L
ny = -viewNormal[1] # P
nz = viewNormal[2] # S
import math
if abs(ny) > 1e-6:
primaryAngleDeg = math.atan(-nx/ny) * 180.0 / math.pi
elif nx >= 0:
primaryAngleDeg = 90.0
else:
primaryAngleDeg = -90.0
secondaryAngleDeg = math.asin(nz) * 180.0 / math.pi
return [primaryAngleDeg, secondaryAngleDeg]
def formatPositionerAngle(positionerAngles):
primaryAngleDeg, secondaryAngleDeg = positionerAngles
text = f'{"RAO" if primaryAngleDeg < 0 else "LAO"} {abs(primaryAngleDeg):.1f}\n'
text += f'{"CRA" if secondaryAngleDeg < 0 else "CAU"} {abs(secondaryAngleDeg):.1f}'
return text
def cameraUpdated(cameraNode, view):
viewNormal = cameraNode.GetCamera().GetDirectionOfProjection()
positionerAngleText = formatPositionerAngle(positionerAngleFromViewNormal(viewNormal))
view.cornerAnnotation().SetText(vtk.vtkCornerAnnotation.UpperRight, positionerAngleText)
view.cornerAnnotation().GetTextProperty().SetColor(1,1,0) # yellow
view.scheduleRender()
layoutManager = slicer.app.layoutManager()
view = layoutManager.threeDWidget(threeDViewIndex).threeDView()
threeDViewNode = view.mrmlViewNode()
cameraNode = slicer.modules.cameras.logic().GetViewActiveCameraNode(threeDViewNode)
cameraObservation = cameraNode.AddObserver(vtk.vtkCommand.ModifiedEvent, lambda caller, event, view=view: cameraUpdated(caller, view))
cameraUpdated(cameraNode, view)
# Execute the next line to stop updating the positioner angles in the view corner
# cameraNode.RemoveObserver(cameraObservation)
We are developing a fluoro simulator module for interventional cardiology as part of the SlicerHeart project. The module will be able to display not just the angles but simulated fluoro images and compute optimal viewing angles, etc. We’ll release it when the results are first published - probably within a year.