SimpleITK  1.2.4
Commands and Events for SimpleITK

SimpleITK has the ability to add commands or callbacks as observers of events that may occur during data processing. This feature can be used to add progress reporting to a console, to monitor the process of optimization, to abort a process, or to improve the integration of SimpleITK into Graphical User Interface event queues.

Events

Events are a simple enumerated type in SimpleITK, represented by the EventEnum type. More information about each event type can be found in the documentation for the enum. All SimpleITK filters, including the reading and writing ones, are derived from the ProcessObject class which has support for events. SimpleITK utilizes the native ITK event system but has simpler events and methods to add an observer or commands. The goal is to provide a simpler interface more suitable for scripting languages.

Commands

The command design pattern is used to allow user code to be executed when an event occurs. It is encapsulated in the Command class. The Command class provides a virtual Execute method to be overridden in derived classes. Additionally, SimpleITK provides internal reference tracking between the ProcessObject and the Command. This reference tracking allows an object to be created on the stack or dynamically allocated, without additional burden when the object

Command Directors for Wrapped Languages

SimpleITK uses SWIG's director feature to enable wrapped languages to derive classes from the Command class. Thus a user may override the Command class's Execute method for custom call-backs. The following languages support deriving classes from the Command class:

CommandPython

1 class MyCommand(sitk.Command):
2  def __init__(self, po):
3  # required
4  super(MyCommand,self).__init__()
5  self.processObject = po
6 
7  def Execute(self):
8  print("{0} Progress: {1:1.2f}".format(self.processObject.GetName(),self.processObject.GetProgress()))

CommandCSharp

class MyCommand : Command {
private ProcessObject m_ProcessObject;
public MyCommand(ProcessObject po){
m_ProcessObject = po;
}
public override void Execute() {
Console.WriteLine("{0} Progress: {1:0.00}", m_ProcessObject.GetName(), m_ProcessObject.GetProgress() );
}
}

CommandRuby

1 class MyCommand < Simpleitk::Command
2  def initialize(po)
3  # Explicit call to supoer class initlaizer is required to
4  # initialize the SWIG director class to enable overloaded methods
5  super()
6  @po = po
7  end
8 
9  # The Command method to be executed on the event from the filter.
10  def execute
11  puts "%s Progress: %0.2f" % [@po.get_name, @po.get_progress]
12  end
13 end

Command Functions and Lambdas for Wrapped Languages

Not all scripting languages are naturally object oriented, and it is often easier to simply define a callback inline with a lambda function. The following language supports inline function definitions for functions for the ProcessObject::AddCommand method:

CommandFunctionPython

1 gaussian.AddCommand(sitk.sitkStartEvent, lambda: print("StartEvent"))
2 gaussian.AddCommand(sitk.sitkEndEvent, lambda: print("EndEvent"))

CommandFunctionR

1 gaussian$AddCommand( 'sitkStartEvent', function(method) {cat("StartEvent\n")} )
2 gaussian$AddCommand( 'sitkEndEvent', function(method) {cat("EndEvent\n")} )