From 7868b64c4e819d813b546c31d4a998c5f47e9502 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Thu, 24 Oct 2024 11:36:04 -0400 Subject: [PATCH 1/5] fix(report): Resample fieldmap for plotting --- fmriprep/workflows/bold/outputs.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/fmriprep/workflows/bold/outputs.py b/fmriprep/workflows/bold/outputs.py index 70d1a4ac..1be3f7eb 100644 --- a/fmriprep/workflows/bold/outputs.py +++ b/fmriprep/workflows/bold/outputs.py @@ -316,6 +316,18 @@ def init_func_fit_reports_wf( mem_gb=1, ) + fmap_boldref = pe.Node( + ApplyTransforms( + dimension=3, + default_value=0, + float=True, + invert_transform_flags=[True], + interpolation='LanczosWindowedSinc', + ), + name='fmap_boldref', + mem_gb=1, + ) + # SDC1 sdcreg_report = pe.Node( FieldmapReportlet( @@ -323,7 +335,7 @@ def init_func_fit_reports_wf( moving_label='Fieldmap reference', show='both', ), - name='sdecreg_report', + name='sdcreg_report', mem_gb=0.1, ) @@ -360,19 +372,23 @@ def init_func_fit_reports_wf( name='ds_sdc_report', ) - # fmt:off workflow.connect([ (inputnode, fmapref_boldref, [ ('fmap_ref', 'input_image'), ('coreg_boldref', 'reference_image'), ('boldref2fmap_xfm', 'transforms'), ]), + (inputnode, fmap_boldref, [ + ('fieldmap', 'input_image'), + ('coreg_boldref', 'reference_image'), + ('boldref2fmap_xfm', 'transforms'), + ]), (inputnode, sdcreg_report, [ ('sdc_boldref', 'reference'), - ('fieldmap', 'fieldmap'), ('bold_mask', 'mask'), ]), (fmapref_boldref, sdcreg_report, [('output_image', 'moving')]), + (fmap_boldref, sdcreg_report, [('output_image', 'fieldmap')]), (inputnode, ds_sdcreg_report, [('source_file', 'source_file')]), (sdcreg_report, ds_sdcreg_report, [('out_report', 'in_file')]), (inputnode, sdc_report, [ @@ -382,8 +398,7 @@ def init_func_fit_reports_wf( (boldref_wm, sdc_report, [('output_image', 'wm_seg')]), (inputnode, ds_sdc_report, [('source_file', 'source_file')]), (sdc_report, ds_sdc_report, [('out_report', 'in_file')]), - ]) - # fmt:on + ]) # fmt:skip # EPI-T1 registration # Resample T1w image onto EPI-space From c64bbb9fc696232d7be3aaaa71e316291e0b5093 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Thu, 24 Oct 2024 12:05:06 -0400 Subject: [PATCH 2/5] doc: Add changelog entry --- CHANGES.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index d04bde35..4bccb7fe 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,10 @@ +24.1.2 (To be determined) +========================= +Bug fix release in the 24.1.x series. + +* FIX: Ensure fieldmap is resampled correctly in report (#3387) + + 24.1.1 (October 10, 2024) ========================= Bug fix release in the 24.1.x series. From c4014f2d1b0d58df1acfdac0f877d3ec872a7475 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Thu, 24 Oct 2024 12:05:19 -0400 Subject: [PATCH 3/5] doc: Normalize changelog --- CHANGES.rst | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 4bccb7fe..fbc51b57 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -12,10 +12,11 @@ Bug fix release in the 24.1.x series. Precomputed functional derivatives were not being correcly detected, and a couple fixes for rare issues. - * FIX: Remove checks for unit zooms and symmetric rotations in template warp (#3376) - * FIX: Stop excluding FS minc_modify_header used during fallback registration (#3372) - * FIX: Repair search for precomputed bold references (#3370) - * FIX: Repair search for precomputed transforms (#3369) +* FIX: Remove checks for unit zooms and symmetric rotations in template warp (#3376) +* FIX: Stop excluding FS minc_modify_header used during fallback registration (#3372) +* FIX: Repair search for precomputed bold references (#3370) +* FIX: Repair search for precomputed transforms (#3369) + 24.1.0 (September 16, 2024) =========================== @@ -23,12 +24,13 @@ New feature release in the 24.1.x series. Handling of gradient echo fieldmaps is improved. - * FIX: Select volumetric dseg.tsv from recent TemplateFlow releases (#3257) - * RF: Adapt to less T1w-centric smriprep (#3333) - * RF: Use acres over vendored data loader (#3323) - * DOC: Add benchmark page (#3312) - * MAINT: Move to tox to simplify test/CI setup (#3326) - * CI: Fix expected outputs for fieldmaps (#3321) +* FIX: Select volumetric dseg.tsv from recent TemplateFlow releases (#3257) +* RF: Adapt to less T1w-centric smriprep (#3333) +* RF: Use acres over vendored data loader (#3323) +* DOC: Add benchmark page (#3312) +* MAINT: Move to tox to simplify test/CI setup (#3326) +* CI: Fix expected outputs for fieldmaps (#3321) + 24.0.1 (July 16, 2024) ====================== From f1a67c01df4e375a7d23244dd75619658c70c44c Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Tue, 10 Dec 2024 17:15:30 -0500 Subject: [PATCH 4/5] fix: Listify sessions when generating reports --- fmriprep/reports/core.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fmriprep/reports/core.py b/fmriprep/reports/core.py index 33fb92f7..6926d720 100644 --- a/fmriprep/reports/core.py +++ b/fmriprep/reports/core.py @@ -76,6 +76,8 @@ def generate_reports( if isinstance(subject_list, str): subject_list = [subject_list] + if isinstance(session_list, str): + session_list = [session_list] errors = [] for subject_label in subject_list: From 5c55606a8f2467c7429fd6435870df8eb4e9865c Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Tue, 10 Dec 2024 17:25:28 -0500 Subject: [PATCH 5/5] fix: Use removeprefix instead of lstrip or ternary operator --- fmriprep/cli/parser.py | 5 +---- fmriprep/reports/core.py | 8 ++++---- fmriprep/utils/bids.py | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/fmriprep/cli/parser.py b/fmriprep/cli/parser.py index 63b4cd9d..635724cb 100644 --- a/fmriprep/cli/parser.py +++ b/fmriprep/cli/parser.py @@ -105,9 +105,6 @@ def _to_gb(value): units = value[len(digits) :] or 'M' return int(digits) * scale[units[0]] - def _drop_sub(value): - return value[4:] if value.startswith('sub-') else value - def _process_value(value): import bids @@ -205,7 +202,7 @@ def _slice_time_ref(value, parser): '--participant_label', action='store', nargs='+', - type=_drop_sub, + type=lambda label: label.removeprefix('sub-'), help='A space delimited list of participant identifiers or a single ' 'identifier (the sub- prefix can be removed)', ) diff --git a/fmriprep/reports/core.py b/fmriprep/reports/core.py index 33fb92f7..9544ea32 100644 --- a/fmriprep/reports/core.py +++ b/fmriprep/reports/core.py @@ -79,6 +79,7 @@ def generate_reports( errors = [] for subject_label in subject_list: + subject_label = subject_label.removeprefix('sub-') # The number of sessions is intentionally not based on session_list but # on the total number of sessions, because I want the final derivatives # folder to be the same whether sessions were run one at a time or all-together. @@ -95,7 +96,7 @@ def generate_reports( else: # Beyond a threshold, we separate the anatomical report from the functional. bootstrap_file = data.load('reports-spec-anat.yml') - html_report = f'sub-{subject_label.lstrip("sub-")}_anat.html' + html_report = f'sub-{subject_label}_anat.html' report_error = run_reports( output_dir, @@ -121,12 +122,11 @@ def generate_reports( subject=subject_label, **filters ) - # Drop ses- prefixes - session_list = [ses[4:] if ses.startswith('ses-') else ses for ses in session_list] + session_list = [ses.removeprefix('ses-') for ses in session_list] for session_label in session_list: bootstrap_file = data.load('reports-spec-func.yml') - html_report = f'sub-{subject_label.lstrip("sub-")}_ses-{session_label}_func.html' + html_report = f'sub-{subject_label}_ses-{session_label}_func.html' report_error = run_reports( output_dir, diff --git a/fmriprep/utils/bids.py b/fmriprep/utils/bids.py index 5ca78d91..f700ed06 100644 --- a/fmriprep/utils/bids.py +++ b/fmriprep/utils/bids.py @@ -217,7 +217,7 @@ def validate_input_dir(exec_env, bids_dir, participant_label, need_T1w=True): # Limit validation only to data from requested participants if participant_label: all_subs = {s.name[4:] for s in bids_dir.glob('sub-*')} - selected_subs = {s[4:] if s.startswith('sub-') else s for s in participant_label} + selected_subs = {s.removeprefix('sub-') for s in participant_label} bad_labels = selected_subs.difference(all_subs) if bad_labels: error_msg = (