Skip to content

Commit 340b9a1

Browse files
committed
Merge pull request #540 from bpinsard/spm_interfaces
spm interface to apply inverse deformation
2 parents 388335b + 1fcf6d3 commit 340b9a1

File tree

2 files changed

+87
-5
lines changed

2 files changed

+87
-5
lines changed

nipype/interfaces/spm/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010
from .model import (Level1Design, EstimateModel, EstimateContrast, Threshold,
1111
OneSampleTTestDesign, TwoSampleTTestDesign,
1212
PairedTTestDesign, MultipleRegressionDesign)
13+
from .utils import Analyze2nii, CalcCoregAffine, ApplyTransform, Reslice, ApplyInverseDeformation
1314

14-
from .utils import Analyze2nii, CalcCoregAffine, ApplyTransform, Reslice

nipype/interfaces/spm/utils.py

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
22
# vi: set ft=python sts=4 ts=4 sw=4 et:
3-
from nipype.interfaces.spm.base import SPMCommandInputSpec, SPMCommand, Info
3+
from nipype.interfaces.spm.base import SPMCommandInputSpec, SPMCommand, Info, scans_for_fnames, scans_for_fname
44
from nipype.interfaces.matlab import MatlabCommand
5-
from nipype.interfaces.base import (TraitedSpec, BaseInterface,
6-
BaseInterfaceInputSpec, isdefined)
5+
from nipype.interfaces.base import (TraitedSpec, BaseInterface,
6+
BaseInterfaceInputSpec, isdefined,
7+
OutputMultiPath, InputMultiPath)
78
from nipype.interfaces.base import File, traits
8-
from nipype.utils.filemanip import split_filename, fname_presuffix
9+
from nipype.utils.filemanip import split_filename, fname_presuffix, filename_to_list,list_to_filename
910
import os
11+
import numpy as np
1012

1113
class Analyze2niiInputSpec(SPMCommandInputSpec):
1214
analyze_file = File(exists=True, mandatory=True)
@@ -206,3 +208,83 @@ def _list_outputs(self):
206208
outputs['out_file'] = os.path.abspath(self.inputs.out_file)
207209
return outputs
208210

211+
class ApplyInverseDeformationInput(SPMCommandInputSpec):
212+
in_files = InputMultiPath(
213+
File(exists=True), mandatory=True, field='fnames',
214+
desc='Files on which deformation is applied')
215+
target = File(
216+
exists=True,
217+
field='comp{1}.inv.space',
218+
desc='File defining target space')
219+
deformation = File(
220+
exists=True,
221+
field='comp{1}.inv.comp{1}.sn2def.matname',
222+
desc='SN SPM deformation file',
223+
xor=['deformation_field'])
224+
deformation_field = File(
225+
exists=True,
226+
field='comp{1}.inv.comp{1}.def',
227+
desc='SN SPM deformation file',
228+
xor=['deformation'])
229+
interpolation = traits.Range(
230+
low=0, hign=7, field='interp',
231+
desc='degree of b-spline used for interpolation')
232+
233+
bounding_box = traits.List(
234+
traits.Float(),
235+
field='comp{1}.inv.comp{1}.sn2def.bb',
236+
minlen=6, maxlen=6,
237+
desc='6-element list (opt)')
238+
voxel_sizes = traits.List(
239+
traits.Float(),
240+
field='comp{1}.inv.comp{1}.sn2def.vox',
241+
minlen=3, maxlen=3,
242+
desc='3-element list (opt)')
243+
244+
245+
class ApplyInverseDeformationOutput(TraitedSpec):
246+
out_files = OutputMultiPath(File(exists=True),
247+
desc='Transformed files')
248+
249+
250+
class ApplyInverseDeformation(SPMCommand):
251+
""" Uses spm to apply inverse deformation stored in a .mat file or a
252+
deformation field to a given file
253+
254+
Examples
255+
--------
256+
257+
>>> import nipype.interfaces.spm.utils as spmu
258+
>>> inv = spmu.ApplyInverseDeformation()
259+
>>> inv.inputs.in_files = 'functional.nii'
260+
>>> inv.inputs.deformation = 'struct_to_func.mat'
261+
>>> inv.inputs.target = 'structural.nii'
262+
>>> inv.run() # doctest: +SKIP
263+
"""
264+
265+
input_spec = ApplyInverseDeformationInput
266+
output_spec = ApplyInverseDeformationOutput
267+
268+
_jobtype = 'util'
269+
_jobname = 'defs'
270+
271+
def _format_arg(self, opt, spec, val):
272+
"""Convert input to appropriate format for spm
273+
"""
274+
if opt == 'in_files':
275+
return scans_for_fnames(filename_to_list(val))
276+
if opt == 'target':
277+
return scans_for_fname(filename_to_list(val))
278+
if opt == 'deformation':
279+
return np.array([list_to_filename(val)], dtype=object)
280+
if opt == 'deformation_field':
281+
return np.array([list_to_filename(val)], dtype=object)
282+
return val
283+
284+
def _list_outputs(self):
285+
outputs = self._outputs().get()
286+
outputs['out_files'] = []
287+
for filename in self.inputs.in_files:
288+
_, fname = os.path.split(filename)
289+
outputs['out_files'].append(os.path.realpath('w%s' % fname))
290+
return outputs

0 commit comments

Comments
 (0)