def test_as_list(x): y = utils.as_list(x) assert isinstance(y, list)
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'.")
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\'.')
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\'.')