Skip to content

Commit 67054f4

Browse files
committed
enh: wb cifti-smoothing
1 parent 86a3ea3 commit 67054f4

6 files changed

+240
-0
lines changed

nipype/interfaces/workbench/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
# vi: set ft=python sts=4 ts=4 sw=4 et:
44

55
from .metric import MetricResample
6+
from .cifti import CiftiSmooth

nipype/interfaces/workbench/cifti.py

+144
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# -*- coding: utf-8 -*-
2+
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
3+
# vi: set ft=python sts=4 ts=4 sw=4 et:
4+
"""This module provides interfaces for workbench CIFTI commands"""
5+
from __future__ import (print_function, division, unicode_literals,
6+
absolute_import)
7+
import os
8+
9+
from ..base import (TraitedSpec, File, traits, CommandLineInputSpec)
10+
from .base import WBCommand
11+
from ... import logging
12+
13+
iflogger = logging.getLogger('nipype.interface')
14+
15+
16+
class CiftiSmoothInputSpec(CommandLineInputSpec):
17+
in_file = File(
18+
exists=True,
19+
mandatory=True,
20+
argstr="%s",
21+
position=0,
22+
desc="The input CIFTI file")
23+
sigma_surf = traits.Float(
24+
mandatory=True,
25+
argstr="%s",
26+
position=1,
27+
desc="the sigma for the gaussian surface smoothing kernel, in mm")
28+
sigma_vol = traits.Float(
29+
mandatory=True,
30+
argstr="%s",
31+
position=2,
32+
desc="the sigma for the gaussian volume smoothing kernel, in mm")
33+
direction = traits.Enum(
34+
"ROW",
35+
"COLUMN",
36+
mandatory=True,
37+
argstr="%s",
38+
position=3,
39+
desc="which dimension to smooth along, ROW or COLUMN")
40+
out_file = File(
41+
name_source=["in_file"],
42+
name_template="smoothed_%s.nii",
43+
keep_extension=True,
44+
argstr="%s",
45+
position=4,
46+
desc="The output CIFTI")
47+
left_surf = File(
48+
exists=True,
49+
mandatory=True,
50+
position=5,
51+
argstr="-left-surface %s",
52+
desc="Specify the left surface to use")
53+
left_corrected_areas = File(
54+
exists=True,
55+
position=6,
56+
argstr="-left-corrected-areas %s",
57+
desc="vertex areas (as a metric) to use instead of computing them from "
58+
"the left surface.")
59+
right_surf = File(
60+
exists=True,
61+
mandatory=True,
62+
position=7,
63+
argstr="-right-surface %s",
64+
desc="Specify the right surface to use")
65+
right_corrected_areas = File(
66+
exists=True,
67+
position=8,
68+
argstr="-right-corrected-areas %s",
69+
desc="vertex areas (as a metric) to use instead of computing them from "
70+
"the right surface")
71+
cerebellum_surf = File(
72+
exists=True,
73+
position=9,
74+
argstr="-cerebellum-surface %s",
75+
desc="specify the cerebellum surface to use")
76+
cerebellum_corrected_areas = File(
77+
exists=True,
78+
position=10,
79+
requires=["cerebellum_surf"],
80+
argstr="cerebellum-corrected-areas %s",
81+
desc="vertex areas (as a metric) to use instead of computing them from "
82+
"the cerebellum surface")
83+
cifti_roi = File(
84+
exists=True,
85+
position=11,
86+
argstr="-cifti-roi %s",
87+
desc="CIFTI file for ROI smoothing")
88+
fix_zeros_vol = traits.Bool(
89+
position=12,
90+
argstr="-fix-zeros-volume",
91+
desc="treat values of zero in the volume as missing data")
92+
fix_zeros_surf = traits.Bool(
93+
position=13,
94+
argstr="-fix-zeros-surface",
95+
desc="treat values of zero on the surface as missing data")
96+
merged_volume = traits.Bool(
97+
position=14,
98+
argstr="-merged-volume",
99+
desc="smooth across subcortical structure boundaries")
100+
101+
102+
class CiftiSmoothOutputSpec(TraitedSpec):
103+
out_file = File(exists=True, desc="output CIFTI file")
104+
105+
106+
class CiftiSmooth(WBCommand):
107+
"""
108+
Smooth a CIFTI file
109+
110+
The input cifti file must have a brain models mapping on the chosen
111+
dimension, columns for .dtseries, and either for .dconn. By default,
112+
data in different structures is smoothed independently (i.e., "parcel
113+
constrained" smoothing), so volume structures that touch do not smooth
114+
across this boundary. Specify ``merged_volume`` to ignore these
115+
boundaries. Surface smoothing uses the ``GEO_GAUSS_AREA`` smoothing method.
116+
117+
The ``*_corrected_areas`` options are intended for when it is unavoidable
118+
to smooth on group average surfaces, it is only an approximate correction
119+
for the reduction of structure in a group average surface. It is better
120+
to smooth the data on individuals before averaging, when feasible.
121+
122+
The ``fix_zeros_*`` options will treat values of zero as lack of data, and
123+
not use that value when generating the smoothed values, but will fill
124+
zeros with extrapolated values. The ROI should have a brain models
125+
mapping along columns, exactly matching the mapping of the chosen
126+
direction in the input file. Data outside the ROI is ignored.
127+
128+
>>> from nipype.interfaces.workbench import CiftiSmooth
129+
>>> smooth = CiftiSmooth()
130+
>>> smooth.inputs.in_file = 'sub-01_task-rest.dtseries.nii'
131+
>>> smooth.inputs.sigma_surf = 4
132+
>>> smooth.inputs.sigma_vol = 4
133+
>>> smooth.inputs.direction = 'COLUMN'
134+
>>> smooth.inputs.right_surf = 'sub-01.R.midthickness.32k_fs_LR.surf.gii'
135+
>>> smooth.inputs.left_surf = 'sub-01.L.midthickness.32k_fs_LR.surf.gii'
136+
>>> smooth.cmdline
137+
'wb_command -cifti-smoothing sub-01_task-rest.dtseries.nii 4.0 4.0 COLUMN \
138+
smoothed_sub-01_task-rest.dtseries.nii \
139+
-left-surface sub-01.L.midthickness.32k_fs_LR.surf.gii \
140+
-right-surface sub-01.R.midthickness.32k_fs_LR.surf.gii'
141+
"""
142+
input_spec = CiftiSmoothInputSpec
143+
output_spec = CiftiSmoothOutputSpec
144+
_cmd = 'wb_command -cifti-smoothing'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT
2+
from __future__ import unicode_literals
3+
from ..cifti import CiftiSmooth
4+
5+
6+
def test_CiftiSmooth_inputs():
7+
input_map = dict(
8+
args=dict(argstr='%s', ),
9+
cerebellum_corrected_areas=dict(
10+
argstr='cerebellum-corrected-areas %s',
11+
position=10,
12+
requires=['cerebellum_surf'],
13+
),
14+
cerebellum_surf=dict(
15+
argstr='-cerebellum-surface %s',
16+
position=9,
17+
),
18+
cifti_roi=dict(
19+
argstr='-cifti-roi %s',
20+
position=11,
21+
),
22+
direction=dict(
23+
argstr='%s',
24+
mandatory=True,
25+
position=3,
26+
),
27+
environ=dict(
28+
nohash=True,
29+
usedefault=True,
30+
),
31+
fix_zeros_surf=dict(
32+
argstr='-fix-zeros-surface',
33+
position=13,
34+
),
35+
fix_zeros_vol=dict(
36+
argstr='-fix-zeros-volume',
37+
position=12,
38+
),
39+
in_file=dict(
40+
argstr='%s',
41+
mandatory=True,
42+
position=0,
43+
),
44+
left_corrected_areas=dict(
45+
argstr='-left-corrected-areas %s',
46+
position=6,
47+
),
48+
left_surf=dict(
49+
argstr='-left-surface %s',
50+
mandatory=True,
51+
position=5,
52+
),
53+
merged_volume=dict(
54+
argstr='-merged-volume',
55+
position=14,
56+
),
57+
out_file=dict(
58+
argstr='%s',
59+
keep_extension=True,
60+
name_source=['in_file'],
61+
name_template='smoothed_%s.nii',
62+
position=4,
63+
),
64+
right_corrected_areas=dict(
65+
argstr='-right-corrected-areas %s',
66+
position=8,
67+
),
68+
right_surf=dict(
69+
argstr='-right-surface %s',
70+
mandatory=True,
71+
position=7,
72+
),
73+
sigma_surf=dict(
74+
argstr='%s',
75+
mandatory=True,
76+
position=1,
77+
),
78+
sigma_vol=dict(
79+
argstr='%s',
80+
mandatory=True,
81+
position=2,
82+
),
83+
)
84+
inputs = CiftiSmooth.input_spec()
85+
86+
for key, metadata in list(input_map.items()):
87+
for metakey, value in list(metadata.items()):
88+
assert getattr(inputs.traits()[key], metakey) == value
89+
def test_CiftiSmooth_outputs():
90+
output_map = dict(out_file=dict(), )
91+
outputs = CiftiSmooth.output_spec()
92+
93+
for key, metadata in list(output_map.items()):
94+
for metakey, value in list(metadata.items()):
95+
assert getattr(outputs.traits()[key], metakey) == value

nipype/testing/data/sub-01.L.midthickness.32k_fs_LR.surf.gii

Whitespace-only changes.

nipype/testing/data/sub-01.R.midthickness.32k_fs_LR.surf.gii

Whitespace-only changes.

nipype/testing/data/sub-01_task-rest.dtseries.nii

Whitespace-only changes.

0 commit comments

Comments
 (0)