Skip to content

Commit a30b2e6

Browse files
committed
Merge branch 'master' of github.com:nipy/nipype into enh/qwarp
2 parents 3f47b2e + a17af6b commit a30b2e6

File tree

7 files changed

+152
-7
lines changed

7 files changed

+152
-7
lines changed

examples/rsfmri_vol_surface_preprocessing_nipy.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666

6767
from nipype.algorithms.rapidart import ArtifactDetect
6868
from nipype.algorithms.misc import TSNR
69-
from nipype.algorithms.compcor import ACompCor
69+
from nipype.algorithms.confounds import ACompCor
7070
from nipype.interfaces.utility import Rename, Merge, IdentityInterface
7171
from nipype.utils.filemanip import filename_to_list
7272
from nipype.interfaces.io import DataSink, FreeSurferSource
@@ -75,7 +75,7 @@
7575
import numpy as np
7676
import scipy as sp
7777
import nibabel as nb
78-
from nipype.utils import NUMPY_MMAP
78+
from nipype.utils.config import NUMPY_MMAP
7979

8080
imports = ['import os',
8181
'import nibabel as nb',

nipype/algorithms/rapidart.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,8 @@ def _list_outputs(self):
330330
return outputs
331331

332332
def _plot_outliers_with_wave(self, wave, outliers, name):
333+
import matplotlib
334+
matplotlib.use(config.get("execution", "matplotlib_backend"))
333335
import matplotlib.pyplot as plt
334336
plt.plot(wave)
335337
plt.ylim([wave.min(), wave.max()])

nipype/interfaces/freesurfer/preprocess.py

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -630,8 +630,26 @@ class ReconAllInputSpec(CommandLineInputSpec):
630630
desc="Enable parallel execution")
631631
hires = traits.Bool(argstr="-hires", min_ver='6.0.0',
632632
desc="Conform to minimum voxel size (for voxels < 1mm)")
633+
mprage = traits.Bool(argstr='-mprage',
634+
desc=('Assume scan parameters are MGH MP-RAGE '
635+
'protocol, which produces darker gray matter'))
636+
big_ventricles = traits.Bool(argstr='-bigventricles',
637+
desc=('For use in subjects with enlarged '
638+
'ventricles'))
639+
brainstem = traits.Bool(argstr='-brainstem-structures',
640+
desc='Segment brainstem structures')
641+
hippocampal_subfields_T1 = traits.Bool(
642+
argstr='-hippocampal-subfields-T1', min_ver='6.0.0',
643+
desc='segment hippocampal subfields using input T1 scan')
644+
hippocampal_subfields_T2 = traits.Tuple(
645+
File(exists=True), traits.Str(),
646+
argstr='-hippocampal-subfields-T2 %s %s', min_ver='6.0.0',
647+
desc=('segment hippocampal subfields using T2 scan, identified by '
648+
'ID (may be combined with hippocampal_subfields_T1)'))
633649
expert = File(exists=True, argstr='-expert %s',
634650
desc="Set parameters using expert file")
651+
xopts = traits.Enum("use", "clean", "overwrite", argstr='-xopts-%s',
652+
desc="Use, delete or overwrite existing expert options file")
635653
subjects_dir = Directory(exists=True, argstr='-sd %s', hash_files=False,
636654
desc='path to subjects directory', genfile=True)
637655
flags = traits.Str(argstr='%s', desc='additional parameters')
@@ -933,6 +951,13 @@ def _format_arg(self, name, trait_spec, value):
933951
if name == 'T1_files':
934952
if self._is_resuming():
935953
return ''
954+
if name == 'hippocampal_subfields_T1' and \
955+
isdefined(self.inputs.hippocampal_subfields_T2):
956+
return ''
957+
if all((name == 'hippocampal_subfields_T2',
958+
isdefined(self.inputs.hippocampal_subfields_T1) and
959+
self.inputs.hippocampal_subfields_T1)):
960+
trait_spec.argstr = trait_spec.argstr.replace('T2', 'T1T2')
936961
return super(ReconAll, self)._format_arg(name, trait_spec, value)
937962

