forked from dchaimow/fmri-analysis
-
Notifications
You must be signed in to change notification settings - Fork 0
/
wbcommand.py
231 lines (206 loc) · 7.77 KB
/
wbcommand.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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# -*- coding: utf-8 -*-
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
"""This module provides interfaces for workbench surface commands"""
import os
from nipype.interfaces.base import TraitedSpec, File, traits, CommandLineInputSpec
from nipype.interfaces.workbench.base import WBCommand
from nipype import logging
iflogger = logging.getLogger("nipype.interface")
class MetricResampleInputSpec(CommandLineInputSpec):
in_file = File(
exists=True,
mandatory=True,
argstr="%s",
position=0,
desc="The metric file to resample",
)
current_sphere = File(
exists=True,
mandatory=True,
argstr="%s",
position=1,
desc="A sphere surface with the mesh that the metric is currently on",
)
new_sphere = File(
exists=True,
mandatory=True,
argstr="%s",
position=2,
desc="A sphere surface that is in register with <current-sphere> and"
" has the desired output mesh",
)
method = traits.Enum(
"ADAP_BARY_AREA",
"BARYCENTRIC",
argstr="%s",
mandatory=True,
position=3,
desc="The method name - ADAP_BARY_AREA method is recommended for"
" ordinary metric data, because it should use all data while"
" downsampling, unlike BARYCENTRIC. If ADAP_BARY_AREA is used,"
" exactly one of area_surfs or area_metrics must be specified",
)
out_file = File(
name_source=["new_sphere"],
name_template="%s.out",
keep_extension=True,
argstr="%s",
position=4,
desc="The output metric",
)
area_surfs = traits.Bool(
position=5,
argstr="-area-surfs",
xor=["area_metrics"],
desc="Specify surfaces to do vertex area correction based on",
)
area_metrics = traits.Bool(
position=5,
argstr="-area-metrics",
xor=["area_surfs"],
desc="Specify vertex area metrics to do area correction based on",
)
current_area = File(
exists=True,
position=6,
argstr="%s",
desc="A relevant anatomical surface with <current-sphere> mesh OR"
" a metric file with vertex areas for <current-sphere> mesh",
)
new_area = File(
exists=True,
position=7,
argstr="%s",
desc="A relevant anatomical surface with <current-sphere> mesh OR"
" a metric file with vertex areas for <current-sphere> mesh",
)
roi_metric = File(
exists=True,
position=8,
argstr="-current-roi %s",
desc="Input roi on the current mesh used to exclude non-data vertices",
)
valid_roi_out = traits.Bool(
position=9,
argstr="-valid-roi-out",
desc="Output the ROI of vertices that got data from valid source vertices",
)
largest = traits.Bool(
position=10,
argstr="-largest",
desc="Use only the value of the vertex with the largest weight",
)
class MetricResampleOutputSpec(TraitedSpec):
out_file = File(exists=True, desc="the output metric")
roi_file = File(desc="ROI of vertices that got data from valid source vertices")
class MetricResample(WBCommand):
"""
Resample a metric file to a different mesh
Resamples a metric file, given two spherical surfaces that are in
register. If ``ADAP_BARY_AREA`` is used, exactly one of -area-surfs or
``-area-metrics`` must be specified.
The ``ADAP_BARY_AREA`` method is recommended for ordinary metric data,
because it should use all data while downsampling, unlike ``BARYCENTRIC``.
The recommended areas option for most data is individual midthicknesses
for individual data, and averaged vertex area metrics from individual
midthicknesses for group average data.
The ``-current-roi`` option only masks the input, the output may be slightly
dilated in comparison, consider using ``-metric-mask`` on the output when
using ``-current-roi``.
The ``-largest option`` results in nearest vertex behavior when used with
``BARYCENTRIC``. When resampling a binary metric, consider thresholding at
0.5 after resampling rather than using ``-largest``.
>>> from nipype.interfaces.workbench import MetricResample
>>> metres = MetricResample()
>>> metres.inputs.in_file = 'sub-01_task-rest_bold_space-fsaverage5.L.func.gii'
>>> metres.inputs.method = 'ADAP_BARY_AREA'
>>> metres.inputs.current_sphere = 'fsaverage5_std_sphere.L.10k_fsavg_L.surf.gii'
>>> metres.inputs.new_sphere = 'fs_LR-deformed_to-fsaverage.L.sphere.32k_fs_LR.surf.gii'
>>> metres.inputs.area_metrics = True
>>> metres.inputs.current_area = 'fsaverage5.L.midthickness_va_avg.10k_fsavg_L.shape.gii'
>>> metres.inputs.new_area = 'fs_LR.L.midthickness_va_avg.32k_fs_LR.shape.gii'
>>> metres.cmdline
'wb_command -metric-resample sub-01_task-rest_bold_space-fsaverage5.L.func.gii \
fsaverage5_std_sphere.L.10k_fsavg_L.surf.gii \
fs_LR-deformed_to-fsaverage.L.sphere.32k_fs_LR.surf.gii \
ADAP_BARY_AREA fs_LR-deformed_to-fsaverage.L.sphere.32k_fs_LR.surf.out \
-area-metrics fsaverage5.L.midthickness_va_avg.10k_fsavg_L.shape.gii \
fs_LR.L.midthickness_va_avg.32k_fs_LR.shape.gii'
"""
input_spec = MetricResampleInputSpec
output_spec = MetricResampleOutputSpec
_cmd = "wb_command -metric-resample"
def _format_arg(self, opt, spec, val):
if opt in ["current_area", "new_area"]:
if not self.inputs.area_surfs and not self.inputs.area_metrics:
raise ValueError(
"{} was set but neither area_surfs or"
" area_metrics were set".format(opt)
)
if opt == "method":
if (
val == "ADAP_BARY_AREA"
and not self.inputs.area_surfs
and not self.inputs.area_metrics
):
raise ValueError(
"Exactly one of area_surfs or area_metrics" " must be specified"
)
if opt == "valid_roi_out" and val:
# generate a filename and add it to argstr
roi_out = self._gen_filename(self.inputs.in_file, suffix="_roi")
iflogger.info("Setting roi output file as", roi_out)
spec.argstr += " " + roi_out
return super(MetricResample, self)._format_arg(opt, spec, val)
def _list_outputs(self):
outputs = super(MetricResample, self)._list_outputs()
if self.inputs.valid_roi_out:
roi_file = self._gen_filename(self.inputs.in_file, suffix="_roi")
outputs["roi_file"] = os.path.abspath(roi_file)
return outputs
# metric-smoothing
class MetricSmoothing(CommandLineInputSpec):
surface = File(
exists=True,
mandatory=True,
argstr="%s",
position=0,
desc="The surface to smooth on",
)
in_file = File(
exists=True,
mandatory=True,
argstr="%s",
position=1,
desc="The metric to smooth",
)
smoothing_kernel = traits.Float(
mandatory=True,
argstr="%s",
position=2,
desc="The size of the gaussian smoothing kernel in mm, as sigma by default",
)
out_file = File(
name_source=["in_file"],
name_template="smoothed_%s.nii",
keep_extension=True,
argstr="%s",
position=3,
desc="The output metric",
)
fwhm = traits.Bool(argstr="-fwhm", desc="Kernel size is FWHM, not sigma")
roi = File()
match_columns = traits.Bool() # only if roi0
fix_zeros = traits.Bool()
column
# metric-remove-islands
# metric-weighted-stats
# metric-math
# metric-dilate
# metric-mask
# volume-to-surface-mapping
# surface-average
# surface-cortex-layer
# label-to-volume-mapping
# cifti-math