Skip to content

Commit cffd29c

Browse files
committed
Add normalization report
1 parent e689043 commit cffd29c

File tree

3 files changed

+157
-1
lines changed

3 files changed

+157
-1
lines changed

Diff for: src/fmripost_aroma/data/io_spec.json

+12
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,18 @@
7878
"extension": [
7979
".tsv"
8080
]
81+
},
82+
"anat_dseg": {
83+
"datatype": "anat",
84+
"space": null,
85+
"res": null,
86+
"den": null,
87+
"desc": null,
88+
"suffix": "dseg",
89+
"extension": [
90+
".nii.gz",
91+
".nii"
92+
]
8193
}
8294
},
8395
"transforms": {

Diff for: src/fmripost_aroma/workflows/base.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ def init_single_run_wf(bold_file):
285285

286286
from fmripost_aroma.utils.bids import collect_derivatives, extract_entities
287287
from fmripost_aroma.workflows.aroma import init_denoise_wf, init_ica_aroma_wf
288+
from fmripost_aroma.workflows.outputs import init_func_fit_reports_wf
288289

289290
spaces = config.workflow.spaces
290291
omp_nthreads = config.nipype.omp_nthreads
@@ -294,7 +295,6 @@ def init_single_run_wf(bold_file):
294295

295296
bold_metadata = config.execution.layout.get_metadata(bold_file)
296297
mem_gb = estimate_bold_mem_usage(bold_file)[1]
297-
ica_aroma_wf = init_ica_aroma_wf(bold_file=bold_file, metadata=bold_metadata, mem_gb=mem_gb)
298298

299299
entities = extract_entities(bold_file)
300300

@@ -365,6 +365,8 @@ def init_single_run_wf(bold_file):
365365
)
366366
skip_vols = get_nss(functional_cache['confounds'])
367367

368+
# Run ICA-AROMA
369+
ica_aroma_wf = init_ica_aroma_wf(bold_file=bold_file, metadata=bold_metadata, mem_gb=mem_gb)
368370
ica_aroma_wf.inputs.inputnode.confounds = functional_cache['confounds']
369371
ica_aroma_wf.inputs.inputnode.skip_vols = skip_vols
370372

@@ -479,6 +481,13 @@ def init_single_run_wf(bold_file):
479481
]),
480482
]) # fmt:skip
481483

484+
# Generate reportlets
485+
func_fit_reports_wf = init_func_fit_reports_wf(output_dir=config.execution.output_dir)
486+
func_fit_reports_wf.inputs.inputnode.source_file = bold_file
487+
func_fit_reports_wf.inputs.inputnode.anat2std_xfm = functional_cache['anat2mni152nlin6asym']
488+
func_fit_reports_wf.inputs.inputnode.anat_dseg = functional_cache['anat_dseg']
489+
workflow.connect([(mni6_buffer, func_fit_reports_wf, [('bold', 'inputnode.bold_mni6')])])
490+
482491
if config.workflow.denoise_method:
483492
# Now denoise the output-space BOLD data using ICA-AROMA
484493
denoise_wf = init_denoise_wf(bold_file=bold_file, metadata=bold_metadata)

Diff for: src/fmripost_aroma/workflows/outputs.py

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
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+
# Copyright The NiPreps Developers <[email protected]>
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
# We support and encourage derived works from this project, please read
19+
# about our expectations at
20+
#
21+
# https://www.nipreps.org/community/licensing/
22+
#
23+
"""Writing out derivative files."""
24+
25+
from __future__ import annotations
26+
27+
from fmriprep.utils.bids import dismiss_echo
28+
from nipype.interfaces import utility as niu
29+
from nipype.pipeline import engine as pe
30+
from niworkflows.interfaces.fixes import FixHeaderApplyTransforms as ApplyTransforms
31+
from niworkflows.utils.images import dseg_label
32+
33+
from fmripost_aroma.config import DEFAULT_MEMORY_MIN_GB
34+
from fmripost_aroma.interfaces.bids import DerivativesDataSink
35+
36+
37+
def init_func_fit_reports_wf(
38+
*,
39+
output_dir: str,
40+
name='func_fit_reports_wf',
41+
) -> pe.Workflow:
42+
"""Set up a battery of datasinks to store reports in the right location.
43+
44+
Parameters
45+
----------
46+
freesurfer : :obj:`bool`
47+
FreeSurfer was enabled
48+
output_dir : :obj:`str`
49+
Directory in which to save derivatives
50+
name : :obj:`str`
51+
Workflow name (default: func_fit_reports_wf)
52+
53+
Inputs
54+
------
55+
source_file
56+
Input BOLD images
57+
"""
58+
from nireports.interfaces.reporting.base import (
59+
SimpleBeforeAfterRPT as SimpleBeforeAfter,
60+
)
61+
62+
from fmripost_aroma.interfaces.nilearn import MeanImage
63+
64+
workflow = pe.Workflow(name=name)
65+
66+
inputfields = [
67+
'source_file',
68+
'bold_mni6',
69+
'anat_dseg',
70+
'anat2std_xfm',
71+
]
72+
inputnode = pe.Node(niu.IdentityInterface(fields=inputfields), name='inputnode')
73+
74+
# Average the BOLD image over time
75+
calculate_mean_bold = pe.Node(
76+
MeanImage(),
77+
name='calculate_mean_bold',
78+
mem_gb=1,
79+
)
80+
workflow.connect([(inputnode, calculate_mean_bold, [('bold_mni6', 'bold_file')])])
81+
82+
# Warp the tissue segmentation to MNI
83+
dseg_to_mni6 = pe.Node(
84+
ApplyTransforms(interpolation='MultiLabel'),
85+
name='dseg_to_mni6',
86+
mem_gb=1,
87+
)
88+
workflow.connect([
89+
(inputnode, dseg_to_mni6, [
90+
('anat_dseg', 'input_image'),
91+
('anat2std_xfm', 'transforms'),
92+
('bold_mni6', 'reference_image'),
93+
]),
94+
]) # fmt:skip
95+
96+
mni6_wm = pe.Node(
97+
niu.Function(function=dseg_label),
98+
name='mni6_wm',
99+
mem_gb=DEFAULT_MEMORY_MIN_GB,
100+
)
101+
mni6_wm.inputs.label = 2 # BIDS default is WM=2
102+
workflow.connect([(dseg_to_mni6, mni6_wm, [('output_image', 'in_file')])])
103+
104+
# EPI-MNI registration
105+
epi_mni_report = pe.Node(
106+
SimpleBeforeAfter(
107+
before_label='T1w',
108+
after_label='EPI',
109+
dismiss_affine=True,
110+
),
111+
name='epi_mni_report',
112+
mem_gb=0.1,
113+
)
114+
workflow.connect([
115+
(inputnode, epi_mni_report, [('coreg_boldref', 'after')]),
116+
(calculate_mean_bold, epi_mni_report, [('out_file', 'before')]),
117+
(mni6_wm, epi_mni_report, [('output_image', 'wm_seg')]),
118+
]) # fmt:skip
119+
120+
ds_epi_mni_report = pe.Node(
121+
DerivativesDataSink(
122+
base_directory=output_dir,
123+
desc='coreg',
124+
suffix='bold',
125+
datatype='figures',
126+
dismiss_entities=dismiss_echo(),
127+
),
128+
name='ds_epi_mni_report',
129+
)
130+
workflow.connect([
131+
(inputnode, ds_epi_mni_report, [('source_file', 'source_file')]),
132+
(epi_mni_report, ds_epi_mni_report, [('out_report', 'in_file')]),
133+
]) # fmt:skip
134+
135+
return workflow

0 commit comments

Comments
 (0)