Difference between revisions of "Slicer3:Execution Model Documentation:Python"

From NAMIC Wiki
Jump to: navigation, search
Line 34: Line 34:
 
* Progress functionality
 
* Progress functionality
 
* Casting image arguments to proper MRML volume objects before calling '''Execute'''
 
* Casting image arguments to proper MRML volume objects before calling '''Execute'''
 +
 +
==Python Module collection==
 +
 +
===PythonScript.py===
 +
 +
This module allows to run external Python code saved in a .py file on an image or surface (or both), and have the results loaded back in Slicer. It doesn't really do anything itself, but it's handy for:
 +
* writing Python modules, since one can store the actual module code in a file without having to copy it to Slicer3-build/lib/Slicer3/Plugins
 +
* writing quick one-shot filtering operations that are not elegible to become full-fledged modules
 +
* experimenting with Python in Slicer.
 +
 +
XML = """<?xml version="1.0" encoding="utf-8"?>
 +
<executable>
 +
 +
  <category>Python Modules</category>
 +
  <title>Python Script</title>
 +
  <description>Run external Python code on a surface or image.</description>
 +
  <version>1.0</version>
 +
  <documentation-url></documentation-url>
 +
  <license></license>
 +
  <contributor>Luca Antiga and Daniel Blezek</contributor>
 +
 +
  <parameters>
 +
    <label>Python Script Parameters</label>
 +
    <description>Parameters for Python script</description>
 +
    <file>
 +
      <name>scriptFileName</name>
 +
      <longflag>scriptFileName</longflag>
 +
      <description>File containing Python code to run</description>
 +
      <label>Script file</label>
 +
    </file>
 +
  </parameters>
 +
 +
  <parameters>
 +
    <label>IO</label>
 +
    <description>Input/output parameters</description>
 +
 +
    <geometry>
 +
      <name>inputSurface</name>
 +
      <longflag>inputSurface</longflag>
 +
      <label>Input Surface</label>
 +
      <channel>input</channel>
 +
      <description>Input surface to be filtered</description>
 +
    </geometry>
 +
 +
    <image>
 +
      <name>inputVolume</name>
 +
      <longflag>inputVolume</longflag>
 +
      <label>Input Volume</label>
 +
      <channel>input</channel>
 +
      <description>Input image to be filtered</description>
 +
    </image>
 +
 +
    <geometry>
 +
      <name>outputSurface</name>
 +
      <longflag>outputSurface</longflag>
 +
      <label>Output Surface</label>
 +
      <channel>output</channel>
 +
      <description>Output filtered surface</description>
 +
    </geometry>
 +
 +
    <image>
 +
      <name>outputVolume</name>
 +
      <longflag>outputVolume</longflag>
 +
      <label>Output Volume</label>
 +
      <channel>output</channel>
 +
      <description>Output filtered volume</description>
 +
    </image>
 +
 +
 +
  </parameters>
 +
 +
</executable>
 +
"""
 +
 +
 +
def Execute (scriptFileName="", inputSurface="", inputVolume="", outputSurface="", outputVolume=""):
 +
 +
    Slicer = __import__("Slicer")
 +
    slicer = Slicer.Slicer()
 +
    scene = slicer.MRMLScene
 +
 +
    if inputSurface:
 +
        inputSurface = scene.GetNodeByID(inputSurface)
 +
 +
    if inputVolume:
 +
        inputVolume = scene.GetNodeByID(inputVolume)
 +
 +
    if outputSurface:
 +
        outputSurface = scene.GetNodeByID(outputSurface)
 +
 +
    if outputVolume:
 +
        outputVolume = scene.GetNodeByID(outputVolume)
 +
 +
    try:
 +
        execfile(scriptFileName)
 +
    except Exception, error:
 +
        slicer.Application.ErrorMessage("Python script error: %s" % error)
 +
 +
    return
 +
 +
Of note in the code, the try...except block intercepts Python exceptions and prints them out in Slicer's message console.

Revision as of 12:20, 7 November 2007

Home < Slicer3:Execution Model Documentation:Python

A Python interpreter has been integrated into Slicer3. More details of the Python language can be found at Python.org. This interpreter may be used to execute Python script plugins. The modules have a few specific requirements to be correctly found and used as plugins. Like the standard executable and shared library plugins, Python plugins need to be self describing. To do this, the script must have a top level variable called XML or provide a toXML procedure. For example:

