Realistic Analysis Integration Example¶
In this example, we will integrate a basic version of Nipype’s interface for FSL’s SUSAN noise-reduction algorithm for MRI images. This example is adapted from django_mri.
Input and Output Specification¶
InputSpecificationManager
and
OutputSpecificationManager
provide a from_dict()
method which can generate specifications based on a
dict
with the following structure:
SPECIFICATION = {
"definition_key_1": {
"type": InputDefinitionSubclass,
"attribute": "value"
},
"definition_key_2": {
"type": InputDefinitionSubclass,
"attribute": "value2"
},
}
If we try to recreate SUSAN’s specifications from the Nipype’s docs according to this structure, it might look something like:
from django_analyses.models.input.definitions import (
BooleanInputDefinition,
FileInputDefinition,
FloatInputDefinition,
IntegerInputDefinition,
StringInputDefinition,
)
from django_analyses.models.output.definitions import FileOutputDefinition
SUSAN_INPUT_SPECIFICATION = {
"brightness_threshold": {
"type": FloatInputDefinition,
"required": True,
"description": "Should be greater than noise level and less than contrast of edges to be preserved.",
},
"fwhm": {
"type": FloatInputDefinition,
"required": True,
"description": "FWHM of smoothing, in millimeters.",
},
"in_file": {
"type": FileInputDefinition,
"required": True,
"description": "Filename of input time-series.",
},
"dimension": {
"type": IntegerInputDefinition,
"required": False,
"default": 3,
"min_value": 2,
"max_value": 3,
},
"out_file": {
"type": StringInputDefinition,
"required": False,
"description": "Desired output file path.",
"is_output_path": True,
"default": "smooth.nii.gz",
},
"output_type": {
"type": StringInputDefinition,
"required": False,
"description": "Output file format.",
"choices": ["NIFTI", "NIFTI_PAIR", "NIFTI_GZ", "NIFTI_PAIR_GZ"],
"default": "NIFTI_GZ",
},
"use_median": {
"type": BooleanInputDefinition,
"required": False,
"default": True,
"description": "Whether to use a local median filter in the cases where single-point noise is detected.",
},
"args": {
"type": StringInputDefinition,
"required": False,
"description": "Additional parameters to pass to the command.",
},
}
SUSAN_OUTPUT_SPECIFICATION = {
"smoothed_file": {
"type": FileOutputDefinition,
"description": "Smoothed output file.",
}
}
Analysis Definition¶
Similarly to the input and output specifications, the
AnalysisManager
class exposes a
from_list()
method
which we could use to easily add analyses to the database.
First we’ll create the complete definition in another file:
from susan_specifications import SUSAN_INPUT_SPECIFICATION, SUSAN_OUTPUT_SPECIFICATION
analysis_definitions = [
{
"title": "SUSAN",
"description": "Reduces noise in 2/3D images by averaging voxels with similar intensity.",
"versions": [
{
"title": "1.0.0",
"description": "FSL 6.0 version of the SUSAN algorithm.",
"input": SUSAN_INPUT_SPECIFICATION,
"output": SUSAN_OUTPUT_SPECIFICATION,
"nested_results_attribute": "outputs.get_traitsfree",
}
],
}
]
Note
The nested_results_attribute
field allows us to integrate smoothly with
Nipype’s
BaseTraitedSpec
class by extracting the results
dictionary from the returned object.
For more information see Integration Customization.
All that’s left to do is:
>>> from analysis_definitions import analysis_definitions
>>> from django_analyses.models import Analysis
>>> results = Analysis.objects.from_list(analysis_definitions)
>>> results
{'SUSAN': {'model': <Analysis: SUSAN>, 'created': True, 'versions': {'1.0.0': {'model': <AnalysisVersion: SUSAN v1.0.0>, 'created': True}}}}
The from_list()
method
returns a dictionary with references to the specified
Analysis
and
AnalysisVersion
instances and whether
they have been created or not.
SUSAN is now an available analysis in our database. Only one thing missing…
Interface Integration¶
In order to django_analyses to be able to locate the interface used to run this
analysis version, we must add to our project’s ANALYSIS_INTERFACES
setting:
from nipype.interfaces.fsl import SUSAN
...
ANALYSIS_INTERFACES = {"SUSAN": {"1.0.0": SUSAN}}
All done!