Skip to content

Commit 742a18f

Browse files
authored
Merge pull request #141 from oesteban/fix/checking-target-epi-names
FIX: Correctly check *SDCFlows*' registry of ``IntendedFor`` files
2 parents d94d442 + 6f27c1f commit 742a18f

File tree

6 files changed

+96
-26
lines changed

6 files changed

+96
-26
lines changed

dmriprep/config/reports-spec.yml

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,30 @@ sections:
2727
overlaid on the participant's T1w template.
2828
subtitle: Surface reconstruction
2929
- name: Fieldmaps
30-
ordering: session,run
30+
ordering: session,run,fmapid
3131
reportlets:
32+
- bids: {datatype: figures, desc: mapped, suffix: fieldmap}
33+
caption: Inhomogeneities of the <em>B<sub>0</sub></em> field introduce (oftentimes severe) spatial distortions
34+
along the phase-encoding direction of the image. Some scanners produce a <em>B<sub>0</sub></em>
35+
mapping of the field, using Spiral Echo Imaging (SEI) or postprocessing a "phase-difference"
36+
acquisition. The plot below shows an anatomical "magnitude" reference and the corresponding
37+
fieldmap.
38+
description: Hover over the panels with the mouse pointer to also visualize the intensity of the
39+
field inhomogeneity in Hertz.
40+
static: false
41+
subtitle: "Susceptibility-derived Distortion Correction (SDC): field inhomogeneity estimation"
42+
- bids: {datatype: figures, desc: phasediff, suffix: fieldmap}
43+
caption: Inhomogeneities of the <em>B<sub>0</sub></em> field introduce (oftentimes severe) spatial distortions
44+
along the phase-encoding direction of the image. A Gradient-Recalled Echo (GRE) scheme for the
45+
mapping of the <em>B<sub>0</sub></em> inhomogeneities by subtracting the phase maps obtained at
46+
two subsequent echoes. The plot below shows an anatomical "magnitude" reference and the corresponding
47+
fieldmap.
48+
description: Hover over the panels with the mouse pointer to also visualize the intensity of the
49+
field inhomogeneity in Hertz.
50+
static: false
51+
subtitle: "Susceptibility-derived Distortion Correction (SDC): field inhomogeneity estimation"
3252
- bids: {datatype: figures, desc: pepolar, suffix: fieldmap}
33-
caption: Inhomogeneities of the *B0* field introduce (oftentimes severe) spatial distortions
53+
caption: Inhomogeneities of the <em>B<sub>0</sub></em> field introduce (oftentimes severe) spatial distortions
3454
along the phase-encoding direction of the image. Utilizing two or more images with different
3555
phase-encoding polarities (PEPolar) or directions, it is possible to estimate the inhomogeneity
3656
of the field. The plot below shows a reference EPI (echo-planar imaging) volume generated
@@ -44,11 +64,16 @@ sections:
4464
reportlets:
4565
- bids: {datatype: figures, desc: validation, suffix: dwi}
4666
- bids: {datatype: figures, desc: brain, suffix: mask}
47-
caption: Average b=0 that serves for reference in early preprocessing steps.
48-
descriptions: The reference b=0 is obtained as the voxel-wise median across
49-
all b=0 found in the dataset, after accounting for signal drift.
50-
The red contour shows the brain mask calculated using this reference b=0.
51-
subtitle: Reference b=0 and brain mask
67+
caption: Average <em>b=0</em> that serves for reference in early preprocessing steps.
68+
descriptions: The reference <em>b=0</em> is obtained as the voxel-wise median across
69+
all <em>b=0</em> found in the dataset, after accounting for signal drift.
70+
The red contour shows the brain mask calculated using this reference <em>b=0</em>.
71+
subtitle: Reference <em>b=0</em> and brain mask
72+
- bids: {datatype: figures, desc: sdc, suffix: dwi}
73+
caption: Susceptibility distortions correction (SDC).
74+
description: The reportlet shows a <em>b=0</em> reference <em>before</em> and <em>after</em> distortion correction.
75+
static: false
76+
subtitle: Unwarping of susceptibility distortions
5277
- bids: {datatype: figures, desc: coreg, suffix: dwi}
5378
caption: Diffusion-weighted data and anatomical data (EPI-space and T1w-space)
5479
were aligned with <code>mri_coreg</code> (FreeSurfer).

dmriprep/data/boilerplate.bib

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,13 @@ @article{nipype1
4545
}
4646