XML = """<?xml version="1.0" encoding="utf-8"?>
<executable>
  <category>Filtering.Denoising</category>
  ...

def toXML():
  return XML;


Details of the XML format are found in the main Execution Model documentation. Rather than construct a command line to pass into Python, Slicer3 directly calls an Execute procedure. It is assumed that the Execute function expects positional arguments first, and any optional arguments are passed in as keyword arguments. For instance, the GradientAnisotropicDiffusion.py module provides an Execute:

def Execute ( inputVolume, outputVolume, conductance=1.0, timeStep=0.0625, iterations=1 ):
    print "Executing Python Demo Application!"
    Slicer = __import__ ( "Slicer" );
    slicer = Slicer.Slicer()
    in = slicer.MRMLScene.GetNodeByID ( inputVolume );
    out = slicer.MRMLScene.GetNodeByID ( outputVolume );

    filter = slicer.vtkITKGradientAnisotropicDiffusionImageFilter.New()
    filter.SetConductanceParameter ( conductance )
    filter.SetTimeStep ( timeStep )
    filter.SetNumberOfIterations ( iterations )
    filter.SetInput ( in.GetImageData() )
    filter.Update()
    out.SetAndObserveImageData(filter.GetOutput())
    return


The function first constructs a Slicer object by importing the Slicer module. The Slicer object is the main interface into Slicer3 as a whole. The first two arguments, inputVolume and outputVolume are not proper MRMLVolumes, and must be looked up using the Slicer object. The filter is constructed through the Slicer object, and the parameters are set. After the filter is updated, the output image is put using the SetAndObserveImageData method on the output volume.

ToDo
  • Progress functionality
  • Casting image arguments to proper MRML volume objects before calling Execute

Python Module collection

PythonScript.py

This module allows to run external Python code saved in a .py file on an image or surface (or both), and have the results loaded back in Slicer. It doesn't really do anything itself, but it's handy for:

  • writing Python modules, since one can store the actual module code in a file without having to copy it to Slicer3-build/lib/Slicer3/Plugins
  • writing quick one-shot filtering operations that are not elegible to become full-fledged modules
  • experimenting with Python in Slicer.
XML = """<?xml version="1.0" encoding="utf-8"?>
<executable>

  <category>Python Modules</category>
  <title>Python Script</title>
  <description>Run external Python code on a surface or image.</description>
  <version>1.0</version>
  <documentation-url></documentation-url>
  <license></license>
  <contributor>Luca Antiga and Daniel Blezek</contributor>

  <parameters>
    <label>Python Script Parameters</label>
    <description>Parameters for Python script</description>
    <file>
      <name>scriptFileName</name>
      <longflag>scriptFileName</longflag>
      <description>File containing Python code to run</description>
      <label>Script file</label>
    </file>
  </parameters>

  <parameters>
    <label>IO</label>
    <description>Input/output parameters</description>

    <geometry>
      <name>inputSurface</name>
      <longflag>inputSurface</longflag>
      <label>Input Surface</label>
      <channel>input</channel>
      <description>Input surface to be filtered</description>
    </geometry>

    <image>
      <name>inputVolume</name>
      <longflag>inputVolume</longflag>
      <label>Input Volume</label>
      <channel>input</channel>
      <description>Input image to be filtered</description>
    </image>

    <geometry>
      <name>outputSurface</name>
      <longflag>outputSurface</longflag>
      <label>Output Surface</label>
      <channel>output</channel>
      <description>Output filtered surface</description>
    </geometry>

    <image>
     <name>outputVolume</name>
     <longflag>outputVolume</longflag>
     <label>Output Volume</label>
     <channel>output</channel>
     <description>Output filtered volume</description>
   </image>


  </parameters>

</executable>
"""


def Execute (scriptFileName="", inputSurface="", inputVolume="", outputSurface="", outputVolume=""):

    Slicer = __import__("Slicer")
    slicer = Slicer.Slicer()
    scene = slicer.MRMLScene

    if inputSurface:
        inputSurface = scene.GetNodeByID(inputSurface)

    if inputVolume:
        inputVolume = scene.GetNodeByID(inputVolume)

    if outputSurface:
        outputSurface = scene.GetNodeByID(outputSurface)

   if outputVolume:
       outputVolume = scene.GetNodeByID(outputVolume)

    try:
        execfile(scriptFileName)
    except Exception, error:
        slicer.Application.ErrorMessage("Python script error: %s" % error)

    return

Of note in the code, the try...except block intercepts Python exceptions and prints them out in Slicer's message console.