Difference between revisions of "Slicer3:Execution Model"

From NAMIC Wiki
Jump to: navigation, search
m (Update from Wiki)
 
m (Text replacement - "http://www.slicer.org/slicerWiki/index.php/" to "https://www.slicer.org/wiki/")
 
(7 intermediate revisions by 3 users not shown)
Line 1: Line 1:
=== Abstract ===
+
<big>'''Note:''' We are migrating this content to the slicer.org domain - <font color="orange">The newer page is [https://www.slicer.org/wiki/Slicer3:Execution_Model  here]</font></big>a
 
 
The purpose of this proposal is to facilitate a "run-everywhere" philosophy for algorithm writers. If NAMIC adopts a standard for algorithm "self-description" that is followed when command line executables are written, Slicer, the grid, clusters, etc... should be able to use the executables directly in their environment.
 
 
 
=== Execution model for stand-alone executables ===
 
 
 
For Slicer3 to interact with stand-alone executables, a communications protocol must be created and implemented on both sides. This implies that the executable must be able to describe itself in sufficient detail for Slicer3 to run it and retrieve the results of the algorithm.
 
 
 
=== Initial Standard ===
 
 
 
This sample describes the initial standard. The current best implementation is to write your XML algorithm description by hand, then have your executable respond to the --xml flag by producing the XML description to standard output.
 
 
 
Some notes about the sample below.
 
 
 
# The <category> tag corresponds to where the executable should show up in a menu on the calling Application
 
# <parameters> tags are grouped together by name in the GUI, in the example "Registration Parameters" and "IO"
 
# The currently described parameters are
 
## <integer> for simple integers
 
## <double> for floating point numbers
 
## <string> for string arguments
 
## <boolean> for boolean switches
 
## <image> for images. The current standard is 3d images, but may be agumented in the future
 
## <file> for files.
 
## <integer-vector> for a comma separated list of integers
 
## <float-vector> for a comma separated list of floats
 
## <double-vector> for a comma separated list of doubles
 
# Most parameters share some common attributes
 
## <flag> the short flag for this parameter, ''i.e.'' <flag>f</flag>
 
## <longflag> the long flag for this parameter, ''i.e.'' <longflag>foo</longflag>
 
## <label> the text to display next to the parameter
 
## <default> default value
 
## <description> a useful description of the parameter, suitable for tool tips, ''etc...''
 
## <constraints> currently <minimum>, <maximum>, and <step> for <integer> and <double>
 
# For positional arguments, an index is required, in this case Fixed and Moving images are indices 0 and 1
 
# For images, there is a <channel> tag. <channel>input</channel> indicates that this file is read by the executable, <channel>output</channel> indicates the executale writes the image
 
 
 
==== To Do ====
 
 
 
* Add radiobutton like choices
 
* Add image format discription, ''i.e.'' does this algorithm handle 2D images, need DICOM files, ''etc...''
 
* Establish convention for progress indications
 
* XSD
 
 
 
<br />
 
 
 
==== This is the example from the NAMIC Sandbox. ====
 
 
 
 
{practical:CommandLineAPI-Linux}1356:./CLRegistration --xml
 
<?xml version="1.0" encoding="utf-8"?>
 
<executable>
 
  <category>registration</category>
 
  <title>NAMIC sample registration</title>
 
  <description>Registers two images together using a rigid transform and MI</description>
 
  <version>1.0</version>
 
  <documentationurl></documentationurl>
 
  <license></license>
 
  <contributor>Daniel Blezek</contributor>
 
 
  <parameters>
 
    <label>Registration Parameters</label>
 
    <description>Parameters used for registration</description>
 
    <integer>
 
      <flag>b</flag>
 
      <longflag>histogrambins</longflag>
 
      <description>Number of histogram bins to use for Mattes Mutual Information</description>
 
      <label>Histogram Bins</label>
 
      <default>30</default>
 
      <constraints>
 
        <minimum>1</minimum>
 
        <maximum>500</maximum>
 
        <step>5</step>
 
      </constraints>
 
    </integer>
 
 
    <integer>
 
      <flag>s</flag>
 
      <longflag>spatialsamples</longflag>
 
      <description>Number of spatial samples to use in estimating Mattes Mutual Information</description>
 
      <label>Spatial Samples</label>
 
      <default>10000</default>
 
      <constraints>
 
        <minimum>1000</minimum>
 
        <maximum>50000</maximum>
 
        <step>1000</step>
 
      </constraints>
 
    </integer>
 
 
    <string>
 
      <flag>i</flag>
 
      <longflag>iterations</longflag>
 
      <description>Comma separated list of iterations must have the same number of elements as learning rate</description>
 
      <label>Iterations</label>
 
      <default>200,100</default>
 
    </string>
 
 
    <string>
 
      <flag>l</flag>
 
      <longflag>learningrate</longflag>
 
      <description>Comma separated list of learning rates must have the same number of elements as iterations</description>
 
      <label>Learning Rates</label>
 
      <default>0.05,0.005</default>
 
    </string>
 
 
    <double>
 
      <longflag>translationscale</longflag>
 
      <flag>t</flag>
 
      <description>Relative scale of translations to rotations, i.e. a value of 100 means 10mm = 1 degree</description>
 
      <label>Translation scaling</label>
 
      <default>100.0</default>
 
      <constraints>
 
        <minimum>10.0</minimum>
 
        <maximum>500.0</maximum>
 
        <step>50.0</step>
 
      </constraints>
 
    </double>
 
  </parameters>
 
 
  <parameters>
 
    <label>IO</label>
 
    <description>Input/output parameters</description>
 
    <image>
 
      <name>Fixed</name>
 
      <label>Fixed Image</label>
 
      <channel>input</channel>
 
      <index>0</index>
 
      <description>Fixed image to register to</description>
 
    </image>
 
    <image>
 
      <name>Moving</name>
 
      <label>Moving Image</label>
 
      <channel>input</channel>
 
      <index>1</index>
 
      <description>Moving image</description>
 
    </image>
 
    <image>
 
      <name>Output</name>
 
      <label>Output Volume</label>
 
      <channel>output</channel>
 
      <index>2</index>
 
      <description>Resampled Moving Image</description>
 
    </image>
 
  </parameters>
 
 
</executable>
 
 
 
 
 
==== Sample screenshots ====
 
 
 
{|
 
|- valign="top"
 
!
 
<div class="thumb tright"><div style="width: 182px">[[Image:NAMICSampleRegistrationMenu.png|[[Image:180px-NAMICSampleRegistrationMenu.png|Sample GUI generated from XML above ]]]]<div class="thumbcaption"><div class="magnify" style="float: right">[[Image:NAMICSampleRegistrationMenu.png|[[Image:magnify-clip.png|Enlarge]]]]</div>Sample GUI generated from XML above </div></div></div>
 
|}
 
 
 
==== Open questions ====
 
 
 
# What classes of algorithms should Slicer3 be aware of?
 
## Registration, classification, segmentation, filtering?
 
# How should Slicer3 communicate with the executables?
 
## Special FileIO objects (for ITK) has been suggested.
 
## MMapped files for efficient IO.
 
## Shared memory.
 
## Standard files.
 
# Does Slicer3 need to communicate with the executing process?
 
## For status, "Cancel" operations, ''etc''...
 
 
 
=== Proposal ===
 
 
 
If we adopt a standard XML description of the parameters to the algorithm, any application should be able to parse the XML and construct a GUI suitable for interaction with the software.
 
 
 
Below are potential ideas for an XML file format:
 
 
 
==== Initial JSON output from sample registration package ====
 
 
 
 
/* JSON version 1.0 */
 
{
 
        "class" : "registration",
 
        "name" : "CLRegistration",
 
        "info" : "Register two volumes",
 
        "executable" : "CLRegistration",
 
        "requiredparameters": {
 
                "fixed" : {
 
                      "type" : "file",
 
                      "index" : "0",
 
                      "channel" : "input",
 
                      /* what about image dimension: 2, 3, ... */
 
                      },
 
                "moving" : {
 
                      },
 
                "output" : {
 
                      }
 
        "parameters" : {
 
                "histogrambins" : {
 
                        "flag" : "b",
 
                        "name" : "histogrambins",
 
                        "displayname" : "Number of histogram bins",
 
                        "description" : "Number of histogram bins",
 
                        "type" : "integer",
 
                        "guihints" : "slider",
 
                        "range" : "[5-200]",
 
                        "default" : "100"
 
                        },
 
                "randomseed" : {
 
                        "flag" : "d",
 
                        "name" : "randomseed",
 
                        },
 
                "gradtolerance" : {
 
                        "flag" : "g",
 
                        "name" : "gradtolerance",
 
                        },
 
                "iterations" : {
 
                        "flag" : "i",
 
                        "name" : "iterations",
 
                        },
 
                "learningrate" : {
 
                        "flag" : "l",
 
                        "name" : "learningrate",
 
                        },
 
                "spatialsamples" : {
 
                        "flag" : "s",
 
                        "name" : "spatialsamples",
 
                        },
 
                "translationscale" : {
 
                        "flag" : "t",
 
                        "name" : "translationscale",
 
                        },
 
                "noinitializetransform" : {
 
                        "flag" : "u",
 
                        "name" : "noinitializetransform",
 
                        },
 
                "help" : {
 
                        "flag" : "h",
 
                        "name" : "help",
 
                        },
 
                "json" : {
 
                        "flag" : "j",
 
                        "name" : "json",
 
                        },
 
                }
 
}
 
 
 
XML Version of the same description
 
 
 
<sl
 
        class = "registration"
 
        name = "CLRegistration"
 
        info = "Register two volumes"
 
        executable = "CLRegistration">
 
        <requiredparameters>
 
                <requirement name="fixed">
 
                      type = "file"
 
                      index = "0"
 
                      channel = "input"
 
                      <!-- what about image dimension: 2 3 ... -->
 
                </requirement>
 
                <requirement name="moving" />
 
                <requirement name="output" />
 
        </requiredparameters>
 
        <parameters>
 
                <parameter name="histogrambins"
 
                        flag = "b"
 
                        name = "histogrambins"
 
                        displayname = "Number of histogram bins"
 
                        description = "Number of histogram bins"
 
                        type = "integer"
 
                        guihints = "slider"
 
                        range = "[5-200]"
 
                        default = "100"
 
                        />
 
                <parameter name="randomseed"
 
                        flag = "d"
 
                        name = "randomseed"
 
                        />
 
                <parameter name="gradtolerance"
 
                        flag = "g"
 
                        name = "gradtolerance"
 
                        />
 
                <parameter name="iterations"
 
                        flag = "i"
 
                        name = "iterations"
 
                        />
 
                <parameter name="learningrate"
 
                        flag = "l"
 
                        name = "learningrate"
 
                        />
 
                <parameter name="spatialsamples"
 
                        flag = "s"
 
                        name = "spatialsamples"
 
                        />
 
                <parameter name="translationscale"
 
                        flag = "t"
 
                        name = "translationscale"
 
                        />
 
                <parameter name="noinitializetransform"
 
                        flag = "u"
 
                        name = "noinitializetransform"
 
                        />
 
                <parameter name="help"
 
                        flag = "h"
 
                        name = "help"
 
                        />
 
                <parameter name="json"
 
                        flag = "j"
 
                        name = "json"
 
                        />
 
        </parameters>
 
</sl>
 
 
 
==== Data-centric proposal ====
 
 
 
 
<?xml version="1.0" encoding="utf-8"?>
 
<executable class="registration">
 
  <Name>CLRegistration</name>
 
  <Description>Registers two images, writes the resampled moving image</description>
 
  <Parameters>
 
    <Parameter required="false" flag="t" name="threshold">
 
      <Description>Threshold</Description>
 
      <Type>integer</Type>
 
      <Constraints>
 
        <Range minimum="0" maximum="100"/>
 
      </Constraints>
 
    </Parameter>
 
    <Parameter required="true">
 
    </Parameter>
 
  </Parameters>
 
</executable>
 
 
 
 
==== GUI-centric proposal ====
 
 
 
 
<?xml version="1.0" encoding="utf-8"?>
 
<executable class="register">
 
  <name>Register3d</name>
 
  <version>1.0</version>
 
  <description>This registers and resamples two images</description>
 
 
  <parameters>
 
    <!-- a switch is a boolean flag, likely a checkbox.
 
          on the command line, name is the long version, flag is the
 
          one character version of the argument
 
          -->
 
    <switch name="interpolate" flag="i" default="true" required="false">
 
      <description></description>
 
    </switch>
 
 
    <!-- a value takes a single argument, may be required to be present
 
          and has a type.  In this case, the "metric" value is constrained to be
 
          one of the listed options below. This should be represented by a
 
          group of radio buttons or drop down menu.
 
          -->
 
    <value name="metric" flag="m" default="mattes" required="false" type="string">
 
      <description></description>
 
      <constraints>
 
        <list>
 
          <constraint>mattes</constraint>
 
          <constraint>mi</constraint>
 
          <constraint>normalizedcorrelation</constraint>
 
        </list>
 
      </constraints>
 
    </value>
 
 
    <!-- an integer value with a range -->
 
    <value name="threshold" flag="t" type="integer">
 
      <constraints>
 
        <range minimum="0" maximum="100"/>
 
        <increment>.1</increment>
 
      </constraints>
 
    </value>
 
 
    <!-- a value argument that allow several instances of the argument to be specified.
 
          The values are appended to each other and returned in a vector.
 
          In the GUI, this could be a list of numbers in a string, or a
 
          dynamic list constructed by the user.
 
          -->
 
    <value name="iterations" flag="e" type="iteration" allowrepeats="true">
 
      <constraints>
 
        <range minimum="1"/>
 
      </constraints>
 
    </value>
 
 
    <!-- xor specifies that only one of it's contained parameters
 
          be specified.  In this case, we want a file or url, but not
 
          both -->
 
    <xor>
 
      <value name="file" flag="f" type="filename"/>
 
      <value name="url" flag="u"/>
 
    </xor>
 
 
    <!-- unlabeledvalue do not have a flag associated with them, and are positional.
 
          In this case, we are looking for 3 filenames.
 
          -->
 
    <unlabeledvalue name="fixedimage" position="0" type="filename"/>
 
    <unlabeledvalue name="movingimage" position="1" type="filename"/>
 
    <unlabeledvalue name="outputimage" position="2" type="filename"/>
 
  </parameters>
 
</executable>
 
 
 
==== JSON description ====
 
 
 
 
/* JSON version 1.0
 
    January 11, 2005 */
 
{
 
  "class" : "registration",
 
  "name" : "CLRegistration",
 
  "info" : "Registers two images, writes the resampled moving image",
 
  "executable" : "CLRegistration",
 
  "parameters" :
 
"threshold" : {
 
"info" : "threshold"
 
"flag" : "t",
 
"required" : "true",
 
"type" : "integer",
 
"default" : "50",
 
"contraints" : {
 
"range" : {
 
"minimum" : "0",
 
"maximum" : "100" } },
 
"guihints" : {
 
"control" : "slider",
 
"group" : "preprocessing" } },
 
"xsigma" : {
 
"info" : "X Direction in sigma",
 
"flag" : "x",
 
"required" : "false",
 
"type" : "float",
 
"default" : "1.0",
 
"contraints" : {
 
"range" : {
 
"minimum" : "0",
 
"maximum" : "5.0" } },
 
"guihints" : {
 
"control" : "slider",
 
"group" : "preprocessing" } },
 
"fixedfile" : {
 
"info" : "Fixed Image",
 
"order" : "0",
 
"required" : "true",
 
"type" : "file",
 
"contraints" : {
 
"filetypes" : [
 
"ITK",
 
"Slicerd",
 
"MRML" ] },
 
"guihints" : {
 
"control" : "fileselection",
 
"group" : "io" } },
 
 
}
 
 
 
=== Related Work ===
 
 
 
==== MetaCommand ====
 
 
 
Julien Jomier and Stephen Aylward have added support for command line parsing to itk with the MetaCommand class (Utilities/MetaIO/metaCommand.{h,cxx}). It supports a -xml flag to output args in an xml syntax.
 
 
 
==== Qt Designer XML Format ====
 
 
 
Qt has an xml syntax for representing their GUI layouts. It's unclear if this tool could be used to design layouts used by other GUI packages.
 
 
 
==== ParaView Server ====
 
 
 
ParaView has a syntax to extend the GUI described [http://www.paraview.org/Wiki/ParaView:Extend on their wiki here].
 
 
 
==== LONI Pipeline ====
 
 
 
Parameters to executables are described in an XML file as part of the process of wrapping them for the pipeline. These XML descriptions are quite similar to the example given above. Some example pipelines are available at the [http://www.loni.ucla.edu/twiki/bin/view/Pipeline/PipelineModules Pipeline Wiki]. A working draft of the language description is found also on the [http://www.loni.ucla.edu/twiki/bin/view/Pipeline/DeveloperDocumentation Wiki].
 
 
 
==== JSON ====
 
 
 
Mike Halle suggested looking a JSON to describe the command line arguments to the parser, then to fill in the values from the command line. With this description, a GUI could build an interface for your code and/or communicate with your executable using JSON. Requires a standard set of elements.
 
 
 
[http://www.json.org/ JSON (JavaScript Object Notation)] is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.</pre>
 
 
 
==== DICOM Working Group 23 ====
 
 
 
Dave Channin suggests this group be aware of the efforts of [http://medical.nema.org/DICOM/minutes/WG-23/ DICOM Working Group 23] along these lines. Although termed ''application hosting'' the work group is defining a DICOM standard mechanism by which a workstation can ''invoke'' an algorithm, send it (DICOM) data and receive from it (DICOM) results (as well as statuses, etc.) Although still in draft form they are thinking about using web services and in particular, [http://www.globus.org/ogsa/ OGSA (Open Grid Services Architecture)]. This has the interesting repercussion of allowing invoked algorihtms to be run locally or over the grid. This effort may be of interest to this group along two lines: 1) IMNSHO, Slicer should support the DICOM WG23 plug so as to be able to invoke compliant algorithms, and 2) Algorithm developers need to decide whether to add their specific functionality to ''base Slicer'' or as a DICOM WG23. In th elatter case it would then be possible to run these (presumably VTK and iTK based) algorithms not only on Slicer but on other (potentially commercial workstations) that support DICOM WG23. (I hope this is the right group to consider this).
 

Latest revision as of 17:48, 10 July 2017

Home < Slicer3:Execution Model

Note: We are migrating this content to the slicer.org domain - The newer page is herea