dicom
dicom
¶
DICOM file loading for osipy.
This module provides functions for loading DICOM series into PerfusionDataset containers with metadata extraction.
Supports both single-series and multi-series DCE data where each timepoint may be stored in a separate DICOM series directory.
References
DICOM Standard: https://www.dicomstandard.org/
build_affine_from_dicom
¶
Build NIfTI affine matrix from DICOM geometry tags.
This function builds an affine matrix that maps voxel indices (i, j, k) to patient coordinates (x, y, z) in millimeters.
| PARAMETER | DESCRIPTION |
|---|---|
dcm
|
DICOM dataset with ImageOrientationPatient and ImagePositionPatient.
TYPE:
|
slice_thickness
|
Slice thickness in mm.
TYPE:
|
transpose_slices
|
If True, assumes slices will be transposed when loading (col, row order). This matches standard NIfTI conventions used by tools like dcm2niix. If False, assumes slices stored in DICOM native (row, col) order.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ndarray
|
4x4 affine matrix mapping voxel indices to patient coordinates. |
Notes
DICOM geometry conventions: - ImageOrientationPatient[0:3]: row direction cosines (direction of increasing column) - ImageOrientationPatient[3:6]: column direction cosines (direction of increasing row) - PixelSpacing[0]: row spacing (distance between rows, in column direction) - PixelSpacing[1]: column spacing (distance between columns, in row direction)
When transpose_slices=True (default): - Data is stored as array[col, row, slice] after transposing each DICOM slice - This matches the convention used by most DICOM-to-NIfTI converters - Affine column 0 maps to row direction (along increasing column index) - Affine column 1 maps to column direction (along increasing row index)
load_dicom
¶
Load DICOM series as PerfusionDataset.
| PARAMETER | DESCRIPTION |
|---|---|
path
|
Path to DICOM directory or single file.
TYPE:
|
prompt_missing
|
If True, prompt user for missing required metadata. If False, raise MetadataError for missing required tags.
TYPE:
|
modality
|
Perfusion modality. If None, attempts to infer from DICOM tags.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
PerfusionDataset
|
Loaded imaging data with metadata. |
| RAISES | DESCRIPTION |
|---|---|
FileNotFoundError
|
If path does not exist. |
IOError
|
If no valid DICOM files found. |
MetadataError
|
If required metadata missing and prompt_missing=False. |
DataValidationError
|
If data dimensions are invalid. |
Examples:
>>> from osipy.common.io.dicom import load_dicom
>>> dataset = load_dicom("dicom_folder/", prompt_missing=True)
>>> print(dataset.acquisition_params.tr)
5.0
Notes
This implementation uses pydicom for DICOM file handling. Vendor-specific private tags are attempted after standard tags.
load_dicom_multi_series
¶
Load DCE data from multiple DICOM series directories.
This function handles datasets where each DCE timepoint is stored in a separate DICOM series directory (common in TCIA datasets like QIN-Breast-DCE-MRI).
| PARAMETER | DESCRIPTION |
|---|---|
series_dirs
|
List of paths to DICOM series directories, one per timepoint. Can be provided in any order - the function will auto-detect temporal ordering from DICOM metadata.
TYPE:
|
time_points
|
Explicit time points in seconds for each series (after sorting). If None, times are extracted from DICOM metadata (SeriesDescription patterns like TT=X.Xs, AcquisitionTime, etc.).
TYPE:
|
prompt_missing
|
If True, prompt user for missing required metadata. If False, raise MetadataError for missing required tags.
TYPE:
|
modality
|
Perfusion modality. Defaults to DCE if None.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
PerfusionDataset
|
4D dataset with shape (x, y, z, n_timepoints) and time_points array. |
| RAISES | DESCRIPTION |
|---|---|
IOError
|
If series directories don't exist or have inconsistent dimensions. |
DataValidationError
|
If series have mismatched spatial dimensions. |
Examples:
Load QIN-Breast-DCE-MRI with auto-detected timepoints:
>>> from osipy.common.io.dicom import load_dicom_multi_series
>>> series = [
... "data/series_tt49.6s/",
... "data/series_tt69.7s/",
... "data/series_tt89.9s/",
... ]
>>> dataset = load_dicom_multi_series(series)
>>> print(dataset.time_points)
[49.6, 69.7, 89.9]
Load with explicit time points:
>>> dataset = load_dicom_multi_series(
... series_dirs=series,
... time_points=[0, 20.1, 40.2], # Relative times in seconds
... )
Notes
The function automatically: - Detects temporal ordering from SeriesDescription, AcquisitionTime, or SeriesNumber - Validates that all series have matching spatial dimensions - Builds proper NIfTI affine from DICOM geometry tags - Extracts acquisition parameters (TR, TE, flip angle) from first series