Skip to main content

Parse Siemens CSA header information

Project description

CSA Header

Parse CSA header information from Siemens MRI acquisitions with Python.

PyPI - Version PyPI - Python Version Tests codecov pre-commit.ci status License: MIT


Some Siemens MRI scans may include CSA headers that provide valuable information about the acquisition and storage of the data. These headers are stored as private data elements, usually looking something like:

(0029, 1010) CSA Image Header Type          OB: 'IMAGE NUM 4'
(0029, 1010) CSA Image Header Version       OB: '20100114'
(0029, 1010) CSA Image Header Info          OB: Array of 11560 bytes
(0029, 1020) CSA Series Header Type         OB: 'MR'
(0029, 1020) CSA Series Header Version      OB: '20100114'
(0029, 1020) CSA Series Header Info         OB: Array of 80248 bytes

The CSA Image Header Info and CSA Series Header Info elements contain encoded information which is crucial for the correct interpretation of the associated acquisition data.

For a detailed explanation on the CSA encoding scheme, please see this excellent article from NiBabel's documentation site.

Features

  • Fast and Lightweight: Minimal dependencies (numpy, pydicom)
  • Comprehensive Parsing: Supports both CSA header types (Type 1 and Type 2)
  • ASCCONV Support: Automatic parsing of embedded ASCCONV protocol parameters
  • Type-Safe: Complete type hints for all public APIs
  • Well-Tested: 96% test coverage with 161 tests
  • Python 3.9+: Modern Python with support through Python 3.13
  • NiBabel Compatible: Integrates seamlessly with neuroimaging workflows

Table of Contents

Installation

pip install csa_header

Optional Dependencies

For working with the provided NiBabel integration examples:

pip install csa_header[examples]

For development (includes pre-commit hooks and IPython):

pip install csa_header[dev]

Quickstart

Use pydicom to read a DICOM header:

>>> import pydicom
>>> dcm = pydicom.dcmread("/path/to/file.dcm")

Extract a data element containing a CSA header, e.g., for CSA Series Header Info:

>>> data_element = dcm.get((0x29, 0x1020))
>>> data_element
(0029, 1020) [CSA Series Header Info]            OB: Array of 180076 elements

Read the raw byte array from the data element:

>>> raw_csa = data_element.value
>>> raw_csa
b'SV10\x04\x03\x02\x01O\x00\x00\x00M\x00\x00\x00UsedPatientWeight\x00      <Visible> "true" \n      \n      <ParamStr\x01\x00\x00\x00IS\x00\x00\x06...'

Parse the contents of the CSA header with the CsaHeader class:

>>> from csa_header import CsaHeader
>>> parsed_csa = CsaHeader(raw_csa).read()
>>> parsed_csa
{
    'NumberOfPrescans': {'index': 1, 'VR': 'IS', 'VM': 1, 'value': 0},
    'TransmitterCalibration': {'index': 2, 'VR': 'DS', 'VM': 1, 'value': 247.102},
    'PhaseGradientAmplitude': {'index': 3, 'VR': 'DS', 'VM': 1, 'value': 0.0},
    'ReadoutGradientAmplitude': {'index': 4, 'VR': 'DS', 'VM': 1, 'value': 0.0},
    'SelectionGradientAmplitude': {'index': 5, 'VR': 'DS', 'VM': 1, 'value': 0.0},
    'GradientDelayTime': {'index': 6,
    'VR': 'DS',
    'VM': 3,
    'value': [36.0, 35.0, 31.0]},
    'RfWatchdogMask': {'index': 7, 'VR': 'IS', 'VM': 1, 'value': 0},
    'RfPowerErrorIndicator': {'index': 8, 'VR': 'DS', 'VM': 1, 'value': None},
    'SarWholeBody': {'index': 9, 'VR': 'DS', 'VM': 3, 'value': None},
    'Sed': {'index': 10,
    'VR': 'DS',
    'VM': 3,
    'value': [1000000.0, 324.74800987, 324.74800832]}
    ...
}

Advanced Usage

Extracting ASCCONV Protocol

CSA headers often contain the complete scanner protocol in ASCCONV format under the MrPhoenixProtocol tag. This is automatically parsed into a nested dictionary:

>>> parsed_csa = CsaHeader(raw_csa).read()
>>> protocol = parsed_csa.get('MrPhoenixProtocol')
>>> if protocol:
...     # Access protocol parameters
...     tr = protocol['alTR'][0]  # Repetition time
...     te = protocol['alTE'][0]  # Echo time
...     print(f"TR: {tr} ms, TE: {te} ms")
TR: 2000 ms, TE: 30 ms

Diffusion MRI (DWI) Parameters

Extract diffusion-specific parameters for DTI/DWI analysis:

