diff --git a/src/fmriprep-prep.sh b/src/fmriprep-prep.sh index 38ca5cf..6e5e03a 100755 --- a/src/fmriprep-prep.sh +++ b/src/fmriprep-prep.sh @@ -7,6 +7,7 @@ export t1_niigz=/INPUTS/t1.nii.gz export fmri_niigzs=/INPUTS/fmri.nii.gz export rpefwd_niigz="" export rperev_niigz="" +export slicetiming="" export bids_dir=/INPUTS/BIDS export sub=01 export ses=01 @@ -24,6 +25,7 @@ while [[ $# -gt 0 ]]; do --bids_dir) export bids_dir="$2"; shift; shift ;; --sub) export sub="$2"; shift; shift ;; --ses) export ses="$2"; shift; shift ;; + --slicetiming) export slicetiming="$2"; shift; shift ;; --fmri_niigzs) next="$2" while ! [[ "$next" =~ -.* ]] && [[ $# > 1 ]]; do @@ -79,7 +81,7 @@ for fmri_niigz in ${fmri_list[@]}; do fmri_tag="sub-${sub}/${intended_tag}" cp "${fmri_niigz}" "${bids_dir}/${fmri_tag}.nii.gz" - update_json.py --jsonfile ${fmri_json} --polarity + \ + update_json.py --fmri_niigz ${fmri_niigz} --polarity + --slicetiming "${slicetiming}" \ > "${bids_dir}/${fmri_tag}.json" intended_tags=(${intended_tags[@]} "${intended_tag}.nii.gz") @@ -94,13 +96,13 @@ if [ -n "${rpefwd_niigz}" ]; then rpefwd_json="${rpefwd_niigz%.nii.gz}.json" rpefwd_tag="sub-${sub}/ses-${ses}/fmap/sub-${sub}_ses-${ses}_dir-fwd_epi" cp "${rpefwd_niigz}" "${bids_dir}/${rpefwd_tag}.nii.gz" - update_json.py --jsonfile ${rpefwd_json} --polarity + --intendedfor ${intended_tags[@]} \ + update_json.py --fmri_niigz ${rpefwd_niigz} --polarity + --intendedfor ${intended_tags[@]} \ > "${bids_dir}/${rpefwd_tag}.json" rperev_json="${rperev_niigz%.nii.gz}.json" rperev_tag="sub-${sub}/ses-${ses}/fmap/sub-${sub}_ses-${ses}_dir-rev_epi" cp "${rperev_niigz}" "${bids_dir}/${rperev_tag}.nii.gz" - update_json.py --jsonfile ${rperev_json} --polarity - --intendedfor ${intended_tags[@]} \ + update_json.py --fmri_niigz ${rperev_niigz} --polarity - --intendedfor ${intended_tags[@]} \ > "${bids_dir}/${rperev_tag}.json" fi diff --git a/src/update_json.py b/src/update_json.py index d028110..b73fd53 100755 --- a/src/update_json.py +++ b/src/update_json.py @@ -2,32 +2,71 @@ import argparse import json +import nibabel import sys parser = argparse.ArgumentParser() -parser.add_argument('--jsonfile') +parser.add_argument('--fmri_niigz') parser.add_argument('--polarity') parser.add_argument('--intendedfor', nargs='*') +parser.add_argument('--slicetiming') args = parser.parse_args() -with open(args.jsonfile) as f: + +jsonfile = args.fmri_niigz.replace('.nii.gz','.json') +with open(jsonfile) as f: jobj = json.loads(f.read()) - - # Verify that this is a Philips scan before applying the Philips- - # specific fixes for TotalReadoutTime and PhaseEncodingDirection - if jobj['Manufacturer'] != 'Philips': - raise Exception(f'Manufacturer is {jobj["Manufacturer"]} - expecting Philips') - - jobj['TotalReadoutTime'] = jobj['EstimatedTotalReadoutTime'] - - if args.polarity=='+': - jobj['PhaseEncodingDirection'] = jobj['PhaseEncodingAxis'] - elif args.polarity=='-': - jobj['PhaseEncodingDirection'] = jobj['PhaseEncodingAxis'] + '-' + + +## Phase encoding direction/info + +# Verify that this is a Philips scan before applying the Philips- +# specific fixes for TotalReadoutTime and PhaseEncodingDirection +if jobj['Manufacturer'] != 'Philips': + raise Exception(f'Manufacturer is {jobj["Manufacturer"]} - expecting Philips') + +jobj['TotalReadoutTime'] = jobj['EstimatedTotalReadoutTime'] + +if args.polarity=='+': + jobj['PhaseEncodingDirection'] = jobj['PhaseEncodingAxis'] +elif args.polarity=='-': + jobj['PhaseEncodingDirection'] = jobj['PhaseEncodingAxis'] + '-' +else: + raise Exception(f'Unknown polarity {args.polarity}') + +if args.intendedfor: + jobj['IntendedFor'] = args.intendedfor + + +## Slice timing + +if args.slicetiming: + + # Get number of slices and TR from .nii.gz. Assume + # slice axis is the third one. + nii = nibabel.load(args.fmri_niigz) + nslices = nii.header['dim'][3] + tr = nii.header['pixdim'][4] + + # Check for existing + if 'SliceTiming' in jobj: + raise Exception(f'SliceTiming field exists in {jsonfile}') + if 'SliceEncodingDirection' in jobj: + raise Exception(f'SliceEncodingDirection field exists in {jsonfile}') + + # Get repetition time from .json to crosscheck + tr2 = jobj['RepetitionTime'] + if abs(tr2-tr)>0.001: + raise Exception(f'TR in {jsonfile} does not match {args.fmri_niigz}') + + # We can only handle certain specific cases + # Philips_ASCEND_k: ascending on third axis + if args.slicetiming=='Philips_ASCEND_k': + jobj['SliceEncodingDirection'] = 'k' + jobj['SliceTiming'] = list(range(0,nslices) / nslices * tr) else: - raise Exception(f'Unknown polarity {args.polarity}') + raise Exception(f'Cannot handle slice timing of {args.slicetiming}') + - if args.intendedfor: - jobj['IntendedFor'] = args.intendedfor - - print(json.dumps(jobj, indent = 4)) +## Print it out +print(json.dumps(jobj, indent = 4))