Esempio n. 1
0
def test_as_list(x):
    y = utils.as_list(x)
    assert isinstance(y, list)
Esempio n. 2
0
def sweep_directory(
        derivatives_path,
        modality,
        space,
        subj=None,
        sesh=None,
        run=None):
    """
    Given a BIDS derivatives directory containing preprocessed functional MRI
    or diffusion MRI data (e.g. fMRIprep or dMRIprep), crawls the outputs and
    prepares necessary inputs for the PyNets pipeline.

    *Note: Since this function searches for derivative file inputs, it does
     not impose strict BIDS compliance, which can therefore create errors in
     the case that files are missing or redundant. Please ensure that there
     redundant files are removed and that BIDS naming conventions are
     followed closely.
    """

    if modality == "dwi":
        dwis = []
        bvals = []
        bvecs = []
    elif modality == "func":
        funcs = []
        confs = []
    masks = []
    anats = []

    # initialize BIDs tree on derivatives_path
    layout = bids.layout.BIDSLayout(
        derivatives_path, validate=False, derivatives=True, absolute_paths=True
    )

    # get all files matching the specific modality we are using
    all_subs = layout.get_subjects()
    if not subj:
        # list of all the subjects
        subjs = all_subs
    elif isinstance(subj, list):
        subjs = [sub for sub in subj if sub in all_subs]
    else:
        # make it a list so we can iterate
        subjs = as_list(subj)

    # Accommodate for different spaces
    if space is None:
        if modality == "dwi":
            spaces = layout.get_spaces(
                suffix="dwi", extension=[
                    ".nii", ".nii.gz"])
        elif modality == "func":
            spaces = layout.get_spaces(
                suffix="bold", extension=[
                    ".nii", ".nii.gz"])
        if spaces:
            spaces = sorted(spaces)
            space = spaces[0]
            if len(spaces) > 1:
                space_list = ", ".join(spaces)
                print(
                    f"No space was provided, but multiple spaces were "
                    f"detected: {space_list}. Selecting the first (ordered"
                    f" lexicographically): {space}")

    for sub in subjs:
        all_seshs = layout.get_sessions(subject=sub)
        if not sesh:
            seshs = all_seshs
            # in case there are non-session level inputs
            seshs += []
        elif isinstance(sesh, list):
            seshs = [ses for ses in sesh if ses in all_seshs]
        else:
            # make a list so we can iterate
            seshs = as_list(sesh)

        print(f"Subject: {sub}\nSession(s): {seshs}\nModality: {modality}")

        for ses in seshs:
            # the attributes for our modality img
            mod_attributes = [sub, ses]
            # the keys for our modality img
            mod_keys = ["subject", "session"]
            # our query we will use for each modality img
            mod_query = {"datatype": modality}

            for attr, key in zip(mod_attributes, mod_keys):
                if attr:
                    mod_query[key] = attr

            # grab anat
            anat_attributes = [sub, ses]
            anat_keys = ["subject", "session"]
            # our query for the anatomical image
            anat_query = {
                "datatype": "anat",
                "suffix": ["T1w", "anat"],
                "extension": [".nii", ".nii.gz"],
            }
            for attr, key in zip(anat_attributes, anat_keys):
                if attr:
                    anat_query[key] = attr
            # make a query to find the desired files from the BIDSLayout
            anat = layout.get(**anat_query)
            anat = [
                i for i in anat if "MNI" not in i.filename and "space" not in
                                   i.filename]
            if len(anat) > 1 and run is not None:
                anat = [i for i in anat if f"run-{run}" in i.filename]

            if anat:
                for an in anat:
                    anats.append(an.path)

            # grab mask
            mask_query = {
                "datatype": "anat",
                "suffix": "mask",
                "extension": [".nii", ".nii.gz"],
            }
            for attr, key in zip(anat_attributes, anat_keys):
                if attr:
                    mask_query[key] = attr

            mask = layout.get(**mask_query)
            if len(mask) > 1 and run is not None:
                mask = [i for i in mask if f"run-{run}" in i.filename]
            mask = [
                i for i in mask if "MNI" not in i.filename and "space" not in
                                   i.filename]

            if modality == "dwi":
                dwi = layout.get(
                    **merge_dicts(
                        mod_query,
                        {"extension": [".nii", ".nii.gz"],
                         },
                    )
                )
                if len(dwi) > 1 and run is not None:
                    dwi = [i for i in dwi if f"run-{run}" in i.filename]
                bval = layout.get(
                    **merge_dicts(mod_query, {"extension": ["bval", "bvals"]}))
                if len(bval) > 1 and run is not None:
                    bval = [i for i in bval if f"run-{run}" in i.filename]
                bvec = layout.get(
                    **merge_dicts(mod_query, {"extension": ["bvec", "bvecs"]}))
                if len(bvec) > 1 and run is not None:
                    bvec = [i for i in bvec if f"run-{run}" in i.filename]

                if dwi and bval and bvec:
                    if not mask:
                        for (dw, bva, bve) in zip(dwi, bval, bvec):
                            if dw.path not in dwis:
                                dwis.append(dw.path)
                                bvals.append(bva.path)
                                bvecs.append(bve.path)
                    else:
                        for (dw, bva, bve, mas) in zip(dwi, bval, bvec, mask):
                            if dw.path not in dwis:
                                dwis.append(dw.path)
                                bvals.append(bva.path)
                                bvecs.append(bve.path)
                                masks.append(mas.path)

            elif modality == "func":
                func = layout.get(
                    **merge_dicts(
                        mod_query,
                        {
                            "extension": [".nii", ".nii.gz"],
                        },
                    )
                )
                if len(func) > 1 and run is not None:
                    func = [i for i in func if f"run-{run}" in i.filename]
                if len(func) > 1 and space is not None:
                    if "MNI" in [i.filename for i in func]:
                        raise ValueError('MNI-space BOLD images are not '
                                         'currently supported, but are all '
                                         'that are currently detected. '
                                         'Is a T1w/anat-coregistered '
                                         'preprocessed BOLD image available? '
                                         'See documentation for more details.')
                    else:
                        func = [i for i in func if space in i.filename]

                conf = layout.get(
                    **merge_dicts(mod_query, {"extension":
                                                  [".tsv", ".tsv.gz"]})
                )
                conf = [i for i in conf if "confounds_regressors" in
                        i.filename]
                if len(conf) > 1 and run is not None:
                    conf = [i for i in conf if f"run-{run}" in i.filename]

                if func:
                    if not conf and not mask:
                        for fun in func:
                            if fun.path not in funcs:
                                funcs.append(fun.path)
                    elif not conf and mask:
                        for fun, mas in zip(func, mask):
                            if fun.path not in funcs:
                                funcs.append(fun.path)
                                masks.append(mas.path)
                    elif conf and not mask:
                        for fun, con in zip(func, conf):
                            if fun.path not in funcs:
                                funcs.append(fun.path)
                                confs.append(con.path)
                    else:
                        for fun, con, mas in zip(func, conf, mask):
                            if fun.path not in funcs:
                                funcs.append(fun.path)
                                masks.append(mas.path)
                                confs.append(con.path)

    if len(anats) == 0:
        anats = None

    if len(masks) == 0:
        masks = None

    if modality == "dwi":
        if not len(dwis) or not len(bvals) or not len(bvecs):
            print("No dMRI files found in BIDS spec. Skipping...\n")
            return None, None, None, None, None, None, None, subjs, seshs
        else:
            return None, None, dwis, bvals, bvecs, anats, masks, subjs, seshs

    elif modality == "func":
        if not len(funcs):
            print("No fMRI files found in BIDS spec. Skipping...\n")
            return None, None, None, None, None, None, None, subjs, seshs
        else:
            return funcs, confs, None, None, None, anats, masks, subjs, seshs
    else:
        raise ValueError(
            "Incorrect modality passed. Choices are 'func' and 'dwi'.")
Esempio n. 3
0
def sweep_directory(derivatives_path, modality, space, func_desc, subj=None,
                    sesh=None):
    """
    Given a BIDS derivatives directory containing preprocessed functional MRI or diffusion MRI data
    (e.g. fMRIprep or dMRIprep), crawls the outputs and prepares necessary inputs for the PyNets pipeline.

    *Note: Since this function searches for derivative file inputs, it does not impose strict BIDS compliance, which
    can therefore create errors in the case that files are missing or redundant. Please ensure that there redundant
    files are removed and that BIDS naming conventions are followed closely.
    """

    if modality == 'dwi':
        dwis = []
        bvals = []
        bvecs = []
    elif modality == 'func':
        funcs = []
        confs = []
    masks = []
    anats = []

    # initialize BIDs tree on derivatives_path
    layout = bids.layout.BIDSLayout(derivatives_path, validate=False, derivatives=True, absolute_paths=True)

    # get all files matching the specific modality we are using
    all_subs = layout.get_subjects()
    if not subj:
        # list of all the subjects
        subjs = all_subs
    elif isinstance(subj, list):
        subjs = [sub for sub in subj if sub in all_subs]
    else:
        # make it a list so we can iterate
        subjs = as_list(subj)

    # Accommodate for different spaces
    if space is None:
        if modality == 'dwi':
            spaces = layout.get_spaces(
                suffix='dwi',
                extension=['.nii', '.nii.gz'])
        elif modality == 'func':
            spaces = layout.get_spaces(
                suffix='bold',
                extension=['.nii', '.nii.gz'])
        if spaces:
            spaces = sorted(spaces)
            space = spaces[0]
            if len(spaces) > 1:
                space_list = ', '.join(spaces)
                print(
                    f'No space was provided, but multiple spaces were detected: {space_list}. '
                    f'Selecting the first (ordered lexicographically): {space}')

    for sub in subjs:
        all_seshs = layout.get_sessions(subject=sub)
        if not sesh:
            seshs = all_seshs
            # in case there are non-session level inputs
            seshs += []
        elif isinstance(sesh, list):
            seshs = [ses for ses in sesh if ses in all_seshs]
        else:
            # make a list so we can iterate
            seshs = as_list(sesh)

        # print(f"Subject: {sub}\nSession(s): {seshs}\nModality: {modality}")

        for ses in seshs:
            # the attributes for our modality img
            mod_attributes = [sub, ses]
            # the keys for our modality img
            mod_keys = ['subject', 'session']
            # our query we will use for each modality img
            mod_query = {'datatype': modality}

            for attr, key in zip(mod_attributes, mod_keys):
                if attr:
                    mod_query[key] = attr

            # grab anat
            anat_attributes = [sub, ses]
            anat_keys = ['subject', 'session']
            # our query for the anatomical image
            anat_query = {'datatype': 'anat', 'suffix': 'T1w',
                          'extensions': ['.nii', '.nii.gz']}
            for attr, key in zip(anat_attributes, anat_keys):
                if attr:
                    anat_query[key] = attr
            # make a query to find the desired files from the BIDSLayout
            anat = layout.get(**anat_query)
            anat = [i for i in anat if 'MNI' not in i.filename and 'space' not in i.filename]

            if anat:
                for an in anat:
                    anats.append(an.path)

            # grab mask
            mask_query = {'datatype': 'anat', 'suffix': 'mask',
                          'extensions': ['.nii', '.nii.gz']}
            for attr, key in zip(anat_attributes, anat_keys):
                if attr:
                    mask_query[key] = attr

            mask = layout.get(**mask_query)
            mask = [i for i in mask if 'MNI' not in i.filename and 'space' not in i.filename]

            if modality == 'dwi':
                dwi = layout.get(**merge_dicts(mod_query, {'extensions': ['.nii', '.nii.gz'], 'suffix': ['dwi']}))
                bval = layout.get(**merge_dicts(mod_query, {'extensions': 'bval'}))
                bvec = layout.get(**merge_dicts(mod_query, {'extensions': 'bvec'}))
                if dwi and bval and bvec:
                    if not mask:
                        for (dw, bva, bve) in zip(dwi, bval, bvec):
                            if dw.path not in dwis:
                                dwis.append(dw.path)
                                bvals.append(bva.path)
                                bvecs.append(bve.path)
                    else:
                        for (dw, bva, bve, mas) in zip(dwi, bval, bvec, mask):
                            if dw.path not in dwis:
                                dwis.append(dw.path)
                                bvals.append(bva.path)
                                bvecs.append(bve.path)
                                masks.append(mas.path)

            elif modality == 'func':
                func = layout.get(**merge_dicts(mod_query, {'extensions': ['.nii', '.nii.gz'],
                                                            'suffix': ['bold', 'masked', func_desc],
                                                            'space': space}))
                func = [i for i in func if func_desc in i.filename]
                conf = layout.get(**merge_dicts(mod_query, {'extensions': ['.tsv', '.tsv.gz']}))
                conf = [i for i in conf if 'confounds_regressors' in i.filename]

                if func:
                    if not conf and not mask:
                        for fun in func:
                            if fun.path not in funcs:
                                funcs.append(fun.path)
                    elif not conf and mask:
                        for fun, mas in zip(func, mask):
                            if fun.path not in funcs:
                                funcs.append(fun.path)
                                masks.append(mas.path)
                    elif conf and not mask:
                        for fun, con in zip(func, conf):
                            if fun.path not in funcs:
                                funcs.append(fun.path)
                                confs.append(con.path)
                    else:
                        for fun, con, mas in zip(func, conf, mask):
                            if fun.path not in funcs:
                                funcs.append(fun.path)
                                masks.append(mas.path)
                                confs.append(con.path)

    if len(anats) == 0:
        anats = None

    if len(masks) == 0:
        masks = None

    if modality == 'dwi':
        if not len(dwis) or not len(bvals) or not len(bvecs):
            print("No dMRI files found in BIDs spec. Skipping...\n")
            return None, None, None, None, None, None, None, subjs, seshs
        else:
            return None, None, dwis, bvals, bvecs, anats, masks, subjs, seshs

    elif modality == 'func':
        if not len(funcs):
            print("No fMRI files found in BIDs spec. Skipping...\n")
            return None, None, None, None, None, None, None, subjs, seshs
        else:
            return funcs, confs, None, None, None, anats, masks, subjs, seshs
    else:
        raise ValueError('Incorrect modality passed. Choices are \'func\' and \'dwi\'.')
