Skip to content

Commit 4abb15c

Browse files
committed
make new nipype interface
1 parent 27b824f commit 4abb15c

File tree

4 files changed

+48
-52
lines changed

4 files changed

+48
-52
lines changed

fmriprep/interfaces/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
from .utils import TPM2ROI, AddTPMs, AddTSVHeader, ConcatAffines, JoinTSVColumns
1717
from .fmap import FieldEnhance, FieldToRadS, FieldToHz, Phasediff2Fieldmap
1818
from .confounds import GatherConfounds, ICAConfounds, FMRISummary
19-
from .itk import MCFLIRT2ITK, MultiApplyTransforms
19+
from .itk import MCFLIRT2ITK, Volreg2ITK, MultiApplyTransforms
2020
from .multiecho import FirstEcho

fmriprep/interfaces/itk.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
1010
"""
1111
import os
12+
from pathlib import Path
1213
from mimetypes import guess_type
1314
from tempfile import TemporaryDirectory
1415
import numpy as np
@@ -78,6 +79,49 @@ def _run_interface(self, runtime):
7879
return runtime
7980

8081

82+
class Volreg2ITKInputSpec(BaseInterfaceInputSpec):
83+
in_file = File(exists=True, mandatory=True,
84+
desc='mat file generated by AFNI\'s 3dVolreg')
85+
86+
87+
class Volreg2ITKOutputSpec(TraitedSpec):
88+
out_file = File(desc='the output ITKTransform file')
89+
90+
91+
class Volreg2ITK(SimpleInterface):
92+
93+
"""
94+
Convert an AFNI's mat file into an ITK Transform file.
95+
"""
96+
input_spec = Volreg2ITKInputSpec
97+
output_spec = Volreg2ITKOutputSpec
98+
99+
def _run_interface(self, runtime):
100+
# Load AFNI mat entries and append (0, 0, 0, 1) for homogeneous coordinates
101+
orig_afni_mat = np.loadtxt(self.inputs.in_file)
102+
afni_affines = [np.vstack((orig_afni_mat[i, :].reshape(3, 4, order='C'), [0, 0, 0, 1]))
103+
for i in range(orig_afni_mat.shape[0])]
104+
105+
out_file = Path(fname_presuffix(self.inputs.in_file,
106+
suffix='_mc4d_itk.txt', newpath=runtime.cwd))
107+
108+
fixed_params = 'FixedParameters: 0 0 0' # Center of rotation does not change
109+
lines = ["#Insight Transform File V1.0"]
110+
for i, affine in enumerate(afni_affines):
111+
lines.append("#Transform %d" % i)
112+
lines.append("Transform: AffineTransform_double_3_3")
113+
114+
ants_affine_2d = np.hstack((affine[:3, :3].reshape(1, -1), affine[:3, 3].reshape(1, -1)))
115+
params = ants_affine_2d.reshape(-1, 1).astype('float64')
116+
params_list = ["%g" % i for i in params.tolist()]
117+
lines.append("Parameters: %s" % ' '.join(params_list))
118+
lines.append(fixed_params)
119+
120+
out_file.write_text('\n'.join(lines))
121+
self._results['out_file'] = str(out_file)
122+
return runtime
123+
124+
81125
class MultiApplyTransformsInputSpec(ApplyTransformsInputSpec):
82126
input_image = InputMultiPath(File(exists=True), mandatory=True,
83127
desc='input time-series as a list of volumes after splitting'

fmriprep/utils/misc.py

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -29,49 +29,6 @@ def split_and_rm_rotshear_func(in_file):
2929
return out_files
3030

3131

32-
def afni2itk_func(in_file):
33-
import os
34-
from numpy import loadtxt, hstack, vstack, zeros, float64
35-
36-
def read_afni_affine(input_file, debug=False):
37-
orig_afni_mat = loadtxt(input_file)
38-
if debug:
39-
print(orig_afni_mat)
40-
41-
output = []
42-
for i in range(orig_afni_mat.shape[0]):
43-
output.append(vstack((orig_afni_mat[i, :].reshape(3, 4, order='C'), [0, 0, 0, 1])))
44-
return output
45-
46-
def get_ants_dict(affine, debug=False):
47-
out_dict = {}
48-
ants_affine_2d = hstack((affine[:3, :3].reshape(1, -1), affine[:3, 3].reshape(1, -1)))
49-
out_dict['AffineTransform_double_3_3'] = ants_affine_2d.reshape(-1, 1).astype(float64)
50-
out_dict['fixed'] = zeros((3, 1))
51-
if debug:
52-
print(out_dict)
53-
54-
return out_dict
55-
56-
out_file = os.path.abspath('mc4d.txt')
57-
with open(out_file, 'w') as fp:
58-
fp.write("#Insight Transform File V1.0\n")
59-
for i, affine in enumerate(read_afni_affine(in_file)):
60-
fp.write("#Transform %d\n" % i)
61-
fp.write("Transform: AffineTransform_double_3_3\n")
62-
trans_dict = get_ants_dict(affine)
63-
64-
params_list = ["%g" % i for i in list(trans_dict['AffineTransform_double_3_3'])]
65-
params_str = ' '.join(params_list)
66-
fp.write("Parameters: " + params_str + "\n")
67-
68-
fixed_params_list = ["%g" % i for i in list(trans_dict['fixed'])]
69-
fixed_params_str = ' '.join(fixed_params_list)
70-
fp.write("FixedParameters: " + ' '.join(fixed_params_str) + "\n")
71-
72-
return out_file
73-
74-
7532
def fix_multi_T1w_source_name(in_files):
7633
"""
7734
Make up a generic source name when there are multiple T1s

fmriprep/workflows/bold/hmc.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from nipype.pipeline import engine as pe
1313
from nipype.interfaces import utility as niu, fsl, afni
1414
from niworkflows.interfaces import NormalizeMotionParams
15-
from fmriprep.utils.misc import afni2itk_func
15+
from ...interfaces import Volreg2ITK
1616
from ...engine import Workflow
1717

1818
DEFAULT_MEMORY_MIN_GB = 0.01
@@ -75,12 +75,7 @@ def init_bold_hmc_wf(mem_gb, omp_nthreads, name='bold_hmc_wf'):
7575
# Head motion correction (hmc)
7676
mc = pe.Node(afni.Volreg(args='-prefix NULL -twopass',
7777
zpad=4, outputtype='NIFTI_GZ'), name="mc", mem_gb=mem_gb * 3)
78-
79-
afni2itk = pe.Node(niu.Function(function=afni2itk_func,
80-
input_names=["in_file"],
81-
output_names=["out_files"]), name='afni2itk',
82-
mem_gb=0.05)
83-
78+
afni2itk = pe.Node(Volreg2ITK(), name='afni2itk', mem_gb=0.05)
8479
normalize_motion = pe.Node(NormalizeMotionParams(format='AFNI'),
8580
name="normalize_motion",
8681
mem_gb=DEFAULT_MEMORY_MIN_GB)
@@ -90,7 +85,7 @@ def init_bold_hmc_wf(mem_gb, omp_nthreads, name='bold_hmc_wf'):
9085
('bold_file', 'in_file')]),
9186
(mc, afni2itk, [('oned_matrix_save', 'in_file')]),
9287
(mc, normalize_motion, [('oned_file', 'in_file')]),
93-
(afni2itk, outputnode, [('out_files', 'xforms')]),
88+
(afni2itk, outputnode, [('out_file', 'xforms')]),
9489
(normalize_motion, outputnode, [('out_file', 'movpar_file')]),
9590
])
9691

0 commit comments

Comments
 (0)