Skip to content

Instantly share code, notes, and snippets.

@utooley
Forked from tsalo/assign_intendedfor.py
Last active February 21, 2022 21:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save utooley/60a4f02fd47212781dc75bdf6a7f6095 to your computer and use it in GitHub Desktop.
Save utooley/60a4f02fd47212781dc75bdf6a7f6095 to your computer and use it in GitHub Desktop.
Add "IntendedFor" field to BIDS field map jsons for the associated fMRI and DWI scans based on acquisition time.
import json
import bisect
from glob import glob
from os.path import join, splitext
from bids.layout import BIDSLayout
from dateutil.parser import parse
# subj_dir *must* have trailing /, use os.path.join to make sure
subj_dir = join("/my_dir","")
subj='NDARINVZ02PLW9B'
sess = '01'
data_suffix = '.nii.gz'
layout = BIDSLayout(subj_dir)
def files_to_dict(file_list):
"""Convert list of BIDS Files to dictionary where key is
acquisition time (datetime.datetime object) and value is
the File object.
"""
out_dict = {}
for f in file_list:
fn = f.path
with open(fn, 'r') as fi:
data = json.load(fi)
dt = parse(data['AcquisitionTime'])
out_dict[dt] = f
return out_dict
# Get json files for field maps
fmap_jsons = layout.get(subject= subj, session=sess, modality='fmap', extensions='.json')
for dir_ in ['AP', 'PA']:
# Run field map directions independently
dir_jsons = [fm for fm in fmap_jsons if '_dir-{0}_'.format(dir_) in fm.filename]
fmap_dict = files_to_dict(dir_jsons)
dts = sorted(fmap_dict.keys())
intendedfor_dict = {fmap.path: [] for fmap in dir_jsons}
# Get all scans with associated field maps (bold + dwi)
func_jsons = layout.get(subject= subj, session= sess, type='bold', extensions='json') +\
layout.get(subject= subj, session= sess, type='dwi', extensions='json')
func_dict = files_to_dict(func_jsons)
for func in func_dict.keys():
fn, _ = splitext(func_dict[func].path)
fn += data_suffix
fn=fn.split(subj_dir)[-1]
fn = fn.split("/",1)[1]
# Find most immediate field map before scan
idx = bisect.bisect_right(dts, func) - 1
fmap_file = fmap_dict[dts[idx]].path
intendedfor_dict[fmap_file].append(fn) #should this be adjusted so that it's immediately before or after?
for fmap_file in intendedfor_dict.keys():
with open(fmap_file, 'r') as fi:
data = json.load(fi)
# No overwriting, for now
if 'IntendedFor' not in data.keys():
data['IntendedFor'] = intendedfor_dict[fmap_file]
with open(fmap_file, 'w') as fo:
json.dump(data, fo)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment