Skip to content

Commit 10f3366

Browse files
committed
Merge branch 'master' into enh/MRTrix3
2 parents 432e0f6 + 7f160b0 commit 10f3366

File tree

14 files changed

+193
-92
lines changed

14 files changed

+193
-92
lines changed

CHANGES

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ Next release
5555
* FIX: typo in nipype.interfaces.freesurfer.utils.py Tkregister2 (https://github.com/nipy/nipype/pull/1083)
5656
* FIX: SSHDataGrabber outputs now return full path to the grabbed/downloaded files. (https://github.com/nipy/nipype/pull/1086)
5757
* FIX: Add QA output for TSNR to resting workflow (https://github.com/nipy/nipype/pull/1088)
58+
* FIX: Change N4BiasFieldCorrection to use short tag for dimensionality (backward compatible) (https://github.com/nipy/nipype/pull/1096)
59+
* ENH: Added -newgrid input to Warp in AFNI (3dWarp wrapper) (https://github.com/nipy/nipype/pull/1128)
60+
* FIX: Fixed AFNI Copy interface to use positional inputs as required (https://github.com/nipy/nipype/pull/1131)
61+
* ENH: Added a check in Dcm2nii to check if nipype created the config.ini file and remove if true (https://github.com/nipy/nipype/pull/1132)
62+
* ENH: Use a while loop to wait for Xvfb (up to a max wait time "xvfb_max_wait" in config file, default 10)
63+
(https://github.com/nipy/nipype/pull/1142)
5864

5965
Release 0.10.0 (October 10, 2014)
6066
============

doc/users/config_file.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ Execution
125125
all pending jobs and checking for job completion. To be nice to cluster
126126
schedulers the default is set to 60 seconds.
127127

128+
*xvfb_max_wait*
129+
Maximum time (in seconds) to wait for Xvfb to start, if the _redirect_x parameter of an Interface is True.
130+
128131
Example
129132
~~~~~~~
130133

examples/fmri_ants_openfmri.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ def create_reg_workflow(name='registration'):
124124
'transformed_files',
125125
'transformed_mean',
126126
'anat2target',
127+
'mean2anat_mask'
127128
]),
128129
name='outputspec')
129130

@@ -171,6 +172,13 @@ def create_reg_workflow(name='registration'):
171172
register.connect(mean2anat, 'out_matrix_file',
172173
mean2anatbbr, 'in_matrix_file')
173174

175+
"""
176+
Create a mask of the median image coregistered to the anatomical image
177+
"""
178+
179+
mean2anat_mask = Node(fsl.BET(mask=True), name='mean2anat_mask')
180+
register.connect(mean2anatbbr, 'out_file', mean2anat_mask, 'in_file')
181+
174182
"""
175183
Convert the BBRegister transformation to ANTS ITK format
176184
"""
@@ -276,6 +284,8 @@ def create_reg_workflow(name='registration'):
276284
register.connect(warpall, 'output_image', outputnode, 'transformed_files')
277285
register.connect(mean2anatbbr, 'out_matrix_file',
278286
outputnode, 'func2anat_transform')
287+
register.connect(mean2anat_mask, 'mask_file',
288+
outputnode, 'mean2anat_mask')
279289
register.connect(reg, 'composite_transform',
280290
outputnode, 'anat2target_transform')
281291

@@ -333,7 +343,8 @@ def create_fs_reg_workflow(name='registration'):
333343
'transformed_files',
334344
'min_cost_file',
335345
'anat2target',
336-
'aparc'
346+
'aparc',
347+
'mean2anat_mask'
337348
]),
338349
name='outputspec')
339350

@@ -349,7 +360,7 @@ def create_fs_reg_workflow(name='registration'):
349360
register.connect(fssource, 'T1', convert, 'in_file')
350361

351362
# Coregister the median to the surface
352-
bbregister = Node(freesurfer.BBRegister(),
363+
bbregister = Node(freesurfer.BBRegister(registered_file=True),
353364
name='bbregister')
354365
bbregister.inputs.init = 'fsl'
355366
bbregister.inputs.contrast_type = 't2'
@@ -359,6 +370,10 @@ def create_fs_reg_workflow(name='registration'):
359370
register.connect(inputnode, 'mean_image', bbregister, 'source_file')
360371
register.connect(inputnode, 'subjects_dir', bbregister, 'subjects_dir')
361372

373+
# Create a mask of the median coregistered to the anatomical image
374+
mean2anat_mask = Node(fsl.BET(mask=True), name='mean2anat_mask')
375+
register.connect(bbregister, 'registered_file', mean2anat_mask, 'in_file')
376+
362377
"""
363378
use aparc+aseg's brain mask
364379
"""
@@ -500,6 +515,8 @@ def create_fs_reg_workflow(name='registration'):
500515
outputnode, 'out_reg_file')
501516
register.connect(bbregister, 'min_cost_file',
502517
outputnode, 'min_cost_file')
518+
register.connect(mean2anat_mask, 'mask_file',
519+
outputnode, 'mean2anat_mask')
503520
register.connect(reg, 'composite_transform',
504521
outputnode, 'anat2target_transform')
505522
register.connect(merge, 'out', outputnode, 'transforms')
@@ -964,6 +981,8 @@ def get_subs(subject_id, conds, run_id, model_id, task_id):
964981
subs.append(('/model%03d/task%03d_' % (model_id, task_id), '/'))
965982
subs.append(('_bold_dtype_mcf_bet_thresh_dil', '_mask'))
966983
subs.append(('_output_warped_image', '_anat2target'))
984+
subs.append(('median_flirt_brain_mask', 'median_brain_mask'))
985+
subs.append(('median_bbreg_brain_mask', 'median_brain_mask'))
967986
return subs
968987

969988
subsgen = pe.Node(niu.Function(input_names=['subject_id', 'conds', 'run_id',
@@ -998,6 +1017,7 @@ def get_subs(subject_id, conds, run_id, model_id, task_id):
9981017
('outputspec.motion_plots',
9991018
'qa.motion.plots'),
10001019
('outputspec.mask', 'qa.mask')])])
1020+
wf.connect(registration, 'outputspec.mean2anat_mask', datasink, 'qa.mask.mean2anat')
10011021
wf.connect(art, 'norm_files', datasink, 'qa.art.@norm')
10021022
wf.connect(art, 'intensity_files', datasink, 'qa.art.@intensity')
10031023
wf.connect(art, 'outlier_files', datasink, 'qa.art.@outlier_files')

nipype/interfaces/afni/preprocess.py

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ class WarpInputSpec(AFNICommandInputSpec):
233233
argstr="-gridset %s",
234234
exists=True)
235235

