Difference between revisions of "Documentation/Nightly/ScriptRepository"

From Slicer Wiki
Jump to: navigation, search
Line 244: Line 244:
 
</pre>
 
</pre>
  
 +
== Customize viewer layout ==
 +
 +
Show a custom layout of a 3D view on top of the red slice view:
 +
 +
<pre>
 +
customLayout = ("<layout type=\"vertical\" split=\"true\" >"
 +
  " <item>"
 +
  "  <view class=\"vtkMRMLViewNode\" singletontag=\"1\">"
 +
  "    <property name=\"viewlabel\" action=\"default\">1</property>"
 +
  "  </view>"
 +
  " </item>"
 +
  " <item>"
 +
  "  <view class=\"vtkMRMLSliceNode\" singletontag=\"Red\">"
 +
  "  <property name=\"orientation\" action=\"default\">Axial</property>"
 +
  "  <property name=\"viewlabel\" action=\"default\">R</property>"
 +
  "  <property name=\"viewcolor\" action=\"default\">#F34A33</property>"
 +
  "  </view>"
 +
  " </item>"
 +
  "</layout>")
 +
 
 +
customLayoutId=501
 +
 +
layoutManager = slicer.app.layoutManager()
 +
layoutManager.layoutLogic().GetLayoutNode().AddLayoutDescription(customLayoutId, customLayout)                                       
 +
layoutManager.setLayout(customLayoutId)
 +
</pre>
 +
 +
See description of standard layouts (that can be used as examples) here:
 +
https://github.com/Slicer/Slicer/blob/master/Libs/MRML/Logic/vtkMRMLLayoutLogic.cxx
  
 
== Running an ITK filter in Python using SimpleITK ==
 
== Running an ITK filter in Python using SimpleITK ==

Revision as of 20:59, 24 April 2015

Home < Documentation < Nightly < ScriptRepository


For the latest Slicer documentation, visit the read-the-docs.



Community-contributed modules

