Skip to content

Fix/compcor #1992

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/documentation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Previous versions: `0.12.0 <http://nipype.readthedocs.io/en/0.12.0/>`_ `0.11.0
:maxdepth: 2

users/index

.. toctree::
:maxdepth: 1

Expand Down
2 changes: 1 addition & 1 deletion doc/users/config_file.rst
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ Execution
crashfiles allow interactive debugging and rerunning of nodes, while text
crashfiles allow portability across machines and shorter load time.
(possible values: ``pklz`` and ``txt``; default value: ``pklz``)

Example
~~~~~~~

Expand Down
417 changes: 217 additions & 200 deletions nipype/algorithms/confounds.py

Large diffs are not rendered by default.

10 changes: 8 additions & 2 deletions nipype/algorithms/tests/test_auto_ACompCor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@
def test_ACompCor_inputs():
input_map = dict(components_file=dict(usedefault=True,
),
header=dict(),
header_prefix=dict(),
ignore_exception=dict(nohash=True,
usedefault=True,
),
mask_file=dict(),
mask_files=dict(),
mask_index=dict(requires=['mask_files'],
xor=['merge_method'],
),
merge_method=dict(requires=['mask_files'],
xor=['mask_index'],
),
num_components=dict(usedefault=True,
),
realigned_file=dict(mandatory=True,
Expand Down
28 changes: 10 additions & 18 deletions nipype/algorithms/tests/test_auto_TCompCor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@
def test_TCompCor_inputs():
input_map = dict(components_file=dict(usedefault=True,
),
header=dict(),
header_prefix=dict(),
ignore_exception=dict(nohash=True,
usedefault=True,
),
mask_file=dict(),
mask_files=dict(),
mask_index=dict(requires=['mask_files'],
xor=['merge_method'],
),
merge_method=dict(requires=['mask_files'],
xor=['mask_index'],
),
num_components=dict(usedefault=True,
),
percentile_threshold=dict(usedefault=True,
Expand All @@ -30,22 +36,8 @@ def test_TCompCor_inputs():


def test_TCompCor_outputs():
output_map = dict(components_file=dict(usedefault=True,
),
header=dict(),
high_variance_mask=dict(),
ignore_exception=dict(nohash=True,
usedefault=True,
),
mask_file=dict(),
num_components=dict(usedefault=True,
),
realigned_file=dict(mandatory=True,
),
regress_poly_degree=dict(usedefault=True,
),
use_regress_poly=dict(usedefault=True,
),
output_map = dict(components_file=dict(),
high_variance_masks=dict(),
)
outputs = TCompCor.output_spec()

Expand Down
50 changes: 32 additions & 18 deletions nipype/algorithms/tests/test_compcor.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import pytest
from ...testing import utils
from ..confounds import CompCor, TCompCor, ACompCor
from ...interfaces.base import Undefined


class TestCompCor():
Expand Down Expand Up @@ -48,11 +47,13 @@ def test_compcor(self):
['-0.1246655485', '-0.1235705610']]

self.run_cc(CompCor(realigned_file=self.realigned_file,
mask_files=self.mask_files),
mask_files=self.mask_files,
mask_index=0),
expected_components)

self.run_cc(ACompCor(realigned_file=self.realigned_file,
mask_files=self.mask_files,
mask_index=0,
components_file='acc_components_file'),
expected_components, 'aCompCor')

Expand All @@ -64,40 +65,44 @@ def test_tcompcor(self):
['0.4566907310', '0.6983205193'],
['-0.7132557407', '0.1340170559'],
['0.5022537643', '-0.5098322262'],
['-0.1342351356', '0.1407855119']], 'tCompCor')
['-0.1342351356', '0.1407855119']],
'tCompCor')

def test_tcompcor_no_percentile(self):
ccinterface = TCompCor(realigned_file=self.realigned_file)
ccinterface.run()

mask = nb.load('mask.nii').get_data()
mask = nb.load('mask_000.nii.gz').get_data()
num_nonmasked_voxels = np.count_nonzero(mask)
assert num_nonmasked_voxels == 1

def test_compcor_no_regress_poly(self):
self.run_cc(CompCor(realigned_file=self.realigned_file,
mask_files=self.mask_files,
use_regress_poly=False), [['0.4451946442', '-0.7683311482'],
['-0.4285129505', '-0.0926034137'],
['0.5721540256', '0.5608764842'],
['-0.5367548139', '0.0059943226'],
['-0.0520809054', '0.2940637551']])
mask_files=self.mask_files,
mask_index=0,
use_regress_poly=False),
[['0.4451946442', '-0.7683311482'],
['-0.4285129505', '-0.0926034137'],
['0.5721540256', '0.5608764842'],
['-0.5367548139', '0.0059943226'],
['-0.0520809054', '0.2940637551']])

def test_tcompcor_asymmetric_dim(self):
asymmetric_shape = (2, 3, 4, 5)
asymmetric_data = utils.save_toy_nii(np.zeros(asymmetric_shape),
'asymmetric.nii')

TCompCor(realigned_file=asymmetric_data).run()
assert nb.load('mask.nii').get_data().shape == asymmetric_shape[:3]
assert nb.load('mask_000.nii.gz').get_data().shape == asymmetric_shape[:3]

def test_compcor_bad_input_shapes(self):
shape_less_than = (1, 2, 2, 5) # dim 0 is < dim 0 of self.mask_files (2)
shape_more_than = (3, 3, 3, 5) # dim 0 is > dim 0 of self.mask_files (2)

for data_shape in (shape_less_than, shape_more_than):
data_file = utils.save_toy_nii(np.zeros(data_shape), 'temp.nii')
interface = CompCor(realigned_file=data_file, mask_files=self.mask_files)
interface = CompCor(realigned_file=data_file,
mask_files=self.mask_files[0])
with pytest.raises(ValueError, message="Dimension mismatch"): interface.run()

def test_tcompcor_bad_input_dim(self):
Expand All @@ -112,19 +117,25 @@ def test_tcompcor_merge_intersect_masks(self):
mask_files=self.mask_files,
merge_method=method).run()
if method == 'union':
assert np.array_equal(nb.load('mask.nii').get_data(),
assert np.array_equal(nb.load('mask_000.nii.gz').get_data(),
([[[0,0],[0,0]],[[0,0],[1,0]]]))
if method == 'intersect':
assert np.array_equal(nb.load('mask.nii').get_data(),
assert np.array_equal(nb.load('mask_000.nii.gz').get_data(),
([[[0,0],[0,0]],[[0,1],[0,0]]]))

def test_tcompcor_index_mask(self):
TCompCor(realigned_file=self.realigned_file,
mask_files=self.mask_files,
mask_index=1).run()
assert np.array_equal(nb.load('mask.nii').get_data(),
assert np.array_equal(nb.load('mask_000.nii.gz').get_data(),
([[[0,0],[0,0]],[[0,1],[0,0]]]))

def test_tcompcor_multi_mask_no_index(self):
interface = TCompCor(realigned_file=self.realigned_file,
mask_files=self.mask_files)
with pytest.raises(ValueError, message='more than one mask file'):
interface.run()

def run_cc(self, ccinterface, expected_components, expected_header='CompCor'):
# run
ccresult = ccinterface.run()
Expand All @@ -137,12 +148,15 @@ def run_cc(self, ccinterface, expected_components, expected_header='CompCor'):
assert ccinterface.inputs.num_components == 6

with open(ccresult.outputs.components_file, 'r') as components_file:
expected_n_components = min(ccinterface.inputs.num_components, self.fake_data.shape[3])
expected_n_components = min(ccinterface.inputs.num_components,
self.fake_data.shape[3])

components_data = [line.split('\t') for line in components_file]

header = components_data.pop(0) # the first item will be '#', we can throw it out
expected_header = [expected_header + str(i) for i in range(expected_n_components)]
# the first item will be '#', we can throw it out
header = components_data.pop(0)
expected_header = [expected_header + '{:02d}'.format(i) for i in
range(expected_n_components)]
for i, heading in enumerate(header):
assert expected_header[i] in heading

Expand Down
4 changes: 2 additions & 2 deletions nipype/interfaces/afni/preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -2417,7 +2417,7 @@ class QwarpPlusMinusOutputSpec(TraitedSpec):


class QwarpPlusMinus(CommandLine):
"""A version of 3dQwarp for performing field susceptibility correction
"""A version of 3dQwarp for performing field susceptibility correction
using two images with opposing phase encoding directions.

For complete details, see the `3dQwarp Documentation.
Expand All @@ -2434,7 +2434,7 @@ class QwarpPlusMinus(CommandLine):
>>> qwarp.cmdline # doctest: +ALLOW_UNICODE
'3dQwarp -prefix Qwarp.nii.gz -plusminus -base sub-01_dir-RL_epi.nii.gz -nopadWARP -source sub-01_dir-LR_epi.nii.gz'
>>> res = warp.run() # doctest: +SKIP

"""
_cmd = '3dQwarp -prefix Qwarp.nii.gz -plusminus'
input_spec = QwarpPlusMinusInputSpec
Expand Down
2 changes: 1 addition & 1 deletion nipype/interfaces/afni/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ class FWHMx(AFNICommandBase):
_cmd = '3dFWHMx'
input_spec = FWHMxInputSpec
output_spec = FWHMxOutputSpec

references_ = [{'entry': BibTeX('@article{CoxReynoldsTaylor2016,'
'author={R.W. Cox, R.C. Reynolds, and P.A. Taylor},'
'title={AFNI and clustering: false positive rates redux},'
Expand Down
10 changes: 5 additions & 5 deletions nipype/interfaces/fsl/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class RobustFOVInputSpec(FSLCommandInputSpec):
brainsize = traits.Int(desc=('size of brain in z-dimension (default '
'170mm/150mm)'),
argstr='-b %d')
out_transform = File(desc=("Transformation matrix in_file to out_roi "
out_transform = File(desc=("Transformation matrix in_file to out_roi "
"output name"),
argstr="-m %s",
name_source=['in_file'], hash_files=False,
Expand All @@ -83,17 +83,17 @@ class RobustFOVInputSpec(FSLCommandInputSpec):
class RobustFOVOutputSpec(TraitedSpec):
out_roi = File(exists=True, desc="ROI volume output name")
out_transform = File(exists=True,
desc=("Transformation matrix in_file to out_roi "
desc=("Transformation matrix in_file to out_roi "
"output name"))


class RobustFOV(FSLCommand):
"""Automatically crops an image removing lower head and neck.
Interface is stable 5.0.0 to 5.0.9, but default brainsize changed from

Interface is stable 5.0.0 to 5.0.9, but default brainsize changed from
150mm to 170mm.
"""

_cmd = 'robustfov'
input_spec = RobustFOVInputSpec
output_spec = RobustFOVOutputSpec
Expand Down