Skip to content

FIX: Select Eddy command at runtime #1871

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 22, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 53 additions & 32 deletions nipype/interfaces/fsl/epi.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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):
Expand All @@ -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

"""
Expand All @@ -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
Expand All @@ -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':
Expand All @@ -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)

Expand All @@ -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

Expand Down