4747
@article{nipype2,
48-
author = {Gorgolewski, Krzysztof J. and Esteban, Oscar and Markiewicz, Christopher J. and Ziegler, Erik and Ellis, David Gage and Notter, Michael Philipp and Jarecka, Dorota and Johnson, Hans and Burns, Christopher and Manhães-Savio, Alexandre and Hamalainen, Carlo and Yvernault, Benjamin and Salo, Taylor and Jordan, Kesshi and Goncalves, Mathias and Waskom, Michael and Clark, Daniel and Wong, Jason and Loney, Fred and Modat, Marc and Dewey, Blake E and Madison, Cindee and Visconti di Oleggio Castello, Matteo and Clark, Michael G. and Dayan, Michael and Clark, Dav and Keshavan, Anisha and Pinsard, Basile and Gramfort, Alexandre and Berleant, Shoshana and Nielson, Dylan M. and Bougacha, Salma and Varoquaux, Gael and Cipollini, Ben and Markello, Ross and Rokem, Ariel and Moloney, Brendan and Halchenko, Yaroslav O. and Wassermann , Demian and Hanke, Michael and Horea, Christian and Kaczmarzyk, Jakub and Gilles de Hollander and DuPre, Elizabeth and Gillman, Ashley and Mordom, David and Buchanan, Colin and Tungaraza, Rosalia and Pauli, Wolfgang M. and Iqbal, Shariq and Sikka, Sharad and Mancini, Matteo and Schwartz, Yannick and Malone, Ian B. and Dubois, Mathieu and Frohlich, Caroline and Welch, David and Forbes, Jessica and Kent, James and Watanabe, Aimi and Cumba, Chad and Huntenburg, Julia M. and Kastman, Erik and Nichols, B. Nolan and Eshaghi, Arman and Ginsburg, Daniel and Schaefer, Alexander and Acland, Benjamin and Giavasis, Steven and Kleesiek, Jens and Erickson, Drew and Küttner, René and Haselgrove, Christian and Correa, Carlos and Ghayoor, Ali and Liem, Franz and Millman, Jarrod and Haehn, Daniel and Lai, Jeff and Zhou, Dale and Blair, Ross and Glatard, Tristan and Renfro, Mandy and Liu, Siqi and Kahn, Ari E. and Pérez-García, Fernando and Triplett, William and Lampe, Leonie and Stadler, Jörg and Kong, Xiang-Zhen and Hallquist, Michael and Chetverikov, Andrey and Salvatore, John and Park, Anne and Poldrack, Russell and Craddock, R. Cameron and Inati, Souheil and Hinds, Oliver and Cooper, Gavin and Perkins, L. Nathan and Marina, Ana and Mattfeld, Aaron and Noel, Maxime and Lukas Snoek and Matsubara, K and Cheung, Brian and Rothmei, Simon and Urchs, Sebastian and Durnez, Joke and Mertz, Fred and Geisler, Daniel and Floren, Andrew and Gerhard, Stephan and Sharp, Paul and Molina-Romero, Miguel and Weinstein, Alejandro and Broderick, William and Saase, Victor and Andberg, Sami Kristian and Harms, Robbert and Schlamp, Kai and Arias, Jaime and Papadopoulos Orfanos, Dimitri and Tarbert, Claire and Tambini, Arielle and De La Vega, Alejandro and Nickson, Thomas and Brett, Matthew and Falkiewicz, Marcel and Podranski, Kornelius and Linkersdörfer, Janosch and Flandin, Guillaume and Ort, Eduard and Shachnev, Dmitry and McNamee, Daniel and Davison, Andrew and Varada, Jan and Schwabacher, Isaac and Pellman, John and Perez-Guevara, Martin and Khanuja, Ranjeet and Pannetier, Nicolas and McDermottroe, Conor and Ghosh, Satrajit},
49-
title = {Nipype},
50-
year = 2018,
48+
author = {Esteban, Oscar and Markiewicz, Christopher J. and Burns, Christopher and Goncalves, Mathias and Jarecka, Dorota and Ziegler, Erik and Berleant, Shoshana and Ellis, David Gage and Pinsard, Basile and Madison, Cindee and Waskom, Michael and Notter, Michael Philipp and Clark, Daniel and Manhães-Savio, Alexandre and Clark, Dav and Jordan, Kesshi and Dayan, Michael and Halchenko, Yaroslav O. and Loney, Fred and Salo, Taylor and Dewey, Blake E and Johnson, Hans and Bougacha, Salma and Keshavan, Anisha and Yvernault, Benjamin and Hamalainen, Carlo and Christian, Horea and Ćirić, Rastko and Dubois, Mathieu and Joseph, Michael and Cipollini, Ben and Tilley II, Steven and Visconti di Oleggio Castello, Matteo and Wong, Jason and De La Vega, Alejandro and Kaczmarzyk, Jakub and Huntenburg, Julia M. and Clark, Michael G. and Benderoff, Erin and Erickson, Drew and Kent, James D. and Hanke, Michael and Giavasis, Steven and Moloney, Brendan and Nichols, B. Nolan and Tungaraza, Rosalia and Frohlich, Caroline and Wassermann, Demian and de Hollander, Gilles and Eshaghi, Arman and Millman, Jarrod and Mancini, Matteo and Nielson, Dylan M. and Varoquaux, Gael and Watanabe, Aimi and Mordom, David and Guillon, Jérémy and Koudoro, Serge and Chetverikov, Andrey and Rokem, Ariel and Acland, Benjamin and Forbes, Jessica and Markello, Ross and Gillman, Ashley and Kong, Xiang-Zhen and Geisler, Daniel and Salvatore, John and Gramfort, Alexandre and Doll, Anna and Buchanan, Colin and DuPre, Elizabeth and Liu, Siqi and Schaefer, Alexander and Kleesiek, Jens and Sikka, Sharad and Schwartz, Yannick and Lee, John A. and Mattfeld, Aaron and Richie-Halford, Adam and Liem, Franz and Perez-Guevara, Martin Felipe and Heinsfeld, Anibal Sólon and Haselgrove, Christian and Durnez, Joke and Lampe, Leonie and Poldrack, Russell and Glatard, Tristan and Tabas, Alejandro and Cumba, Chad and Pérez-García, Fernando and Blair, Ross and Iqbal, Shariq and Welch, David and Triplett, William and Ghayoor, Ali and Craddock, R. Cameron and Correa, Carlos and Papadopoulos Orfanos, Dimitri and Stadler, Jörg and Warner, Joshua and Sisk, Lucinda M. and Falkiewicz, Marcel and Sharp, Paul and Rothmei, Simon and Kim, Sin and Weinstein, Alejandro and Kahn, Ari E. and Kastman, Erik and Bottenhorn, Katherine and Grignard, Martin and Perkins, L. Nathan and Contier, Oliver and Zhou, Dale and Bielievtsov, Dmytro and Cooper, Gavin and Stojic, Hrvoje and Linkersdörfer, Janosch and Waller, Lea and Renfro, Mandy and Hinds, Oliver and Stanley, Olivia and Küttner, René and Pauli, Wolfgang M. and Glen, Daniel and Kimbler, Adam and Meyers, Benjamin and Tarbert, Claire and Ginsburg, Daniel and Haehn, Daniel and Margulies, Daniel S. and Ma, Feilong and Malone, Ian B. and Snoek, Lukas and Brett, Matthew and Cieslak, Matthew and Hallquist, Michael and Molina-Romero, Miguel and Bilgel, Murat and Lee, Nat and Inati, Souheil and Gerhard, Stephan and Mathotaarachchi, Sulantha and Saase, Victor and Van, Andrew and Steele, Christopher John and Ort, Eduard and Condamine, Eric and Lerma-Usabiaga, Garikoitz and Schwabacher, Isaac and Arias, Jaime and Lai, Jeff and Pellman, John and Huguet, Jordi and Junhao WEN and Leinweber, Katrin and Chawla, Kshitij and Weninger, Leon and Modat, Marc and Harms, Robbert and Andberg, Sami Kristian and Baratz, Zvi and Matsubara, K and González Orozco, Abel A. and Marina, Ana and Davison, Andrew and Floren, Andrew and Park, Anne and Cheung, Brian and McDermottroe, Conor and McNamee, Daniel and Shachnev, Dmitry and Flandin, Guillaume and Gonzalez, Ivan and Varada, Jan and Schlamp, Kai and Podranski, Kornelius and Huang, Lijie and Noel, Maxime and Crusoe, Michael R. and Pannetier, Nicolas and Khanuja, Ranjeet and Urchs, Sebastian and Nickson, Thomas and Huang, Lijie and Broderick, William and Tambini, Arielle and Mihai, Paul Glad and Gorgolewski, Krzysztof J. and Ghosh, Satrajit},
49+
title = {Nipype: neuroimaging in {Python} - pipelines and interfaces},
5150
doi = {10.5281/zenodo.596855},
5251
publisher = {Zenodo},
53-
journal = {Software}
52+
journal = {Software},
53+
year = 2020,
54+
keywords = {neuroimaging, pipeline, workflow}
5455
}
5556

