Slicer3:Chain CLMs
Contents
Chain CLMs
Goals
- Create an infrastructure for Slicer3 that allows the user to create custom CLMs capable of executing a subset of predefined CLMs in a predefined sequential order.
- These custom CLMs must be capable to apply a user-defined argument replacement policy, before invoking a CLM. In essence the values of predefined outputs of some aggregated CLMs will be passed as inputs to other predefined aggregated CLMs (with a higher sequential execution order).
Description
The following is a design of an infrastructure to provide basic CLM chaining capabilities in Slicer3.
Generic Chain CLM Application
- The generic chain CLM application is the engine of the infrastructure.
- This application takes all information regarding how to chain a list of CLM modules and carries on such tasks when required.
- Chaining a list of CLM modules is done by proxying to them in order to create an appropriate composite CLM descriptor and to execute the aggregated CLMs in the custom pre-configured way.
- A particular "Chain CLM" will be a script which internally:
- Invokes this generic application.
- Configures it with a specific fixed "Chain Descriptor".
- A particular "Chain CLM" script (X-ChainCLM.sh) will look like:
#!/bin/sh java -cp slicerCLMPs.jar ChainCLMApp X-Modules.xml
where "X-Modules.xml" is the "Chain Descriptor" that shall be used to determine how to sequentially execute and chain the results and arguments of an ordered list of CLMs.
Chain Descriptor
- This is an XML file which contains all the information necessary to deterministically proxy into CLMs and "chain them".
- It must conform to the following schema:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:clm="http://www.na-mic.org/clm" targetNamespace="http://www.na-mic.org/clm" elementFormDefault="qualified"> <xs:element name="modules"> <xs:complexType> <xs:sequence> <xs:element name="module" type="clm:module" minOccurs="2" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="module"> <xs:sequence> <xs:element name="argument" type="clm:argument" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> <xs:attribute name="id" type="xs:string"/> </xs:complexType> <xs:complexType name="argument"> <xs:attribute name="name" type="xs:string"/> <xs:attribute name="value-ref" type="xs:string"/> </xs:complexType> </xs:schema>
- "Chain Descriptor" example 1:
<?xml version="1.0" encoding="UTF-8"?> <modules xmlns="http://www.na-mic.org/clm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.na-mic.org/schemas/chainCLM.xsd"> <module id="Module1"/> <module id="Module2"> <argument name="param2A" value-ref="Module1.param1A" /> <argument name="param2B" value-ref="Module1.param1B" /> </module> <module id="Module3"> <argument name="param3C" value-ref="Module1.param1C" /> <argument name="param3D" value-ref="Module2.param2D" /> </module> </modules>
- "Chain Descriptor" example 2:
<?xml version="1.0" encoding="UTF-8"?> <modules xmlns="http://www.na-mic.org/clm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.na-mic.org/schemas/chainCLM.xsd"> <module id="RicianFilterDWI"/> <module id="TensorEstimatorDTI"> <argument name="inputDWI" value-ref="RicianFilterDWI.outputDWI" /> </module> <module id="DiffusionScalar"> <argument name="inputDTI" value-ref="TensorEstimatorDTI.outputDiffusionTensorDTI" /> </module> </modules>
Internal Functionality
- Configuring the generic "ChainCLMApp" application with a specific "Chain Descriptor" allows:
- The generation of the appropriate CLM descriptor by tweaking the CLM descriptors of its aggregated CLMs.
- The sequential invocation of the aggregated CLMs with a deterministic argument replacement policy (described by the "argument" elements of the "Chain Descriptor").
Jim's notes
Goals:
- Chaining should be simple. Ideally, the person making the chain would only have to indicate what modules to chain and how map the outputs of one module to the inputs of another.
- Chains should be runnable from within Slicer3 as any other command line module
- Chains should be runnable from the command line, and hence the grid
The chain description XML schema proposed above is a bit different than what I was expecting. I'm inferring that the chained module would have to know alot about Slicer3 and the modules it ships with.
My thoughts were that the XML of the chain would look very similar to the XML of an individual module. Almost as if you had concatenated them together with some clever namespace mechanisms and assignment of values. To create a chain, I was thinking of command like
$ chainXPP RicianFilterDWI TensorEstimatorDTI DiffusionScalar -o DWIChain
This would create an XML file DWIChain.xml
<?xml version="1.0" encoding="utf-8"?> <chain> <category>Filtering.DWI</category> <title>Diffusion Chain</title> <description>Diffusion imaging preprocessing chain composed of denoising, tensor estimation, and scalar descriptor estimation</description> <executable> <category>Filtering.DWI</category> <title>Rician LMMSE Image Filter</title> <description> Filters a set of diffusion weighted images in the mean squared error sense using a Rician noise model. The noise parameter is automatically estimated. </description> <version>0.0.1.$Revision: 1 $(alpha)</version> <documentation-url></documentation-url> <license></license> <contributor>Santiago Aja Fernandez and Marc Niethammer</contributor> <parameters> <label>DWI Noise Removal Parameters</label> <description>Parameters for Rician LMMSE image filter</description> <integer> <name>iIterations</name> <label>Number of iterations</label> <longflag>--iter</longflag> <description>Number of iterations for the noise removal filter.</description> <default>1</default> <constraints> <minimum>0</minimum> <maximum>25</maximum> <step>1</step> </constraints> </integer> <integer-vector> <name>iRadiusEstimation</name> <label>Estimation Radius</label> <longflag>--re</longflag> <description>Estimation radius.</description> <default>3,3,0</default> </integer-vector> <integer-vector> <name>iRadiusFiltering</name> <label>Filtering Radius</label> <longflag>--rf</longflag> <description>Filtering radius.</description> <default>3,3,0</default> </integer-vector> <integer> <name>iMinimumNumberOfUsedVoxelsF</name> <label>Minimum voxels # for filtering.</label> <longflag>--mnvf</longflag> <description>Minimum number of voxels in kernel used for filtering.</description> <default>1</default> </integer> <integer> <name>iMinimumNumberOfUsedVoxelsE</name> <label>Minimum voxels # for estimation.</label> <longflag>--mnve</longflag> <description>Minimum number of voxels in kernel used for estimation.</description> <default>1</default> </integer> <integer> <name>dMinSTD</name> <label>Minimum noise STD.</label> <longflag>--minnstd</longflag> <description>Minimum allowed noise standard deviation.</description> <default>0</default> </integer> <integer> <name>dMaxSTD</name> <label>Maximum noise STD.</label> <longflag>--maxnstd</longflag> <description>Maximum allowed noise standard deviation.</description> <default>10000</default> </integer> <double> <name>dResFact</name> <label>Histogram resolution factor.</label> <longflag>--hrf</longflag> <description>How many histogram bins per unit interval.</description> <default>2.0</default> </double> <boolean> <name>bUseAbsoluteValue</name> <label>Use absolute value.</label> <longflag>--uav</longflag> <description>Use absolute value in case of negative square.</description> <default>true</default> </boolean> <boolean> <name>bWriteHistograms</name> <label>Write histograms.</label> <longflag>--wh</longflag> <description>Writes the computed histogram information to hist_???.dat</description> <default>false</default> </boolean> </parameters> <parameters> <label>IO</label> <description>Input/output parameters</description> <image type="diffusion-weighted"> <name>inputVolume</name> <label>Input Volume</label> <channel>input</channel> <index>0</index> <description>Input DWI volume.</description> </image> <image type="diffusion-weighted"> <name>outputVolume</name> <label>Output Volume</label> <channel>output</channel> <index>1</index> <description>Output DWI volume.</description> </image> </parameters> </executable> <executable> <category> Diffusion Tensor.Estimation </category> <title> Diffusion Tensor Estimation </title> <description> Performs a tensor model estimation from diffusion weighted images. There are three estimation methods available: least squares, weigthed least squares and non-linear estimation. The first method is the traditional method for tensor estimation and the fastest one. Weigthed least squares takes into account the noise characteristics of the MRI images to weight the DWI samples used in the estimation based on its intensity magnitude. The last method is the more complex. </description> <version>0.1.0.$Revision: 1892 $(alpha)</version> <documentation-url></documentation-url> <license></license> <contributor>Raul San Jose</contributor> <acknowledgements>This command module is based on the estimation capabilities of teem</acknowledgements> <parameters> <label>IO</label> <description>Input/output parameters</description> <image type="diffusion-weighted"> <name>inputVolume</name> <label>Input DWI Volume</label> <channel>input</channel> <index>0</index> <description>Input DWI volume</description> </image> <image type="tensor"> <name>outputTensor</name> <label>Output DTI Volume</label> <channel>output</channel> <index>1</index> <description>Estimated DTI volume</description> </image> <image type ="scalar"> <name>outputBaseline</name> <label>Output Baseline Volume</label> <channel>output</channel> <index>2</index> <description>Estimated DTI volume</description> </image> <image type ="label"> <name>thresholdMask</name> <label>Otsu Threshold Mask</label> <channel>output</channel> <index>3</index> <description>Otsu Threshold Mask</description> </image> </parameters> <parameters> <label>Estimation Parameters</label> <description> Parameters for the estimation algorithm</description> <string-enumeration> <name>estimationMethod</name> <flag>e</flag> <longflag>enumeration</longflag> <description>An enumeration of strings</description> <label>Estimation Parameters</label> <default>Least Squares</default> <element>Least Squares</element> <element>Weigthed Least Squares</element> <element>Non Linear</element> </string-enumeration> <double> <name>otsuOmegaThreshold</name> <label>Otsu Omega Threshold Parameter</label> <flag>o</flag> <longflag>otsuomegathreshold</longflag> <description>Control the sharpness of the threshold in the Otsu computation. 0: lower threshold, 1: higher threhold</description> <default>0.5</default> <constraints> <minimum>0.0</minimum> <maximum>1.0</maximum> <step>0.1</step> </constraints> </double> <boolean> <name>removeIslands</name> <label>Remove Islands in Threshold Mask</label> <longflag>--removeislands</longflag> <description>Remove Islands in Threshold Mask?</description> <default>true</default> </boolean> <boolean> <name>applyMask</name> <label>Apply Mask to Tensor Image</label> <longflag>--applymask</longflag> <description>Apply Threshold Mask to Tensor?</description> <default>true</default> </boolean> </parameters> </executable> ... </chain>
and a driver program DWIChain.cxx that would be linked against a library ModuleChain.so. ModuleChain.so would have the driver logic to orchestrate the execution of one module followed by another.
Key Investigators
- UCSD BIRN-CC: Jeffrey Grethe, Marco Ruiz
- Isomics: Steve Pieper
- GE: Jim Miller
- Kitware: Will Schroeder