Skip to content

Commit e605dfe

Browse files
authored
Merge pull request #1993 from jdkent/master
ENH: Adding a python wrapper for ICA_AROMA
2 parents 8398de7 + 261fade commit e605dfe

File tree

2 files changed

+186
-0
lines changed

2 files changed

+186
-0
lines changed

nipype/interfaces/fsl/ICA_AROMA.py

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# -*- coding: utf-8 -*-
2+
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
3+
# vi: set ft=python sts=4 ts=4 sw=4 et:
4+
"""This commandline module provides classes for interfacing with the
5+
`ICA-AROMA.py<https://github.com/rhr-pruim/ICA-AROMA>`_ command line tool.
6+
Change directory to provide relative paths for doctests
7+
>>> import os
8+
>>> filepath = os.path.dirname(os.path.realpath(__file__))
9+
>>> datadir = os.path.realpath(os.path.join(filepath,
10+
... '../../testing/data'))
11+
>>> os.chdir(datadir)
12+
"""
13+
from nipype.interfaces.base import (
14+
TraitedSpec,
15+
CommandLineInputSpec,
16+
CommandLine,
17+
File,
18+
Directory,
19+
traits,
20+
OutputMultiPath
21+
)
22+
import os
23+
24+
class ICA_AROMAInputSpec(CommandLineInputSpec):
25+
feat_dir = Directory(exists=True, mandatory=True,
26+
argstr='-feat %s',
27+
xor=['in_file', 'mat_file', 'fnirt_warp_file', 'motion_parameters'],
28+
desc='If a feat directory exists and temporal filtering '
29+
'has not been run yet, ICA_AROMA can use the files in '
30+
'this directory.')
31+
in_file = File(exists=True, mandatory=True,
32+
argstr='-i %s', xor=['feat_dir'],
33+
desc='volume to be denoised')
34+
out_dir = Directory('out', mandatory=True,
35+
argstr='-o %s',
36+
desc='output directory')
37+
mask = File(exists=True, argstr='-m %s', xor=['feat_dir'],
38+
desc='path/name volume mask')
39+
dim = traits.Int(argstr='-dim %d',
40+
desc='Dimensionality reduction when running '
41+
'MELODIC (defualt is automatic estimation)')
42+
TR = traits.Float(argstr='-tr %.3f',
43+
desc='TR in seconds. If this is not specified '
44+
'the TR will be extracted from the '
45+
'header of the fMRI nifti file.')
46+
melodic_dir = Directory(exists=True, argstr='-meldir %s',
47+
desc='path to MELODIC directory if MELODIC has already been run')
48+
mat_file = File(exists=True, argstr='-affmat %s', xor=['feat_dir'],
49+
desc='path/name of the mat-file describing the '
50+
'affine registration (e.g. FSL FLIRT) of the '
51+
'functional data to structural space (.mat file)')
52+
fnirt_warp_file = File(exists=True, argstr='-warp %s', xor=['feat_dir'],
53+
desc='File name of the warp-file describing '
54+
'the non-linear registration (e.g. FSL FNIRT) '
55+
'of the structural data to MNI152 space (.nii.gz)')
56+
motion_parameters = File(exists=True, mandatory=True,
57+
argstr='-mc %s', xor=['feat_dir'],
58+
desc='motion parameters file')
59+
denoise_type = traits.Enum('nonaggr', 'aggr', 'both', 'no', usedefault=True,
60+
mandatory=True, argstr='-den %s',
61+
desc='Type of denoising strategy:\n'
62+
'-none: only classification, no denoising\n'
63+
'-nonaggr (default): non-aggresssive denoising, i.e. partial component regression\n'
64+
'-aggr: aggressive denoising, i.e. full component regression\n'
65+
'-both: both aggressive and non-aggressive denoising (two outputs)')
66+
67+
class ICA_AROMAOutputSpec(TraitedSpec):
68+
aggr_denoised_file = File(exists=True,
69+
desc='if generated: aggressively denoised volume')
70+
nonaggr_denoised_file = File(exists=True,
71+
desc='if generated: non aggressively denoised volume' )
72+
out_dir = Directory(exists=True,
73+
desc='directory contains (in addition to the denoised files): '
74+
'melodic.ica + classified_motion_components + '
75+
'classification_overview + feature_scores + melodic_ic_mni)')
76+
77+
class ICA_AROMA(CommandLine):
78+
"""
79+
Interface for the ICA_AROMA.py script.
80+
81+
ICA-AROMA (i.e. 'ICA-based Automatic Removal Of Motion Artifacts') concerns
82+
a data-driven method to identify and remove motion-related independent
83+
components from fMRI data. To that end it exploits a small, but robust
84+
set of theoretically motivated features, preventing the need for classifier
85+
re-training and therefore providing direct and easy applicability.
86+
87+
See link for further documentation: https://github.com/rhr-pruim/ICA-AROMA
88+
89+
Example
90+
-------
91+
92+
>>> from nipype.interfaces.fsl import ICA_AROMA
93+
>>> from nipype.testing import example_data
94+
>>> AROMA_obj = ICA_AROMA.ICA_AROMA()
95+
>>> AROMA_obj.inputs.in_file = 'functional.nii'
96+
>>> AROMA_obj.inputs.mat_file = 'func_to_struct.mat'
97+
>>> AROMA_obj.inputs.fnirt_warp_file = 'warpfield.nii'
98+
>>> AROMA_obj.inputs.motion_parameters = 'fsl_mcflirt_movpar.txt'
99+
>>> AROMA_obj.inputs.mask = 'mask.nii.gz'
100+
>>> AROMA_obj.inputs.denoise_type = 'both'
101+
>>> AROMA_obj.inputs.out_dir = 'ICA_testout'
102+
>>> AROMA_obj.cmdline # doctest: +ALLOW_UNICODE
103+
'ICA_AROMA.py -den both -warp warpfield.nii -i functional.nii -m mask.nii.gz -affmat func_to_struct.mat -mc fsl_mcflirt_movpar.txt -o ICA_testout'
104+
"""
105+
_cmd = 'ICA_AROMA.py'
106+
input_spec = ICA_AROMAInputSpec
107+
output_spec = ICA_AROMAOutputSpec
108+
109+
def _list_outputs(self):
110+
out_dir = os.path.abspath(self.inputs.out_dir)
111+
outputs['out_dir'] = out_dir
112+
113+
if self.inputs.denoise_type in ('aggr', 'both'):
114+
outputs['aggr_denoised_file'] = os.path.join(out_dir, 'denoised_func_data_aggr.nii.gz')
115+
if self.inputs.denoise_type in ('nonaggr', 'both'):
116+
outputs['nonaggr_denoised_file'] = os.path.join(out_dir, 'denoised_func_data_nonaggr.nii.gz')
117+
118+
return outputs
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT
2+
from __future__ import unicode_literals
3+
from ..ICA_AROMA import ICA_AROMA
4+
5+
6+
def test_ICA_AROMA_inputs():
7+
input_map = dict(TR=dict(argstr='-tr %.3f',
8+
),
9+
args=dict(argstr='%s',
10+
),
11+
denoise_type=dict(argstr='-den %s',
12+
mandatory=True,
13+
usedefault=True,
14+
),
15+
dim=dict(argstr='-dim %d',
16+
),
17+
environ=dict(nohash=True,
18+
usedefault=True,
19+
),
20+
feat_dir=dict(argstr='-feat %s',
21+
mandatory=True,
22+
xor=['in_file', 'mat_file', 'fnirt_warp_file', 'motion_parameters'],
23+
),
24+
fnirt_warp_file=dict(argstr='-warp %s',
25+
xor=['feat_dir'],
26+
),
27+
ignore_exception=dict(nohash=True,
28+
usedefault=True,
29+
),
30+
in_file=dict(argstr='-i %s',
31+
mandatory=True,
32+
xor=['feat_dir'],
33+
),
34+
mask=dict(argstr='-m %s',
35+
xor=['feat_dir'],
36+
),
37+
mat_file=dict(argstr='-affmat %s',
38+
xor=['feat_dir'],
39+
),
40+
melodic_dir=dict(argstr='-meldir %s',
41+
),
42+
motion_parameters=dict(argstr='-mc %s',
43+
mandatory=True,
44+
xor=['feat_dir'],
45+
),
46+
out_dir=dict(argstr='-o %s',
47+
mandatory=True,
48+
),
49+
terminal_output=dict(nohash=True,
50+
),
51+
)
52+
inputs = ICA_AROMA.input_spec()
53+
54+
for key, metadata in list(input_map.items()):
55+
for metakey, value in list(metadata.items()):
56+
assert getattr(inputs.traits()[key], metakey) == value
57+
58+
59+
def test_ICA_AROMA_outputs():
60+
output_map = dict(aggr_denoised_file=dict(),
61+
nonaggr_denoised_file=dict(),
62+
out_dir=dict(),
63+
)
64+
outputs = ICA_AROMA.output_spec()
65+
66+
for key, metadata in list(output_map.items()):
67+
for metakey, value in list(metadata.items()):
68+
assert getattr(outputs.traits()[key], metakey) == value

0 commit comments

Comments
 (0)