5657
@article{n4,

dmriprep/workflows/base.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ def init_single_subject_wf(subject_id):
253253
spaces=spaces,
254254
t1w=subject_data["t1w"],
255255
)
256+
anat_preproc_wf.__desc__ = f"\n\n{anat_preproc_wf.__desc__}"
256257

257258
# fmt:off
258259
workflow.connect([
@@ -290,17 +291,16 @@ def init_single_subject_wf(subject_id):
290291

291292
# Append the dMRI section to the existing anatomical excerpt
292293
# That way we do not need to stream down the number of DWI datasets
293-
anat_preproc_wf.__postdesc__ = (
294-
(anat_preproc_wf.__postdesc__ or "")
295-
+ f"""
294+
anat_preproc_wf.__postdesc__ = f"""\
295+
{anat_preproc_wf.__postdesc__ or ''}
296+
296297
Diffusion data preprocessing
297298
298299
: For each of the {len(subject_data["dwi"])} DWI scans found per subject
299300
(across all sessions), the gradient table was vetted and converted into the *RASb*
300301
format (i.e., given in RAS+ scanner coordinates, normalized b-vectors and scaled b-values),
301302
and a *b=0* average for reference to the subsequent steps of preprocessing was calculated.
302303
"""
303-
)
304304

305305
# SDC Step 0: Determine whether fieldmaps can/should be estimated
306306
fmap_estimators = None
@@ -360,6 +360,12 @@ def init_single_subject_wf(subject_id):
360360
output_dir=str(output_dir),
361361
subject=subject_id,
362362
)
363+
fmap_wf.__desc__ = f"""
364+
*B<sub>0</sub>* fieldmap data preprocessing
365+
366+
: A total of {len(fmap_estimators)} fieldmaps were found available within the input
367+
BIDS structure for this particular subject.
368+
"""
363369

364370
# TODO: Requires nipreps/sdcflows#147
365371
for dwi_preproc_wf in dwi_preproc_list:

dmriprep/workflows/dwi/base.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ def init_dwi_preproc_wf(dwi_file, has_fieldmap=False):
5252
fmap_id
5353
The BIDS modality label of the fieldmap being used
5454
55-
5655
Outputs
5756
-------
5857
dwi_reference
@@ -81,13 +80,17 @@ def init_dwi_preproc_wf(dwi_file, has_fieldmap=False):
8180
)
8281

8382
if has_fieldmap:
83+
import re
8484
from sdcflows.fieldmaps import get_identifier
8585

86-
estimator_key = get_identifier(dwi_file)
86+
dwi_rel = re.sub(
87+
r"^sub-[a-zA-Z0-9]*/", "", str(dwi_file.relative_to(layout.root))
88+
)
89+
estimator_key = get_identifier(dwi_rel)
8790
if not estimator_key:
8891
has_fieldmap = False
8992
config.loggers.workflow.critical(
90-
f"None of the available B0 fieldmaps are associated to <{dwi_file}>"
93+
f"None of the available B0 fieldmaps are associated to <{dwi_rel}>"
9194
)
9295

9396
# Build workflow
@@ -167,7 +170,8 @@ def init_dwi_preproc_wf(dwi_file, has_fieldmap=False):
167170

168171
ds_report_reg = pe.Node(
169172
DerivativesDataSink(
170-
base_directory=str(config.execution.output_dir), datatype="figures",
173+
base_directory=str(config.execution.output_dir),
174+
datatype="figures",
171175
),
172176
name="ds_report_reg",
173177
run_without_submitting=True,
@@ -198,7 +202,10 @@ def _bold_reg_suffix(fallback):
198202
# fmt: on
199203

200204
# REPORTING ############################################################
201-
reportlets_wf = init_reportlets_wf(str(config.execution.output_dir))
205+
reportlets_wf = init_reportlets_wf(
206+
str(config.execution.output_dir),
207+
sdc_report=has_fieldmap,
208+
)
202209
# fmt: off
203210
workflow.connect([
204211
(inputnode, reportlets_wf, [("dwi_file", "inputnode.source_file")]),
@@ -221,14 +228,20 @@ def _bold_reg_suffix(fallback):
221228
# fmt: on
222229
return workflow
223230

231+
from niworkflows.interfaces import SimpleBeforeAfter
224232
from niworkflows.interfaces.utility import KeySelect
225233
from sdcflows.workflows.apply.registration import init_coeff2epi_wf
226234
from sdcflows.workflows.apply.correction import init_unwarp_wf
227235

228236
coeff2epi_wf = init_coeff2epi_wf(
229-
omp_nthreads=config.nipype.omp_nthreads, write_coeff=True
237+
debug=config.execution.debug,
238+
omp_nthreads=config.nipype.omp_nthreads,
239+
write_coeff=True,
240+
)
241+
unwarp_wf = init_unwarp_wf(
242+
debug=config.execution.debug,
243+
omp_nthreads=config.nipype.omp_nthreads
230244
)
231-
unwarp_wf = init_unwarp_wf(omp_nthreads=config.nipype.omp_nthreads)
232245
unwarp_wf.inputs.inputnode.metadata = layout.get_metadata(str(dwi_file))
233246

234247
output_select = pe.Node(
@@ -243,6 +256,12 @@ def _bold_reg_suffix(fallback):
243256
f"'IntendedFor' <{dwi_file}>, using {estimator_key[0]}"
244257
)
245258

259+
sdc_report = pe.Node(
260+
SimpleBeforeAfter(before_label="Distorted", after_label="Corrected",),
261+
name="sdc_report",
262+
mem_gb=0.1,
263+
)
264+
246265
# fmt: off
247266
workflow.connect([
248267
(inputnode, output_select, [("fmap", "fmap"),
@@ -260,7 +279,12 @@ def _bold_reg_suffix(fallback):
260279
(dwi_reference_wf, unwarp_wf, [("outputnode.ref_image", "inputnode.distorted")]),
261280
(coeff2epi_wf, unwarp_wf, [
262281
("outputnode.fmap_coeff", "inputnode.fmap_coeff")]),
263-
(unwarp_wf, outputnode, [("outputnode.corrected", "dwi_reference")]),
282+
(dwi_reference_wf, sdc_report, [("outputnode.ref_image", "before")]),
283+
(unwarp_wf, sdc_report, [("outputnode.corrected", "after"),
284+
("outputnode.corrected_mask", "wm_seg")]),
285+
(sdc_report, reportlets_wf, [("out_report", "inputnode.sdc_report")]),
286+
(unwarp_wf, outputnode, [("outputnode.corrected", "dwi_reference"),
287+
("outputnode.corrected_mask", "dwi_mask")]),
264288
])
265289
# fmt: on
266290

dmriprep/workflows/dwi/outputs.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
from ...interfaces import DerivativesDataSink
66

77

8-
def init_reportlets_wf(output_dir, name="reportlets_wf"):
8+
def init_reportlets_wf(output_dir, sdc_report=False, name="reportlets_wf"):
99
"""Set up a battery of datasinks to store reports in the right location."""
1010
from niworkflows.interfaces.masks import SimpleShowMaskRPT
1111

1212
workflow = Workflow(name=name)
1313

1414
inputnode = pe.Node(
1515
niu.IdentityInterface(
16-
fields=["source_file", "dwi_ref", "dwi_mask", "validation_report"]
16+
fields=["source_file", "dwi_ref", "dwi_mask", "validation_report", "sdc_report"]
1717
),
1818
name="inputnode",
1919
)
@@ -44,4 +44,18 @@ def init_reportlets_wf(output_dir, name="reportlets_wf"):
4444
(mask_reportlet, ds_report_mask, [("out_report", "in_file")]),
4545
])
4646
# fmt:on
47+
if sdc_report:
48+
ds_report_sdc = pe.Node(
49+
DerivativesDataSink(
50+
base_directory=output_dir, desc="sdc", suffix="dwi", datatype="figures"
51+
),
52+
name="ds_report_sdc",
53+
run_without_submitting=True,
54+
)
55+
# fmt:off
56+
workflow.connect([
57+
(inputnode, ds_report_sdc, [("source_file", "source_file"),
58+
("sdc_report", "in_file")]),
59+
])
60+
# fmt:on
4761
return workflow

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ install_requires =
2929
numpy
3030
pybids >= 0.11.1
3131
pyyaml
32-
sdcflows @ git+https://github.com/nipreps/sdcflows.git@9b5c167d81e7670ef2121151b2d59fe190c0167c
32+
sdcflows @ git+https://github.com/nipreps/sdcflows.git@f0765424eaf171fc143a6c1d58a221051ee76926
3333
smriprep >= 0.8.0rc0
3434
templateflow ~= 0.6
3535
toml

0 commit comments

Comments
 (0)