Skip to content

[FIX]: AFNI Allineate #2098

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
Sep 11, 2017
Merged
Show file tree
Hide file tree
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
95 changes: 59 additions & 36 deletions nipype/interfaces/afni/preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class AlignEpiAnatPyOutputSpec(TraitedSpec):
desc="matrix to volume register and align epi"
"to anatomy and put into standard space")
epi_vr_motion = File(
desc="motion parameters from EPI time-series"
desc="motion parameters from EPI time-series"
"registration (tsh included in name if slice"
"timing correction is also included).")
skullstrip = File(
Expand All @@ -131,20 +131,20 @@ class AlignEpiAnatPy(AFNIPythonCommand):
an EPI and an anatomical structural dataset, and applies the resulting
transformation to one or the other to bring them into alignment.

This script computes the transforms needed to align EPI and
anatomical datasets using a cost function designed for this purpose. The
script combines multiple transformations, thereby minimizing the amount of
This script computes the transforms needed to align EPI and
anatomical datasets using a cost function designed for this purpose. The
script combines multiple transformations, thereby minimizing the amount of
interpolation applied to the data.

Basic Usage:
align_epi_anat.py -anat anat+orig -epi epi+orig -epi_base 5

The user must provide EPI and anatomical datasets and specify the EPI
sub-brick to use as a base in the alignment.
sub-brick to use as a base in the alignment.

Internally, the script always aligns the anatomical to the EPI dataset,
and the resulting transformation is saved to a 1D file.
As a user option, the inverse of this transformation may be applied to the
and the resulting transformation is saved to a 1D file.
As a user option, the inverse of this transformation may be applied to the
EPI dataset in order to align it to the anatomical data instead.

This program generates several kinds of output in the form of datasets
Expand Down Expand Up @@ -182,7 +182,7 @@ def _list_outputs(self):
epi_prefix = ''.join(self._gen_fname(self.inputs.in_file).split('+')[:-1])
outputtype = self.inputs.outputtype
if outputtype == 'AFNI':
ext = '.HEAD'
ext = '.HEAD'
else:
Info.output_type_to_ext(outputtype)
matext = '.1D'
Expand Down Expand Up @@ -220,32 +220,37 @@ class AllineateInputSpec(AFNICommandInputSpec):
out_file = File(
desc='output file from 3dAllineate',
argstr='-prefix %s',
name_source='in_file',
name_template='%s_allineate',
genfile=True,
xor=['allcostx'])
out_param_file = File(
argstr='-1Dparam_save %s',
desc='Save the warp parameters in ASCII (.1D) format.')
desc='Save the warp parameters in ASCII (.1D) format.',
xor=['in_param_file','allcostx'])
in_param_file = File(
exists=True,
argstr='-1Dparam_apply %s',
desc='Read warp parameters from file and apply them to '
'the source dataset, and produce a new dataset')
'the source dataset, and produce a new dataset',
xor=['out_param_file'])
out_matrix = File(
argstr='-1Dmatrix_save %s',
desc='Save the transformation matrix for each volume.')
desc='Save the transformation matrix for each volume.',
xor=['in_matrix','allcostx'])
in_matrix = File(
desc='matrix to align input file',
argstr='-1Dmatrix_apply %s')
# TODO: implement sensible xors for allcostx and suppres prefix in command when allcosx is used
argstr='-1Dmatrix_apply %s',
position=-3,
xor=['out_matrix'])
overwrite = traits.Bool(
desc='overwrite output file if it already exists',
argstr='-overwrite')

allcostx= File(
desc='Compute and print ALL available cost functionals for the un-warped inputs'
'AND THEN QUIT. If you use this option none of the other expected outputs will be produced',
argstr='-allcostx |& tee %s',
position=-1,
xor=['out_file'])