938963
@property
@@ -949,10 +974,22 @@ def cmdline(self):
949974
if not isdefined(subjects_dir):
950975
subjects_dir = self._gen_subjects_dir()
951976

977+
# Check only relevant steps
978+
directive = self.inputs.directive
979+
if not isdefined(directive):
980+
steps = []
981+
elif directive == 'autorecon1':
982+
steps = self._autorecon1_steps
983+
elif directive.startswith('autorecon2'):
984+
steps = self._autorecon2_steps
985+
elif directive == 'autorecon3':
986+
steps = self._autorecon3_steps
987+
else:
988+
steps = self._steps
989+
952990
no_run = True
953991
flags = []
954-
for idx, step in enumerate(self._steps):
955-
step, outfiles, infiles = step
992+
for step, outfiles, infiles in steps:
956993
flag = '-{}'.format(step)
957994
noflag = '-no{}'.format(step)
958995
if noflag in cmd:
@@ -989,11 +1026,30 @@ def _prep_expert_file(self):
9891026
if lines == []:
9901027
return ''
9911028

1029+
contents = ''.join(lines)
1030+
if not isdefined(self.inputs.xopts) and \
1031+
self.get_expert_file() == contents:
1032+
return ' -xopts-use'
1033+
9921034
expert_fname = os.path.abspath('expert.opts')
9931035
with open(expert_fname, 'w') as fobj:
994-
fobj.write(''.join(lines))
1036+
fobj.write(contents)
9951037
return ' -expert {}'.format(expert_fname)
9961038

1039+
def _get_expert_file(self):
1040+
# Read pre-existing options file, if it exists
1041+
if isdefined(self.inputs.subjects_dir):
1042+
subjects_dir = self.inputs.subjects_dir
1043+
else:
1044+
subjects_dir = self._gen_subjects_dir()
1045+
1046+
xopts_file = os.path.join(subjects_dir, self.inputs.subject_id,
1047+
'scripts', 'expert-options')
1048+
if not os.path.exists(xopts_file):
1049+
return ''
1050+
with open(xopts_file, 'r') as fobj:
1051+
return fobj.read()
1052+
9971053

9981054
class BBRegisterInputSpec(FSTraitedSpec):
9991055
subject_id = traits.Str(argstr='--s %s',

nipype/interfaces/freesurfer/tests/test_auto_ReconAll.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ def test_ReconAll_inputs():
1111
),
1212
args=dict(argstr='%s',
1313
),
14+
big_ventricles=dict(argstr='-bigventricles',
15+
),
16+
brainstem=dict(argstr='-brainstem-structures',
17+
),
1418
directive=dict(argstr='-%s',
1519
position=0,
1620
usedefault=True,
@@ -24,12 +28,20 @@ def test_ReconAll_inputs():
2428
),
2529
hemi=dict(argstr='-hemi %s',
2630
),
31+
hippocampal_subfields_T1=dict(argstr='-hippocampal-subfields-T1',
32+
min_ver='6.0.0',
33+
),
34+
hippocampal_subfields_T2=dict(argstr='-hippocampal-subfields-T2 %s %s',
35+
min_ver='6.0.0',
36+
),
2737
hires=dict(argstr='-hires',
2838
min_ver='6.0.0',
2939
),
3040
ignore_exception=dict(nohash=True,
3141
usedefault=True,
3242
),
43+
mprage=dict(argstr='-mprage',
44+
),
3345
mri_aparc2aseg=dict(xor=['expert'],
3446
),
3547
mri_ca_label=dict(xor=['expert'],
@@ -98,6 +110,8 @@ def test_ReconAll_inputs():
98110
use_T2=dict(argstr='-T2pial',
99111
min_ver='5.3.0',
100112
),
113+
xopts=dict(argstr='-xopts-%s',
114+
),
101115
)
102116
inputs = ReconAll.input_spec()
103117

nipype/interfaces/fsl/epi.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
from ..base import (traits, TraitedSpec, InputMultiPath, File,
2828
isdefined)
29-
from .base import FSLCommand, FSLCommandInputSpec
29+
from .base import FSLCommand, FSLCommandInputSpec, Info
3030

