Skip to content

Commit 60c42b7

Browse files
committed
fix: clean up missing connections, fix sdc_unwarp workflow
The sdc_unwarp workflow contained a pretty weird FoV mask with a very unclear objective. For that reason, in this commit the FoV mask is replaced by a mask calculated unwarping the original mask of the dataset.
1 parent 62c183a commit 60c42b7

File tree

3 files changed

+35
-60
lines changed

3 files changed

+35
-60
lines changed

sdcflows/workflows/base.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
DEFAULT_MEMORY_MIN_GB = 0.01
2020

2121

22-
def init_sdc_estimate_wf(fmaps, epi_meta, omp_nthreads=1, debug=False, ignore=None):
22+
def init_sdc_estimate_wf(fmaps, epi_meta, omp_nthreads=1, debug=False):
2323
"""
2424
Build a :abbr:`SDC (susceptibility distortion correction)` workflow.
2525
@@ -66,7 +66,7 @@ def init_sdc_estimate_wf(fmaps, epi_meta, omp_nthreads=1, debug=False, ignore=No
6666
6767
Outputs
6868
-------
69-
epi_file
69+
epi_corrected
7070
The EPI scan reference after unwarping.
7171
epi_mask
7272
The corresponding new mask after unwarping
@@ -87,28 +87,25 @@ def init_sdc_estimate_wf(fmaps, epi_meta, omp_nthreads=1, debug=False, ignore=No
8787
name='inputnode')
8888

8989
outputnode = pe.Node(niu.IdentityInterface(
90-
fields=['output_ref', 'epi_mask', 'epi_brain',
90+
fields=['epi_corrected', 'epi_mask', 'epi_brain',
9191
'out_warp', 'syn_ref', 'method']),
9292
name='outputnode')
9393

9494
# No fieldmaps - forward inputs to outputs
95-
ignored = False if ignore is None else 'fieldmaps' in ignore
96-
if not fmaps or ignored:
95+
if not fmaps:
9796
workflow.__postdesc__ = """\
98-
Susceptibility distortion correction (SDC) has been skipped because the
99-
dataset does not contain extra field map acquisitions correctly described
100-
with metadata, and the experimental SDC-SyN method was not explicitly selected.
97+
Susceptibility distortion correction (SDC) was omitted.
10198
"""
10299
outputnode.inputs.method = 'None'
103100
workflow.connect([
104-
(inputnode, outputnode, [('epi_file', 'output_ref'),
101+
(inputnode, outputnode, [('epi_file', 'epi_corrected'),
105102
('epi_mask', 'epi_mask'),
106103
('epi_brain', 'epi_brain')]),
107104
])
108105
return workflow
109106

110107
workflow.__postdesc__ = """\
111-
Based on the estimated susceptibility distortion, an unwarped
108+
Based on the estimated susceptibility distortion, a corrected
112109
EPI (echo-planar imaging) reference was calculated for a more
113110
accurate co-registration with the anatomical reference.
114111
"""
@@ -210,7 +207,7 @@ def init_sdc_estimate_wf(fmaps, epi_meta, omp_nthreads=1, debug=False, ignore=No
210207
('epi_brain', 'inputnode.in_reference_brain')]),
211208
(inputnode, sdc_unwarp_wf, [
212209
('epi_file', 'inputnode.in_reference'),
213-
('epi_brain', 'inputnode.in_reference_brain')]),
210+
('epi_mask', 'inputnode.in_reference_mask')]),
214211
(fmap_wf, fmap2field_wf, [
215212
('outputnode.fmap', 'inputnode.fmap'),
216213
('outputnode.fmap_ref', 'inputnode.fmap_ref'),
@@ -252,7 +249,7 @@ def init_sdc_estimate_wf(fmaps, epi_meta, omp_nthreads=1, debug=False, ignore=No
252249
workflow.connect([
253250
(sdc_unwarp_wf, outputnode, [
254251
('outputnode.out_warp', 'out_warp'),
255-
('outputnode.out_reference', 'epi_file'),
252+
('outputnode.out_reference', 'epi_corrected'),
256253
('outputnode.out_reference_brain', 'epi_brain'),
257254
('outputnode.out_mask', 'epi_mask')]),
258255
])

sdcflows/workflows/tests/test_base.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,7 @@ def test_base(method):
7474
epi_meta = EPI_METADATA.copy()
7575

7676
if method == 'skip':
77-
wf = init_sdc_estimate_wf(fmaps=[], epi_meta=epi_meta)
78-
assert wf.inputs.outputnode.method == 'None'
79-
80-
wf = init_sdc_estimate_wf(fmaps=fieldmaps, epi_meta=epi_meta, ignore=('fieldmaps', ))
77+
wf = init_sdc_estimate_wf(fmaps=None, epi_meta=epi_meta)
8178
assert wf.inputs.outputnode.method == 'None'
8279

8380
with pytest.raises(ValueError):

sdcflows/workflows/unwarp.py

Lines changed: 25 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,9 @@
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-
"""
4-
.. _sdc_unwarp :
5-
6-
Unwarping
7-
~~~~~~~~~
8-
9-
.. topic :: Abbreviations
10-
11-
fmap
12-
fieldmap
13-
VSM
14-
voxel-shift map -- a 3D nifti where displacements are in pixels (not mm)
15-
DFM
16-
displacements field map -- a nifti warp file compatible with ANTs (mm)
17-
18-
"""
3+
"""Apply the estimated fieldmap to perform susceptibility-derived distortion correction."""
194
from nipype.pipeline import engine as pe
20-
from nipype.interfaces import fsl, utility as niu
5+
from nipype.interfaces import utility as niu
216
from niworkflows.engine.workflows import LiterateWorkflow as Workflow
22-
from niworkflows.interfaces.images import FilledImageLike
237
from niworkflows.interfaces.registration import ANTSApplyTransformsRPT
248
from niworkflows.func.util import init_enhance_and_skullstrip_bold_wf
259

@@ -31,10 +15,8 @@ def init_sdc_unwarp_wf(omp_nthreads, debug, name='sdc_unwarp_wf'):
3115
This workflow takes in a displacements field through which the
3216
input reference can be corrected for susceptibility-derived distortion.
3317
34-
It also calculates a new mask for the input dataset, which takes into
35-
account the (corrected) distortions.
36-
The mask is restricted to the field of view of the fieldmap since outside
37-
of it corrections could not be performed.
18+
It also calculates a new mask for the input dataset, after the distortions
19+
have been accounted for.
3820
3921
.. workflow ::
4022
:graph2use: orig
@@ -58,26 +40,26 @@ def init_sdc_unwarp_wf(omp_nthreads, debug, name='sdc_unwarp_wf'):
5840
in_warp : os.pathlike
5941
The :abbr:`DFM (displacements field map)` that corrects for
6042
susceptibility-derived distortions estimated elsewhere.
61-
in_reference
43+
in_reference : os.pathlike
6244
the reference image to be unwarped.
63-
in_reference_brain
64-
a skull-stripped version corresponding to the ``in_reference``.
45+
in_reference_mask : os.pathlike
46+
the reference image mask to be unwarped
6547
6648
Outputs
6749
-------
68-
out_reference
50+
out_reference : str
6951
the ``in_reference`` after unwarping
70-
out_reference_brain
52+
out_reference_brain : str
7153
the ``in_reference`` after unwarping and skullstripping
72-
out_warp
54+
out_warp : str
7355
the ``in_warp`` field is forwarded for compatibility
74-
out_mask
56+
out_mask : str
7557
mask of the unwarped input file
7658
7759
"""
7860
workflow = Workflow(name=name)
7961
inputnode = pe.Node(niu.IdentityInterface(
80-
fields=['in_warp', 'in_reference', 'in_reference_brain']),
62+
fields=['in_warp', 'in_reference', 'in_reference_mask']),
8163
name='inputnode')
8264
outputnode = pe.Node(niu.IdentityInterface(
8365
fields=['out_reference', 'out_reference_brain', 'out_warp', 'out_mask']),
@@ -89,30 +71,29 @@ def init_sdc_unwarp_wf(omp_nthreads, debug, name='sdc_unwarp_wf'):
8971
interpolation='LanczosWindowedSinc'),
9072
name='unwarp_reference')
9173

92-
fieldmap_fov_mask = pe.Node(FilledImageLike(dtype='uint8'), name='fieldmap_fov_mask')
93-
fmap_fov2ref_apply = pe.Node(ANTSApplyTransformsRPT(
94-
generate_report=False, dimension=3, interpolation='NearestNeighbor',
95-
float=True),
96-
name='fmap_fov2ref_apply')
74+
unwarp_mask = pe.Node(ANTSApplyTransformsRPT(
75+
dimension=3, generate_report=False, float=True,
76+
interpolation='NearestNeighbor'), name='unwarp_mask')
9777

98-
apply_fov_mask = pe.Node(fsl.ApplyMask(), name="apply_fov_mask")
9978
enhance_and_skullstrip_bold_wf = init_enhance_and_skullstrip_bold_wf(omp_nthreads=omp_nthreads,
10079
pre_mask=True)
10180
workflow.connect([
10281
(inputnode, unwarp_reference, [
10382
('in_warp', 'transforms'),
10483
('in_reference', 'reference_image'),
10584
('in_reference', 'input_image')]),
106-
(inputnode, fieldmap_fov_mask, [('in_warp', 'in_file')]),
107-
(fieldmap_fov_mask, fmap_fov2ref_apply, [('out_file', 'input_image')]),
108-
(inputnode, fmap_fov2ref_apply, [('in_reference', 'reference_image')]),
109-
(fmap_fov2ref_apply, apply_fov_mask, [('output_image', 'mask_file')]),
110-
(unwarp_reference, apply_fov_mask, [('output_image', 'in_file')]),
111-
(apply_fov_mask, enhance_and_skullstrip_bold_wf, [('out_file', 'inputnode.in_file')]),
112-
(apply_fov_mask, outputnode, [('out_file', 'out_reference')]),
85+
(inputnode, unwarp_mask, [
86+
('in_warp', 'transforms'),
87+
('in_reference_mask', 'reference_image'),
88+
('in_reference_mask', 'input_image')]),
89+
(unwarp_reference, enhance_and_skullstrip_bold_wf, [
90+
('output_image', 'inputnode.in_file')]),
91+
(unwarp_mask, enhance_and_skullstrip_bold_wf, [
92+
('output_image', 'inputnode.pre_mask')]),
93+
(inputnode, outputnode, [('in_warp', 'out_warp')]),
94+
(unwarp_reference, outputnode, [('output_image', 'out_reference')]),
11395
(enhance_and_skullstrip_bold_wf, outputnode, [
11496
('outputnode.mask_file', 'out_mask'),
11597
('outputnode.skull_stripped_file', 'out_reference_brain')]),
116-
(inputnode, outputnode, [('in_warp', 'out_warp')]),
11798
])
11899
return workflow

0 commit comments

Comments
 (0)