diff --git a/nipype/interfaces/fsl/epi.py b/nipype/interfaces/fsl/epi.py index 2a54ec14b4..2b45d62c2d 100644 --- a/nipype/interfaces/fsl/epi.py +++ b/nipype/interfaces/fsl/epi.py @@ -12,7 +12,8 @@ ... '../../testing/data')) >>> os.chdir(datadir) """ -from __future__ import print_function, division, unicode_literals, absolute_import +from __future__ import print_function, division, unicode_literals, \ + absolute_import from builtins import str import os @@ -106,7 +107,7 @@ def _run_interface(self, runtime): out_file = self.inputs.out_fieldmap im = nb.load(out_file, mmap=NUMPY_MMAP) dumb_img = nb.Nifti1Image(np.zeros(im.shape), im.affine, - im.header) + im.header) out_nii = nb.funcs.concat_images((im, dumb_img)) nb.save(out_nii, out_file) @@ -450,26 +451,25 @@ class EddyInputSpec(FSLCommandInputSpec): class EddyOutputSpec(TraitedSpec): - out_corrected = File(exists=True, - desc=('4D image file containing all the corrected ' - 'volumes')) - out_parameter = File(exists=True, - desc=('text file with parameters definining the ' - 'field and movement for each scan')) - out_rotated_bvecs = File(exists=True, - desc=('File containing rotated b-values for all volumes')) - out_movement_rms = File(exists=True, - desc=('Summary of the "total movement" in each volume')) - out_restricted_movement_rms = File(exists=True, - desc=('Summary of the "total movement" in each volume ' - 'disregarding translation in the PE direction')) - out_shell_alignment_parameters = File(exists=True, - desc=('File containing rigid body movement parameters ' - 'between the different shells as estimated by a ' - 'post-hoc mutual information based registration')) - out_outlier_report = File(exists=True, - desc=('Text-file with a plain language report ' - 'on what outlier slices eddy has found')) + out_corrected = File( + exists=True, desc='4D image file containing all the corrected volumes') + out_parameter = File( + exists=True, desc=('text file with parameters definining the field and' + 'movement for each scan')) + out_rotated_bvecs = File( + exists=True, desc='File containing rotated b-values for all volumes') + out_movement_rms = File( + exists=True, desc='Summary of the "total movement" in each volume') + out_restricted_movement_rms = File( + exists=True, desc=('Summary of the "total movement" in each volume ' + 'disregarding translation in the PE direction')) + out_shell_alignment_parameters = File( + exists=True, desc=('File containing rigid body movement parameters ' + 'between the different shells as estimated by a ' + 'post-hoc mutual information based registration')) + out_outlier_report = File( + exists=True, desc=('Text-file with a plain language report on what ' + 'outlier slices eddy has found')) class Eddy(FSLCommand): @@ -491,10 +491,16 @@ class Eddy(FSLCommand): >>> eddy.inputs.in_acqp = 'epi_acqp.txt' >>> eddy.inputs.in_bvec = 'bvecs.scheme' >>> eddy.inputs.in_bval = 'bvals.scheme' + >>> eddy.inputs.use_cuda = True >>> eddy.cmdline # doctest: +ELLIPSIS +ALLOW_UNICODE - 'eddy_openmp --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme \ + 'eddy_cuda --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme \ --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii \ --out=.../eddy_corrected' + >>> eddy.inputs.use_cuda = False + >>> eddy.cmdline # doctest: +ELLIPSIS +ALLOW_UNICODE + 'eddy_openmp --acqp=epi_acqp.txt --bvals=bvals.scheme \ +--bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt \ +--mask=epi_mask.nii --out=.../eddy_corrected' >>> res = eddy.run() # doctest: +SKIP """ @@ -507,12 +513,13 @@ class Eddy(FSLCommand): def __init__(self, **inputs): super(Eddy, self).__init__(**inputs) self.inputs.on_trait_change(self._num_threads_update, 'num_threads') - if isdefined(self.inputs.use_cuda): - self._use_cuda() if not isdefined(self.inputs.num_threads): self.inputs.num_threads = self._num_threads else: self._num_threads_update() + self.inputs.on_trait_change(self._use_cuda, 'use_cuda') + if isdefined(self.inputs.use_cuda): + self._use_cuda() def _num_threads_update(self): self._num_threads = self.inputs.num_threads @@ -524,10 +531,21 @@ def _num_threads_update(self): self.inputs.num_threads) def _use_cuda(self): - if self.inputs.use_cuda: - _cmd = 'eddy_cuda' - else: - _cmd = 'eddy_openmp' + self._cmd = 'eddy_cuda' if self.inputs.use_cuda else 'eddy_openmp' + + def _run_interface(self, runtime): + # If 'eddy_openmp' is missing, use 'eddy' + FSLDIR = os.getenv('FSLDIR', '') + cmd = self._cmd + if all((FSLDIR != '', + cmd == 'eddy_openmp', + not os.path.exists(os.path.join(FSLDIR, cmd)))): + self._cmd = 'eddy' + runtime = super(Eddy, self)._run_interface(runtime) + + # Restore command to avoid side-effects + self._cmd = cmd + return runtime def _format_arg(self, name, spec, value): if name == 'in_topup_fieldcoef': @@ -551,7 +569,8 @@ def _list_outputs(self): out_restricted_movement_rms = os.path.abspath( '%s.eddy_restricted_movement_rms' % self.inputs.out_base) out_shell_alignment_parameters = os.path.abspath( - '%s.eddy_post_eddy_shell_alignment_parameters' % self.inputs.out_base) + '%s.eddy_post_eddy_shell_alignment_parameters' + % self.inputs.out_base) out_outlier_report = os.path.abspath( '%s.eddy_outlier_report' % self.inputs.out_base) @@ -560,9 +579,11 @@ def _list_outputs(self): if os.path.exists(out_movement_rms): outputs['out_movement_rms'] = out_movement_rms if os.path.exists(out_restricted_movement_rms): - outputs['out_restricted_movement_rms'] = out_restricted_movement_rms + outputs['out_restricted_movement_rms'] = \ + out_restricted_movement_rms if os.path.exists(out_shell_alignment_parameters): - outputs['out_shell_alignment_parameters'] = out_shell_alignment_parameters + outputs['out_shell_alignment_parameters'] = \ + out_shell_alignment_parameters if os.path.exists(out_outlier_report): outputs['out_outlier_report'] = out_outlier_report