Esempio n. 4
0
def sweep_directory(bdir, subj=None, sesh=None, task=None, run=None, modality=None):
    """
    Given a BIDs formatted directory, crawls the BIDs dir and prepares the
    necessary inputs for the PyNets pipeline. Uses regexes to check matches for
    BIDs compliance.
    """
    if modality == 'dwi':
        dwis = []
        bvals = []
        bvecs = []
    elif modality == 'func':
        funcs = []
    anats = []
    # initialize BIDs tree on bdir
    layout = bids.layout.BIDSLayout(bdir, validate=False)
    # get all files matching the specific modality we are using
    if not subj:
        # list of all the subjects
        subjs = layout.get_subjects()
    else:
        # make it a list so we can iterate
        subjs = as_list(subj)
        assert subj in subjs, "subject {} is not in the bids folder".format(subj)
    for sub in subjs:
        if not sesh:
            seshs = layout.get_sessions(subject=sub, derivatives=False)
            # in case there are non-session level inputs
            seshs += [None]
        else:
            # make a list so we can iterate
            seshs = as_list(sesh)

        if not task:
            tasks = layout.get_tasks(subject=sub, derivatives=False)
            tasks += [None]
        else:
            tasks = as_list(task)

        if not run:
            runs = layout.get_runs(subject=sub, derivatives=False)
            runs += [None]
        else:
            runs = as_list(run)

        print('\n')
        print(sub)
        print("%s%s" % ('Subject:', sub))
        print("%s%s" % ('Sessions:', seshs))
        print("%s%s" % ('Tasks:', tasks))
        print("%s%s" % ('Runs:', runs))
        print('\n')
        # all the combinations of sessions and tasks that are possible
        for (ses, tas, ru) in product(seshs, tasks, runs):
            # the attributes for our modality img
            mod_attributes = [sub, ses, tas, ru]
            # the keys for our modality img
            mod_keys = ['subject', 'session', 'task', 'run']
            # our query we will use for each modality img
            mod_query = {'datatype': modality}
            if modality == 'dwi':
                type_img = 'dwi'  # use the dwi image
            elif modality == 'func':
                type_img = 'bold'  # use the bold image
            else:
                raise ValueError('ERROR: No valid bids modality specified.')
            mod_query['suffix'] = type_img

            for attr, key in zip(mod_attributes, mod_keys):
                if attr:
                    mod_query[key] = attr

            anat_attributes = [sub, ses]  # the attributes for our anat img
            anat_keys = ['subject', 'session']  # the keys for our modality img
            # our query for the anatomical image
            anat_query = {'datatype': 'anat', 'suffix': 'T1w',
                          'extensions': 'nii.gz|nii'}
            for attr, key in zip(anat_attributes, anat_keys):
                if attr:
                    anat_query[key] = attr
            # make a query to fine the desired files from the BIDSLayout
            anat = layout.get(**anat_query)
            if modality == 'dwi':
                dwi = layout.get(**merge_dicts(mod_query, {'extensions': 'nii.gz|nii'}))
                bval = layout.get(**merge_dicts(mod_query, {'extensions': 'bval'}))
                bvec = layout.get(**merge_dicts(mod_query, {'extensions': 'bvec'}))
                if dwi and bval and bvec:
                    for (dw, bva, bve) in zip(dwi, bval, bvec):
                        if dw.filename not in dwis:
                            # if all the required files exist, append by the first
                            # match (0 index)
                            if anat:
                                anats.append(anat[0].filename)
                            dwis.append(dw.filename)
                            bvals.append(bva.filename)
                            bvecs.append(bve.filename)

            elif modality == 'func':
                func = layout.get(**merge_dicts(mod_query, {'extensions': 'nii.gz|nii'}))
                if func and anat:
                    for fun in func:
                        if fun.filename not in funcs:
                            funcs.append(fun.filename)
                            anats.append(anat[0].filename)
    if modality == 'dwi':
        if not len(dwis) or not len(bvals) or not len(bvecs):
            print("No dMRI files found in BIDs spec. Skipping...")
        return dwis, bvals, bvecs, anats

    elif modality == 'func':
        if not len(funcs):
            print("No fMRI files found in BIDs spec. Skipping...")
        if anats:
            return funcs, None, None, anats
        else:
            return funcs, None, None, None
    else:
        raise ValueError('Incorrect modality passed. Choices are \'func\' and \'dwi\'.')