Skip to content

Commit adb3623

Browse files
committed
fix: allow multiple masks for interface
1 parent 1188b50 commit adb3623

File tree

2 files changed

+45
-35
lines changed

2 files changed

+45
-35
lines changed

nipype/algorithms/confounds.py

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ def _list_outputs(self):
302302
class CompCorInputSpec(BaseInterfaceInputSpec):
303303
realigned_file = File(exists=True, mandatory=True,
304304
desc='already realigned brain image (4D)')
305-
mask_file = File(exists=True, desc='mask file that determines ROI (3D)')
305+
mask_file = InputMultiPath(File(exists=True, desc='mask file(s) that determines ROI (3D)'))
306306
components_file = File('components_file.txt', exists=False,
307307
usedefault=True,
308308
desc='filename to store physiological components')
@@ -351,36 +351,43 @@ class CompCor(BaseInterface):
351351

352352
def _run_interface(self, runtime):
353353
imgseries = nb.load(self.inputs.realigned_file, mmap=NUMPY_MMAP).get_data()
354-
mask = nb.load(self.inputs.mask_file, mmap=NUMPY_MMAP).get_data()
355-
356-
if imgseries.shape[:3] != mask.shape:
357-
raise ValueError('Inputs for CompCor, func {} and mask {}, do not have matching '
358-
'spatial dimensions ({} and {}, respectively)'
359-
.format(self.inputs.realigned_file, self.inputs.mask_file,
360-
imgseries.shape[:3], mask.shape))
361-
362-
voxel_timecourses = imgseries[mask > 0]
363-
# Zero-out any bad values
364-
voxel_timecourses[np.isnan(np.sum(voxel_timecourses, axis=1)), :] = 0
365-
366-
# from paper:
367-
# "The constant and linear trends of the columns in the matrix M were
368-
# removed [prior to ...]"
369-
degree = self.inputs.regress_poly_degree if self.inputs.use_regress_poly else 0
370-
voxel_timecourses = regress_poly(degree, voxel_timecourses)
371-
372-
# "Voxel time series from the noise ROI (either anatomical or tSTD) were
373-
# placed in a matrix M of size Nxm, with time along the row dimension
374-
# and voxels along the column dimension."
375-
M = voxel_timecourses.T
376-
377-
# "[... were removed] prior to column-wise variance normalization."
378-
M = M / self._compute_tSTD(M, 1.)
379-
380-
# "The covariance matrix C = MMT was constructed and decomposed into its
381-
# principal components using a singular value decomposition."
382-
u, _, _ = linalg.svd(M, full_matrices=False)
383-
components = u[:, :self.inputs.num_components]
354+
components = None
355+
356+
for mask_file in self.inputs.mask_file:
357+
mask = nb.load(mask_file, mmap=NUMPY_MMAP).get_data()
358+
359+
if imgseries.shape[:3] != mask.shape:
360+
raise ValueError('Inputs for CompCor, func {} and mask {}, do not have matching '
361+
'spatial dimensions ({} and {}, respectively)'
362+
.format(self.inputs.realigned_file, mask_file,
363+
imgseries.shape[:3], mask.shape))
364+
365+
voxel_timecourses = imgseries[mask > 0]
366+
# Zero-out any bad values
367+
voxel_timecourses[np.isnan(np.sum(voxel_timecourses, axis=1)), :] = 0
368+
369+
# from paper:
370+
# "The constant and linear trends of the columns in the matrix M were
371+
# removed [prior to ...]"
372+
degree = self.inputs.regress_poly_degree if self.inputs.use_regress_poly else 0
373+
voxel_timecourses = regress_poly(degree, voxel_timecourses)
374+
375+
# "Voxel time series from the noise ROI (either anatomical or tSTD) were
376+
# placed in a matrix M of size Nxm, with time along the row dimension
377+
# and voxels along the column dimension."
378+
M = voxel_timecourses.T
379+
380+
# "[... were removed] prior to column-wise variance normalization."
381+
M = M / self._compute_tSTD(M, 1.)
382+
383+
# "The covariance matrix C = MMT was constructed and decomposed into its
384+
# principal components using a singular value decomposition."
385+
u, _, _ = linalg.svd(M, full_matrices=False)
386+
if components is None:
387+
components = u[:, :self.inputs.num_components]
388+
else:
389+
components = np.hstack((components, u[:, :self.inputs.num_components]))
390+
384391
components_file = os.path.join(os.getcwd(), self.inputs.components_file)
385392

386393
self._set_header()

nipype/pipeline/plugins/slurm.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from ...interfaces.base import CommandLine
1616
from .base import (SGELikeBatchManagerBase, logger, iflogger, logging)
1717

18+
import subprocess
1819

1920

2021
class SLURMPlugin(SGELikeBatchManagerBase):
@@ -60,10 +61,11 @@ def __init__(self, **kwargs):
6061

6162
def _is_pending(self, taskid):
6263
# subprocess.Popen requires taskid to be a string
63-
res = CommandLine('squeue',
64-
args=' '.join(['-j', '%s' % taskid]),
65-
terminal_output='allatonce').run()
66-
return res.runtime.stdout.find(str(taskid)) > -1
64+
proc = subprocess.Popen(["squeue", '-j', '%s' % taskid],
65+
stdout=subprocess.PIPE,
66+
stderr=subprocess.PIPE)
67+
o, _ = proc.communicate()
68+
return o.find(str(taskid)) > -1
6769

6870
def _submit_batchtask(self, scriptfile, node):
6971
"""
@@ -127,3 +129,4 @@ def _submit_batchtask(self, scriptfile, node):
127129
self._pending[taskid] = node.output_dir()
128130
logger.debug('submitted sbatch task: %d for node %s' % (taskid, node._id))
129131
return taskid
132+

0 commit comments

Comments
 (0)