Skip to content

Refactor of BIDSDataGrabber to allow grabbing without functional data #947

Closed
@mnoergaard

Description

@mnoergaard

What happened?

As a part of the refactor of fMRIPrep to PETPrep, the data is currently being collected using the BIDSDataGrabber interface in niworkflows. However, this interface is currently expecting functional (i.e. bold) data to be present, if the --anat-only flag is not specified. However, for the refactor of PETPrep, a normal case would be to have the anatomical data and the dynamic PET data, and so the current solution would not work, unless the _require_funcs could be set to false. Currently, I have updated the BIDSDataGrabber interface to look like this, and could also just include it locally in petprep for now, if it is problematic to change it within niworkflows.

"class _BIDSDataGrabberInputSpec(BaseInterfaceInputSpec):
subject_data = traits.Dict(Str, traits.Any)
subject_id = Str()

class _BIDSDataGrabberOutputSpec(TraitedSpec):
out_dict = traits.Dict(desc='output data structure')
fmap = OutputMultiObject(desc='output fieldmaps')
bold = OutputMultiObject(desc='output functional images')
sbref = OutputMultiObject(desc='output sbrefs')
t1w = OutputMultiObject(desc='output T1w images')
roi = OutputMultiObject(desc='output ROI images')
t2w = OutputMultiObject(desc='output T2w images')
flair = OutputMultiObject(desc='output FLAIR images')
pet = OutputMultiObject(desc='output PET images')
dwi = OutputMultiObject(desc='output DWI images')
asl = OutputMultiObject(desc='output ASL images')

class BIDSDataGrabber(SimpleInterface):
"""
Collect files from a BIDS directory structure.

.. testsetup::

    >>> data_dir_canary()

>>> bids_src = BIDSDataGrabber(anat_only=False)
>>> bids_src.inputs.subject_data = bids_collect_data(
...     str(datadir / 'ds114'), '01', bids_validate=False)[0]
>>> bids_src.inputs.subject_id = '01'
>>> res = bids_src.run()
>>> res.outputs.t1w  # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
['.../ds114/sub-01/ses-retest/anat/sub-01_ses-retest_T1w.nii.gz',
 '.../ds114/sub-01/ses-test/anat/sub-01_ses-test_T1w.nii.gz']

"""

input_spec = _BIDSDataGrabberInputSpec
output_spec = _BIDSDataGrabberOutputSpec
_require_funcs = False

def __init__(self, *args, **kwargs):
    anat_only = kwargs.pop('anat_only', None)
    anat_derivatives = kwargs.pop('anat_derivatives', None)
    require_t1w = kwargs.pop('require_t1w', True)
    super().__init__(*args, **kwargs)
    if anat_only is not None:
        self._require_funcs = not anat_only
    self._require_t1w = require_t1w and anat_derivatives is None

def _run_interface(self, runtime):
    bids_dict = self.inputs.subject_data

    self._results['out_dict'] = bids_dict
    self._results.update(bids_dict)

    if self._require_t1w and not bids_dict['t1w']:
        raise FileNotFoundError(
            f'No T1w images found for subject sub-{self.inputs.subject_id}'
        )

    for imtype in ['t2w', 'flair', 'fmap', 'sbref', 'roi', 'pet', 'asl']:
        if not bids_dict[imtype]:
            LOGGER.info('No "%s" images found for sub-%s', imtype, self.inputs.subject_id)

    return runtime" 

What command did you use?

fmriprep /Users/martinnorgaard/Documents/GitHub/petprep_dev/fmriprep/data/tests/pet /Users/martinnorgaard/Documents/GitHub/petprep_dev/fmriprep/data/tests/pet/derivatives participant --fs-subjects-dir /Users/martinnorgaard/Documents/GitHub/petprep_dev/fmriprep/data/tests/pet/derivatives/freesurfer --reference-frame 10 --no-msm --skull-strip-t1w skip

What version of the software are you running?

1.13.3

How are you running this software?

Local installation ("bare-metal")

Is your data BIDS valid?

Yes

Are you reusing any previously computed results?

FreeSurfer

Please copy and paste any relevant log output.

Additional information / screenshots

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions