From eacffcf48c85bc15a59c3b1cd759e27582f9731e Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Thu, 6 Oct 2022 15:25:50 +0200 Subject: [PATCH 1/6] MAINT: Keep workflow up with debug/sloppy in sdcflows' workflow Follows-up with nipreps/sdcflows#287 --- fmriprep/workflows/bold/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index 961115b77..a4fcd6d79 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -1111,6 +1111,7 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False): coeff2epi_wf = init_coeff2epi_wf( debug="fieldmaps" in config.execution.debug, omp_nthreads=config.nipype.omp_nthreads, + sloppy=config.execution.sloppy, write_coeff=True, ) unwarp_wf = init_unwarp_wf( From 0f569f7878aaa1cfed5ae7026fd88eb42b7965e1 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Thu, 6 Oct 2022 17:01:27 +0200 Subject: [PATCH 2/6] enh: add reportlet generation when debugging fieldmaps --- fmriprep/data/reports-spec.yml | 18 +++++---- fmriprep/workflows/bold/base.py | 68 +++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 8 deletions(-) diff --git a/fmriprep/data/reports-spec.yml b/fmriprep/data/reports-spec.yml index 76f259e2b..d85036f5e 100644 --- a/fmriprep/data/reports-spec.yml +++ b/fmriprep/data/reports-spec.yml @@ -76,17 +76,19 @@ sections: reportlets: - bids: {datatype: figures, desc: summary, suffix: bold} - bids: {datatype: figures, desc: validation, suffix: bold} - - bids: {datatype: figures, desc: fieldmap, suffix: bold} + - bids: {datatype: figures, desc: fmapCoreg, suffix: bold} caption: The estimated fieldmap was aligned to the corresponding EPI reference - with a rigid-registration process of the magnitude part of the fieldmap, + with a rigid-registration process of the anatomical reference of the fieldmap, using antsRegistration. - Overlaid on top of the co-registration results, the displacements along the - phase-encoding direction are represented in arbitrary units. - Please note that the color scale is centered around zero (i.e. full transparency), - but the extremes might be different (i.e., the maximum of red colors could be - orders of magnitude above or below the minimum of blue colors.) + Overlaid on top of the co-registration results, the final BOLD mask is represented + with a red contour for reference. static: false - subtitle: Estimated fieldmap and alignment to the corresponding EPI reference + subtitle: Alignment between the anatomical reference of the fieldmap and the target EPI (debug mode) + - bids: {datatype: figures, space: boldrun, suffix: fieldmap} + caption: Estimated fieldmap, as reconstructed on the target BOLD run space to allow + the assessment of its alignement with the distorted data. + static: false + subtitle: "Reconstructed B0 map in the corresponding run's space (debug mode)" - bids: {datatype: figures, desc: sdc, suffix: bold} caption: Results of performing susceptibility distortion correction (SDC) on the EPI diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index a4fcd6d79..f361858ae 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -1187,6 +1187,74 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False): ]) # fmt:on + if "fieldmaps" in config.execution.debug: + # Generate additional reportlets to assess SDC + from sdcflows.utils.misc import front as _pop + from sdcflows.interfaces.reportlets import FieldmapReportlet + + # First, one for checking the co-registration between fieldmap and EPI + sdc_coreg_report = pe.Node( + SimpleBeforeAfter( + before_label="Distorted target", + after_label="Fieldmap ref.", + ), + name="sdc_coreg_report", + mem_gb=0.1, + ) + ds_report_sdc_coreg = pe.Node( + DerivativesDataSink( + base_directory=fmriprep_dir, + datatype="figures", + desc="fmapCoreg", + dismiss_entities=("echo",), + suffix="bold", + ), + name="ds_report_sdc_coreg", + run_without_submitting=True, + ) + + # Second, showing the fieldmap reconstructed from coefficients in the EPI space + fmap_report = pe.Node(FieldmapReportlet(), "fmap_report") + fmap_report.interface._always_run = True + + ds_fmap_report = pe.Node( + DerivativesDataSink( + base_directory=fmriprep_dir, + datatype="figures", + space="boldrun", + dismiss_entities=("echo", ), + suffix="fieldmap", + ), + name="ds_fmap_report", + run_without_submitting=True, + ) + + # fmt:off + workflow.connect([ + (initial_boldref_wf, sdc_coreg_report, [ + ("outputnode.ref_image", "before"), + ]), + (coeff2epi_wf, sdc_coreg_report, [ + ("coregister.inverse_warped_image", "after"), + ]), + (final_boldref_wf, sdc_coreg_report, [ + ("outputnode.bold_mask", "wm_seg"), + ]), + (inputnode, ds_report_sdc_coreg, [("bold_file", "source_file")]), + (sdc_coreg_report, ds_report_sdc_coreg, [("out_report", "in_file")]), + (unwarp_wf, fmap_report, [(("outputnode.fieldmap", _pop), "fieldmap")]), + (coeff2epi_wf, fmap_report, [ + ("coregister.inverse_warped_image", "reference"), + ]), + (final_boldref_wf, fmap_report, [ + ("outputnode.bold_mask", "mask"), + ]), + + (fmap_report, ds_fmap_report, [("out_report", "in_file")]), + (inputnode, ds_fmap_report, [("bold_file", "source_file")]), + ]) + # fmt:on + if not multiecho: # fmt:off workflow.connect([ From f7cdfae867b6e1a4b2583c0f48a6c529aef8631e Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Fri, 7 Oct 2022 16:55:50 +0200 Subject: [PATCH 3/6] fix: revise reportlet naming at the output and improve report spec --- fmriprep/data/reports-spec.yml | 11 +++++++++-- fmriprep/workflows/bold/base.py | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/fmriprep/data/reports-spec.yml b/fmriprep/data/reports-spec.yml index d85036f5e..11ce4220d 100644 --- a/fmriprep/data/reports-spec.yml +++ b/fmriprep/data/reports-spec.yml @@ -66,7 +66,7 @@ sections: (for instance, T1w or T2w), it is possible to estimate the inhomogeneity of the field by means of nonlinear registration. The plot below shows a reference EPI (echo-planar imaging) volume generated using two or more EPI images with the same PE encoding, after alignment to the anatomical scan. - description: Hover on the panels with the mouse pointer to also visualize the intensity of the + description: Hover on the panels with the mouse pointer to also visualize the intensity of the inhomogeneity of the field in Hertz. static: false subtitle: "Preprocessed estimation by nonlinear registration to an anatomical scan (“fieldmap-less”)" @@ -84,9 +84,16 @@ sections: with a red contour for reference. static: false subtitle: Alignment between the anatomical reference of the fieldmap and the target EPI (debug mode) - - bids: {datatype: figures, space: boldrun, suffix: fieldmap} + - bids: {datatype: figures, desc: fieldmap, suffix: bold} caption: Estimated fieldmap, as reconstructed on the target BOLD run space to allow the assessment of its alignement with the distorted data. + The anatomical reference is the fieldmap's reference moved into the target EPI's grid through + the estimated transformation. + In other words, this plot should be equivalent to that of the + Preprocessed estimation with varying Phase-Encoding (PE) blips shown above in the + fieldmap section. + Therefore, the fieldmap should be positioned relative to the anatomical reference exactly + as it is positioned in the reportlet above. static: false subtitle: "Reconstructed B0 map in the corresponding run's space (debug mode)" - bids: {datatype: figures, desc: sdc, suffix: bold} diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index f361858ae..f039a9ad3 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -1221,9 +1221,9 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False): DerivativesDataSink( base_directory=fmriprep_dir, datatype="figures", - space="boldrun", + desc="fieldmap", dismiss_entities=("echo", ), - suffix="fieldmap", + suffix="bold", ), name="ds_fmap_report", run_without_submitting=True, From 5cd8c94e7b394488153e714b559071d96f07e98b Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Fri, 7 Oct 2022 17:04:26 +0200 Subject: [PATCH 4/6] sty: run black on edited file --- fmriprep/workflows/bold/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index f039a9ad3..89cb2fcb4 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -1189,8 +1189,8 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False): if "fieldmaps" in config.execution.debug: # Generate additional reportlets to assess SDC - from sdcflows.utils.misc import front as _pop from sdcflows.interfaces.reportlets import FieldmapReportlet + from sdcflows.utils.misc import front as _pop # First, one for checking the co-registration between fieldmap and EPI sdc_coreg_report = pe.Node( @@ -1222,7 +1222,7 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False): base_directory=fmriprep_dir, datatype="figures", desc="fieldmap", - dismiss_entities=("echo", ), + dismiss_entities=("echo",), suffix="bold", ), name="ds_fmap_report", From e9a6f355346b7c77a46e1d29ac49d71bb261e17b Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Sat, 8 Oct 2022 00:13:03 +0200 Subject: [PATCH 5/6] fix: pin development branch of SDCFlows --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 8cf65adc4..7ab81d494 100644 --- a/setup.cfg +++ b/setup.cfg @@ -35,7 +35,7 @@ install_requires = psutil >= 5.4 pybids >= 0.15.0 requests - sdcflows ~= 2.1.1 + sdcflows @ git+https://github.com/nipreps/sdcflows.git@master smriprep ~= 0.9.2 tedana ~= 0.0.9 templateflow >= 0.6 From 1a9aa1afbee360bde9acdaf25e0177c1658286be Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Mon, 10 Oct 2022 16:23:12 +0200 Subject: [PATCH 6/6] Apply suggestions from code review Co-authored-by: Mathias Goncalves --- fmriprep/workflows/bold/base.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index 89cb2fcb4..190383eed 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -1190,7 +1190,6 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False): if "fieldmaps" in config.execution.debug: # Generate additional reportlets to assess SDC from sdcflows.interfaces.reportlets import FieldmapReportlet - from sdcflows.utils.misc import front as _pop # First, one for checking the co-registration between fieldmap and EPI sdc_coreg_report = pe.Node( @@ -1215,7 +1214,6 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False): # Second, showing the fieldmap reconstructed from coefficients in the EPI space fmap_report = pe.Node(FieldmapReportlet(), "fmap_report") - fmap_report.interface._always_run = True ds_fmap_report = pe.Node( DerivativesDataSink( @@ -1242,7 +1240,7 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False): ]), (inputnode, ds_report_sdc_coreg, [("bold_file", "source_file")]), (sdc_coreg_report, ds_report_sdc_coreg, [("out_report", "in_file")]), - (unwarp_wf, fmap_report, [(("outputnode.fieldmap", _pop), "fieldmap")]), + (unwarp_wf, fmap_report, [(("outputnode.fieldmap", pop_file), "fieldmap")]), (coeff2epi_wf, fmap_report, [ ("coregister.inverse_warped_image", "reference"), ]),