236+
newgrid = traits.Float(desc="specify grid of this size (mm)",
237+
argstr="-newgrid %f")
238+
236239
zpad = traits.Int(desc="pad input dataset with N planes" +
237240
" of zero on all sides.",
238241
argstr="-zpad %d")
@@ -254,7 +257,13 @@ class Warp(AFNICommand):
254257
>>> warp.inputs.out_file = "trans.nii.gz"
255258
>>> warp.cmdline
256259
'3dWarp -deoblique -prefix trans.nii.gz structural.nii'
257-
>>> res = warp.run() # doctest: +SKIP
260+
261+
>>> warp_2 = afni.Warp()
262+
>>> warp_2.inputs.in_file = 'structural.nii'
263+
>>> warp_2.inputs.newgrid = 1.0
264+
>>> warp_2.inputs.out_file = "trans.nii.gz"
265+
>>> warp_2.cmdline
266+
'3dWarp -newgrid 1.000000 -prefix trans.nii.gz structural.nii'
258267
259268
"""
260269

@@ -667,7 +676,7 @@ class CopyInputSpec(AFNICommandInputSpec):
667676
exists=True,
668677
copyfile=False)
669678
out_file = File(name_template="%s_copy", desc='output image file name',
670-
argstr='-prefix %s', name_source="in_file")
679+
argstr='%s', position=-1, name_source="in_file")
671680

672681

673682
class Copy(AFNICommand):
@@ -681,11 +690,26 @@ class Copy(AFNICommand):
681690
========
682691
683692
>>> from nipype.interfaces import afni as afni
684-
>>> copy = afni.Copy()
685-
>>> copy.inputs.in_file = 'functional.nii'
686-
>>> copy.inputs.out_file = 'new_func.nii'
687-
>>> res = copy.run() # doctest: +SKIP
688-
693+
>>> copy3d = afni.Copy()
694+
>>> copy3d.inputs.in_file = 'functional.nii'
695+
>>> copy3d.cmdline
696+
'3dcopy functional.nii functional_copy'
697+
698+
>>> from copy import deepcopy
699+
>>> copy3d_2 = deepcopy(copy3d)
700+
>>> copy3d_2.inputs.outputtype = 'NIFTI'
701+
>>> copy3d_2.cmdline
702+
'3dcopy functional.nii functional_copy.nii'
703+
704+
>>> copy3d_3 = deepcopy(copy3d)
705+
>>> copy3d_3.inputs.outputtype = 'NIFTI_GZ'
706+
>>> copy3d_3.cmdline
707+
'3dcopy functional.nii functional_copy.nii.gz'
708+
709+
>>> copy3d_4 = deepcopy(copy3d)
710+
>>> copy3d_4.inputs.out_file = 'new_func.nii'
711+
>>> copy3d_4.cmdline
712+
'3dcopy functional.nii new_func.nii'
689713
"""
690714