xor=['out_file', 'out_matrix', 'out_param_file', 'out_weight_file'])
_cost_funcs = [
'leastsq', 'ls',
'mutualinfo', 'mi',
Expand Down Expand Up @@ -356,7 +361,8 @@ class AllineateInputSpec(AFNICommandInputSpec):
'Must be defined on the same grid as the base dataset')
out_weight_file = traits.File(
argstr='-wtprefix %s',
desc='Write the weight volume to disk as a dataset')
desc='Write the weight volume to disk as a dataset',
xor=['allcostx'])
source_mask = File(
exists=True,
argstr='-source_mask %s',
Expand Down Expand Up @@ -414,8 +420,10 @@ class AllineateInputSpec(AFNICommandInputSpec):


class AllineateOutputSpec(TraitedSpec):
out_file = File(desc='output image file name')
matrix = File(desc='matrix to align input file')
out_file = File(exists=True, desc='output image file name')
out_matrix = File(exists=True, desc='matrix to align input file')
out_param_file = File(exists=True, desc='warp parameters')
out_weight_file = File(exists=True, desc='weight volume')
allcostx = File(desc='Compute and print ALL available cost functionals for the un-warped inputs')


Expand All @@ -434,7 +442,7 @@ class Allineate(AFNICommand):
>>> allineate.inputs.out_file = 'functional_allineate.nii'
>>> allineate.inputs.in_matrix = 'cmatrix.mat'
>>> allineate.cmdline # doctest: +ALLOW_UNICODE
'3dAllineate -source functional.nii -1Dmatrix_apply cmatrix.mat -prefix functional_allineate.nii'
'3dAllineate -source functional.nii -prefix functional_allineate.nii -1Dmatrix_apply cmatrix.mat'
>>> res = allineate.run() # doctest: +SKIP

>>> from nipype.interfaces import afni
Expand All @@ -443,7 +451,7 @@ class Allineate(AFNICommand):
>>> allineate.inputs.reference = 'structural.nii'
>>> allineate.inputs.allcostx = 'out.allcostX.txt'
>>> allineate.cmdline # doctest: +ALLOW_UNICODE
'3dAllineate -source functional.nii -prefix functional_allineate -base structural.nii -allcostx |& tee out.allcostX.txt'
'3dAllineate -source functional.nii -base structural.nii -allcostx |& tee out.allcostX.txt'
>>> res = allineate.run() # doctest: +SKIP
"""

Expand All @@ -459,24 +467,38 @@ def _format_arg(self, name, trait_spec, value):

def _list_outputs(self):
outputs = self.output_spec().get()
if not isdefined(self.inputs.out_file):
outputs['out_file'] = self._gen_filename(self.inputs.in_file,
suffix=self.inputs.suffix)
else:
outputs['out_file'] = os.path.abspath(self.inputs.out_file)

if isdefined(self.inputs.out_matrix):
outputs['matrix'] = os.path.abspath(os.path.join(os.getcwd(),\
self.inputs.out_matrix +'.aff12.1D'))
if self.inputs.out_file:
outputs['out_file'] = op.abspath(self.inputs.out_file)

if self.inputs.out_weight_file:
outputs['out_weight_file'] = op.abspath(self.inputs.out_weight_file)

if self.inputs.out_matrix:
path, base, ext = split_filename(self.inputs.out_matrix)
if ext.lower() not in ['.1d', '.1D']:
outputs['out_matrix'] = self._gen_fname(self.inputs.out_matrix,
suffix='.aff12.1D')
else:
outputs['out_matrix'] = op.abspath(self.inputs.out_matrix)

if self.inputs.out_param_file:
path, base, ext = split_filename(self.inputs.out_param_file)
if ext.lower() not in ['.1d', '.1D']:
outputs['out_param_file'] = self._gen_fname(self.inputs.out_param_file,
suffix='.param.1D')
else:
outputs['out_param_file'] = op.abspath(self.inputs.out_param_file)

if isdefined(self.inputs.allcostX):
outputs['allcostX'] = os.path.abspath(os.path.join(os.getcwd(),\
if isdefined(self.inputs.allcostx):
outputs['allcostX'] = os.path.abspath(os.path.join(os.getcwd(),
self.inputs.allcostx))
return outputs

def _gen_filename(self, name):
if name == 'out_file':
return self._list_outputs()[name]
return None


class AutoTcorrelateInputSpec(AFNICommandInputSpec):
Expand Down Expand Up @@ -535,6 +557,7 @@ class AutoTcorrelate(AFNICommand):
'3dAutoTcorrelate -eta2 -mask mask.nii -mask_only_targets -prefix functional_similarity_matrix.1D -polort -1 functional.nii'
>>> res = corr.run() # doctest: +SKIP
"""

input_spec = AutoTcorrelateInputSpec
output_spec = AFNICommandOutputSpec
_cmd = '3dAutoTcorrelate'
Expand Down Expand Up @@ -620,7 +643,7 @@ class AutoTLRCInputSpec(CommandLineInputSpec):
mandatory=True,
exists=True,
copyfile=False)
base = traits.Str(
base = traits.Str(
desc = ' Reference anatomical volume'
' Usually this volume is in some standard space like'
' TLRC or MNI space and with afni dataset view of'
Expand Down Expand Up @@ -706,7 +729,7 @@ def _list_outputs(self):
ext = '.HEAD'
outputs['out_file'] = os.path.abspath(self._gen_fname(self.inputs.in_file, suffix='+tlrc')+ext)
return outputs

class BandpassInputSpec(AFNICommandInputSpec):
in_file = File(
desc='input file to 3dBandpass',
Expand Down
16 changes: 12 additions & 4 deletions nipype/interfaces/afni/tests/test_auto_Allineate.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
def test_Allineate_inputs():
input_map = dict(allcostx=dict(argstr='-allcostx |& tee %s',
position=-1,
xor=['out_file'],
xor=['out_file', 'out_matrix', 'out_param_file', 'out_weight_file'],
),
args=dict(argstr='%s',
),
Expand Down Expand Up @@ -41,8 +41,11 @@ def test_Allineate_inputs():
mandatory=True,
),
in_matrix=dict(argstr='-1Dmatrix_apply %s',
position=-3,
xor=['out_matrix'],
),
in_param_file=dict(argstr='-1Dparam_apply %s',
xor=['out_param_file'],
),
interpolation=dict(argstr='-interp %s',
),
Expand All @@ -66,17 +69,20 @@ def test_Allineate_inputs():
),
out_file=dict(argstr='-prefix %s',
genfile=True,
name_source='in_file',
name_template='%s_allineate',
xor=['allcostx'],
),
out_matrix=dict(argstr='-1Dmatrix_save %s',
xor=['in_matrix', 'allcostx'],
),
out_param_file=dict(argstr='-1Dparam_save %s',
xor=['in_param_file', 'allcostx'],
),
out_weight_file=dict(argstr='-wtprefix %s',
xor=['allcostx'],
),
outputtype=dict(),
overwrite=dict(argstr='-overwrite',
),
reference=dict(argstr='-base %s',
),
replacebase=dict(argstr='-replacebase',
Expand Down Expand Up @@ -117,8 +123,10 @@ def test_Allineate_inputs():

def test_Allineate_outputs():
output_map = dict(allcostx=dict(),
matrix=dict(),
out_file=dict(),
out_matrix=dict(),
out_param_file=dict(),
out_weight_file=dict(),
)
outputs = Allineate.output_spec()

Expand Down