0
# Configuration and Utilities
1
2
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.
3
4
## Capabilities
5
6
### Configuration Management
7
8
Global configuration system for controlling pydicom behavior, validation, and debugging options.
9
10
```python { .api }
11
def debug(debug_on=True, default_handler=True):
12
"""
13
Configure pydicom debugging output.
14
15
Parameters:
16
- debug_on: bool - Enable or disable debug mode
17
- default_handler: bool - Use default logging handler
18
19
Returns:
20
None - Configures global debugging state
21
"""
22
23
def DS_numpy(use_numpy=True):
24
"""
25
Set whether multi-valued DS elements are returned as numpy arrays.
26
27
Parameters:
28
- use_numpy: bool - Use numpy arrays for multi-value DS elements
29
30
Raises:
31
ValueError - If use_DS_decimal and use_numpy are both True
32
"""
33
34
def DS_decimal(use_Decimal_boolean=True):
35
"""
36
Set DS class to be derived from Decimal or float.
37
38
Parameters:
39
- use_Decimal_boolean: bool - Use Decimal for DS elements
40
41
Raises:
42
ValueError - If use_Decimal_boolean and use_DS_numpy are both True
43
"""
44
45
# Configuration Variables
46
use_DS_numpy: bool # Default: False - Use numpy for multi-value DS elements
47
use_IS_numpy: bool # Default: False - Use numpy for multi-value IS elements
48
use_DS_decimal: bool # Default: False - Use Decimal for DS elements
49
allow_DS_float: bool # Default: False - Allow floats for DSdecimal creation
50
51
# Validation Constants
52
IGNORE: int # Value: 0 - No validation performed
53
WARN: int # Value: 1 - Warning issued on validation errors
54
RAISE: int # Value: 2 - Exception raised on validation errors
55
56
class Settings:
57
"""
58
Global settings class for package behavior configuration.
59
60
Provides centralized configuration for validation, pixel data handling,
61
character encoding, and other package-wide settings.
62
"""
63
64
def __init__(self):
65
"""Initialize settings with default values."""
66
67
# Validation Configuration
68
@property
69
def reading_validation_mode(self):
70
"""str: Validation mode for reading operations ("raise", "warn", "ignore")."""
71
72
@reading_validation_mode.setter
73
def reading_validation_mode(self, value):
74
"""Set reading validation mode."""
75
76
@property
77
def writing_validation_mode(self):
78
"""str: Validation mode for writing operations."""
79
80
@writing_validation_mode.setter
81
def writing_validation_mode(self, value):
82
"""Set writing validation mode."""
83
84
# Pixel Data Configuration
85
@property
86
def pixel_data_handlers(self):
87
"""list: Available pixel data handlers in priority order."""
88
89
@property
90
def convert_wrong_length_to_UN(self):
91
"""bool: Convert elements with wrong length to UN VR."""
92
93
@convert_wrong_length_to_UN.setter
94
def convert_wrong_length_to_UN(self, value):
95
"""Set wrong length conversion behavior."""
96
97
# Character Encoding
98
@property
99
def assume_implicit_vr_switch(self):
100
"""bool: Assume VR switches to implicit in sequences."""
101
102
@assume_implicit_vr_switch.setter
103
def assume_implicit_vr_switch(self, value):
104
"""Set implicit VR switch assumption."""
105
106
# Global settings instance
107
settings = Settings()
108
```
109
110
### Data Dictionary Access
111
112
Functions for accessing DICOM data dictionary information including tag descriptions, VR types, and keyword mappings.
113
114
```python { .api }
115
def dictionary_description(tag):
116
"""
117
Get DICOM description for tag.
118
119
Parameters:
120
- tag: int, Tag, or tuple - DICOM tag
121
122
Returns:
123
str - Description from DICOM dictionary
124
125
Raises:
126
KeyError - If tag not found in dictionary
127
"""
128
129
def dictionary_VR(tag):
130
"""
131
Get Value Representation for tag from dictionary.
132
133
Parameters:
134
- tag: int, Tag, or tuple - DICOM tag
135
136
Returns:
137
str - Value Representation (VR) for tag
138
139
Raises:
140
KeyError - If tag not found in dictionary
141
"""
142
143
def dictionary_VM(tag):
144
"""
145
Get Value Multiplicity for tag from dictionary.
146
147
Parameters:
148
- tag: int, Tag, or tuple - DICOM tag
149
150
Returns:
151
str - Value Multiplicity (VM) specification
152
153
Raises:
154
KeyError - If tag not found in dictionary
155
"""
156
157
def keyword_for_tag(tag):
158
"""
159
Get DICOM keyword for tag.
160
161
Parameters:
162
- tag: int, Tag, or tuple - DICOM tag
163
164
Returns:
165
str - DICOM keyword
166
167
Raises:
168
KeyError - If tag not found in dictionary
169
"""
170
171
def tag_for_keyword(keyword):
172
"""
173
Get DICOM tag for keyword.
174
175
Parameters:
176
- keyword: str - DICOM keyword
177
178
Returns:
179
Tag - DICOM tag object
180
181
Raises:
182
KeyError - If keyword not found in dictionary
183
"""
184
```
185
186
### Private Dictionary Management
187
188
Functions for managing private DICOM dictionaries and vendor-specific elements.
189
190
```python { .api }
191
def add_dict_entry(tag, VR, keyword, description, VM="1", is_retired=False):
192
"""
193
Add entry to DICOM dictionary.
194
195
Parameters:
196
- tag: int or Tag - DICOM tag
197
- VR: str - Value Representation
198
- keyword: str - DICOM keyword
199
- description: str - Element description
200
- VM: str - Value Multiplicity specification
201
- is_retired: bool - Whether element is retired
202
"""
203
204
def add_private_dict_entry(private_creator, tag, VR, keyword, description, VM="1"):
205
"""
206
Add private dictionary entry.
207
208
Parameters:
209
- private_creator: str - Private creator identification
210
- tag: int - Private tag (element part only)
211
- VR: str - Value Representation
212
- keyword: str - Private keyword
213
- description: str - Element description
214
- VM: str - Value Multiplicity specification
215
"""
216
217
def get_private_dict_entry(private_creator, keyword):
218
"""
219
Get private dictionary entry.
220
221
Parameters:
222
- private_creator: str - Private creator identification
223
- keyword: str - Private keyword
224
225
Returns:
226
dict - Dictionary entry with tag, VR, description, VM
227
"""
228
229
def private_dictionary_description(private_creator, tag):
230
"""
231
Get description for private tag.
232
233
Parameters:
234
- private_creator: str - Private creator identification
235
- tag: int - Private tag
236
237
Returns:
238
str - Description of private element
239
"""
240
```
241
242
### Validation Configuration
243
244
Constants and functions for controlling validation behavior throughout the package.
245
246
```python { .api }
247
# Validation mode constants
248
IGNORE = "ignore"
249
WARN = "warn"
250
RAISE = "raise"
251
252
def future_behavior(enable=True):
253
"""
254
Enable future API behavior changes.
255
256
Parameters:
257
- enable: bool - Enable future behavior mode
258
259
Returns:
260
None - Configures future behavior flags
261
"""
262
263
def set_validation_mode(mode, reading=True, writing=True):
264
"""
265
Set validation mode for operations.
266
267
Parameters:
268
- mode: str - Validation mode ("ignore", "warn", "raise")
269
- reading: bool - Apply to reading operations
270
- writing: bool - Apply to writing operations
271
"""
272
273
def get_validation_mode(operation="reading"):
274
"""
275
Get current validation mode.
276
277
Parameters:
278
- operation: str - Operation type ("reading" or "writing")
279
280
Returns:
281
str - Current validation mode
282
"""
283
```
284
285
### Pixel Data Handler Management
286
287
Configuration and management of pixel data handlers for different compression formats.
288
289
```python { .api }
290
def get_pixel_data_handlers():
291
"""
292
Get list of available pixel data handlers.
293
294
Returns:
295
list - Available handlers with capabilities
296
"""
297
298
def set_pixel_data_handler_priority(handler_names):
299
"""
300
Set priority order for pixel data handlers.
301
302
Parameters:
303
- handler_names: list - Handler names in priority order
304
"""
305
306
def get_pixel_data_handler(transfer_syntax_uid):
307
"""
308
Get appropriate handler for transfer syntax.
309
310
Parameters:
311
- transfer_syntax_uid: str - Transfer syntax UID
312
313
Returns:
314
module - Handler module for transfer syntax
315
"""
316
317
def pixel_data_handler_info():
318
"""
319
Get information about pixel data handler availability.
320
321
Returns:
322
dict - Handler availability and capabilities
323
"""
324
```
325
326
### Debugging and Diagnostics
327
328
Tools for debugging DICOM files and analyzing package behavior.
329
330
```python { .api }
331
def dump_file(filename, stop_when=None):
332
"""
333
Dump DICOM file contents for debugging.
334
335
Parameters:
336
- filename: str - Path to DICOM file
337
- stop_when: callable - Function to determine when to stop reading
338
339
Returns:
340
str - Formatted dump of file contents
341
"""
342
343
def hex_dump(data, start_offset=0, max_lines=None):
344
"""
345
Create hexadecimal dump of binary data.
346
347
Parameters:
348
- data: bytes - Binary data to dump
349
- start_offset: int - Starting byte offset for display
350
- max_lines: int - Maximum lines to display
351
352
Returns:
353
str - Hexadecimal dump representation
354
"""
355
356
def analyze_file(filename):
357
"""
358
Analyze DICOM file structure and content.
359
360
Parameters:
361
- filename: str - Path to DICOM file
362
363
Returns:
364
dict - Analysis results including structure, elements, errors
365
"""
366
367
def validate_file(filename):
368
"""
369
Validate DICOM file against standard.
370
371
Parameters:
372
- filename: str - Path to DICOM file
373
374
Returns:
375
list - Validation errors and warnings
376
"""
377
```
378
379
### Code Generation Utilities
380
381
Tools for generating Python code from DICOM files and structures.
382
383
```python { .api }
384
def codify_file(filename, save_as=None):
385
"""
386
Generate Python code to recreate DICOM file.
387
388
Parameters:
389
- filename: str - Path to DICOM file
390
- save_as: str - Optional output file for generated code
391
392
Returns:
393
str - Python code to recreate the dataset
394
"""
395
396
def codify_dataset(dataset, save_as=None):
397
"""
398
Generate Python code for dataset.
399
400
Parameters:
401
- dataset: Dataset - Dataset to convert to code
402
- save_as: str - Optional output file for generated code
403
404
Returns:
405
str - Python code to recreate the dataset
406
"""
407
408
def generate_test_data(modality="CT", save_as=None):
409
"""
410
Generate test DICOM dataset.
411
412
Parameters:
413
- modality: str - Modality for test data
414
- save_as: str - Optional file to save test dataset
415
416
Returns:
417
Dataset - Generated test dataset
418
"""
419
```
420
421
### File Format Utilities
422
423
Utilities for working with different DICOM file formats and standards compliance.
424
425
```python { .api }
426
def is_dicom_file(filename):
427
"""
428
Check if file is valid DICOM format.
429
430
Parameters:
431
- filename: str - Path to file
432
433
Returns:
434
bool - True if file appears to be DICOM
435
"""
436
437
def get_file_info(filename):
438
"""
439
Get basic information about DICOM file.
440
441
Parameters:
442
- filename: str - Path to DICOM file
443
444
Returns:
445
dict - File information (size, transfer syntax, etc.)
446
"""
447
448
def fix_file_meta_info(dataset):
449
"""
450
Fix or create proper File Meta Information.
451
452
Parameters:
453
- dataset: Dataset - Dataset to fix
454
455
Returns:
456
None - Modifies dataset in place
457
"""
458
459
def anonymize_dataset(dataset, remove_curves=True, remove_overlays=True):
460
"""
461
Anonymize dataset by removing identifying information.
462
463
Parameters:
464
- dataset: Dataset - Dataset to anonymize
465
- remove_curves: bool - Remove curve data
466
- remove_overlays: bool - Remove overlay data
467
468
Returns:
469
None - Modifies dataset in place
470
"""
471
```
472
473
### Character Encoding Utilities
474
475
Functions for handling character encoding in DICOM files.
476
477
```python { .api }
478
def default_encoding():
479
"""
480
Get default character encoding.
481
482
Returns:
483
str - Default encoding name
484
"""
485
486
def convert_encodings(text, from_encoding, to_encoding):
487
"""
488
Convert text between character encodings.
489
490
Parameters:
491
- text: str or bytes - Text to convert
492
- from_encoding: str - Source encoding
493
- to_encoding: str - Target encoding
494
495
Returns:
496
str - Converted text
497
"""
498
499
def decode_bytes(value, encodings, delimiters=None):
500
"""
501
Decode bytes using specified encodings.
502
503
Parameters:
504
- value: bytes - Bytes to decode
505
- encodings: list - Encodings to try
506
- delimiters: set - Characters that separate text components
507
508
Returns:
509
str - Decoded text
510
"""
511
```
512
513
## Usage Examples
514
515
### Basic Configuration
516
517
```python
518
import pydicom
519
from pydicom.config import debug, settings
520
521
# Enable debugging
522
debug(True)
523
524
# Configure validation behavior
525
settings.reading_validation_mode = "warn" # Warn on validation errors
526
settings.writing_validation_mode = "raise" # Raise on write validation errors
527
528
# Read file with configured behavior
529
dataset = pydicom.dcmread("test.dcm")
530
531
print(f"Reading validation: {settings.reading_validation_mode}")
532
print(f"Writing validation: {settings.writing_validation_mode}")
533
```
534
535
### Dictionary Lookups
536
537
```python
538
from pydicom.datadict import (dictionary_description, dictionary_VR,
539
keyword_for_tag, tag_for_keyword)
540
541
# Look up tag information
542
tag = 0x00100010 # Patient Name
543
544
try:
545
description = dictionary_description(tag)
546
vr = dictionary_VR(tag)
547
keyword = keyword_for_tag(tag)
548
549
print(f"Tag {tag:08X}:")
550
print(f" Description: {description}")
551
print(f" VR: {vr}")
552
print(f" Keyword: {keyword}")
553
except KeyError as e:
554
print(f"Tag not found: {e}")
555
556
# Reverse lookup
557
try:
558
patient_id_tag = tag_for_keyword("PatientID")
559
print(f"PatientID tag: {patient_id_tag}")
560
except KeyError as e:
561
print(f"Keyword not found: {e}")
562
```
563
564
### Private Dictionary Management
565
566
```python
567
from pydicom.datadict import add_private_dict_entry, get_private_dict_entry
568
569
# Add custom private dictionary entry
570
private_creator = "MyCompany MRI System 1.0"
571
572
add_private_dict_entry(
573
private_creator=private_creator,
574
tag=0x01, # Element part only
575
VR="LO",
576
keyword="MyCustomField",
577
description="Custom field for special processing",
578
VM="1"
579
)
580
581
# Retrieve private dictionary entry
582
try:
583
entry = get_private_dict_entry(private_creator, "MyCustomField")
584
print(f"Private entry: {entry}")
585
except KeyError:
586
print("Private entry not found")
587
```
588
589
### Validation Configuration
590
591
```python
592
from pydicom.config import IGNORE, WARN, RAISE, set_validation_mode
593
import pydicom
594
595
# Set different validation modes
596
set_validation_mode(WARN, reading=True, writing=False)
597
set_validation_mode(RAISE, reading=False, writing=True)
598
599
# Test with potentially invalid file
600
try:
601
dataset = pydicom.dcmread("potentially_invalid.dcm")
602
print("File read with warnings (if any)")
603
604
# This might raise an error if validation fails
605
pydicom.dcmwrite("output.dcm", dataset)
606
607
except Exception as e:
608
print(f"Validation error: {e}")
609
```
610
611
### Pixel Data Handler Configuration
612
613
```python
614
from pydicom.config import (get_pixel_data_handlers,
615
set_pixel_data_handler_priority,
616
pixel_data_handler_info)
617
618
# Check available handlers
619
handlers = get_pixel_data_handlers()
620
print("Available pixel data handlers:")
621
for handler in handlers:
622
print(f" {handler}")
623
624
# Get handler information
625
info = pixel_data_handler_info()
626
for handler, details in info.items():
627
print(f"\n{handler}:")
628
print(f" Available: {details.get('available', False)}")
629
print(f" Formats: {details.get('formats', [])}")
630
631
# Set handler priority
632
set_pixel_data_handler_priority(['gdcm', 'pillow', 'pylibjpeg'])
633
```
634
635
### File Analysis and Debugging
636
637
```python
638
from pydicom.util.dump import dump_file
639
from pydicom.util.hexutil import hex_dump
640
import pydicom
641
642
# Analyze file structure
643
def analyze_dicom_file(filename):
644
try:
645
# Basic file info
646
dataset = pydicom.dcmread(filename, stop_before_pixels=True)
647
648
print(f"File: {filename}")
649
print(f"SOP Class: {getattr(dataset, 'SOPClassUID', 'Unknown')}")
650
print(f"Modality: {getattr(dataset, 'Modality', 'Unknown')}")
651
print(f"Transfer Syntax: {getattr(dataset.file_meta, 'TransferSyntaxUID', 'Unknown')}")
652
653
# Count elements
654
element_count = len(dataset)
655
print(f"Number of elements: {element_count}")
656
657
# Check for pixel data
658
if hasattr(dataset, 'PixelData'):
659
print("Contains pixel data")
660
661
return True
662
663
except Exception as e:
664
print(f"Error analyzing {filename}: {e}")
665
return False
666
667
# Example usage
668
analyze_dicom_file("test.dcm")
669
```
670
671
### Code Generation
672
673
```python
674
from pydicom.util.codify import codify_file, codify_dataset
675
from pydicom import Dataset
676
677
# Generate code from existing file
678
python_code = codify_file("example.dcm")
679
print("Generated Python code:")
680
print(python_code[:500] + "...") # Show first 500 characters
681
682
# Generate code from dataset
683
dataset = Dataset()
684
dataset.PatientName = "Test^Patient"
685
dataset.PatientID = "12345"
686
dataset.StudyDate = "20231215"
687
688
code = codify_dataset(dataset)
689
print("\nGenerated code for dataset:")
690
print(code)
691
692
# Save generated code to file
693
codify_file("example.dcm", save_as="recreate_example.py")
694
```
695
696
### File Validation and Fixing
697
698
```python
699
from pydicom.util.fixer import fix_file_meta_info
700
from pydicom.util.dump import validate_file
701
import pydicom
702
703
# Load dataset that might need fixing
704
dataset = pydicom.dcmread("needs_fixing.dcm", force=True)
705
706
# Fix file meta information
707
print("Fixing file meta information...")
708
fix_file_meta_info(dataset)
709
710
# Validate the fixed dataset
711
errors = validate_file("needs_fixing.dcm")
712
if errors:
713
print("Validation errors found:")
714
for error in errors:
715
print(f" {error}")
716
else:
717
print("File validation passed")
718
719
# Save fixed dataset
720
pydicom.dcmwrite("fixed.dcm", dataset)
721
```
722
723
### Anonymization
724
725
```python
726
from pydicom.util.anonymize import anonymize_dataset
727
import pydicom
728
729
# Load dataset for anonymization
730
dataset = pydicom.dcmread("patient_data.dcm")
731
732
print("Original patient info:")
733
print(f" Name: {getattr(dataset, 'PatientName', 'Not set')}")
734
print(f" ID: {getattr(dataset, 'PatientID', 'Not set')}")
735
print(f" Birth Date: {getattr(dataset, 'PatientBirthDate', 'Not set')}")
736
737
# Anonymize dataset
738
anonymize_dataset(dataset, remove_curves=True, remove_overlays=True)
739
740
print("\nAfter anonymization:")
741
print(f" Name: {getattr(dataset, 'PatientName', 'Not set')}")
742
print(f" ID: {getattr(dataset, 'PatientID', 'Not set')}")
743
print(f" Birth Date: {getattr(dataset, 'PatientBirthDate', 'Not set')}")
744
745
# Save anonymized dataset
746
pydicom.dcmwrite("anonymized.dcm", dataset)
747
```
748
749
### Character Encoding Handling
750
751
```python
752
from pydicom.charset import default_encoding, convert_encodings, decode_bytes
753
754
# Check default encoding
755
default_enc = default_encoding()
756
print(f"Default encoding: {default_enc}")
757
758
# Convert between encodings
759
text = "Patient Name with accents: café"
760
encoded = text.encode('iso8859-1')
761
converted = convert_encodings(encoded, 'iso8859-1', 'utf-8')
762
print(f"Converted text: {converted}")
763
764
# Decode bytes with multiple possible encodings
765
binary_data = b"M\xfcller^Hans"
766
encodings_to_try = ['iso8859-1', 'utf-8', 'cp1252']
767
768
try:
769
decoded = decode_bytes(binary_data, encodings_to_try)
770
print(f"Decoded: {decoded}")
771
except UnicodeDecodeError as e:
772
print(f"Could not decode: {e}")
773
```
774
775
### Advanced Configuration
776
777
```python
778
from pydicom.config import settings, future_behavior
779
import pydicom
780
781
# Configure advanced settings
782
settings.convert_wrong_length_to_UN = True
783
settings.assume_implicit_vr_switch = False
784
785
# Enable future behavior changes
786
future_behavior(True)
787
788
# Configure pixel data behavior
789
settings.pixel_data_handlers = ['gdcm', 'pillow']
790
791
print("Advanced configuration:")
792
print(f" Convert wrong length to UN: {settings.convert_wrong_length_to_UN}")
793
print(f" Assume implicit VR switch: {settings.assume_implicit_vr_switch}")
794
print(f" Pixel handlers: {settings.pixel_data_handlers}")
795
796
# Test with configured behavior
797
dataset = pydicom.dcmread("test_image.dcm")
798
if hasattr(dataset, 'pixel_array'):
799
pixels = dataset.pixel_array
800
print(f"Loaded pixel array: shape {pixels.shape}")
801
```