691715
_cmd = '3dcopy'

nipype/interfaces/afni/tests/test_auto_Copy.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ def test_Copy_inputs():
1616
mandatory=True,
1717
position=-2,
1818
),
19-
out_file=dict(argstr='-prefix %s',
19+
out_file=dict(argstr='%s',
2020
name_source='in_file',
2121
name_template='%s_copy',
22+
position=-1,
2223
),
2324
outputtype=dict(),
2425
terminal_output=dict(nohash=True,

nipype/interfaces/afni/tests/test_auto_Warp.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ def test_Warp_inputs():
2626
),
2727
mni2tta=dict(argstr='-mni2tta',
2828
),
29+
newgrid=dict(argstr='-newgrid %f',
30+
),
2931
out_file=dict(argstr='-prefix %s',
3032
name_source='in_file',
3133
name_template='%s_warp',

nipype/interfaces/ants/segmentation.py

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ def _list_outputs(self):
223223

224224

225225
class N4BiasFieldCorrectionInputSpec(ANTSCommandInputSpec):
226-
dimension = traits.Enum(3, 2, argstr='--image-dimension %d',
226+
dimension = traits.Enum(3, 2, argstr='-d %d',
227227
usedefault=True,
228228
desc='image dimension (2 or 3)')
229229
input_image = File(argstr='--input-image %s', mandatory=True,
@@ -237,8 +237,7 @@ class N4BiasFieldCorrectionInputSpec(ANTSCommandInputSpec):
237237
bspline_fitting_distance = traits.Float(argstr="--bspline-fitting %s")
238238
bspline_order = traits.Int(requires=['bspline_fitting_distance'])
239239
shrink_factor = traits.Int(argstr="--shrink-factor %d")
240-
n_iterations = traits.List(traits.Int(), argstr="--convergence %s",
241-
requires=['convergence_threshold'])
240+
n_iterations = traits.List(traits.Int(), argstr="--convergence %s")
242241
convergence_threshold = traits.Float(requires=['n_iterations'])
243242
save_bias = traits.Bool(False, mandatory=True, usedefault=True,
244243
desc=('True if the estimated bias should be saved'
@@ -277,26 +276,33 @@ class N4BiasFieldCorrection(ANTSCommand):
277276
>>> n4.inputs.bspline_fitting_distance = 300
278277
>>> n4.inputs.shrink_factor = 3
279278
>>> n4.inputs.n_iterations = [50,50,30,20]
280-
>>> n4.inputs.convergence_threshold = 1e-6
281279
>>> n4.cmdline
282280
'N4BiasFieldCorrection --bspline-fitting [ 300 ] \
283-
--image-dimension 3 --input-image structural.nii \
284-
--convergence [ 50x50x30x20, 1e-06 ] --output structural_corrected.nii \
281+
-d 3 --input-image structural.nii \
282+
--convergence [ 50x50x30x20 ] --output structural_corrected.nii \
285283
--shrink-factor 3'
286284
287285
>>> n4_2 = copy.deepcopy(n4)
288-
>>> n4_2.inputs.bspline_order = 5
286+
>>> n4_2.inputs.convergence_threshold = 1e-6
289287
>>> n4_2.cmdline
290-
'N4BiasFieldCorrection --bspline-fitting [ 300, 5 ] \
291-
--image-dimension 3 --input-image structural.nii \
288+
'N4BiasFieldCorrection --bspline-fitting [ 300 ] \
289+
-d 3 --input-image structural.nii \
292290
--convergence [ 50x50x30x20, 1e-06 ] --output structural_corrected.nii \
293291
--shrink-factor 3'
294292
295-
>>> n4_3 = N4BiasFieldCorrection()
296-
>>> n4_3.inputs.input_image = 'structural.nii'
297-
>>> n4_3.inputs.save_bias = True
293+
>>> n4_3 = copy.deepcopy(n4_2)
294+
>>> n4_3.inputs.bspline_order = 5
298295
>>> n4_3.cmdline
299-
'N4BiasFieldCorrection --image-dimension 3 --input-image structural.nii \
296+
'N4BiasFieldCorrection --bspline-fitting [ 300, 5 ] \
297+
-d 3 --input-image structural.nii \
298+
--convergence [ 50x50x30x20, 1e-06 ] --output structural_corrected.nii \
299+
--shrink-factor 3'
300+
301+
>>> n4_4 = N4BiasFieldCorrection()
302+
>>> n4_4.inputs.input_image = 'structural.nii'
303+
>>> n4_4.inputs.save_bias = True
304+
>>> n4_4.cmdline
305+
'N4BiasFieldCorrection -d 3 --input-image structural.nii \
300306
--output [ structural_corrected.nii, structural_bias.nii ]'
301307
"""
302308

@@ -335,10 +341,12 @@ def _format_arg(self, name, trait_spec, value):
335341
newval = '[ %g ]' % value
336342
return trait_spec.argstr % newval
337343

338-
if ((name == 'n_iterations') and
339-
(isdefined(self.inputs.convergence_threshold))):
340-
newval = '[ %s, %g ]' % ('x'.join([str(elt) for elt in value]),
341-
self.inputs.convergence_threshold)
344+
if name == 'n_iterations':
345+
if isdefined(self.inputs.convergence_threshold):
346+
newval = '[ %s, %g ]' % ('x'.join([str(elt) for elt in value]),
347+
self.inputs.convergence_threshold)
348+
else:
349+
newval = '[ %s ]' % 'x'.join([str(elt) for elt in value])
342350
return trait_spec.argstr % newval
343351

344352
return super(N4BiasFieldCorrection,

nipype/interfaces/ants/tests/test_auto_N4BiasFieldCorrection.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def test_N4BiasFieldCorrection_inputs():
1313
),
1414
convergence_threshold=dict(requires=['n_iterations'],
1515
),
16-
dimension=dict(argstr='--image-dimension %d',
16+
dimension=dict(argstr='-d %d',
1717
usedefault=True,
1818
),
1919
environ=dict(nohash=True,
@@ -28,7 +28,6 @@ def test_N4BiasFieldCorrection_inputs():
2828
mask_image=dict(argstr='--mask-image %s',
2929
),
3030
n_iterations=dict(argstr='--convergence %s',
31-
requires=['convergence_threshold'],
3231
),
3332
num_threads=dict(nohash=True,
3433
usedefault=True,

nipype/interfaces/base.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -994,9 +994,13 @@ def run(self, **inputs):
994994
xvfb_proc = subprocess.Popen(xvfb_cmd,
995995
stdout=open(os.devnull),
996996
stderr=open(os.devnull))
997-
time.sleep(0.2) # give Xvfb time to start
998-
if xvfb_proc.poll() is not None:
999-
raise Exception('Error: Xvfb did not start')
997+
wait_step = 0.2
998+
wait_time = 0
999+
while xvfb_proc.poll() is not None:
1000+
if wait_time > config.get('execution', 'xvfb_max_wait'):
1001+
raise Exception('Error: Xvfb did not start')
1002+
time.sleep(wait_step) # give Xvfb time to start
1003+
wait_time += wait_step
10001004

10011005
runtime.environ['DISPLAY'] = ':%s' % vdisplay_num
10021006

0 commit comments

Comments
 (0)