3131

3232
class PrepareFieldmapInputSpec(FSLCommandInputSpec):
@@ -140,6 +140,13 @@ class TOPUPInputSpec(FSLCommandInputSpec):
140140
out_field = File(argstr='--fout=%s', hash_files=False,
141141
name_source=['in_file'], name_template='%s_field',
142142
desc='name of image file with field (Hz)')
143+
out_warp_prefix = traits.Str("warpfield", argstr='--dfout=%s', hash_files=False,
144+
desc='prefix for the warpfield images (in mm)',
145+
usedefault=True)
146+
out_jac_prefix = traits.Str("jac", argstr='--jacout=%s',
147+
hash_files=False,
148+
desc='prefix for the warpfield images',
149+
usedefault=True)
143150
out_corrected = File(argstr='--iout=%s', hash_files=False,
144151
name_source=['in_file'], name_template='%s_corrected',
145152
desc='name of 4D image file with unwarped images')
@@ -212,6 +219,8 @@ class TOPUPOutputSpec(TraitedSpec):
212219
out_movpar = File(exists=True, desc='movpar.txt output file')
213220
out_enc_file = File(desc='encoding directions file output for applytopup')
214221
out_field = File(desc='name of image file with field (Hz)')
222+
out_warps = traits.List(File(exists=True), desc='warpfield images')
223+
out_jacs = traits.List(File(exists=True), desc='Jacobian images')
215224
out_corrected = File(desc='name of 4D image file with unwarped images')
216225
out_logfile = File(desc='name of log-file')
217226

