diff --git a/fmriprep/utils/bids.py b/fmriprep/utils/bids.py index 0bdc03ff..3f5a27a0 100644 --- a/fmriprep/utils/bids.py +++ b/fmriprep/utils/bids.py @@ -68,14 +68,28 @@ def collect_derivatives( continue derivs_cache[f'{k}_boldref'] = item[0] if len(item) == 1 else item + transforms_cache = {} for xfm, q in spec['transforms'].items(): - query = {**q, **entities} + # Transform extension will often not match provided entities + # (e.g., ".nii.gz" vs ".txt"). + # And transform suffixes will be "xfm", + # whereas relevant src file will be "bold". + query = { + **q, + **{ + k: v + for k, v in entities.items() + if k not in ['suffix', 'extension'] + }, + } if xfm == 'boldref2fmap': - query['to'] = fieldmap_id - item = layout.get(return_type='filename', **q) + # fieldmaps have ids like auto_00000 + query['to'] = fieldmap_id.replace('_', '') + item = layout.get(return_type='filename', **query) if not item: continue - derivs_cache[xfm] = item[0] if len(item) == 1 else item + transforms_cache[xfm] = item[0] if len(item) == 1 else item + derivs_cache['transforms'] = transforms_cache return derivs_cache diff --git a/fmriprep/utils/tests/test_derivative_cache.py b/fmriprep/utils/tests/test_derivative_cache.py new file mode 100644 index 00000000..b6977720 --- /dev/null +++ b/fmriprep/utils/tests/test_derivative_cache.py @@ -0,0 +1,44 @@ +import json +from pathlib import Path + +import pytest + +from fmriprep.data import load as load_data +from fmriprep.utils import bids + + +@pytest.mark.parametrize('xfm', ['boldref2fmap', 'boldref2anat', 'hmc']) +def test_transforms_found_as_str(tmp_path: Path, xfm: str): + spec = ( + json.loads(load_data.readable('io_spec.json').read_text()) + .get('queries') + .get('transforms') + .get(xfm) + ) + entities = { + 'subject': '0', + 'task': 'rest', + 'suffix': 'bold', + 'extension': '.nii.gz', + } + if xfm == 'boldref2fmap': + to_find = f'sub-{entities['subject']}_task-{entities['task']} \ + _from-{spec['from']}_to-auto00000_mode-image_xfm.txt' + else: + to_find = f'sub-{entities['subject']}_task-{entities['task']} \ + _from-{spec['from']}_to-{spec['to']}_mode-image_xfm.txt' + + funcd = tmp_path / f'sub-{entities['subject']}' / 'func' + funcd.mkdir(parents=True) + (funcd / to_find).touch() + + derivs = bids.collect_derivatives( + derivatives_dir=tmp_path, + entities=entities, + fieldmap_id='auto_00000', + ) + transforms_in_derivs = 'transforms' in derivs + xfm_in_transforms = xfm in derivs.get('transforms') + transform_is_str = isinstance(derivs.get('transforms').get(xfm), str) + assert all((transforms_in_derivs, xfm_in_transforms, transform_is_str)) +