Skip to content

Commit 286ab00

Browse files
committed
enh: split out reports to a new module
1 parent 072ce05 commit 286ab00

File tree

5 files changed

+55
-41
lines changed

5 files changed

+55
-41
lines changed

dmriprep/config/reports-spec.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ sections:
3030
ordering: session,acquisition,run
3131
reportlets:
3232
- bids: {datatype: dwi, desc: validation, suffix: dwi}
33+
- bids: {datatype: dwi, desc: brain, suffix: mask}
34+
caption: Average b=0 that serves for reference in early preprocessing steps.
35+
descriptions: The reference b=0 is obtained as the voxel-wise median across
36+
all b=0 found in the dataset, after accounting for signal drift.
37+
The red contour shows the brain mask calculated using this reference b=0.
38+
subtitle: Reference b=0 and brain mask
3339
- name: About
3440
reportlets:
3541
- bids: {datatype: anat, desc: about, suffix: T1w}

dmriprep/workflows/base.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
2-
# vi: set ft=python sts=4 ts=4 sw=4 et:
3-
"""
4-
dMRIPrep base processing workflows.
5-
6-
"""
7-
1+
"""dMRIPrep base processing workflows."""
82
import sys
93
import os
104
from packaging.version import Version

dmriprep/workflows/dwi/base.py

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
"""Orchestrating the dMRI-preprocessing workflow."""
2-
32
from nipype import logging
4-
53
from nipype.pipeline import engine as pe
64
from nipype.interfaces import utility as niu
75

86
from niworkflows.engine.workflows import LiterateWorkflow as Workflow
9-
10-
from ...config import DEFAULT_MEMORY_MIN_GB
11-
12-
from ...interfaces import DerivativesDataSink
137
from ...interfaces.vectors import CheckGradientTable
8+
from .util import init_dwi_reference_wf
9+
from .outputs import init_reportlets_wf
1410

1511

1612
LOGGER = logging.getLogger('nipype.workflow')
@@ -100,10 +96,9 @@ def init_dwi_preproc_wf(
10096
See also
10197
--------
10298
* :py:func:`~dmriprep.workflows.dwi.util.init_dwi_reference_wf`
99+
* :py:func:`~dmriprep.workflows.dwi.outputs.init_reportlets_wf`
103100
104101
"""
105-
from .util import init_dwi_reference_wf
106-
107102
wf_name = _get_wf_name(dwi_file)
108103

109104
# Build workflow
@@ -147,7 +142,7 @@ def init_dwi_preproc_wf(
147142

148143
gradient_table = pe.Node(CheckGradientTable(), name='gradient_table')
149144

150-
dwi_reference_wf = init_dwi_reference_wf(omp_nthreads=1, gen_report=True)
145+
dwi_reference_wf = init_dwi_reference_wf(omp_nthreads=1)
151146

152147
# MAIN WORKFLOW STRUCTURE
153148
workflow.connect([
@@ -158,7 +153,7 @@ def init_dwi_preproc_wf(
158153
(inputnode, dwi_reference_wf, [('dwi_file', 'inputnode.dwi_file')]),
159154
(gradient_table, dwi_reference_wf, [('b0_ixs', 'inputnode.b0_ixs')]),
160155
(dwi_reference_wf, outputnode, [
161-
('outputnode.dwi_file', 'out_dwi'),
156+
('outputnode.ref_image', 'out_dwi'),
162157
('outputnode.dwi_mask', 'out_dwi_mask')]),
163158
(gradient_table, outputnode, [
164159
('out_bvec', 'out_bvec'),
@@ -167,18 +162,14 @@ def init_dwi_preproc_wf(
167162
])
168163

169164
# REPORTING
170-
ds_report_validation = pe.Node(
171-
DerivativesDataSink(base_directory=reportlets_dir,
172-
desc='validation', keep_dtype=True),
173-
name='ds_report_validation', run_without_submitting=True,
174-
mem_gb=DEFAULT_MEMORY_MIN_GB)
175-
165+
reportlets_wf = init_reportlets_wf(reportlets_dir)
176166
workflow.connect([
177-
(inputnode, ds_report_validation, [('dwi', 'source_file')]),
178-
(dwi_reference_wf, ds_report_validation, [
179-
('outputnode.validation_report', 'in_file')]),
167+
(inputnode, reportlets_wf, [('dwi_file', 'inputnode.source_file')]),
168+
(dwi_reference_wf, reportlets_wf, [
169+
('outputnode.ref_image', 'inputnode.dwi_ref'),
170+
('outputnode.dwi_mask', 'inputnode.dwi_mask'),
171+
('outputnode.validation_report', 'inputnode.validation_report')]),
180172
])
181-
182173
return workflow
183174

184175

dmriprep/workflows/dwi/outputs.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""Write outputs (derivatives and reportlets)."""
2+
from nipype.pipeline import engine as pe
3+
from nipype.interfaces import utility as niu
4+
from niworkflows.engine.workflows import LiterateWorkflow as Workflow
5+
from ...interfaces import DerivativesDataSink
6+
7+
8+
def init_reportlets_wf(reportlets_dir, name='reportlets_wf'):
9+
"""Set up a battery of datasinks to store reports in the right location."""
10+
from niworkflows.interfaces.masks import SimpleShowMaskRPT
11+
workflow = Workflow(name=name)
12+
13+
inputnode = pe.Node(niu.IdentityInterface(
14+
fields=['source_file', 'dwi_ref', 'dwi_mask',
15+
'validation_report']),
16+
name='inputnode')
17+
mask_reportlet = pe.Node(SimpleShowMaskRPT(), name='mask_reportlet')
18+
19+
ds_report_mask = pe.Node(
20+
DerivativesDataSink(base_directory=reportlets_dir,
21+
desc='brain', suffix='mask'),
22+
name='ds_report_mask', run_without_submitting=True)
23+
ds_report_validation = pe.Node(
24+
DerivativesDataSink(base_directory=reportlets_dir,
25+
desc='validation', keep_dtype=True),
26+
name='ds_report_validation', run_without_submitting=True)
27+
28+
workflow.connect([
29+
(inputnode, mask_reportlet, [('dwi_ref', 'background_file'),
30+
('dwi_mask', 'mask_file')]),
31+
(inputnode, ds_report_validation, [('source_file', 'source_file')]),
32+
(inputnode, ds_report_mask, [('source_file', 'source_file')]),
33+
(inputnode, ds_report_validation, [('validation_report', 'in_file')]),
34+
(mask_reportlet, ds_report_mask, [('out_report', 'in_file')]),
35+
])
36+
return workflow

dmriprep/workflows/dwi/util.py

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@
66
from niworkflows.engine.workflows import LiterateWorkflow as Workflow
77
from niworkflows.interfaces.images import ValidateImage
88
from niworkflows.interfaces.fixes import FixN4BiasFieldCorrection as N4BiasFieldCorrection
9-
from niworkflows.interfaces.masks import SimpleShowMaskRPT
109
from niworkflows.interfaces.utils import CopyXForm
1110

1211
from ...interfaces.images import ExtractB0, RescaleB0
1312

1413
DEFAULT_MEMORY_MIN_GB = 0.01
1514

1615

17-
def init_dwi_reference_wf(omp_nthreads, name='dwi_reference_wf', gen_report=False):
16+
def init_dwi_reference_wf(omp_nthreads, name='dwi_reference_wf'):
1817
"""
1918
Build a workflow that generates a reference b0 image from a DWI dataset.
2019
@@ -40,8 +39,6 @@ def init_dwi_reference_wf(omp_nthreads, name='dwi_reference_wf', gen_report=Fals
4039
Maximum number of threads an individual process may use
4140
name : str
4241
Name of workflow (default: ``dwi_reference_wf``)
43-
gen_report : bool
44-
Whether a mask report node should be appended in the end
4542
4643
Inputs
4744
------
@@ -112,16 +109,6 @@ def init_dwi_reference_wf(omp_nthreads, name='dwi_reference_wf', gen_report=Fals
112109
('outputnode.mask_file', 'dwi_mask'),
113110
('outputnode.skull_stripped_file', 'ref_image_brain')]),
114111
])
115-
116-
if gen_report:
117-
mask_reportlet = pe.Node(SimpleShowMaskRPT(), name='mask_reportlet')
118-
workflow.connect([
119-
(enhance_and_skullstrip_dwi_wf, mask_reportlet, [
120-
('outputnode.bias_corrected_file', 'background_file'),
121-
('outputnode.mask_file', 'mask_file'),
122-
]),
123-
])
124-
125112
return workflow
126113

127114

0 commit comments

Comments
 (0)