@@ -237,7 +246,8 @@ class TOPUP(FSLCommand):
237246
>>> topup.cmdline # doctest: +ELLIPSIS +ALLOW_UNICODE
238247
'topup --config=b02b0.cnf --datain=topup_encoding.txt \
239248
--imain=b0_b0rev.nii --out=b0_b0rev_base --iout=b0_b0rev_corrected.nii.gz \
240-
--fout=b0_b0rev_field.nii.gz --logout=b0_b0rev_topup.log'
249+
--fout=b0_b0rev_field.nii.gz --jacout=jac --logout=b0_b0rev_topup.log \
250+
--dfout=warpfield'
241251
>>> res = topup.run() # doctest: +SKIP
242252
243253
"""
@@ -270,6 +280,16 @@ def _list_outputs(self):
270280
outputs['out_movpar'] = self._gen_fname(base, suffix='_movpar',
271281
ext='.txt', cwd=base_path)
272282

283+
n_vols = nb.load(self.inputs.in_file).shape[-1]
284+
ext = Info.output_type_to_ext(self.inputs.output_type)
285+
fmt = os.path.abspath('{prefix}_{i:02d}{ext}').format
286+
outputs['out_warps'] = [
287+
fmt(prefix=self.inputs.out_warp_prefix, i=i, ext=ext)
288+
for i in range(1, n_vols + 1)]
289+
outputs['out_jacs'] = [
290+
fmt(prefix=self.inputs.out_jac_prefix, i=i, ext=ext)
291+
for i in range(1, n_vols + 1)]
292+
273293
if isdefined(self.inputs.encoding_direction):
274294
outputs['out_enc_file'] = self._get_encfilename()
275295
return outputs
@@ -423,6 +443,32 @@ class EddyInputSpec(FSLCommandInputSpec):
423443
flm = traits.Enum('linear', 'quadratic', 'cubic', argstr='--flm=%s',
424444
desc='First level EC model')
425445

446+
slm = traits.Enum('none', 'linear', 'quadratic', argstr='--slm=%s',
447+
desc='Second level EC model')
448+
449+
fep = traits.Bool(False, argstr='--fep',
450+
desc='Fill empty planes in x- or y-directions')
451+
452+
interp = traits.Enum('spline', 'trilinear', argstr='--interp=%s',
453+
desc='Interpolation model for estimation step')
454+
455+
nvoxhp = traits.Int(1000, argstr='--nvoxhp=%s',
456+
desc=('# of voxels used to estimate the '
457+
'hyperparameters'))
458+
459+
fudge_factor = traits.Float(10.0, argstr='--ff=%s',
460+
desc=('Fudge factor for hyperparameter '
461+
'error variance'))
462+
463+
dont_sep_offs_move = traits.Bool(False, argstr='--dont_sep_offs_move',
464+
desc=('Do NOT attempt to separate '
465+
'field offset from subject '
466+
'movement'))
467+
468+
dont_peas = traits.Bool(False, argstr='--dont_peas',
469+
desc="Do NOT perform a post-eddy alignment of "
470+
"shells")
471+
426472
fwhm = traits.Float(desc=('FWHM for conditioning filter when estimating '
427473
'the parameters'), argstr='--fwhm=%s')
428474

nipype/interfaces/fsl/tests/test_auto_Eddy.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,23 @@
66
def test_Eddy_inputs():
77
input_map = dict(args=dict(argstr='%s',
88
),
9+
dont_peas=dict(argstr='--dont_peas',
10+
),
11+
dont_sep_offs_move=dict(argstr='--dont_sep_offs_move',
12+
),
913
environ=dict(nohash=True,
1014
usedefault=True,
1115
),
16+
fep=dict(argstr='--fep',
17+
),
1218
field=dict(argstr='--field=%s',
1319
),
1420
field_mat=dict(argstr='--field_mat=%s',
1521
),
1622
flm=dict(argstr='--flm=%s',
1723
),
24+
fudge_factor=dict(argstr='--ff=%s',
25+
),
1826
fwhm=dict(argstr='--fwhm=%s',
1927
),
2028
ignore_exception=dict(nohash=True,
@@ -43,6 +51,8 @@ def test_Eddy_inputs():
4351
),
4452
in_topup_movpar=dict(requires=['in_topup_fieldcoef'],
4553
),
54+
interp=dict(argstr='--interp=%s',
55+
),
4656
is_shelled=dict(argstr='--data_is_shelled',
4757
),
4858
method=dict(argstr='--resamp=%s',
@@ -52,6 +62,8 @@ def test_Eddy_inputs():
5262
num_threads=dict(nohash=True,
5363
usedefault=True,
5464
),
65+
nvoxhp=dict(argstr='--nvoxhp=%s',
66+
),
5567
out_base=dict(argstr='--out=%s',
5668
usedefault=True,
5769
),
@@ -60,6 +72,8 @@ def test_Eddy_inputs():
6072
),
6173
session=dict(argstr='--session=%s',
6274
),
75+
slm=dict(argstr='--slm=%s',
76+
),
6377
terminal_output=dict(nohash=True,
6478
),
6579
use_cuda=dict(),
@@ -74,6 +88,9 @@ def test_Eddy_inputs():
7488
def test_Eddy_outputs():
7589
output_map = dict(out_corrected=dict(),
7690
out_movement_rms=dict(),
91+
out_outlier_map=dict(),
92+
out_outlier_n_sd_map=dict(),
93+
out_outlier_n_sqr_sd_map=dict(),
7794
out_outlier_report=dict(),
7895
out_parameter=dict(),
7996
out_restricted_movement_rms=dict(),

nipype/interfaces/fsl/tests/test_auto_TOPUP.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ def test_TOPUP_inputs():
5454
name_source=['in_file'],
5555
name_template='%s_field',
5656
),
57+
out_warp_prefix=dict(argstr='--dfout=%s',
58+
hash_files=False,
59+
usedefault=True,
60+
),
61+
out_jac_prefix=dict(argstr='--jacout=%s',
62+
hash_files=False,
63+
usedefault=True,
64+
),
5765
out_logfile=dict(argstr='--logout=%s',
5866
hash_files=False,
5967
keep_extension=True,
@@ -98,6 +106,8 @@ def test_TOPUP_outputs():
98106
out_fieldcoef=dict(),
99107
out_logfile=dict(),
100108
out_movpar=dict(),
109+
out_warps=dict(),
110+
out_jacs=dict(),
101111
)
102112
outputs = TOPUP.output_spec()
103113

0 commit comments

Comments
 (0)