Heudiconv: Example Usage

James Kent

Learning Objectives

  • Know the Brain Imaging Data Structure (BIDS) standard
  • Know how to use Docker
  • Know how to use Heudiconv

What Does BIDS Look Like?

Get heudiconv (Singularity)

singularity pull docker://nipy/heudiconv:latest

Get heudiconv (Docker)

  1. Install Docker
  2. Run: docker pull nipy/heudiconv
  3. That's it!

Downloaded Dicoms

Assume dicoms have the form <subject>/[<session>]/SCANS/*/DICOM/*.dcm

Example Dicom Structure

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure (Singularity)

singularity run \
-H ~/singularity_home \
-B /Shared/vosslabhpc:/hpc \
~/simgs/heudiconv-latest.simg \
-d /hpc/Tutorials/heudiconvTest/{subject}/{session}/SCANS/*/DICOM/*.dcm \
-s 102 \
--ses 20160302_3 \
-f convertall \
-c none \
-o /hpc/Tutorials/heudiconvTest/BIDS

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure (Singularity)

singularity run `# we want singularity to run a container` \

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure (Singularity)

singularity run `# we want singularity to run a container` \
-H ~/singularity_home `# use an empty directory for singularity to treat as $HOME (reduces likelihood of conflicting environment variables` \

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure (Singularity)

singularity run `# we want singularity to run a container` \
-H ~/singularity_home `# use an empty directory for singularity to treat as $HOME (reduces likelihood of conflicting environment variables` \
-B /Shared/vosslabhpc:/hpc `# mount the Shared server to the singularity container (to access our data)\

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure (Singularity)

singularity run `# we want singularity to run a container` \
-H ~/singularity_home `# use an empty directory for singularity to treat as $HOME (reduces likelihood of conflicting environment variables` \
-B /Shared/vosslabhpc:/hpc `# mount the Shared server to the singularity container (to access our data)\
~/simgs/heudiconv-latest.simg `# the heudiconv singularity image we are using` \

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure (Singularity)

singularity run `# we want singularity to run a container` \
-H ~/singularity_home `# use an empty directory for singularity to treat as $HOME (reduces likelihood of conflicting environment variables` \
-B /Shared/vosslabhpc:/hpc `# mount the Shared server to the singularity container (to access our data)\
~/simgs/heudiconv-latest.simg `# the heudiconv singularity image we are using` \
-d /hpc/Tutorials/heudiconvTest/{subject}/{session}/SCANS/*/DICOM/*.dcm `# The pattern to select the requested dicoms` \ 

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure (Singularity)

singularity run `# we want singularity to run a container` \
-H ~/singularity_home `# use an empty directory for singularity to treat as $HOME (reduces likelihood of conflicting environment variables` \
-B /Shared/vosslabhpc:/hpc `# mount the Shared server to the singularity container (to access our data)\
~/simgs/heudiconv-latest.simg `# the heudiconv singularity image we are using` \
-d /hpc/Tutorials/heudiconvTest/{subject}/{session}/SCANS/*/DICOM/*.dcm `# The pattern to select the requested dicoms` \ 
-s 102 `# A specific subject used to generate the heuristic file` \ 

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure (Singularity)

singularity run `# we want singularity to run a container` \
-H ~/singularity_home `# use an empty directory for singularity to treat as $HOME (reduces likelihood of conflicting environment variables` \
-B /Shared/vosslabhpc:/hpc `# mount the Shared server to the singularity container (to access our data)\
~/simgs/heudiconv-latest.simg `# the heudiconv singularity image we are using` \
-d /hpc/Tutorials/heudiconvTest/{subject}/{session}/SCANS/*/DICOM/*.dcm `# The pattern to select the requested dicoms` \ 
-s 102 `# A specific subject used to generate the heuristic file` \ 
--ses 20160302_3 `# A specific session used to generate the heuristic file` \ 

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure (Singularity)

singularity run `# we want singularity to run a container` \
-H ~/singularity_home `# use an empty directory for singularity to treat as $HOME (reduces likelihood of conflicting environment variables` \
-B /Shared/vosslabhpc:/hpc `# mount the Shared server to the singularity container (to access our data)\
~/simgs/heudiconv-latest.simg `# the heudiconv singularity image we are using` \
-d /hpc/Tutorials/heudiconvTest/{subject}/{session}/SCANS/*/DICOM/*.dcm `# The pattern to select the requested dicoms` \ 
-s 102 `# A specific subject used to generate the heuristic file` \ 
--ses 20160302_3 `# A specific session used to generate the heuristic file` \ 
-f convertall `# A generic heuristic to convert all dicoms` \ 

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure (Singularity)

singularity run `# we want singularity to run a container` \
-H ~/singularity_home `# use an empty directory for singularity to treat as $HOME (reduces likelihood of conflicting environment variables` \
-B /Shared/vosslabhpc:/hpc `# mount the Shared server to the singularity container (to access our data)\
~/simgs/heudiconv-latest.simg `# the heudiconv singularity image we are using` \
-d /hpc/Tutorials/heudiconvTest/{subject}/{session}/SCANS/*/DICOM/*.dcm `# The pattern to select the requested dicoms` \ 
-s 102 `# A specific subject used to generate the heuristic file` \ 
--ses 20160302_3 `# A specific session used to generate the heuristic file` \ 
-f convertall `# A generic heuristic to match all dicoms` \ 
-c none `# the dicom->nifti converter to use` \ 

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure (Singularity)

singularity run `# we want singularity to run a container` \
-H ~/singularity_home `# use an empty directory for singularity to treat as $HOME (reduces likelihood of conflicting environment variables` \
-B /Shared/vosslabhpc:/hpc `# mount the Shared server to the singularity container (to access our data)\
~/simgs/heudiconv-latest.simg `# the heudiconv singularity image we are using` \
-d /hpc/Tutorials/heudiconvTest/{subject}/{session}/SCANS/*/DICOM/*.dcm `# The pattern to select the requested dicoms` \ 
-s 102 `# A specific subject used to generate the heuristic file` \ 
--ses 20160302_3 `# A specific session used to generate the heuristic file` \ 
-f convertall `# A generic heuristic to convert all dicoms` \ 
-c none `# the dicom->nifti converter to use` \ 
-o /hpc/Tutorials/heudiconvTest/BIDS `# directory to place output`

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure (Docker)

docker run --rm -it \
-v ~/Documents/heudiconvTest:/data:ro \
-v ~/Documents/heudiconvTest/BIDS:/output \
nipy/heudiconv:latest \
-d /data/{subject}/{session}/SCANS/*/DICOM/*.dcm \
-s 102 \
--ses 20160302_3 \
-f convertall \
-c none \
-o /output

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure (Docker)

docker run --rm -it `# run a docker interactively with a terminal environment` \

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure

docker run --rm -it \ # run a docker interactively with a terminal environment
-v ~/Documents/heudiconvTest:/data:ro \ # connect my local directory to the container /data directory

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure

docker run --rm -it \ # run a docker interactively with a terminal environment
-v ~/Documents/heudiconvTest:/data:ro \ # connect my local directory to the container /data directory
-v ~/Documents/heudiconvTest/BIDS:/output \ # connect my local directory to the container /output directory

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure

docker run --rm -it \ # run a docker interactively with a terminal environment
-v ~/Documents/heudiconvTest:/data:ro \ # connect my local directory to the container /data directory
-v ~/Documents/heudiconvTest/BIDS:/output \ # connect my local directory to the container /output directory
nipy/heudiconv:latest \ # The container I want to run

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure

docker run --rm -it \ # run a docker interactively with a terminal environment
-v ~/Documents/heudiconvTest:/data:ro \ # connect my local directory to the container /data directory
-v ~/Documents/heudiconvTest/BIDS:/output \ # connect my local directory to the container /output directory
nipy/heudiconv:latest \ # The container I want to run
-d /data/{subject}/{session}/SCANS/*/DICOM/*.dcm \ # The pattern to select the requested dicoms

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure

docker run --rm -it \ # run a docker interactively with a terminal environment
-v ~/Documents/heudiconvTest:/data:ro \ # connect my local directory to the container /data directory
-v ~/Documents/heudiconvTest/BIDS:/output \ # connect my local directory to the container /output directory
nipy/heudiconv:latest \ # The container I want to run
-d /data/{subject}/{session}/SCANS/*/DICOM/*.dcm \ # The pattern to select the requested dicoms
-s 102 \ # A specific subject used to generate the heuristic file

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure

docker run --rm -it \ # run a docker interactively with a terminal environment
-v ~/Documents/heudiconvTest:/data:ro \ # connect my local directory to the container /data directory
-v ~/Documents/heudiconvTest/BIDS:/output \ # connect my local directory to the container /output directory
nipy/heudiconv:latest \ # The container I want to run
-d /data/{subject}/{session}/SCANS/*/DICOM/*.dcm \ # The pattern to select the requested dicoms
-s 102 \ # A specific subject used to generate the heuristic file
--ses 20160302_3 \ # A specific session used to generate the heuristic file

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure

docker run --rm -it \ # run a docker interactively with a terminal environment
-v ~/Documents/heudiconvTest:/data:ro \ # connect my local directory to the container /data directory
-v ~/Documents/heudiconvTest/BIDS:/output \ # connect my local directory to the container /output directory
nipy/heudiconv:latest \ # The container I want to run
-d /data/{subject}/{session}/SCANS/*/DICOM/*.dcm \ # The pattern to select the requested dicoms
-s 102 \ # A specific subject used to generate the heuristic file
--ses 20160302_3 \ # A specific session used to generate the heuristic file
-f convertall \ # A generic heuristic to convert all dicoms

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure

docker run --rm -it \ # run a docker interactively with a terminal environment
-v ~/Documents/heudiconvTest:/data:ro \ # connect my local directory to the container /data directory
-v ~/Documents/heudiconvTest/BIDS:/output \ # connect my local directory to the container /output directory
nipy/heudiconv:latest \ # The container I want to run
-d /data/{subject}/{session}/SCANS/*/DICOM/*.dcm \ # The pattern to select the requested dicoms
-s 102 \ # A specific subject used to generate the heuristic file
--ses 20160302_3 \ # A specific session used to generate the heuristic file
-f convertall \ # A generic heuristic to convert all dicoms
-c none \ # the dicom->nifti converter to use

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure

docker run --rm -it \ # run a docker interactively with a terminal environment
-v ~/Documents/heudiconvTest:/data:ro \ # connect my local directory to the container /data directory
-v ~/Documents/heudiconvTest/BIDS:/output \ # connect my local directory to the container /output directory
nipy/heudiconv:latest \ # The container I want to run
-d /data/{subject}/{session}/SCANS/*/DICOM/*.dcm \ # The pattern to select the requested dicoms
-s 102 \ # A specific subject used to generate the heuristic file
--ses 20160302_3 \ # A specific session used to generate the heuristic file
-f convertall \ # A generic heuristic to convert all dicoms
-c none \ # the dicom->nifti converter to use
-o /output # the output directory to store the heuristic file

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure

# output
> ls -1 ./BIDS/.heudiconv/sub-102/info
convertall.py
dicominfo_ses-20160302_3.tsv
filegroup_ses-20160302_3.json
sub-102_ses-20160302_3.auto.txt
sub-102_ses-20160302_3.edit.txt

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure

# convertall.py

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
    """

    data = create_key('run{item:03d}')
    info = {data: []}
    last_run = len(seqinfo)

    for s in seqinfo:
        """
        The namedtuple `s` contains the following fields:
        * total_files_till_now
        * example_dcm_file
        * series_id
        * dcm_dir_name
        * unspecified2
        * unspecified3
        * dim1
        * dim2
        * dim3
        * dim4
        * TR
        * TE
        * protocol_name
        * is_motion_corrected
        * is_derived
        * patient_id
        * study_description
        * referring_physician_name
        * series_description
        * image_type
        """

        info[data].append(s.series_id)
    return info

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure

# convertall.py

t1w_low_res = create_key('sub-{subject}/{session}/anat/sub-{subject}_{session}_acq-lowres_T1w')
t1w_high_res = create_key('sub-{subject}/{session}/anat/sub-{subject}_{session}_acq-highres_T1w')
t2w = create_key('sub-{subject}/{session}/anat/sub-{subject}_{session}_T2w')
flanker = create_key('sub-{subject}/{session}/func/sub-{subject}_{session}_task-flanker_bold')
dwi_64dir = create_key('sub-{subject}/{session}/dwi/sub-{subject}_{session}_dwi')
dwi_b0s = create_key('sub-{subject}/{session}/dwi/sub-{subject}_{session}_acq-B0s_dwi')
rest = create_key('sub-{subject}/{session}/func/sub-{subject}_{session}_task-rest_bold')


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
    """

    data = create_key('run{item:03d}')
    info = {data: []}
    last_run = len(seqinfo)

    for s in seqinfo:
        """
        The namedtuple `s` contains the following fields:
        * total_files_till_now
        * example_dcm_file
        * series_id
        * dcm_dir_name
        * unspecified2
        * unspecified3
        * dim1
        * dim2
        * dim3
        * dim4
        * TR
        * TE
        * protocol_name
        * is_motion_corrected
        * is_derived
        * patient_id
        * study_description
        * referring_physician_name
        * series_description
        * image_type
        """

        info[data].append(s.series_id)
    return info

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure

# convertall.py

t1w_low_res = create_key('sub-{subject}/{session}/anat/sub-{subject}_{session}_acq-lowres_T1w')
t1w_high_res = create_key('sub-{subject}/{session}/anat/sub-{subject}_{session}_acq-highres_T1w')
t2w = create_key('sub-{subject}/{session}/anat/sub-{subject}_{session}_T2w')
flanker = create_key('sub-{subject}/{session}/func/sub-{subject}_{session}_task-flanker_bold')
dwi_64dir = create_key('sub-{subject}/{session}/dwi/sub-{subject}_{session}_dwi')
dwi_b0s = create_key('sub-{subject}/{session}/dwi/sub-{subject}_{session}_acq-B0s_dwi')
rest = create_key('sub-{subject}/{session}/func/sub-{subject}_{session}_task-rest_bold')

info = {
                t1w_low_res: [],
                t1w_high_res: [],
                t2w: [],
                flanker: [],
                dwi_64dir: [],
                dwi_b0s: [],
                rest: [],
            }

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
    """

    data = create_key('run{item:03d}')
    info = {data: []}
    last_run = len(seqinfo)

    for s in seqinfo:
        """
        The namedtuple `s` contains the following fields:
        * total_files_till_now
        * example_dcm_file
        * series_id
        * dcm_dir_name
        * unspecified2
        * unspecified3
        * dim1
        * dim2
        * dim3
        * dim4
        * TR
        * TE
        * protocol_name
        * is_motion_corrected
        * is_derived
        * patient_id
        * study_description
        * referring_physician_name
        * series_description
        * image_type
        """

        info[data].append(s.series_id)
    return info

Generate a Heuristic to transfer Dicoms to NIfTI with BIDS structure

# convert_PACR.py

t1w_low_res = create_key('sub-{subject}/{session}/anat/sub-{subject}_{session}_acq-lowres_T1w')
t1w_high_res = create_key('sub-{subject}/{session}/anat/sub-{subject}_{session}_acq-highres_T1w')
t2w = create_key('sub-{subject}/{session}/anat/sub-{subject}_{session}_T2w')
flanker = create_key('sub-{subject}/{session}/func/sub-{subject}_{session}_task-flanker_bold')
dwi_64dir = create_key('sub-{subject}/{session}/dwi/sub-{subject}_{session}_dwi')
dwi_b0s = create_key('sub-{subject}/{session}/dwi/sub-{subject}_{session}_acq-B0s_dwi')
rest = create_key('sub-{subject}/{session}/func/sub-{subject}_{session}_task-rest_bold')

info = {
                t1w_low_res: [],
                t1w_high_res: [],
                t2w: [],
                flanker: [],
                dwi_64dir: [],
                dwi_b0s: [],
                rest: [],
            }

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
    """

    data = create_key('run{item:03d}')
    info = {data: []}
    last_run = len(seqinfo)

    for s in seqinfo:
        """
        The namedtuple `s` contains the following fields:
        * total_files_till_now
        * example_dcm_file
        * series_id
        * dcm_dir_name
        * unspecified2
        * unspecified3
        * dim1
        * dim2
        * dim3
        * dim4
        * TR
        * TE
        * protocol_name
        * is_motion_corrected
        * is_derived
        * patient_id
        * study_description
        * referring_physician_name
        * series_description
        * image_type
        """

        if s.protocol_name == 'MPRAGE GRAPPA2':
            info[t1w_low_res] = [s.series_id]
        if s.protocol_name == 'Axial T2-FLAIR':
            info[t2w] = [s.series_id]
        if s.protocol_name == 'FLANKER':
            info[flanker] = [s.series_id]
        if s.protocol_name == 'REST':
            info[rest] = [s.series_id]
        if s.protocol_name == 'MPRAGE T1 Coronal - TI=900':
            info[t1w_high_res] = [s.series_id]
        if s.protocol_name == 'DTI-64 DIRECTIONS':
            info[dwi_64dir] = [s.series_id]
        if s.protocol_name == 'DTI-EXTRA B0':
            info[dwi_b0s] = [s.series_id]

    return info

Convert the Dicoms to NIfTI in BIDS format using our heuristic (Singularity)

singularity run \
-H ~/singularity_home \
-B /Shared/vosslabhpc:/hpc \
~/simgs/heudiconv-latest.simg \
-d /hpc/Tutorials/heudiconvTest/{subject}/{session}/SCANS/*/DICOM/*.dcm \
-s 102 \
--ses 20160302_3 \
-f /hpc/Tutorials/heudiconvTest/BIDS/code/convert_PACR.py `# place where I saved the edited heuristic converter` \
-c dcm2niix -b `# converter I want to use (into bids format)` \
-o /hpc/Tutorials/heudiconvTest/BIDS

Do the same process for all subjects/sessions

for subject in {100..150}; do
    for session in $(find ./${subject} -type d -maxdepth 1 -mindepth 1 | xargs -I {} basename {}); do
        docker run --rm -it \
        -v ~/Documents/heudiconvTest:/data:ro \
        -v ~/Documents/heudiconvTest/BIDS:/output \
        nipy/heudiconv:latest \
        -d /data/{subject}/{session}/SCANS/*/DICOM/*.dcm \
        -s ${subject} \
        --ses ${session} \
        -f /output/code/convert_PACR.py \
        -c dcm2niix -b \
        -o /output
    done
done

Do the same process for all subjects/sessions

for subject in {100..150}; do
    for session in $(find ./${subject} -type d -maxdepth 1 -mindepth 1 | xargs -I {} basename {}); do
        singularity run \
        -H ~/singularity_home \
        -B /Shared/vosslabhpc:/hpc \
        ~/simgs/heudiconv-latest.simg \
        -d /hpc/Tutorials/heudiconvTest/{subject}/{session}/SCANS/*/DICOM/*.dcm \
        -s ${subject} \
        --ses ${session} \
        -f /hpc/Tutorials/heudiconvTest/BIDS/code/convert_PACR.py  \
        -c dcm2niix -b \
        -o /hpc/Tutorials/heudiconvTest/BIDS
    done
done

Other Resources

Heudiconv Example

By James Kent

Heudiconv Example

  • 3,261