Skip to content

Can't define 2 different B0FieldSource from the same fmap files for fMRIprep #510

@miltoncamacho

Description

@miltoncamacho

What happened?

When running fMRIprep on a subject with two fMRI runs I realized that only one of the fMRI runs where sdc. If I am using:

json of epi fmap1 AP
B0FieldIdentifier: ["sub-x_ses_1a_task1","sub-x_ses_1a_task2"]

json of epi fmap2 PA
B0FieldIdentifier: ["sub-x_ses_1a_task1","sub-x_ses_1a_task2"]

Then I try to use the independent B0FieldSource:

json of bold func1:
B0FieldSource: "sub-x_ses_1a_task1"

json of bold func2:
B0FieldSource: "sub-x_ses_1a_task2"

I get an error since the bidirectional dictionary in:

class bidict(dict):

requires unique keys and values and the values (fmap1 and fmap2) for both bids_id in func1 and func2 (

bids_id=b0_id,
) would be the same.

Was this the intended behaviour? Should I not be able to do this combination? There is probably a good reason for using the bidirectional dictionary that I don't know.

What command did you use?

You can replicate this with:

import shutil

from niworkflows.utils.testing import generate_bids_skeleton

from sdcflows.fieldmaps import clear_registry, get_identifier
from sdcflows.utils.wrangler import find_estimators

def gen_layout(bids_dir, database_dir=None):
    import re

    from bids.layout import BIDSLayout, BIDSLayoutIndexer

    _indexer = BIDSLayoutIndexer(
        validate=False,
        ignore=(
            'code',
            'stimuli',
            'sourcedata',
            'models',
            'derivatives',
            re.compile(r'^\.'),
            re.compile(r'sub-[a-zA-Z0-9]+(/ses-[a-zA-Z0-9]+)?/(beh|eeg|ieeg|meg|micr|perf)'),
        ),
    )

    layout_kwargs = {'indexer': _indexer}

    if database_dir:
        layout_kwargs['database_path'] = database_dir

    layout = BIDSLayout(bids_dir, **layout_kwargs)
    return layout


pepolar_b0ids = {
    '01': [
        {
            'session': '01',
            'anat': [{'suffix': 'T1w', 'metadata': {'EchoTime': 1}}],
            'func': [
                {
                    'task': 'rest',
                    'run': 1,
                    'suffix': 'bold',
                    'metadata': {
                        'RepetitionTime': 0.8,
                        'TotalReadoutTime': 0.5,
                        'PhaseEncodingDirection': 'j',
                        'B0FieldSource': 'b0_pepolar',
                    },
                },
                {
                    'task': 'rest',
                    'run': 2,
                    'suffix': 'bold',
                    'metadata': {
                        'RepetitionTime': 0.8,
                        'TotalReadoutTime': 0.5,
                        'PhaseEncodingDirection': 'j-',
                        'B0FieldSource': 'b0_pepolar_dub',
                    },
                },
            ],
            'fmap': [
                {
                    'run': 1,
                    'suffix': 'epi',
                    'metadata': {
                        'RepetitionTime': 0.8,
                        'TotalReadoutTime': 0.5,
                        'PhaseEncodingDirection': 'j',
                        'B0FieldIdentifier': ['b0_pepolar', 'b0_pepolar_dup'],
                    },
                },
                {
                    'run': 2,
                    'suffix': 'epi',
                    'metadata': {
                        'RepetitionTime': 0.8,
                        'TotalReadoutTime': 0.5,
                        'PhaseEncodingDirection': 'j-',
                        'B0FieldIdentifier': ['b0_pepolar', 'b0_pepolar_dup'],
                    },
                },
            ],
        },
    ]
}

filters = {
    'multi': {'session': '01', 'suffix': ['bold','epi']},
}
clear_registry()
tmpdir = "/tmp/path" #tmp folder where to generated the bids skeleton
bids_dir = str(tmpdir+"/pepolar_b0ids")
shutil.rmtree(bids_dir, ignore_errors=True)
generate_bids_skeleton(bids_dir, pepolar_b0ids)
layout = gen_layout(bids_dir)
est = find_estimators(layout=layout, subject='01', bids_filters=filters["multi"])

should get you:
In [5]: est
Out[5]: [FieldmapEstimation(sources=<2 files>, method=<EstimatorType.PEPOLAR: 2>, bids_id='b0_pepolar')]
but I would expect this to be 
Out[5]: [FieldmapEstimation(sources=<2 files>, method=<EstimatorType.PEPOLAR: 2>, bids_id='b0_pepolar'),FieldmapEstimation(sources=<2 files>, method=<EstimatorType.PEPOLAR: 2>, bids_id='b0_pepolar_dup')]

What version of the software are you running?

25.0.0.dev3+g52209e48a

How are you running this software?

Local installation ("bare-metal")

Is your data BIDS valid?

Yes

Are you reusing any previously computed results?

No

Please copy and paste any relevant log output.

I added some extra debugging statements:
[sdcflows.wrangler - DEBUG]: Dataset includes `B0FieldIdentifier` metadata.Any data missing this metadata will be ignored.
[sdcflows.wrangler - DEBUG]: Searching fieldmaps with B0FieldIdentifier=b0_pepolar
[sdcflows.wrangler - DEBUG]: Found bare_ids [] + listed_ids [<BIDSImageFile filename='/Users/milton/Desktop/tmp-sdcflows-test/pepolar_b0ids/sub-01/ses-01/fmap/sub-01_ses-01_run-1_epi.nii.gz'>, <BIDSImageFile filename='/Users/milton/Desktop/tmp-sdcflows-test/pepolar_b0ids/sub-01/ses-01/fmap/sub-01_ses-01_run-2_epi.nii.gz'>]
this is what the fielmap estimation class gets as bids_id: b0_pepolar
this is what the fielmap estimation class gets as paths: ('/Users/milton/Desktop/tmp-sdcflows-test/pepolar_b0ids/sub-01/ses-01/fmap/sub-01_ses-01_run-1_epi.nii.gz', '/Users/milton/Desktop/tmp-sdcflows-test/pepolar_b0ids/sub-01/ses-01/fmap/sub-01_ses-01_run-2_epi.nii.gz')
[sdcflows.wrangler - DEBUG]: Searching fieldmaps with B0FieldIdentifier=b0_pepolar_dup
[sdcflows.wrangler - DEBUG]: Found bare_ids [] + listed_ids [<BIDSImageFile filename='/Users/milton/Desktop/tmp-sdcflows-test/pepolar_b0ids/sub-01/ses-01/fmap/sub-01_ses-01_run-1_epi.nii.gz'>, <BIDSImageFile filename='/Users/milton/Desktop/tmp-sdcflows-test/pepolar_b0ids/sub-01/ses-01/fmap/sub-01_ses-01_run-2_epi.nii.gz'>]
this is what the fielmap estimation class gets as bids_id: b0_pepolar_dup
this is what the fielmap estimation class gets as paths: ('/Users/milton/Desktop/tmp-sdcflows-test/pepolar_b0ids/sub-01/ses-01/fmap/sub-01_ses-01_run-1_epi.nii.gz', '/Users/milton/Desktop/tmp-sdcflows-test/pepolar_b0ids/sub-01/ses-01/fmap/sub-01_ses-01_run-2_epi.nii.gz')

Additional information / screenshots

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions