Hi everyone,
I am in the process of converting my subjects into BIDS format using heudiconv and I’m having a little trouble getting the last few scans to populate the “IntendedFor” field correctly. Unfortunately, due to parameter changes and additional tasks added to the scan protocol throughout the 60 or so runs we’ve completed, the script I have has run into some nuances that I won’t get into unless needed – I’ve had to run two versions of the script on different scans.
I can’t get the “IntendedFor” field to populate at all in my DWI and resting state fmap json files. I’ve tried messing around with the POPULATE_INTENDED_FOR_OPTS section, but it may be a problem with the main body of my code. Help would be appreciated! For reference, I’ve included my heuristic below and would be happy to provide additional information:
#from __future__ import annotations
#from typing import Optional
#from heudiconv.utils import SeqInfo
import os
def create_key(template, outtype=('nii.gz', 'dicom'), annotation_classes=None):
if template is None or not template:
raise ValueError('Template must be a valid format string')
return template, outtype, annotation_classes
def infotodict(seqinfo):
t1w = create_key('sub-{subject}/anat/sub-{subject}_T1w')
t2w = create_key('sub-{subject}/anat/sub-{subject}_T2w')
dwi = create_key('sub-{subject}/dwi/sub-{subject}_acq-dwi_dir-AP_dwi')
epi1 = create_key('sub-{subject}/func/sub-{subject}_task-rest_acq-func_run-01_bold')
epi2 = create_key('sub-{subject}/func/sub-{subject}_task-move_acq-func_run-01_bold')
epi3 = create_key('sub-{subject}/func/sub-{subject}_task-test_acq-func_run-01_bold')
epi4 = create_key('sub-{subject}/func/sub-{subject}_task-move_acq-func_run-02_bold')
epi5 = create_key('sub-{subject}/func/sub-{subject}_task-test_acq-func_run-02_bold')
fmapAPdsi = create_key('sub-{subject}/fmap/sub-{subject}_acq-dwi_dir-AP_epi')
fmapPAdsi = create_key('sub-{subject}/fmap/sub-{subject}_acq-dwi_dir-PA_epi')
fmapAPrest = create_key('sub-{subject}/fmap/sub-{subject}_acq-rest_dir-AP_epi')
fmapPArest = create_key('sub-{subject}/fmap/sub-{subject}_acq-rest_dir-PA_epi')
fmapAPmovetest = create_key('sub-{subject}/fmap/sub-{subject}_acq-func_dir-AP_epi')
fmapPAmovetest = create_key('sub-{subject}/fmap/sub-{subject}_acq-func_dir-PA_epi')
info = {
t1w: [],
t2w: [],
dwi: [],
epi1: [], epi2: [], epi3: [], epi4: [], epi5: [],
fmapAPdsi: [], fmapPAdsi: [], fmapAPrest: [], fmapPArest: [], fmapAPmovetest: [], fmapPAmovetest: []
}
for s in seqinfo:
# T1w
if s.series_files == 240 and s.protocol_name == '0.8mm_TR2.3_t1_mprage':
info[t1w].append(s.series_id)
# T2w
elif s.series_files == 30 and s.protocol_name == 'anat-T2w_acq-ADNI3Hippocampus':
info[t2w].append(s.series_id)
# dwi
elif s.TR == 3.5 and s.TE == 102: # s.series_files == 134:
# fmap
if (s.series_files == 252): #(s.protocol_name == 'dwi_acq-AP64d2b'):
if ('AP' in s.protocol_name):
if ( len(info[fmapAPdsi]) > 0 ) and ( s.total_files_till_now > latestAP ):
info[fmapAPdsi].clear()
info[fmapAPdsi].append(s.series_id)
latestAP = s.total_files_till_now
elif ('PA' in s.protocol_name):
if ( len(info[fmapPAdsi]) > 0 ) and ( s.total_files_till_now > latestPA ):
info[fmapPAdsi].clear()
info[fmapPAdsi].append(s.series_id)
latestPA = s.total_files_till_now
# dwi scan
else:
info[dwi].append(s.series_id)
# Move/Test scans
elif (s.TR == 2 and s.TE == 25.0):
# fmaps
if (s.series_files == 5):
if ('_AP_' in s.protocol_name):
info[fmapAPmovetest].append(s.series_id)
elif ('_PA_' in s.protocol_name):
info[fmapPAmovetest].append(s.series_id)
else:
if (s.protocol_name == 'BOLD_AP_movement_1'):
info[epi2].append(s.series_id)
elif (s.protocol_name == 'BOLD_AP_testingrun_1'):
info[epi3].append(s.series_id)
elif (s.protocol_name == 'BOLD_AP_movement_2'):
info[epi4].append(s.series_id)
elif (s.protocol_name == 'BOLD_AP_testingrun_2'):
info[epi5].append(s.series_id)
#Resting state
elif (s.TR == 1.66 and s.TE == 26.0):
# fmaps
if (s.series_files == 5):
if ( ('_AP_' in s.protocol_name) or ('dirAP' in s.protocol_name) ):
info[fmapAPrest].append(s.series_id)
elif ( ('_PA_' in s.protocol_name) or ('dirPA' in s.protocol_name) ):
info[fmapPArest].append(s.series_id)
else:
info[epi1].append(s.series_id)
return info
POPULATE_INTENDED_FOR_OPTS = {
'matching_parameters': ['ImagingVolume', 'Shims'],
'criterion': 'Closest'
}