>>> # From image header (0x0029, 0x1020)
>>> image_header = CsaHeader(dcm[0x0029, 0x1020].value).read()
>>> b_value = image_header.get('B_value')
>>> gradient = image_header.get('DiffusionGradientDirection')
>>> print(f"B-value: {b_value}, Gradient: {gradient}")
B-value: 1000, Gradient: [0.707, 0.707, 0.0]

Functional MRI (fMRI) Parameters

Extract slice timing for slice timing correction:

>>> # From series header (0x0029, 0x1010)
>>> series_header = CsaHeader(dcm[0x0029, 0x1010].value).read()
>>> slice_times = series_header.get('MosaicRefAcqTimes')
>>> n_slices = series_header.get('NumberOfImagesInMosaic')
>>> print(f"Slice times: {slice_times[:3]}... ({n_slices} slices)")
Slice times: [0.0, 52.5, 105.0]... (64 slices)

Integration with NiBabel

csa_header works seamlessly with NiBabel for comprehensive neuroimaging workflows:

import nibabel as nib
import pydicom
from csa_header import CsaHeader

# Load DICOM with both pydicom and NiBabel
dcm = pydicom.dcmread('scan.dcm')
nib_img = nib.load('scan.dcm')

# Extract CSA header information
if (0x0029, 0x1010) in dcm:
    csa = CsaHeader(dcm[0x0029, 0x1010].value)
    csa_info = csa.read()

    # Use NiBabel for image data
    data = nib_img.get_fdata()

    # Use CSA for metadata
    slice_times = csa_info.get('MosaicRefAcqTimes', [])

    print(f"Image shape: {data.shape}")
    print(f"Slice timing from CSA: {len(slice_times)} time points")

Use Cases with NiBabel

  • Slice Timing Correction: Extract MosaicRefAcqTimes for accurate fMRI preprocessing
  • Diffusion Imaging: Get b-values and gradient directions for DTI analysis
  • Protocol Verification: Confirm acquisition parameters match expected values
  • Quality Assurance: Extract technical parameters for QA pipelines
  • BIDS Conversion: Generate complete metadata for BIDS-compliant datasets

See examples/nibabel_integration.py for complete integration examples.

Examples

The examples/ directory contains comprehensive usage examples:

  • nibabel_integration.py: Complete workflow combining csa_header with NiBabel
    • Extract DWI parameters (b-values, gradients)
    • Extract fMRI parameters (slice timing, TR/TE)
    • Parse ASCCONV protocol parameters
    • Batch processing multiple DICOM files

Run examples:

python examples/nibabel_integration.py path/to/siemens_dicom.dcm

Tests

This package uses hatch to manage development and packaging. To run the tests, simply run:

hatch run test

Coverage

To run the tests with coverage, run:

hatch run cov

Or, to automatically generate an HTML report and open it in your default browser:

hatch run cov-show

Contributing

Contributions are welcome! This project is community-maintained and aims to be a reliable tool for the medical imaging community.

How to Contribute

  1. Report Issues: Found a bug or have a feature request? Open an issue
  2. Submit Pull Requests: See CONTRIBUTING.md for detailed guidelines
  3. Improve Documentation: Help make the docs better
  4. Share Examples: Contribute integration examples or use cases

Development Setup

# Clone the repository
git clone https://github.com/open-dicom/csa_header.git
cd csa_header

# Install hatch
pip install hatch

# Run tests
hatch run test:test

# Run linting
hatch run lint:all

# Install pre-commit hooks
hatch run pre-commit install

See CONTRIBUTING.md for complete development guidelines including:

  • Code style requirements
  • Testing requirements (90%+ coverage)
  • Commit message conventions
  • Pull request process

License

csa_header is distributed under the terms of the MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

csa_header-1.0.1.tar.gz (88.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

csa_header-1.0.1-py3-none-any.whl (17.9 kB view details)

Uploaded Python 3

File details

Details for the file csa_header-1.0.1.tar.gz.

File metadata

  • Download URL: csa_header-1.0.1.tar.gz
  • Upload date:
  • Size: 88.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.24.1

File hashes

Hashes for csa_header-1.0.1.tar.gz
Algorithm Hash digest
SHA256 f1aa5b61c7f50aa91301466775429e13b3d2fbc7f68c3a1c40ef86e73cd71c60
MD5 8b4c3e611bd9f2539d99615aec81b55d
BLAKE2b-256 0939ea73cc902f737158dac04284f86a72bf95e72c731fe382801f27b91c8c30

See more details on using hashes here.

File details

Details for the file csa_header-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: csa_header-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 17.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.24.1

File hashes

Hashes for csa_header-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a734318020cbc038911b043ff12ac40d3677870f863bc00c1af52de19c05e9ee
MD5 7362ba92933131fdbc7ead943a08aa51
BLAKE2b-256 b97debe7a18e44542dfd0061991630d1ffc23654a6887bbf8f352a4a19765b4b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page