Usage: save the .py file to a directory, add the directory to the additional module paths in the Slicer application settings (choose in the menu: Edit / Application settings, click Modules, click >> next to Additional module paths, click Add, and choose the .py file's location).

Filters

DICOM

Informatics

  • MarkupsInfo.py: Compute the total length between all the points of a markup list.
  • LineProfile.py: Compute intensity profile in a volume along a line.

Community-contributed examples

Usage: Copy-paste the shown code lines or linked .py file contents into Python console in Slicer.

Capture

  • Get a MRML node in the scene based on the node name and call methods of that object. For the MRHead sample data:
 vol=slicer.util.getNode('MR*')
 vol.GetImageData().GetDimensions()
  • Capture the full Slicer screen and save it into a file
 img = qt.QPixmap.grabWidget(slicer.util.mainWindow()).toImage()
 img.save('c:/tmp/test.png')

Launching Slicer

  • How to open an .mrb file with Slicer at the command line?
 Slicer.exe --python-code "slicer.util.loadScene( 'f:/2013-08-23-Scene.mrb' )"
  • How to run a script in the Slicer environment in batch mode (without showing any graphical user interface)?
 Slicer.exe --python-code "doSomething; doSomethingElse; etc." --testing --no-splash --no-main-window

DICOM

  • How to access tags of DICOM images imported into Slicer? For example, to print the first patient's first study's first series' "0020,0032" field:
 db=slicer.dicomDatabase
 patientList=db.patients()
 studyList=db.studiesForPatient(patientList[0])
 seriesList=db.seriesForStudy(studyList[0])
 fileList=db.filesForSeries(seriesList[0])
 print db.fileValue(fileList[0],'0020,0032')
  • How to access tag of a volume loaded from DICOM? For example, get the patient position stored in a volume:
 volumeName='2: ENT IMRT'
 n=slicer.util.getNode(volumeName)
 instUids=n.GetAttribute('DICOM.instanceUIDs').split()
 filename=slicer.dicomDatabase.fileForInstance(instUids[0])
 print slicer.dicomDatabase.fileValue(filename,'0018,5100')

Toolbar functions

  • How to turn on slice intersections in the crosshair menu on the toolbar:
 viewNodes = slicer.mrmlScene.GetNodesByClass('vtkMRMLSliceCompositeNode')
 viewNodes.UnRegister(slicer.mrmlScene)
 viewNodes.InitTraversal()
 viewNode = viewNodes.GetNextItemAsObject()
 while viewNode:
   viewNode.SetSliceIntersectionVisibility(1)
   viewNode = viewNodes.GetNextItemAsObject()

How to find similar functions? For this one I searched for "slice intersections" text in the whole slicer source code, found that the function is implemented in Base\QTGUI\qSlicerViewersToolBar.cxx, then translated the qSlicerViewersToolBarPrivate::setSliceIntersectionVisible(bool visible) method to Python.

Manipulating objects in the slice viewer

  • How to define/edit a circular region of interest in a slice viewer?

Drop two markup points on a slice view and copy-paste the code below into the Python console. After this, as you move the markups you’ll see a circle following the markups.

 # Update the sphere from the fiducial points
 def UpdateSphere(param1, param2):  
   centerPointCoord = [0.0, 0.0, 0.0]
   markups.GetNthFiducialPosition(0,centerPointCoord)
   circumferencePointCoord = [0.0, 0.0, 0.0]
   markups.GetNthFiducialPosition(1,circumferencePointCoord)
   sphere.SetCenter(centerPointCoord)
   radius=math.sqrt((centerPointCoord[0]-circumferencePointCoord[0])**2+(centerPointCoord[1]-circumferencePointCoord[1])**2+(centerPointCoord[2]-circumferencePointCoord[2])**2)
   sphere.SetRadius(radius)
   sphere.SetPhiResolution(30)
   sphere.SetThetaResolution(30)
   sphere.Update()
 
 # Get a reference to the markup
 markups=slicer.util.getNode('F')
 # Create the sphere that will intersect the slice viewer
 sphere = vtk.vtkSphereSource()
 # Initial positioning of the sphere
 UpdateSphere(0,0)
 # Create model node and add to scene
 model = slicer.vtkMRMLModelNode()
 model.SetAndObservePolyData(sphere.GetOutput())
 modelDisplay = slicer.vtkMRMLModelDisplayNode()
 modelDisplay.SetSliceIntersectionVisibility(True) # Show in slice view
 modelDisplay.SetVisibility(False) # Hide in 3D view
 slicer.mrmlScene.AddNode(modelDisplay)
 model.SetAndObserveDisplayNodeID(modelDisplay.GetID())
 modelDisplay.SetInputPolyData(model.GetPolyData())
 slicer.mrmlScene.AddNode(model) 
 # Call UpdateSphere whenever the fiducials are changed
 markups.AddObserver("ModifiedEvent", UpdateSphere, 2)

Add a texture mapped plane to the scene as a model

Note that model textures are not exposed in the GUI and are not saved in the scene

# use dummy image data here
e = vtk.vtkImageEllipsoidSource()

scene = slicer.mrmlScene

# Create model node
model = slicer.vtkMRMLModelNode()
model.SetScene(scene)
model.SetName(scene.GenerateUniqueName("2DImageModel"))

planeSource = vtk.vtkPlaneSource()
model.SetAndObservePolyData(planeSource.GetOutput())

# Create display node
modelDisplay = slicer.vtkMRMLModelDisplayNode()
modelDisplay.SetColor(1,1,0) # yellow
modelDisplay.SetBackfaceCulling(0)
modelDisplay.SetScene(scene)
scene.AddNode(modelDisplay)
model.SetAndObserveDisplayNodeID(modelDisplay.GetID())

# Add to scene
modelDisplay.SetAndObserveTextureImageData(e.GetOutput())
scene.AddNode(model) 


transform = slicer.vtkMRMLLinearTransformNode()
scene.AddNode(transform) 
model.SetAndObserveTransformNodeID(transform.GetID())

vTransform = vtk.vtkTransform()
vTransform.Scale(50,50,50)
vTransform.RotateX(30)
transform.SetAndObserveMatrixTransformToParent(vTransform.GetMatrix())


Export a model to Blender, including color

plyFilePath = "/tmp/fibers.ply"

lineDisplayNode = getNode("*LineDisplay*")

tuber = vtk.vtkTubeFilter()
tuber.SetInput(lineDisplayNode.GetOutputPolyData())

tubes = tuber.GetOutput()
tubes.Update()
scalars = tubes.GetPointData().GetArray(0)
scalars.SetName("scalars")

triangles = vtk.vtkTriangleFilter()
triangles.SetInput(tubes)

colorNode = lineDisplayNode.GetColorNode()
lookupTable = vtk.vtkLookupTable()
lookupTable.DeepCopy(colorNode.GetLookupTable())
lookupTable.SetTableRange(0,1)

plyWriter = vtk.vtkPLYWriter()
plyWriter.SetInput(triangles.GetOutput())
plyWriter.SetLookupTable(lookupTable)
plyWriter.SetArrayName("scalars")

plyWriter.SetFileName(plyFilePath)
plyWriter.Write()

Clone a volume

This example shows how to clone the MRHead sample volume, including its pixel data and display settings.

sourceVolumeNode = slicer.util.getNode('MRHead')
volumesLogic = slicer.modules.volumes.logic()
clonedVolumeNode = volumesLogic.CloneVolume(slicer.mrmlScene, sourceVolumeNode, 'Cloned volume')

Create a new volume

This example shows how to create a new empty volume.

imageSize=[512, 512, 512]
imageSpacing=[1.0, 1.0, 1.0]
voxelType=vtk.VTK_UNSIGNED_CHAR
# Create an empty image volume
imageData=vtk.vtkImageData()
imageData.SetDimensions(imageSize)
imageData.AllocateScalars(voxelType, 1)
thresholder=vtk.vtkImageThreshold()
thresholder.SetInputData(imageData)
thresholder.SetInValue(0)
thresholder.SetOutValue(0)
# Create volume node
volumeNode=slicer.vtkMRMLScalarVolumeNode()
volumeNode.SetSpacing(imageSpacing)
volumeNode.SetImageDataConnection(thresholder.GetOutputPort())
# Add volume to scene
slicer.mrmlScene.AddNode(volumeNode)
displayNode=slicer.vtkMRMLScalarVolumeDisplayNode()
slicer.mrmlScene.AddNode(displayNode)
colorNode = slicer.util.getNode('Grey')
displayNode.SetAndObserveColorNodeID(colorNode.GetID())
volumeNode.SetAndObserveDisplayNodeID(displayNode.GetID())
volumeNode.CreateDefaultStorageNode()

Modify voxels in a volume

This example shows how to change voxels values of the MRHead sample volume. The values will be computed by function f(r,a,s,) = (r-10)*(r-10)+(a+15)*(a+15)+s*s.

volumeNode=slicer.util.getNode('MRHead')
ijkToRas = vtk.vtkMatrix4x4()
volumeNode.GetIJKToRASMatrix(ijkToRas)
imageData=volumeNode.GetImageData()
extent = imageData.GetExtent()
for k in xrange(extent[4], extent[5]+1):
  for j in xrange(extent[2], extent[3]+1):
    for i in xrange(extent[0], extent[1]+1):
      position_Ijk=[i, j, k, 1]
      position_Ras=ijkToRas.MultiplyPoint(position_Ijk)
      r=position_Ras[0]
      a=position_Ras[1]
      s=position_Ras[2]      
      functionValue=(r-10)*(r-10)+(a+15)*(a+15)+s*s
      imageData.SetScalarComponentFromDouble(i,j,k,0,functionValue)
imageData.SetScalarComponentFromFloat(distortionVectorPosition_Ijk[0], distortionVectorPosition_Ijk[1], distortionVectorPosition_Ijk[2], 0, fillValue)
imageData.Modified()

Manipulate a Slice View

>>> lm = slicer.app.layoutManager()
>>> red = lm.sliceWidget('Red')
>>> redLogic = red.sliceLogic()
>>> redLogic.GetSliceOffset()
-10.214302062988281
>>> redLogic.SetSliceOffset(20)

Customize viewer layout

Show a custom layout of a 3D view on top of the red slice view:

customLayout = ("<layout type=\"vertical\" split=\"true\" >"
  " <item>"
  "  <view class=\"vtkMRMLViewNode\" singletontag=\"1\">"
  "    <property name=\"viewlabel\" action=\"default\">1</property>"
  "  </view>"
  " </item>"
  " <item>"
  "  <view class=\"vtkMRMLSliceNode\" singletontag=\"Red\">"
  "   <property name=\"orientation\" action=\"default\">Axial</property>"
  "   <property name=\"viewlabel\" action=\"default\">R</property>"
  "   <property name=\"viewcolor\" action=\"default\">#F34A33</property>"
  "  </view>"
  " </item>"
  "</layout>")
  
customLayoutId=501

layoutManager = slicer.app.layoutManager()
layoutManager.layoutLogic().GetLayoutNode().AddLayoutDescription(customLayoutId, customLayout)                                         
layoutManager.setLayout(customLayoutId)

See description of standard layouts (that can be used as examples) here: https://github.com/Slicer/Slicer/blob/master/Libs/MRML/Logic/vtkMRMLLayoutLogic.cxx

Running an ITK filter in Python using SimpleITK

Open the "Sample Data" module and download "MR Head", then paste the following snippet in Python interactor:

inputImage = sitkUtils.PullFromSlicer('MRHead')
filter = sitk.SignedMaurerDistanceMapImageFilter()
outputImage = filter.Execute(inputImage)
sitkUtils.PushToSlicer(outputImage,'outputImage')

More information: