Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
73b9a0e
debug tcompcor, add log messages and tests
Oct 6, 2016
e811b96
save outputs to cwd
Oct 6, 2016
0c7c649
explicity check + error out if mask file and func file don't match in…
Oct 7, 2016
8313923
python3, pep8
Oct 7, 2016
974a42b
use abs paths; +appropriate way to test this
Oct 7, 2016
741405f
make transforms arg in ApplyTransforms opt
Oct 8, 2016
d38562c
allow ANTS ApplyTransforms to use identity transform
Oct 8, 2016
a512faf
traits mandatory=False is incorrect; ignore unicode in doctests
Oct 8, 2016
6448ee8
test specs auto
Oct 8, 2016
e98bd95
Add more informative error msg
Oct 8, 2016
4f27943
less mysterious error messages
Oct 10, 2016
b04d4e7
better test
Oct 10, 2016
7c7dcd2
check and error if input to fsl ApplyTopUp is not 4 dimensional
Oct 11, 2016
8cfa00f
don't load the whole thing into memory
Oct 11, 2016
dd8dfb4
make specs
Oct 12, 2016
a0a31c4
merge with master
Oct 12, 2016
7f84dff
Merge branch 'master' of http://github.com/nipy/nipype into debugging
Oct 12, 2016
b3187f3
pull from nipy/nipype master
Oct 15, 2016
bba591b
add headers to outputs of compcor, framewise displacement + test fix
Oct 17, 2016
8a660dc
Merge http://github.com/nipy/nipype into debugging
Oct 17, 2016
89b9856
revert 4d validation, fix input spec desc
Oct 18, 2016
a42439f
chdir back to original dir before deleting tempdir
Oct 18, 2016
b85fd5f
fix up test (e.g. pep8)
Oct 18, 2016
35a0bb3
Merge http://github.com/nipy/nipype into debugging
Oct 19, 2016
4f80b2a
use from io import open
Oct 24, 2016
c217a23
revert identity transform
Oct 24, 2016
cd5385e
Merge http://github.com/nipy/nipype into debugging
Oct 24, 2016
9239f7b
try longer timeout
Oct 25, 2016
d5e1a0b
specify tab delimiter
Oct 26, 2016
b48395d
don't let divide by zero errors pass by
Oct 28, 2016
fb3c550
don't calculate var/stddev twice
Oct 31, 2016
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions nipype/algorithms/confounds.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,10 @@ def _list_outputs(self):
class CompCorInputSpec(BaseInterfaceInputSpec):
realigned_file = File(exists=True, mandatory=True,
desc='already realigned brain image (4D)')
mask_file = File(exists=True, mandatory=False,
mask_file = File(exists=True,
desc='mask file that determines ROI (3D)')
components_file = File('components_file.txt', exists=False,
mandatory=False, usedefault=True,
usedefault=True,
desc='filename to store physiological components')
num_components = traits.Int(6, usedefault=True) # 6 for BOLD, 4 for ASL
use_regress_poly = traits.Bool(True, usedefault=True,
Expand Down Expand Up @@ -330,6 +330,13 @@ class CompCor(BaseInterface):
def _run_interface(self, runtime):
imgseries = nb.load(self.inputs.realigned_file).get_data()
mask = nb.load(self.inputs.mask_file).get_data()

if imgseries.shape[:3] != mask.shape:
raise ValueError('Inputs for CompCor, func {} and mask {}, do not have matching '
'spatial dimensions ({} and {}, respectively)'
.format(self.inputs.realigned_file, self.inputs.mask_file,
imgseries.shape[:3], mask.shape))

voxel_timecourses = imgseries[mask > 0]
# Zero-out any bad values
voxel_timecourses[np.isnan(np.sum(voxel_timecourses, axis=1)), :] = 0
Expand Down Expand Up @@ -402,6 +409,11 @@ class TCompCor(CompCor):
def _run_interface(self, runtime):
imgseries = nb.load(self.inputs.realigned_file).get_data()

if imgseries.ndim != 4:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why here you are using the numpy array .ndim property, and you have changed the same in your modification of ApplyTopup to use the nibabel header object? Which one is the appropriate option? If both are equivalent, I prefer this (numpy.ndim) rather than your change to ApplyTopup.

Copy link
Contributor Author

@berleant berleant Oct 12, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference is that using numpy requires loading the data into numpy memory, which is expensive. In fact, in ApplyTopUp, it was erroring out. Here, in TCompCor we are loading data into numpy memory anyway, so it is not an additional cost.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! That's very sound.

raise ValueError('tCompCor expected a 4-D nifti file. Input {} has {} dimensions '
'(shape {})'
.format(self.inputs.realigned_file, imgseries.ndim, imgseries.shape))

# From the paper:
# "For each voxel time series, the temporal standard deviation is
# defined as the standard deviation of the time series after the removal
Expand All @@ -420,11 +432,13 @@ def _run_interface(self, runtime):
threshold_index = int(num_voxels * (1. - self.inputs.percentile_threshold))
threshold_std = sortSTD[threshold_index]
mask = tSTD >= threshold_std
mask = mask.astype(int)
mask = mask.astype(int).T

# save mask
mask_file = 'mask.nii'
mask_file = os.path.abspath('mask.nii')
nb.nifti1.save(nb.Nifti1Image(mask, np.eye(4)), mask_file)
IFLOG.debug('tCompcor computed and saved mask of shape {} to mask_file {}'
.format(mask.shape, mask_file))
self.inputs.mask_file = mask_file

super(TCompCor, self)._run_interface(runtime)
Expand Down Expand Up @@ -513,6 +527,8 @@ def regress_poly(degree, data, remove_mean=True, axis=-1):
If remove_mean is True (default), the data is demeaned (i.e. degree 0).
If remove_mean is false, the data is not.
'''
IFLOG.debug('Performing polynomial regression on data of shape ' + str(data.shape))

datashape = data.shape
timepoints = datashape[axis]

Expand Down
8 changes: 4 additions & 4 deletions nipype/algorithms/tests/test_auto_ArtifactDetect.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def test_ArtifactDetect_inputs():
mask_type=dict(mandatory=True,
),
norm_threshold=dict(mandatory=True,
xor=[u'rotation_threshold', u'translation_threshold'],
xor=['rotation_threshold', 'translation_threshold'],
),
parameter_source=dict(mandatory=True,
),
Expand All @@ -28,18 +28,18 @@ def test_ArtifactDetect_inputs():
realignment_parameters=dict(mandatory=True,
),
rotation_threshold=dict(mandatory=True,
xor=[u'norm_threshold'],
xor=['norm_threshold'],
),
save_plot=dict(usedefault=True,
),
translation_threshold=dict(mandatory=True,
xor=[u'norm_threshold'],
xor=['norm_threshold'],
),
use_differences=dict(maxlen=2,
minlen=2,
usedefault=True,
),
use_norm=dict(requires=[u'norm_threshold'],
use_norm=dict(requires=['norm_threshold'],
usedefault=True,
),
zintensity_threshold=dict(mandatory=True,
Expand Down
6 changes: 2 additions & 4 deletions nipype/algorithms/tests/test_auto_CompCor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@


def test_CompCor_inputs():
input_map = dict(components_file=dict(mandatory=False,
usedefault=True,
input_map = dict(components_file=dict(usedefault=True,
),
ignore_exception=dict(nohash=True,
usedefault=True,
),
mask_file=dict(mandatory=False,
),
mask_file=dict(),
num_components=dict(usedefault=True,
),
realigned_file=dict(mandatory=True,
Expand Down
3 changes: 2 additions & 1 deletion nipype/algorithms/tests/test_auto_FramewiseDisplacement.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ def test_FramewiseDisplacement_inputs():
ignore_exception=dict(nohash=True,
usedefault=True,
),
in_plots=dict(),
in_plots=dict(mandatory=True,
),
normalize=dict(usedefault=True,
),
out_figure=dict(usedefault=True,
Expand Down
4 changes: 2 additions & 2 deletions nipype/algorithms/tests/test_auto_SpecifyModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

def test_SpecifyModel_inputs():
input_map = dict(event_files=dict(mandatory=True,
xor=[u'subject_info', u'event_files'],
xor=['subject_info', 'event_files'],
),
functional_runs=dict(copyfile=False,
mandatory=True,
Expand All @@ -22,7 +22,7 @@ def test_SpecifyModel_inputs():
realignment_parameters=dict(copyfile=False,
),
subject_info=dict(mandatory=True,
xor=[u'subject_info', u'event_files'],
xor=['subject_info', 'event_files'],
),
time_repetition=dict(mandatory=True,
),
Expand Down
4 changes: 2 additions & 2 deletions nipype/algorithms/tests/test_auto_SpecifySPMModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def test_SpecifySPMModel_inputs():
input_map = dict(concatenate_runs=dict(usedefault=True,
),
event_files=dict(mandatory=True,
xor=[u'subject_info', u'event_files'],
xor=['subject_info', 'event_files'],
),
functional_runs=dict(copyfile=False,
mandatory=True,
Expand All @@ -26,7 +26,7 @@ def test_SpecifySPMModel_inputs():
realignment_parameters=dict(copyfile=False,
),
subject_info=dict(mandatory=True,
xor=[u'subject_info', u'event_files'],
xor=['subject_info', 'event_files'],
),
time_repetition=dict(mandatory=True,
),
Expand Down
6 changes: 3 additions & 3 deletions nipype/algorithms/tests/test_auto_SpecifySparseModel.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

def test_SpecifySparseModel_inputs():
input_map = dict(event_files=dict(mandatory=True,
xor=[u'subject_info', u'event_files'],
xor=['subject_info', 'event_files'],
),
functional_runs=dict(copyfile=False,
mandatory=True,
Expand All @@ -30,13 +30,13 @@ def test_SpecifySparseModel_inputs():
stimuli_as_impulses=dict(usedefault=True,
),
subject_info=dict(mandatory=True,
xor=[u'subject_info', u'event_files'],
xor=['subject_info', 'event_files'],
),
time_acquisition=dict(mandatory=True,
),
time_repetition=dict(mandatory=True,
),
use_temporal_deriv=dict(requires=[u'model_hrf'],
use_temporal_deriv=dict(requires=['model_hrf'],
),
volumes_in_cluster=dict(usedefault=True,
),
Expand Down
6 changes: 2 additions & 4 deletions nipype/algorithms/tests/test_auto_TCompCor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@


def test_TCompCor_inputs():
input_map = dict(components_file=dict(mandatory=False,
usedefault=True,
input_map = dict(components_file=dict(usedefault=True,
),
ignore_exception=dict(nohash=True,
usedefault=True,
),
mask_file=dict(mandatory=False,
),
mask_file=dict(),
num_components=dict(usedefault=True,
),
percentile_threshold=dict(usedefault=True,
Expand Down
22 changes: 22 additions & 0 deletions nipype/algorithms/tests/test_compcor.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,28 @@ def test_compcor_no_regress_poly(self):
['-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()
self.assertEqual(nb.load('mask.nii').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_file (2)
shape_more_than = (3, 3, 3, 5) # dim 0 is > dim 0 of self.mask_file (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_file=self.mask_file)
self.assertRaisesRegexp(ValueError, "dimensions", interface.run)

def test_tcompcor_bad_input_dim(self):
bad_dims = (2, 2, 2)
data_file = utils.save_toy_nii(np.zeros(bad_dims), 'temp.nii')
interface = TCompCor(realigned_file=data_file)
self.assertRaisesRegexp(ValueError, '4-D', interface.run)

def run_cc(self, ccinterface, expected_components):
# run
ccresult = ccinterface.run()
Expand Down
2 changes: 1 addition & 1 deletion nipype/interfaces/afni/tests/test_auto_AFNICommand.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def test_AFNICommand_inputs():
usedefault=True,
),
out_file=dict(argstr='-prefix %s',
name_source=[u'in_file'],
name_source=['in_file'],
name_template='%s_afni',
),
outputtype=dict(),
Expand Down
4 changes: 2 additions & 2 deletions nipype/interfaces/afni/tests/test_auto_AutoTcorrelate.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ def test_AutoTcorrelate_inputs():
mask=dict(argstr='-mask %s',
),
mask_only_targets=dict(argstr='-mask_only_targets',
xor=[u'mask_source'],
xor=['mask_source'],
),
mask_source=dict(argstr='-mask_source %s',
xor=[u'mask_only_targets'],
xor=['mask_only_targets'],
),
out_file=dict(argstr='-prefix %s',
name_source='in_file',
Expand Down
2 changes: 1 addition & 1 deletion nipype/interfaces/afni/tests/test_auto_BlurToFWHM.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def test_BlurToFWHM_inputs():
mask=dict(argstr='-blurmaster %s',
),
out_file=dict(argstr='-prefix %s',
name_source=[u'in_file'],
name_source=['in_file'],
name_template='%s_afni',
),
outputtype=dict(),
Expand Down
2 changes: 1 addition & 1 deletion nipype/interfaces/afni/tests/test_auto_BrickStat.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def test_BrickStat_inputs():
position=1,
),
out_file=dict(argstr='-prefix %s',
name_source=[u'in_file'],
name_source=['in_file'],
name_template='%s_afni',
),
outputtype=dict(),
Expand Down
4 changes: 2 additions & 2 deletions nipype/interfaces/afni/tests/test_auto_Calc.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ def test_Calc_inputs():
),
outputtype=dict(),
single_idx=dict(),
start_idx=dict(requires=[u'stop_idx'],
start_idx=dict(requires=['stop_idx'],
),
stop_idx=dict(requires=[u'start_idx'],
stop_idx=dict(requires=['start_idx'],
),
terminal_output=dict(nohash=True,
),
Expand Down
2 changes: 1 addition & 1 deletion nipype/interfaces/afni/tests/test_auto_DegreeCentrality.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def test_DegreeCentrality_inputs():
oned_file=dict(argstr='-out1D %s',
),
out_file=dict(argstr='-prefix %s',
name_source=[u'in_file'],
name_source=['in_file'],
name_template='%s_afni',
),
outputtype=dict(),
Expand Down
2 changes: 1 addition & 1 deletion nipype/interfaces/afni/tests/test_auto_ECM.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def test_ECM_inputs():
memory=dict(argstr='-memory %f',
),
out_file=dict(argstr='-prefix %s',
name_source=[u'in_file'],
name_source=['in_file'],
name_template='%s_afni',
),
outputtype=dict(),
Expand Down
4 changes: 2 additions & 2 deletions nipype/interfaces/afni/tests/test_auto_Eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ def test_Eval_inputs():
),
outputtype=dict(),
single_idx=dict(),
start_idx=dict(requires=[u'stop_idx'],
start_idx=dict(requires=['stop_idx'],
),
stop_idx=dict(requires=[u'start_idx'],
stop_idx=dict(requires=['start_idx'],
),
terminal_output=dict(nohash=True,
),
Expand Down
8 changes: 4 additions & 4 deletions nipype/interfaces/afni/tests/test_auto_FWHMx.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def test_FWHMx_inputs():
args=dict(argstr='%s',
),
arith=dict(argstr='-arith',
xor=[u'geom'],
xor=['geom'],
),
automask=dict(argstr='-automask',
usedefault=True,
Expand All @@ -20,17 +20,17 @@ def test_FWHMx_inputs():
compat=dict(argstr='-compat',
),
demed=dict(argstr='-demed',
xor=[u'detrend'],
xor=['detrend'],
),
detrend=dict(argstr='-detrend',
usedefault=True,
xor=[u'demed'],
xor=['demed'],
),
environ=dict(nohash=True,
usedefault=True,
),
geom=dict(argstr='-geom',
xor=[u'arith'],
xor=['arith'],
),
ignore_exception=dict(nohash=True,
usedefault=True,
Expand Down
2 changes: 1 addition & 1 deletion nipype/interfaces/afni/tests/test_auto_Hist.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_Hist_inputs():
),
out_file=dict(argstr='-prefix %s',
keep_extension=False,
name_source=[u'in_file'],
name_source=['in_file'],
name_template='%s_hist',
),
out_show=dict(argstr='> %s',
Expand Down
2 changes: 1 addition & 1 deletion nipype/interfaces/afni/tests/test_auto_LFCD.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def test_LFCD_inputs():
mask=dict(argstr='-mask %s',
),
out_file=dict(argstr='-prefix %s',
name_source=[u'in_file'],
name_source=['in_file'],
name_template='%s_afni',
),
outputtype=dict(),
Expand Down
2 changes: 1 addition & 1 deletion nipype/interfaces/afni/tests/test_auto_MaskTool.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def test_MaskTool_inputs():
usedefault=True,
),
fill_dirs=dict(argstr='-fill_dirs %s',
requires=[u'fill_holes'],
requires=['fill_holes'],
),
fill_holes=dict(argstr='-fill_holes',
),
Expand Down
4 changes: 2 additions & 2 deletions nipype/interfaces/afni/tests/test_auto_Notes.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def test_Notes_inputs():
input_map = dict(add=dict(argstr='-a "%s"',
),
add_history=dict(argstr='-h "%s"',
xor=[u'rep_history'],
xor=['rep_history'],
),
args=dict(argstr='%s',
),
Expand All @@ -28,7 +28,7 @@ def test_Notes_inputs():
),
outputtype=dict(),
rep_history=dict(argstr='-HH "%s"',
xor=[u'add_history'],
xor=['add_history'],
),
ses=dict(argstr='-ses',
),
Expand Down
Loading