Hi
I’m stuck with something and don’t want to start reinventing the wheel. Could you help?
I am iterating through the scanning sessions in our DICOM store and calling heudiconv for each. I’d like BIDS output.
If I include the subject and session in “outdir” then the func etc directories end up where I want them (e.g., bids/sub-ICN1/sess-2/func). But the study-level bids files then end up in those same session directories (e.g., bids/sub-ICN1/sess-2/dataset_description.json).
But, if I omit the subject and session then the func ends up at the study level.
I’ve tried various ways of implementing - dicom_dir_template and subjs/session below; or using files and infotoids. But I never get right mix. What have I broken?
I’m calling from python, hope that’s allowed.
Thanks for the great tool.
All the best, Rhodri
from heudiconv import bids
from heudiconv.main import workflow
from os import path
import glob
# Path to scan
dcmpth='/mnt/siemens-dicom/anon'
# Each subject
allsubjdicom = glob.glob(path.join(dcmpth,'*_RC_FOUNDCOG'))
for subjdicom in allsubjdicom:
# get pithy sub from DICOM participant name
flds = path.basename(subjdicom).split('_')
sub = '_'.join(flds[:2])
# Each session for this subject
allsessdicom = glob.glob(subjdicom + '/*')
allsessdicom.sort() # sessions in ascending order by time
for ses, sessdicom in enumerate(allsessdicom, start = 1):
print(f'Working on sub-{sub} ses-{ses}')
workflow(dicom_dir_template=path.join(dcmpth,'{subject}_RC_FOUNDCOG',path.basename(sessdicom),'*/*.dcm'),`
converter='dcm2niix',
outdir='/projects/pi-cusackrh/HPC_18_01039/foundcog/bids/',
heuristic='/projects/pi-cusackrh/HPC_18_01039/repos/heudiconv_cusacklab/heuristic.py',
overwrite=True,
bids_options=[],
subjs=[sub],
session=ses)
I think culprit could be in that custom heuristic
1 Like
In here?
import os
from os import path
def create_key(template, outtype=('nii.gz',), 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):
"""Heuristic evaluator for determining which runs belong where
allowed template fields - follow python string module:
item: index within category
subject: participant id
seqitem: run number during scanning
subindex: sub index within group
"""
anat = create_key('anat/sub-{subject}_{session}_run-00{item:01d}_T1w')
func_video = create_key('func/sub-{subject}_{session}_dir-AP_task-videos_run-00{item:01d}_bold')
func_pictures = create_key('func/sub-{subject}_{session}_dir-AP_task-pictures_run-00{item:01d}_bold')
func_rest5 = create_key('func/sub-{subject}_{session}_dir-AP_task-rest5_run-00{item:01d}_bold')
func_rest10 = create_key('func/sub-{subject}_{session}_dir-AP_task-rest10_run-00{item:01d}_bold')
dwi = create_key('dwi/sub-{subject}_{session}_dir-{dir}_run-{item}_dwi')
fmap = create_key('fmap/sub-{subject}_{session}_dir-{dir}_run-{item}_epi')
info = {anat: [], func_video: [], func_pictures: [], func_rest5: [], func_rest10: [], dwi: [], fmap:[] }
for idx, s in enumerate(seqinfo):
if 't2_tse_tra_p3_noisereduction' in s.protocol_name:
info[anat].append(s.series_id)
if (s.dim1 == 64) and (s.dim2 == 64) and ('cmrr_mbep2d_bold_videos_AP' in s.protocol_name):
info[func_video].append(s.series_id)
if (s.dim1 == 64) and (s.dim2 == 64) and ('cmrr_mbep2d_bold_Pictures_AP' in s.protocol_name):
info[func_pictures].append(s.series_id)
if (s.dim1 == 64) and (s.dim2 == 64) and ('cmrr_mbep2d_bold_Resting_10' in s.protocol_name):
info[func_rest10].append(s.series_id)
if (s.dim1 == 64) and (s.dim2 == 64) and ('cmrr_mbep2d_bold_Resting_5' in s.protocol_name):
info[func_rest5].append(s.series_id)
if (s.dim1 == 96) and (s.dim2 == 96) and ('cmrr_mbep2d_diff_AP_mb4_norm_pulse1.5x' in s.protocol_name):
info[dwi].append({'item': s.series_id, 'dir':'AP'})
if (s.dim1 == 96) and (s.dim2 == 96) and ('cmrr_mbep2d_diff_PA_mb4_norm_pulse1.5x' in s.protocol_name):
info[dwi].append({'item': s.series_id, 'dir':'PA'})
if (s.dim1 == 64) and (s.dim2 == 64) and ('cmrr_mbep2d_se_AP' in s.protocol_name):
info[fmap].append({'item': s.series_id, 'dir':'AP'})
if (s.dim1 == 64) and (s.dim2 == 64) and ('cmrr_mbep2d_se_PA' in s.protocol_name):
info[fmap].append({'item': s.series_id, 'dir':'PA'})
print('*** infotodict')
print(info)
return info
# # Get a numeric subject ID for BIDS format from list of DICOM file names
# def infotoids(seqinfos, outdir):
# # Use the sub and ses labels as given in the output path
# fp = outdir.split(path.sep)
# if fp[-1][:4] == 'ses-':
# ses=fp[-1][4:]
# if fp[-2][:4] == 'sub-':
# sub=fp[-2][4:]
# return({'subject':sub, 'session':ses, 'locator':outdir})
P.S. heudiconv version 0.10.0
SOLVED: I’m sorry I realise now it was an error in my create_key commands, I needed
create_key(‘sub-{subject}/{session}/anat/sub-{subject}_{session}_run-00{item:01d}T1w’)
not
create_key('anat/sub-{subject}{session}_run-00{item:01d}_T1w’)
1 Like