A pure Python package for reading and writing DICOM data
—
Package configuration, debugging tools, data dictionary access, and various utility functions providing comprehensive support for DICOM file analysis, validation, debugging, and system configuration for optimal medical imaging workflows.
Global configuration system for controlling pydicom behavior, validation, and debugging options.
def debug(debug_on=True, default_handler=True):
"""
Configure pydicom debugging output.
Parameters:
- debug_on: bool - Enable or disable debug mode
- default_handler: bool - Use default logging handler
Returns:
None - Configures global debugging state
"""
def DS_numpy(use_numpy=True):
"""
Set whether multi-valued DS elements are returned as numpy arrays.
Parameters:
- use_numpy: bool - Use numpy arrays for multi-value DS elements
Raises:
ValueError - If use_DS_decimal and use_numpy are both True
"""
def DS_decimal(use_Decimal_boolean=True):
"""
Set DS class to be derived from Decimal or float.
Parameters:
- use_Decimal_boolean: bool - Use Decimal for DS elements
Raises:
ValueError - If use_Decimal_boolean and use_DS_numpy are both True
"""
# Configuration Variables
use_DS_numpy: bool # Default: False - Use numpy for multi-value DS elements
use_IS_numpy: bool # Default: False - Use numpy for multi-value IS elements
use_DS_decimal: bool # Default: False - Use Decimal for DS elements
allow_DS_float: bool # Default: False - Allow floats for DSdecimal creation
# Validation Constants
IGNORE: int # Value: 0 - No validation performed
WARN: int # Value: 1 - Warning issued on validation errors
RAISE: int # Value: 2 - Exception raised on validation errors
class Settings:
"""
Global settings class for package behavior configuration.
Provides centralized configuration for validation, pixel data handling,
character encoding, and other package-wide settings.
"""
def __init__(self):
"""Initialize settings with default values."""
# Validation Configuration
@property
def reading_validation_mode(self):
"""str: Validation mode for reading operations ("raise", "warn", "ignore")."""
@reading_validation_mode.setter
def reading_validation_mode(self, value):
"""Set reading validation mode."""
@property
def writing_validation_mode(self):
"""str: Validation mode for writing operations."""
@writing_validation_mode.setter
def writing_validation_mode(self, value):
"""Set writing validation mode."""
# Pixel Data Configuration
@property
def pixel_data_handlers(self):
"""list: Available pixel data handlers in priority order."""
@property
def convert_wrong_length_to_UN(self):
"""bool: Convert elements with wrong length to UN VR."""
@convert_wrong_length_to_UN.setter
def convert_wrong_length_to_UN(self, value):
"""Set wrong length conversion behavior."""
# Character Encoding
@property
def assume_implicit_vr_switch(self):
"""bool: Assume VR switches to implicit in sequences."""
@assume_implicit_vr_switch.setter
def assume_implicit_vr_switch(self, value):
"""Set implicit VR switch assumption."""
# Global settings instance
settings = Settings()Functions for accessing DICOM data dictionary information including tag descriptions, VR types, and keyword mappings.
def dictionary_description(tag):
"""
Get DICOM description for tag.
Parameters:
- tag: int, Tag, or tuple - DICOM tag
Returns:
str - Description from DICOM dictionary
Raises:
KeyError - If tag not found in dictionary
"""
def dictionary_VR(tag):
"""
Get Value Representation for tag from dictionary.
Parameters:
- tag: int, Tag, or tuple - DICOM tag
Returns:
str - Value Representation (VR) for tag
Raises:
KeyError - If tag not found in dictionary
"""
def dictionary_VM(tag):
"""
Get Value Multiplicity for tag from dictionary.
Parameters:
- tag: int, Tag, or tuple - DICOM tag
Returns:
str - Value Multiplicity (VM) specification
Raises:
KeyError - If tag not found in dictionary
"""
def keyword_for_tag(tag):
"""
Get DICOM keyword for tag.
Parameters:
- tag: int, Tag, or tuple - DICOM tag
Returns:
str - DICOM keyword
Raises:
KeyError - If tag not found in dictionary
"""
def tag_for_keyword(keyword):
"""
Get DICOM tag for keyword.
Parameters:
- keyword: str - DICOM keyword
Returns:
Tag - DICOM tag object
Raises:
KeyError - If keyword not found in dictionary
"""Functions for managing private DICOM dictionaries and vendor-specific elements.
def add_dict_entry(tag, VR, keyword, description, VM="1", is_retired=False):
"""
Add entry to DICOM dictionary.
Parameters:
- tag: int or Tag - DICOM tag
- VR: str - Value Representation
- keyword: str - DICOM keyword
- description: str - Element description
- VM: str - Value Multiplicity specification
- is_retired: bool - Whether element is retired
"""
def add_private_dict_entry(private_creator, tag, VR, keyword, description, VM="1"):
"""
Add private dictionary entry.
Parameters:
- private_creator: str - Private creator identification
- tag: int - Private tag (element part only)
- VR: str - Value Representation
- keyword: str - Private keyword
- description: str - Element description
- VM: str - Value Multiplicity specification
"""
def get_private_dict_entry(private_creator, keyword):
"""
Get private dictionary entry.
Parameters:
- private_creator: str - Private creator identification
- keyword: str - Private keyword
Returns:
dict - Dictionary entry with tag, VR, description, VM
"""
def private_dictionary_description(private_creator, tag):
"""
Get description for private tag.
Parameters:
- private_creator: str - Private creator identification
- tag: int - Private tag
Returns:
str - Description of private element
"""Constants and functions for controlling validation behavior throughout the package.
# Validation mode constants
IGNORE = "ignore"
WARN = "warn"
RAISE = "raise"
def future_behavior(enable=True):
"""
Enable future API behavior changes.
Parameters:
- enable: bool - Enable future behavior mode
Returns:
None - Configures future behavior flags
"""
def set_validation_mode(mode, reading=True, writing=True):
"""
Set validation mode for operations.
Parameters:
- mode: str - Validation mode ("ignore", "warn", "raise")
- reading: bool - Apply to reading operations
- writing: bool - Apply to writing operations
"""
def get_validation_mode(operation="reading"):
"""
Get current validation mode.
Parameters:
- operation: str - Operation type ("reading" or "writing")
Returns:
str - Current validation mode
"""Configuration and management of pixel data handlers for different compression formats.
def get_pixel_data_handlers():
"""
Get list of available pixel data handlers.
Returns:
list - Available handlers with capabilities
"""
def set_pixel_data_handler_priority(handler_names):
"""
Set priority order for pixel data handlers.
Parameters:
- handler_names: list - Handler names in priority order
"""
def get_pixel_data_handler(transfer_syntax_uid):
"""
Get appropriate handler for transfer syntax.
Parameters:
- transfer_syntax_uid: str - Transfer syntax UID
Returns:
module - Handler module for transfer syntax
"""
def pixel_data_handler_info():
"""
Get information about pixel data handler availability.
Returns:
dict - Handler availability and capabilities
"""Tools for debugging DICOM files and analyzing package behavior.
def dump_file(filename, stop_when=None):
"""
Dump DICOM file contents for debugging.
Parameters:
- filename: str - Path to DICOM file
- stop_when: callable - Function to determine when to stop reading
Returns:
str - Formatted dump of file contents
"""
def hex_dump(data, start_offset=0, max_lines=None):
"""
Create hexadecimal dump of binary data.
Parameters:
- data: bytes - Binary data to dump
- start_offset: int - Starting byte offset for display
- max_lines: int - Maximum lines to display
Returns:
str - Hexadecimal dump representation
"""
def analyze_file(filename):
"""
Analyze DICOM file structure and content.
Parameters:
- filename: str - Path to DICOM file
Returns:
dict - Analysis results including structure, elements, errors
"""
def validate_file(filename):
"""
Validate DICOM file against standard.
Parameters:
- filename: str - Path to DICOM file
Returns:
list - Validation errors and warnings
"""Tools for generating Python code from DICOM files and structures.
def codify_file(filename, save_as=None):
"""
Generate Python code to recreate DICOM file.
Parameters:
- filename: str - Path to DICOM file
- save_as: str - Optional output file for generated code
Returns:
str - Python code to recreate the dataset
"""
def codify_dataset(dataset, save_as=None):
"""
Generate Python code for dataset.
Parameters:
- dataset: Dataset - Dataset to convert to code
- save_as: str - Optional output file for generated code
Returns:
str - Python code to recreate the dataset
"""
def generate_test_data(modality="CT", save_as=None):
"""
Generate test DICOM dataset.
Parameters:
- modality: str - Modality for test data
- save_as: str - Optional file to save test dataset
Returns:
Dataset - Generated test dataset
"""Utilities for working with different DICOM file formats and standards compliance.
def is_dicom_file(filename):
"""
Check if file is valid DICOM format.
Parameters:
- filename: str - Path to file
Returns:
bool - True if file appears to be DICOM
"""
def get_file_info(filename):
"""
Get basic information about DICOM file.
Parameters:
- filename: str - Path to DICOM file
Returns:
dict - File information (size, transfer syntax, etc.)
"""
def fix_file_meta_info(dataset):
"""
Fix or create proper File Meta Information.
Parameters:
- dataset: Dataset - Dataset to fix
Returns:
None - Modifies dataset in place
"""
def anonymize_dataset(dataset, remove_curves=True, remove_overlays=True):
"""
Anonymize dataset by removing identifying information.
Parameters:
- dataset: Dataset - Dataset to anonymize
- remove_curves: bool - Remove curve data
- remove_overlays: bool - Remove overlay data
Returns:
None - Modifies dataset in place
"""Functions for handling character encoding in DICOM files.
def default_encoding():
"""
Get default character encoding.
Returns:
str - Default encoding name
"""
def convert_encodings(text, from_encoding, to_encoding):
"""
Convert text between character encodings.
Parameters:
- text: str or bytes - Text to convert
- from_encoding: str - Source encoding
- to_encoding: str - Target encoding
Returns:
str - Converted text
"""
def decode_bytes(value, encodings, delimiters=None):
"""
Decode bytes using specified encodings.
Parameters:
- value: bytes - Bytes to decode
- encodings: list - Encodings to try
- delimiters: set - Characters that separate text components
Returns:
str - Decoded text
"""import pydicom
from pydicom.config import debug, settings
# Enable debugging
debug(True)
# Configure validation behavior
settings.reading_validation_mode = "warn" # Warn on validation errors
settings.writing_validation_mode = "raise" # Raise on write validation errors
# Read file with configured behavior
dataset = pydicom.dcmread("test.dcm")
print(f"Reading validation: {settings.reading_validation_mode}")
print(f"Writing validation: {settings.writing_validation_mode}")from pydicom.datadict import (dictionary_description, dictionary_VR,
keyword_for_tag, tag_for_keyword)
# Look up tag information
tag = 0x00100010 # Patient Name
try:
description = dictionary_description(tag)
vr = dictionary_VR(tag)
keyword = keyword_for_tag(tag)
print(f"Tag {tag:08X}:")
print(f" Description: {description}")
print(f" VR: {vr}")
print(f" Keyword: {keyword}")
except KeyError as e:
print(f"Tag not found: {e}")
# Reverse lookup
try:
patient_id_tag = tag_for_keyword("PatientID")
print(f"PatientID tag: {patient_id_tag}")
except KeyError as e:
print(f"Keyword not found: {e}")from pydicom.datadict import add_private_dict_entry, get_private_dict_entry
# Add custom private dictionary entry
private_creator = "MyCompany MRI System 1.0"
add_private_dict_entry(
private_creator=private_creator,
tag=0x01, # Element part only
VR="LO",
keyword="MyCustomField",
description="Custom field for special processing",
VM="1"
)
# Retrieve private dictionary entry
try:
entry = get_private_dict_entry(private_creator, "MyCustomField")
print(f"Private entry: {entry}")
except KeyError:
print("Private entry not found")from pydicom.config import IGNORE, WARN, RAISE, set_validation_mode
import pydicom
# Set different validation modes
set_validation_mode(WARN, reading=True, writing=False)
set_validation_mode(RAISE, reading=False, writing=True)
# Test with potentially invalid file
try:
dataset = pydicom.dcmread("potentially_invalid.dcm")
print("File read with warnings (if any)")
# This might raise an error if validation fails
pydicom.dcmwrite("output.dcm", dataset)
except Exception as e:
print(f"Validation error: {e}")from pydicom.config import (get_pixel_data_handlers,
set_pixel_data_handler_priority,
pixel_data_handler_info)
# Check available handlers
handlers = get_pixel_data_handlers()
print("Available pixel data handlers:")
for handler in handlers:
print(f" {handler}")
# Get handler information
info = pixel_data_handler_info()
for handler, details in info.items():
print(f"\n{handler}:")
print(f" Available: {details.get('available', False)}")
print(f" Formats: {details.get('formats', [])}")
# Set handler priority
set_pixel_data_handler_priority(['gdcm', 'pillow', 'pylibjpeg'])from pydicom.util.dump import dump_file
from pydicom.util.hexutil import hex_dump
import pydicom
# Analyze file structure
def analyze_dicom_file(filename):
try:
# Basic file info
dataset = pydicom.dcmread(filename, stop_before_pixels=True)
print(f"File: {filename}")
print(f"SOP Class: {getattr(dataset, 'SOPClassUID', 'Unknown')}")
print(f"Modality: {getattr(dataset, 'Modality', 'Unknown')}")
print(f"Transfer Syntax: {getattr(dataset.file_meta, 'TransferSyntaxUID', 'Unknown')}")
# Count elements
element_count = len(dataset)
print(f"Number of elements: {element_count}")
# Check for pixel data
if hasattr(dataset, 'PixelData'):
print("Contains pixel data")
return True
except Exception as e:
print(f"Error analyzing {filename}: {e}")
return False
# Example usage
analyze_dicom_file("test.dcm")from pydicom.util.codify import codify_file, codify_dataset
from pydicom import Dataset
# Generate code from existing file
python_code = codify_file("example.dcm")
print("Generated Python code:")
print(python_code[:500] + "...") # Show first 500 characters
# Generate code from dataset
dataset = Dataset()
dataset.PatientName = "Test^Patient"
dataset.PatientID = "12345"
dataset.StudyDate = "20231215"
code = codify_dataset(dataset)
print("\nGenerated code for dataset:")
print(code)
# Save generated code to file
codify_file("example.dcm", save_as="recreate_example.py")from pydicom.util.fixer import fix_file_meta_info
from pydicom.util.dump import validate_file
import pydicom
# Load dataset that might need fixing
dataset = pydicom.dcmread("needs_fixing.dcm", force=True)
# Fix file meta information
print("Fixing file meta information...")
fix_file_meta_info(dataset)
# Validate the fixed dataset
errors = validate_file("needs_fixing.dcm")
if errors:
print("Validation errors found:")
for error in errors:
print(f" {error}")
else:
print("File validation passed")
# Save fixed dataset
pydicom.dcmwrite("fixed.dcm", dataset)from pydicom.util.anonymize import anonymize_dataset
import pydicom
# Load dataset for anonymization
dataset = pydicom.dcmread("patient_data.dcm")
print("Original patient info:")
print(f" Name: {getattr(dataset, 'PatientName', 'Not set')}")
print(f" ID: {getattr(dataset, 'PatientID', 'Not set')}")
print(f" Birth Date: {getattr(dataset, 'PatientBirthDate', 'Not set')}")
# Anonymize dataset
anonymize_dataset(dataset, remove_curves=True, remove_overlays=True)
print("\nAfter anonymization:")
print(f" Name: {getattr(dataset, 'PatientName', 'Not set')}")
print(f" ID: {getattr(dataset, 'PatientID', 'Not set')}")
print(f" Birth Date: {getattr(dataset, 'PatientBirthDate', 'Not set')}")
# Save anonymized dataset
pydicom.dcmwrite("anonymized.dcm", dataset)from pydicom.charset import default_encoding, convert_encodings, decode_bytes
# Check default encoding
default_enc = default_encoding()
print(f"Default encoding: {default_enc}")
# Convert between encodings
text = "Patient Name with accents: café"
encoded = text.encode('iso8859-1')
converted = convert_encodings(encoded, 'iso8859-1', 'utf-8')
print(f"Converted text: {converted}")
# Decode bytes with multiple possible encodings
binary_data = b"M\xfcller^Hans"
encodings_to_try = ['iso8859-1', 'utf-8', 'cp1252']
try:
decoded = decode_bytes(binary_data, encodings_to_try)
print(f"Decoded: {decoded}")
except UnicodeDecodeError as e:
print(f"Could not decode: {e}")from pydicom.config import settings, future_behavior
import pydicom
# Configure advanced settings
settings.convert_wrong_length_to_UN = True
settings.assume_implicit_vr_switch = False
# Enable future behavior changes
future_behavior(True)
# Configure pixel data behavior
settings.pixel_data_handlers = ['gdcm', 'pillow']
print("Advanced configuration:")
print(f" Convert wrong length to UN: {settings.convert_wrong_length_to_UN}")
print(f" Assume implicit VR switch: {settings.assume_implicit_vr_switch}")
print(f" Pixel handlers: {settings.pixel_data_handlers}")
# Test with configured behavior
dataset = pydicom.dcmread("test_image.dcm")
if hasattr(dataset, 'pixel_array'):
pixels = dataset.pixel_array
print(f"Loaded pixel array: shape {pixels.shape}")Install with Tessl CLI
npx tessl i tessl/pypi-pydicom