Skip to content

Commit 2c551d0

Browse files
committed
(CompCor) more intuitive interface following review from @effigies
1 parent 0373879 commit 2c551d0

File tree

3 files changed

+34
-12
lines changed

3 files changed

+34
-12
lines changed

nipype/algorithms/confounds.py

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -394,16 +394,22 @@ class CompCorInputSpec(BaseInterfaceInputSpec):
394394
'components_file.txt',
395395
usedefault=True,
396396
desc='Filename to store physiological components')
397-
num_components = traits.Float(6, usedefault=True,
398-
desc='Number of components to return from the decomposition.'
399-
'If `num_components` is a positive integer, then '
400-
'`num_components` components will be retained. If '
401-
'`num_components` is a fractional value between 0 and 1, then '
397+
num_components = traits.Either('all', traits.Int,
398+
xor=['variance_threshold'],
399+
desc='Number of components to return from the decomposition. If '
400+
'`num_components` is `all`, then all components will be '
401+
'retained.')
402+
# 6 for BOLD, 4 for ASL
403+
# automatically instantiated to 6 in CompCor below if neither
404+
# `num_components` nor `variance_threshold` is defined (for
405+
# backward compatibility)
406+
variance_threshold = traits.Float(xor=['num_components'],
407+
desc='Select the number of components to be returned automatically '
408+
'based on their ability to explain variance in the dataset. '
409+
'`variance_threshold` is a fractional value between 0 and 1; '
402410
'the number of components retained will be equal to the minimum '
403411
'number of components necessary to explain the provided '
404-
'fraction of variance in the masked time series. If '
405-
'`num_components` is -1, then all components will be retained.')
406-
# 6 for BOLD, 4 for ASL
412+
'fraction of variance in the masked time series.')
407413
pre_filter = traits.Enum(
408414
'polynomial',
409415
'cosine',
@@ -564,8 +570,20 @@ def _run_interface(self, runtime):
564570
'{} cannot detect repetition time from image - '
565571
'Set the repetition_time input'.format(self._header))
566572

573+
if isdefined(self.inputs.variance_threshold):
574+
components_criterion = self.inputs.variance_threshold
575+
elif isdefined(self.inputs.num_components):
576+
components_criterion = self.inputs.num_components
577+
else:
578+
components_criterion = 6
579+
IFLOGGER.warning('`num_components` and `variance_threshold` are '
580+
'not defined. Setting number of components to 6 '
581+
'for backward compatibility. Please set either '
582+
'`num_components` or `variance_threshold`, as '
583+
'this feature may be deprecated in the future.')
584+
567585
components, filter_basis, metadata = compute_noise_components(
568-
imgseries.get_data(), mask_images, self.inputs.num_components,
586+
imgseries.get_data(), mask_images, components_criterion,
569587
self.inputs.pre_filter, degree, self.inputs.high_pass_cutoff, TR,
570588
self.inputs.failure_mode, self.inputs.mask_names)
571589

@@ -1191,7 +1209,7 @@ def compute_noise_components(imgseries, mask_images, components_criterion=0.5,
11911209
Number of noise components to return. If this is a decimal value
11921210
between 0 and 1, then `create_noise_components` will instead return
11931211
the smallest number of components necessary to explain the indicated
1194-
fraction of variance. If `components_criterion` is -1, then all
1212+
fraction of variance. If `components_criterion` is `all`, then all
11951213
components will be returned.
11961214
filter_type: str
11971215
Type of filter to apply to time series before computing
@@ -1218,6 +1236,8 @@ def compute_noise_components(imgseries, mask_images, components_criterion=0.5,
12181236
"""
12191237
components = None
12201238
basis = np.array([])
1239+
if components_criterion == 'all':
1240+
components_criterion = -1
12211241
if not mask_names:
12221242
mask_names = range(len(mask_images))
12231243
for i, img in zip(mask_names, mask_images):

nipype/algorithms/tests/test_auto_ACompCor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def test_ACompCor_inputs():
2020
requires=['mask_files'],
2121
xor=['mask_index'],
2222
),
23-
num_components=dict(usedefault=True, ),
23+
num_components=dict(xor=['variance_threshold'], ),
2424
pre_filter=dict(usedefault=True, ),
2525
realigned_file=dict(mandatory=True, ),
2626
regress_poly_degree=dict(usedefault=True, ),
@@ -31,6 +31,7 @@ def test_ACompCor_inputs():
3131
deprecated='0.15.0',
3232
new_name='pre_filter',
3333
),
34+
variance_threshold=dict(xor=['num_components'], ),
3435
)
3536
inputs = ACompCor.input_spec()
3637

nipype/algorithms/tests/test_auto_TCompCor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def test_TCompCor_inputs():
2020
requires=['mask_files'],
2121
xor=['mask_index'],
2222
),
23-
num_components=dict(usedefault=True, ),
23+
num_components=dict(xor=['variance_threshold'], ),
2424
percentile_threshold=dict(usedefault=True, ),
2525
pre_filter=dict(usedefault=True, ),
2626
realigned_file=dict(mandatory=True, ),
@@ -32,6 +32,7 @@ def test_TCompCor_inputs():
3232
deprecated='0.15.0',
3333
new_name='pre_filter',
3434
),
35+
variance_threshold=dict(xor=['num_components'], ),
3536
)
3637
inputs = TCompCor.input_spec()
3738

0 commit comments

Comments
 (0)