Skip to content

dicom2nifti

tit.pre.dicom2nifti

Source-image ingestion with BIDS-compliant naming.

Converts each modality found under sourcedata/sub-{id}/ into a BIDS-named NIfTI (sub-{id}_{suffix}.nii.gz). DICOM series are converted with dcm2niix; a modality folder that already holds a NIfTI is copied into place instead.

Public API

run_dicom_to_nifti Ingest every supported modality for a subject. MODALITIES Supported modalities and their BIDS datatype directories.

See Also

tit.pre.structural.run_pipeline : Full preprocessing pipeline.

run_dicom_to_nifti

run_dicom_to_nifti(project_dir: str, subject_id: str, *, logger, runner: CommandRunner | None = None) -> None

Ingest a subject's source images into BIDS-named NIfTI files.

Looks for a T1w, T2w, ct, and dwi folder under sourcedata/sub-{subject_id}/ (folder names are matched case-insensitively) and ingests each one that exists. Anatomical images and CT go to the subject's anat/ folder, diffusion images to dwi/ (with their .bval/.bvec sidecars).

Each modality folder is searched recursively. Supported archives (.zip, .tar, .tar.gz, .tgz) are safely extracted to extracted_archives/ first. DICOM files (.dcm/.dicom) are then converted with dcm2niix; if the folder holds no DICOMs but does hold a NIfTI, that file is copied into place instead (compressing a bare .nii on the way). Dotfiles are ignored throughout.

CT is written as anat/sub-{id}_ct.nii.gz. This is a local convention, not BIDS -- see :data:MODALITIES.

Parameters

project_dir : str BIDS project root directory. subject_id : str Subject identifier without the sub- prefix. logger : logging.Logger Logger for progress messages. runner : CommandRunner or None, optional Subprocess runner for streaming output.

Raises

PreprocessError If an output NIfTI already exists for a modality.

See Also

run_pipeline : Full preprocessing pipeline. MODALITIES : Supported modalities and their BIDS datatype directories.

Source code in tit/pre/dicom2nifti.py
def run_dicom_to_nifti(
    project_dir: str,
    subject_id: str,
    *,
    logger,
    runner: CommandRunner | None = None,
) -> None:
    """Ingest a subject's source images into BIDS-named NIfTI files.

    Looks for a ``T1w``, ``T2w``, ``ct``, and ``dwi`` folder under
    ``sourcedata/sub-{subject_id}/`` (folder names are matched
    case-insensitively) and ingests each one that exists. Anatomical images
    and CT go to the subject's ``anat/`` folder, diffusion images to ``dwi/``
    (with their ``.bval``/``.bvec`` sidecars).

    Each modality folder is searched recursively. Supported archives
    (``.zip``, ``.tar``, ``.tar.gz``, ``.tgz``) are safely extracted to
    ``extracted_archives/`` first. DICOM files (``.dcm``/``.dicom``) are then
    converted with ``dcm2niix``; if the folder holds no DICOMs but does hold a
    NIfTI, that file is copied into place instead (compressing a bare ``.nii``
    on the way). Dotfiles are ignored throughout.

    CT is written as ``anat/sub-{id}_ct.nii.gz``. This is a local convention,
    not BIDS -- see :data:`MODALITIES`.

    Parameters
    ----------
    project_dir : str
        BIDS project root directory.
    subject_id : str
        Subject identifier without the ``sub-`` prefix.
    logger : logging.Logger
        Logger for progress messages.
    runner : CommandRunner or None, optional
        Subprocess runner for streaming output.

    Raises
    ------
    PreprocessError
        If an output NIfTI already exists for a modality.

    See Also
    --------
    run_pipeline : Full preprocessing pipeline.
    MODALITIES : Supported modalities and their BIDS datatype directories.
    """
    from tit.telemetry import track_operation
    from tit import constants as _const

    with track_operation(_const.TELEMETRY_OP_PRE_DICOM):
        pm = get_path_manager(project_dir)
        sourcedata_dir = Path(pm.sourcedata_subject(subject_id))

        converted = False
        for modality, datatype in MODALITIES:
            modality_dir = _modality_source_dir(sourcedata_dir, modality)
            if not modality_dir.exists():
                continue
            output_dir = Path(pm.bids_datatype(subject_id, datatype))
            if _ingest_modality(
                modality_dir, output_dir, subject_id, modality, logger, runner
            ):
                converted = True

        if not converted:
            logger.warning("No DICOM or NIfTI files found or converted")