-
Notifications
You must be signed in to change notification settings - Fork 21
/
ants.py
200 lines (165 loc) · 6.33 KB
/
ants.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
"""ANTS interfaces."""
import logging
import os
from nipype.interfaces.ants.base import ANTSCommand, ANTSCommandInputSpec
from nipype.interfaces.base import (
CommandLine,
CommandLineInputSpec,
File,
InputMultiPath,
Str,
TraitedSpec,
isdefined,
traits,
)
from niworkflows.interfaces.fixes import (
FixHeaderApplyTransforms,
_FixTraitApplyTransformsInputSpec,
)
from xcp_d.utils.filemanip import fname_presuffix
LOGGER = logging.getLogger("nipype.interface")
class _ConvertTransformFileInputSpec(CommandLineInputSpec):
dimension = traits.Enum((3, 2), default=3, usedefault=True, argstr="%d", position=0)
in_transform = traits.File(exists=True, argstr="%s", mandatory=True, position=1)
out_transform = traits.File(
argstr="%s",
name_source="in_transform",
name_template="%s.txt",
keep_extension=False,
position=2,
exists=False,
)
class _ConvertTransformFileOutputSpec(TraitedSpec):
out_transform = traits.File(exists=True)
class ConvertTransformFile(CommandLine):
"""Wrapper for the ANTS ConvertTransformFile command.
Utility to read in a transform file (presumed to be in binary format) and output it in various
formats.
Default output is legacy human-readable text format.
Without any options, the output filename extension must be .txt or .tfm to signify a
text-formatted transform file.
"""
_cmd = "ConvertTransformFile"
input_spec = _ConvertTransformFileInputSpec
output_spec = _ConvertTransformFileOutputSpec
class _CompositeInvTransformUtilInputSpec(ANTSCommandInputSpec):
"""Input specification for CompositeInvTransformUtil."""
process = traits.Enum(
"assemble",
"disassemble",
argstr="--%s",
position=1,
usedefault=True,
desc="What to do with the transform inputs (assemble or disassemble)",
)
out_file = File(
exists=False,
argstr="%s",
position=2,
desc="Output file path (only used for disassembly).",
)
in_file = InputMultiPath(
File(exists=True),
mandatory=True,
argstr="%s...",
position=3,
desc="Input transform file(s)",
)
output_prefix = Str(
"transform",
usedefault=True,
argstr="%s",
position=4,
desc="A prefix that is prepended to all output files (only used for assembly).",
)
class _CompositeInvTransformUtilOutputSpec(TraitedSpec):
"""Output specification for CompositeInvTransformUtil."""
affine_transform = File(desc="Affine transform component")
displacement_field = File(desc="Displacement field component")
out_file = File(desc="Compound transformation file")
class CompositeInvTransformUtil(ANTSCommand):
"""Wrapper for the ANTS CompositeTransformUtil command.
ANTs utility which can combine or break apart transform files into their individual
constituent components.
Examples
--------
>>> from nipype.interfaces.ants import CompositeInvTransformUtil
>>> tran = CompositeInvTransformUtil()
>>> tran.inputs.process = 'disassemble'
>>> tran.inputs.in_file = 'output_Composite.h5'
>>> tran.cmdline
'CompositeTransformUtil --disassemble output_Composite.h5 transform'
>>> tran.run() # doctest: +SKIP
example for assembling transformation files
>>> from nipype.interfaces.ants import CompositeInvTransformUtil
>>> tran = CompositeInvTransformUtil()
>>> tran.inputs.process = 'assemble'
>>> tran.inputs.out_file = 'my.h5'
>>> tran.inputs.in_file = ['AffineTransform.mat', 'DisplacementFieldTransform.nii.gz']
>>> tran.cmdline
'CompositeTransformUtil --assemble my.h5 AffineTransform.mat
DisplacementFieldTransform.nii.gz '
>>> tran.run() # doctest: +SKIP
"""
_cmd = "CompositeTransformUtil"
input_spec = _CompositeInvTransformUtilInputSpec
output_spec = _CompositeInvTransformUtilOutputSpec
def _num_threads_update(self):
"""Do not update the number of threads environment variable.
CompositeInvTransformUtil ignores environment variables,
so override environment update from ANTSCommand class.
"""
pass
def _format_arg(self, name, spec, value):
if name == "output_prefix" and self.inputs.process == "assemble":
return ""
if name == "out_file" and self.inputs.process == "disassemble":
return ""
return super(CompositeInvTransformUtil, self)._format_arg(name, spec, value)
def _list_outputs(self):
outputs = self.output_spec().get()
if self.inputs.process == "disassemble":
outputs["affine_transform"] = os.path.abspath(
f"01_{self.inputs.output_prefix}_AffineTransform.mat"
)
outputs["displacement_field"] = os.path.abspath(
f"00_{self.inputs.output_prefix}_DisplacementFieldTransform.nii.gz"
)
if self.inputs.process == "assemble":
outputs["out_file"] = os.path.abspath(self.inputs.out_file)
return outputs
class _ApplyTransformsInputSpec(_FixTraitApplyTransformsInputSpec):
# Nipype's version doesn't have GenericLabel
interpolation = traits.Enum(
"Linear",
"NearestNeighbor",
"CosineWindowedSinc",
"WelchWindowedSinc",
"HammingWindowedSinc",
"LanczosWindowedSinc",
"MultiLabel",
"Gaussian",
"BSpline",
"GenericLabel",
argstr="%s",
usedefault=True,
)
class ApplyTransforms(FixHeaderApplyTransforms):
"""A modified version of FixHeaderApplyTransforms from niworkflows.
The niworkflows version of ApplyTransforms "fixes the resampled image header
to match the xform of the reference image".
This modification overrides the allowed interpolation values,
since FixHeaderApplyTransforms doesn't support GenericLabel,
which is preferred over MultiLabel.
"""
input_spec = _ApplyTransformsInputSpec
def _run_interface(self, runtime):
if not isdefined(self.inputs.output_image):
self.inputs.output_image = fname_presuffix(
self.inputs.input_image,
suffix="_trans.nii.gz",
newpath=runtime.cwd,
use_ext=False,
)
runtime = super(ApplyTransforms, self)._run_interface(runtime)
return runtime