Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add correctFieldMapCase4 to support pepolar fieldmaps #39

Merged
merged 21 commits into from
May 17, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions etc/correctFieldMapCase4
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

if [ "$#" -lt 1 ]
then
echo "Usage: $0 <in_bids> <subj ID> <session id (optional)>"
exit 1
fi
in_bids=$1

exec_path=`dirname $0`


subj=$2
subj=${subj##sub-} #strip off sub- if it exists, to make consistent
if [ "$#" -gt 2 ]
then
ses=$3
ses=${ses##ses-} #strip off sub- if it exists, to make consistent
fi

#correct field map json files

if [ -n "$ses" ]
then
$exec_path/correctFieldMapJsonCase4.py $in_bids sub-$subj ses-$ses
else
$exec_path/correctFieldMapJsonCase4.py $in_bids sub-$subj
fi

69 changes: 69 additions & 0 deletions etc/correctFieldMapJsonCase4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#! /usr/bin/env python3
'''
correct field map json
'''

import os
import sys
import json
import glob
import collections

def correctFieldMapJson(bids_dir,sub,ses=None):

if ses: #ses not None
sub_prefix = '{}_{}'.format(sub,ses)
sub_path_prefix=os.path.join(sub,ses)
sub_root = '{}'.format(sub)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can just be sub_root = sub (or maybe sub_root = str(sub) if sub might not already be a string).

Actually, you may just want to get rid of this variable entirely because it seems to be the same as sub in all cases.

else:
sub_prefix = '{}'.format(sub)
sub_path_prefix = sub_prefix
sub_root = '{}'.format(sub)

sub_dir=os.path.join(bids_dir,sub_path_prefix)
sub_root_dir=os.path.join(bids_dir,sub_root) #without session

for fmri_json_file in glob.glob(os.path.join(sub_dir,'fmap','{}_acq-EPI_dir-*_epi.json'.format(sub_prefix))):

#debug
print(fmri_json_file)

#load json files
with open(fmri_json_file, 'r') as f:
fmri_json = json.load(f,object_pairs_hook=collections.OrderedDict)

# apply to all bold images
cwd=os.getcwd()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we're changing the working directory to get the paths relative to the participant directory? I try to avoid changing directories if possible (can cause problems e.g. if the script fails or is cancelled part way through) but if this is the easiest way to do it, that's fine.

os.chdir(sub_root_dir)
if ses:
all_bold = glob.glob(os.path.join('{}'.format(ses),'func','{}_*_bold.nii.gz'.format(sub_prefix)))
else:
all_bold = glob.glob(os.path.join('func','{}_*_bold.nii.gz'.format(sub_prefix)))

os.chdir(cwd)

fmri_json["IntendedFor"]=all_bold

#update json file
os.system("chmod a+w {}".format(fmri_json_file))
with open(fmri_json_file, 'w') as f:
json.dump(fmri_json, f, indent=4, separators=(',', ': '))
os.system("chmod a-w {}".format(fmri_json_file))


if __name__=="__main__":
if len(sys.argv)-1 < 2:
print ("Usage: python " + os.path.basename(__file__)+ " 'bids_dir' 'sub' 'ses (optional)'")
sys.exit()
else:
bids_dir = sys.argv[1]
sub = sys.argv[2]
if len(sys.argv)-1 > 2:
ses=sys.argv[3]
correctFieldMapJson(bids_dir,sub,ses)
else:
correctFieldMapJson(bids_dir,sub)

#test
#Usage: python correctFieldMapJson.py 'bids_dir' 'sub'
#python correctFieldMapJson.py '/mnt/hgfs/test/correct_fieldmap_json/topsy_7T' 'sub-005'
127 changes: 64 additions & 63 deletions etc/memp2rage_bids_corrector.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,86 +12,87 @@



multiecho_dir = sys.argv[1]
print('multi-echo corrector')
print(multiecho_dir)

#puts all json and nifti files in the folder into lists
json_files = sorted(glob.glob(multiecho_dir + "/*echo_*M*RAGE*.json"))
nifti_files = sorted(glob.glob(multiecho_dir + "/*echo_*M*RAGE*.nii.gz" ))
print(json_files)
print(nifti_files)
for i,k in zip(json_files, nifti_files):
bids_dir = sys.argv[1]
for multiecho_dir in glob.glob(f'{bids_dir}/**/anat',recursive=True):
print('multi-echo corrector')
print(multiecho_dir)

#puts all json and nifti files in the folder into lists
json_files = sorted(glob.glob(multiecho_dir + "/*echo-*_*M*RAGE*.json"))
nifti_files = sorted(glob.glob(multiecho_dir + "/*echo-*_*M*RAGE*.nii.gz" ))
print(json_files)
print(nifti_files)
for i,k in zip(json_files, nifti_files):

#open and load json file
with open(i) as data_file:
data = json.load(data_file)
#open and load json file
with open(i) as data_file:
data = json.load(data_file)

#in the case of echo-1, the EchoNumber tag does not exist in the json file
if ("EchoNumber" not in data) and ("_echo_" in i):
js_addEchoNum = re.sub("_echo_", "_echo-1_", i)
js_changeEnding = re.sub("[0-9].json", ".json", js_addEchoNum)
print('renaming: '+i+' to '+js_changeEnding)
os.rename(i, js_changeEnding)
#in the case of echo-1, the EchoNumber tag does not exist in the json file
if ("EchoNumber" not in data) and ("_echo_" in i):
js_addEchoNum = re.sub("_echo_", "_echo-1_", i)
js_changeEnding = re.sub("[0-9].json", ".json", js_addEchoNum)
print('renaming: '+i+' to '+js_changeEnding)
os.rename(i, js_changeEnding)

ni_addEchoNum = re.sub("_echo_", "_echo-1_", k)
ni_changeEnding = re.sub("[0-9].nii.gz", ".nii.gz", ni_addEchoNum)
print('renaming: '+k+' to '+ni_changeEnding)
os.rename(k, ni_changeEnding)
ni_addEchoNum = re.sub("_echo_", "_echo-1_", k)
ni_changeEnding = re.sub("[0-9].nii.gz", ".nii.gz", ni_addEchoNum)
print('renaming: '+k+' to '+ni_changeEnding)
os.rename(k, ni_changeEnding)

#otherwise get EchoNumber value from json file and insert into filename
elif "EchoNumber" in data:
echonum = data["EchoNumber"]

js_addEchoNum = re.sub("_echo_", "_echo-" + str(echonum) + "_", i)
js_changeEnding = re.sub("[0-9].json", ".json", js_addEchoNum)
print('renaming: '+i+' to '+js_changeEnding)
os.rename(i, js_changeEnding)
#otherwise get EchoNumber value from json file and insert into filename
elif "EchoNumber" in data:
echonum = data["EchoNumber"]

js_addEchoNum = re.sub("_echo_", "_echo-" + str(echonum) + "_", i)
js_changeEnding = re.sub("[0-9].json", ".json", js_addEchoNum)
print('renaming: '+i+' to '+js_changeEnding)
os.rename(i, js_changeEnding)

ni_addEchoNum = re.sub("_echo_", "_echo-" + str(echonum) + "_" , k)
ni_changeEnding = re.sub("[0-9].nii.gz", ".nii.gz", ni_addEchoNum)
print('renaming: '+k+' to '+ni_changeEnding)
os.rename(k, ni_changeEnding)
ni_addEchoNum = re.sub("_echo_", "_echo-" + str(echonum) + "_" , k)
ni_changeEnding = re.sub("[0-9].nii.gz", ".nii.gz", ni_addEchoNum)
print('renaming: '+k+' to '+ni_changeEnding)
os.rename(k, ni_changeEnding)


#combine echos 1 and 2 for memprage
json_files = sorted(glob.glob(multiecho_dir + "/*echo-1_*MEMPRAGE.json"))
nifti_files_echo1 = sorted(glob.glob(multiecho_dir + "/*echo-1_*MEMPRAGE.nii.gz"))
nifti_files_echo2 = sorted(glob.glob(multiecho_dir + "/*echo-2_*MEMPRAGE.nii.gz"))
#combine echos 1 and 2 for memprage
json_files = sorted(glob.glob(multiecho_dir + "/*echo-1_*MEMPRAGE.json"))
nifti_files_echo1 = sorted(glob.glob(multiecho_dir + "/*echo-1_*MEMPRAGE.nii.gz"))
nifti_files_echo2 = sorted(glob.glob(multiecho_dir + "/*echo-2_*MEMPRAGE.nii.gz"))

for i,in_json in enumerate(json_files):
echo1 = nifti_files_echo1[i]
echo2 = nifti_files_echo2[i]
for i,in_json in enumerate(json_files):
echo1 = nifti_files_echo1[i]
echo2 = nifti_files_echo2[i]

out_json = re.sub('_echo-[0-9]+_','_',in_json)
out_json = re.sub('acq-([0-9a-zA-Z]+)4e_','acq-\g<1>AvgEcho12_',out_json)
out_json = re.sub('_MEMPRAGE\.','_T1w.',out_json)
out_nii = re.sub('\.json','.nii.gz',out_json)
out_json = re.sub('_echo-[0-9]+_','_',in_json)
out_json = re.sub('acq-([0-9a-zA-Z]+)4e_','acq-\g<1>AvgEcho12_',out_json)
out_json = re.sub('_MEMPRAGE\.','_T1w.',out_json)
out_nii = re.sub('\.json','.nii.gz',out_json)

#open and load json file
with open(in_json) as data_file:
data = json.load(data_file)
#open and load json file
with open(in_json) as data_file:
data = json.load(data_file)

#remove EchoNumber and EchoTime from JSON
del data['EchoNumber']
del data['EchoTime']
data['EchoNumbers'] = [1,2]
#remove EchoNumber and EchoTime from JSON
del data['EchoNumber']
del data['EchoTime']
data['EchoNumbers'] = [1,2]

with open(out_json, 'w') as outfile:
json.dump(data, outfile, indent=4)
with open(out_json, 'w') as outfile:
json.dump(data, outfile, indent=4)

#average the two niftis
echo1_nib = nib.load(echo1)
echo2_nib = nib.load(echo2)
#average the two niftis
echo1_nib = nib.load(echo1)
echo2_nib = nib.load(echo2)

echo1_vol = echo1_nib.get_fdata()
echo2_vol = echo2_nib.get_fdata()
echo1_vol = echo1_nib.get_fdata()
echo2_vol = echo2_nib.get_fdata()

avg_vol = (echo1_vol + echo2_vol) * 0.5
avg_vol = (echo1_vol + echo2_vol) * 0.5

avg_nib = nib.Nifti1Image(avg_vol, echo1_nib.affine, echo1_nib.header)
avg_nib = nib.Nifti1Image(avg_vol, echo1_nib.affine, echo1_nib.header)

nib.save(avg_nib,out_nii)
nib.save(avg_nib,out_nii)



Expand Down
3 changes: 3 additions & 0 deletions tar2bids
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,9 @@ fi
#merge any vNav files if they exist
python3 $execpath/etc/merge_vNav.py $output_dir

#average m3mprage images
python3 $execpath/etc/memp2rage_bids_corrector.py $output_dir

#remove scans.tsv files as they may be out of date after corrections
rm -f $output_dir/*/*_scans.tsv $output_dir/*/*/*_scans.tsv

Expand Down