0
# Value Representations
1
2
Specialized handling for DICOM Value Representations providing comprehensive support for dates, times, person names, numeric types, and validation functions with proper DICOM format compliance and type conversion capabilities.
3
4
## Capabilities
5
6
### VR Enumeration
7
8
Complete enumeration of DICOM Value Representations with validation and properties.
9
10
```python { .api }
11
class VR:
12
"""
13
DICOM Value Representation enumeration.
14
15
Provides complete set of DICOM VR types with validation and properties
16
for proper handling of different data types in medical imaging.
17
"""
18
19
# String VRs
20
AE = "AE" # Application Entity
21
AS = "AS" # Age String
22
CS = "CS" # Code String
23
DA = "DA" # Date
24
DS = "DS" # Decimal String
25
DT = "DT" # Date Time
26
IS = "IS" # Integer String
27
LO = "LO" # Long String
28
LT = "LT" # Long Text
29
PN = "PN" # Person Name
30
SH = "SH" # Short String
31
ST = "ST" # Short Text
32
TM = "TM" # Time
33
UC = "UC" # Unlimited Characters
34
UI = "UI" # Unique Identifier
35
UR = "UR" # Universal Resource
36
UT = "UT" # Unlimited Text
37
38
# Numeric VRs
39
FL = "FL" # Floating Point Single
40
FD = "FD" # Floating Point Double
41
SL = "SL" # Signed Long
42
SS = "SS" # Signed Short
43
UL = "UL" # Unsigned Long
44
US = "US" # Unsigned Short
45
46
# Binary VRs
47
OB = "OB" # Other Byte
48
OD = "OD" # Other Double
49
OF = "OF" # Other Float
50
OL = "OL" # Other Long
51
OV = "OV" # Other Very Long
52
OW = "OW" # Other Word
53
UN = "UN" # Unknown
54
55
# Special VRs
56
AT = "AT" # Attribute Tag
57
SQ = "SQ" # Sequence
58
```
59
60
### Date and Time Classes
61
62
Specialized classes for DICOM date and time handling with validation and conversion.
63
64
```python { .api }
65
class DA:
66
"""
67
DICOM Date (DA) Value Representation.
68
69
Handles DICOM date format (YYYYMMDD) with validation and conversion
70
to Python date objects for medical imaging workflows.
71
"""
72
73
def __init__(self, val):
74
"""
75
Initialize DICOM date.
76
77
Parameters:
78
- val: str, datetime.date, or datetime.datetime - Date value
79
80
Raises:
81
ValueError - If date format is invalid
82
"""
83
84
@property
85
def date(self):
86
"""datetime.date: Python date object."""
87
88
def __str__(self):
89
"""Return DICOM date string (YYYYMMDD)."""
90
91
def __eq__(self, other):
92
"""Compare dates for equality."""
93
94
def __lt__(self, other):
95
"""Compare dates for ordering."""
96
97
class TM:
98
"""
99
DICOM Time (TM) Value Representation.
100
101
Handles DICOM time format (HHMMSS.FFFFFF) with microsecond precision
102
and validation for medical imaging time stamps.
103
"""
104
105
def __init__(self, val):
106
"""
107
Initialize DICOM time.
108
109
Parameters:
110
- val: str, datetime.time, or datetime.datetime - Time value
111
112
Raises:
113
ValueError - If time format is invalid
114
"""
115
116
@property
117
def time(self):
118
"""datetime.time: Python time object."""
119
120
@property
121
def hour(self):
122
"""int: Hour component (0-23)."""
123
124
@property
125
def minute(self):
126
"""int: Minute component (0-59)."""
127
128
@property
129
def second(self):
130
"""int: Second component (0-59)."""
131
132
@property
133
def microsecond(self):
134
"""int: Microsecond component (0-999999)."""
135
136
def __str__(self):
137
"""Return DICOM time string."""
138
139
class DT:
140
"""
141
DICOM DateTime (DT) Value Representation.
142
143
Handles DICOM datetime format with timezone support and microsecond
144
precision for comprehensive temporal data in medical imaging.
145
"""
146
147
def __init__(self, val):
148
"""
149
Initialize DICOM datetime.
150
151
Parameters:
152
- val: str, datetime.datetime - DateTime value
153
154
Raises:
155
ValueError - If datetime format is invalid
156
"""
157
158
@property
159
def datetime(self):
160
"""datetime.datetime: Python datetime object."""
161
162
@property
163
def date(self):
164
"""datetime.date: Date component."""
165
166
@property
167
def time(self):
168
"""datetime.time: Time component."""
169
170
@property
171
def timezone(self):
172
"""datetime.timezone: Timezone information."""
173
174
def __str__(self):
175
"""Return DICOM datetime string."""
176
```
177
178
### Numeric Classes
179
180
Specialized numeric classes with configurable precision and overflow handling.
181
182
```python { .api }
183
class DS:
184
"""
185
DICOM Decimal String (DS) Value Representation.
186
187
Handles decimal numbers in string format with configurable precision
188
and automatic conversion between decimal and float representations.
189
"""
190
191
def __init__(self, val, validation_mode=None):
192
"""
193
Initialize decimal string.
194
195
Parameters:
196
- val: str, int, float, or Decimal - Numeric value
197
- validation_mode: str - Validation mode ("raise", "warn", "ignore")
198
199
Raises:
200
ValueError - If value cannot be converted to valid DS
201
"""
202
203
@property
204
def real(self):
205
"""float: Real component (for compatibility)."""
206
207
@property
208
def imag(self):
209
"""float: Imaginary component (always 0)."""
210
211
def __float__(self):
212
"""Convert to float."""
213
214
def __int__(self):
215
"""Convert to int."""
216
217
def __str__(self):
218
"""Return string representation."""
219
220
class DSfloat(float):
221
"""
222
Decimal String as float subclass.
223
224
Float-based implementation of DS VR with automatic string formatting
225
and DICOM-compliant precision handling.
226
"""
227
228
def __new__(cls, val):
229
"""Create new DSfloat instance."""
230
231
def __str__(self):
232
"""Return DICOM-formatted string."""
233
234
class DSdecimal:
235
"""
236
Decimal String using Python Decimal for exact precision.
237
238
Decimal-based implementation providing exact decimal arithmetic
239
without floating-point precision issues.
240
"""
241
242
def __init__(self, val):
243
"""Initialize with Decimal precision."""
244
245
class IS:
246
"""
247
DICOM Integer String (IS) Value Representation.
248
249
Handles integer numbers in string format with overflow detection
250
and automatic conversion to Python integers.
251
"""
252
253
def __init__(self, val, validation_mode=None):
254
"""
255
Initialize integer string.
256
257
Parameters:
258
- val: str, int - Integer value
259
- validation_mode: str - Validation mode for overflow handling
260
261
Raises:
262
ValueError - If value cannot be converted to valid IS
263
"""
264
265
def __int__(self):
266
"""Convert to int."""
267
268
def __str__(self):
269
"""Return string representation."""
270
271
class ISfloat(float):
272
"""
273
Integer String as float subclass for overflow handling.
274
275
Float-based IS implementation that handles integer overflow
276
by converting to float representation when needed.
277
"""
278
279
def __new__(cls, val):
280
"""Create new ISfloat instance."""
281
```
282
283
### Person Name Class
284
285
Complex person name handling with component access and internationalization support.
286
287
```python { .api }
288
class PersonName:
289
"""
290
DICOM Person Name (PN) Value Representation.
291
292
Handles complex person names with support for alphabetic, ideographic,
293
and phonetic representations following DICOM standard formatting.
294
"""
295
296
def __init__(self, val, encodings=None, validation_mode=None):
297
"""
298
Initialize person name.
299
300
Parameters:
301
- val: str or bytes - Person name value
302
- encodings: list - Character encodings for name components
303
- validation_mode: str - Validation mode for name validation
304
305
Raises:
306
ValueError - If name format is invalid
307
"""
308
309
@property
310
def family_name(self):
311
"""str: Family name component."""
312
313
@property
314
def given_name(self):
315
"""str: Given name component."""
316
317
@property
318
def middle_name(self):
319
"""str: Middle name component."""
320
321
@property
322
def name_prefix(self):
323
"""str: Name prefix component (title)."""
324
325
@property
326
def name_suffix(self):
327
"""str: Name suffix component."""
328
329
@property
330
def alphabetic(self):
331
"""str: Alphabetic representation."""
332
333
@property
334
def ideographic(self):
335
"""str: Ideographic representation."""
336
337
@property
338
def phonetic(self):
339
"""str: Phonetic representation."""
340
341
@property
342
def components(self):
343
"""list: List of name components [family, given, middle, prefix, suffix]."""
344
345
def formatted(self, format_str="{family}, {given}"):
346
"""
347
Return formatted name string.
348
349
Parameters:
350
- format_str: str - Format template with component placeholders
351
352
Returns:
353
str - Formatted name
354
"""
355
356
def __str__(self):
357
"""Return string representation of person name."""
358
359
def __eq__(self, other):
360
"""Compare person names for equality."""
361
```
362
363
### Validation Functions
364
365
Comprehensive validation functions for different VR types with configurable error handling.
366
367
```python { .api }
368
def validate_value(VR, value, config=None):
369
"""
370
Validate value against VR requirements.
371
372
Parameters:
373
- VR: str - Value Representation
374
- value: Any - Value to validate
375
- config: dict - Validation configuration options
376
377
Returns:
378
Any - Validated/converted value
379
380
Raises:
381
ValueError - If value is invalid for VR type
382
"""
383
384
def validate_pn(value, encodings=None):
385
"""
386
Validate Person Name value.
387
388
Parameters:
389
- value: str or PersonName - Name value to validate
390
- encodings: list - Character encodings
391
392
Returns:
393
PersonName - Validated person name object
394
395
Raises:
396
ValueError - If name format is invalid
397
"""
398
399
def validate_date_time(VR, value):
400
"""
401
Validate date/time values (DA, TM, DT).
402
403
Parameters:
404
- VR: str - Value Representation ("DA", "TM", or "DT")
405
- value: str or datetime object - Value to validate
406
407
Returns:
408
Appropriate date/time object (DA, TM, or DT)
409
410
Raises:
411
ValueError - If date/time format is invalid
412
"""
413
414
def validate_ui(value):
415
"""
416
Validate Unique Identifier (UI) value.
417
418
Parameters:
419
- value: str - UID value to validate
420
421
Returns:
422
str - Validated UID string
423
424
Raises:
425
ValueError - If UID format is invalid
426
"""
427
428
def validate_length(VR, value):
429
"""
430
Validate value length against VR constraints.
431
432
Parameters:
433
- VR: str - Value Representation
434
- value: Any - Value to validate
435
436
Returns:
437
bool - True if length is valid
438
439
Raises:
440
ValueError - If length exceeds VR limits
441
"""
442
```
443
444
### VR Property Functions
445
446
Functions for querying VR properties and characteristics.
447
448
```python { .api }
449
def is_string_VR(VR):
450
"""
451
Check if VR is string type.
452
453
Parameters:
454
- VR: str - Value Representation
455
456
Returns:
457
bool - True if VR is string type
458
"""
459
460
def is_text_VR(VR):
461
"""
462
Check if VR is text type (allows control chars).
463
464
Parameters:
465
- VR: str - Value Representation
466
467
Returns:
468
bool - True if VR is text type
469
"""
470
471
def is_binary_VR(VR):
472
"""
473
Check if VR is binary type.
474
475
Parameters:
476
- VR: str - Value Representation
477
478
Returns:
479
bool - True if VR is binary type
480
"""
481
482
def allows_multiple_values(VR):
483
"""
484
Check if VR allows multiple values.
485
486
Parameters:
487
- VR: str - Value Representation
488
489
Returns:
490
bool - True if VR supports multiple values
491
"""
492
493
def max_length(VR):
494
"""
495
Get maximum length for VR type.
496
497
Parameters:
498
- VR: str - Value Representation
499
500
Returns:
501
int - Maximum allowed length (None for unlimited)
502
"""
503
```
504
505
### Type Conversion Functions
506
507
Functions for converting between VR types and Python types.
508
509
```python { .api }
510
def convert_text(value, encodings=None, VR=None):
511
"""
512
Convert bytes to text using appropriate encoding.
513
514
Parameters:
515
- value: bytes or str - Value to convert
516
- encodings: list - Character encodings to try
517
- VR: str - Target Value Representation
518
519
Returns:
520
str - Converted text value
521
"""
522
523
def convert_numbers(value, VR, is_little_endian=True):
524
"""
525
Convert binary data to numeric values.
526
527
Parameters:
528
- value: bytes - Binary numeric data
529
- VR: str - Numeric VR type (US, UL, SS, SL, FL, FD)
530
- is_little_endian: bool - Byte order
531
532
Returns:
533
tuple or single value - Converted numeric value(s)
534
"""
535
536
def convert_tag_to_int(value):
537
"""
538
Convert tag representation to integer.
539
540
Parameters:
541
- value: bytes, int, or Tag - Tag value
542
543
Returns:
544
int - Tag as 32-bit integer
545
"""
546
```
547
548
## Usage Examples
549
550
### Working with Dates and Times
551
552
```python
553
from pydicom.valuerep import DA, TM, DT
554
import datetime
555
556
# Create DICOM dates
557
study_date = DA("20231215") # From string
558
today = DA(datetime.date.today()) # From date object
559
560
print(f"Study date: {study_date}")
561
print(f"Date object: {study_date.date}")
562
563
# Create DICOM times
564
scan_time = TM("143022.123456") # With microseconds
565
now_time = TM(datetime.datetime.now().time())
566
567
print(f"Scan time: {scan_time}")
568
print(f"Hour: {scan_time.hour}")
569
print(f"Minute: {scan_time.minute}")
570
print(f"Microsecond: {scan_time.microsecond}")
571
572
# Create DICOM datetimes
573
acquisition_dt = DT("20231215143022.123456+0100") # With timezone
574
print(f"Acquisition: {acquisition_dt}")
575
print(f"Datetime: {acquisition_dt.datetime}")
576
print(f"Timezone: {acquisition_dt.timezone}")
577
```
578
579
### Working with Numeric Values
580
581
```python
582
from pydicom.valuerep import DS, IS, DSfloat, ISfloat
583
584
# Decimal strings
585
slice_thickness = DS("2.5")
586
window_width = DS(400.0)
587
588
print(f"Slice thickness: {slice_thickness}")
589
print(f"As float: {float(slice_thickness)}")
590
591
# Handle precision
592
pixel_spacing = DS("0.625000")
593
print(f"Pixel spacing: {pixel_spacing}")
594
595
# Integer strings
596
series_number = IS("3")
597
instance_number = IS(42)
598
599
print(f"Series: {series_number}")
600
print(f"As int: {int(series_number)}")
601
602
# Handle overflow with float fallback
603
large_value = ISfloat(2**32) # Larger than 32-bit int
604
print(f"Large value: {large_value}")
605
```
606
607
### Working with Person Names
608
609
```python
610
from pydicom.valuerep import PersonName
611
612
# Simple person name
613
patient1 = PersonName("Doe^John^Middle^^Dr")
614
615
print(f"Full name: {patient1}")
616
print(f"Family: {patient1.family_name}")
617
print(f"Given: {patient1.given_name}")
618
print(f"Middle: {patient1.middle_name}")
619
print(f"Prefix: {patient1.name_prefix}")
620
621
# Formatted output
622
formatted = patient1.formatted("{prefix} {given} {middle} {family}")
623
print(f"Formatted: {formatted}")
624
625
# Multi-component name (alphabetic, ideographic, phonetic)
626
patient2 = PersonName("Yamada^Tarou=山田^太郎=ヤマダ^タロウ")
627
print(f"Alphabetic: {patient2.alphabetic}")
628
print(f"Ideographic: {patient2.ideographic}")
629
print(f"Phonetic: {patient2.phonetic}")
630
```
631
632
### Value Validation
633
634
```python
635
from pydicom.valuerep import validate_value, validate_pn, validate_date_time, validate_ui
636
637
# Validate different VR types
638
try:
639
# Valid date
640
valid_date = validate_date_time("DA", "20231215")
641
print(f"Valid date: {valid_date}")
642
643
# Invalid date
644
validate_date_time("DA", "20231301") # Invalid month
645
except ValueError as e:
646
print(f"Date validation error: {e}")
647
648
# Validate person name
649
try:
650
valid_name = validate_pn("Doe^John")
651
print(f"Valid name: {valid_name}")
652
except ValueError as e:
653
print(f"Name validation error: {e}")
654
655
# Validate UID
656
try:
657
valid_uid = validate_ui("1.2.840.10008.1.2.1")
658
print(f"Valid UID: {valid_uid}")
659
660
# Invalid UID
661
validate_ui("invalid.uid.format")
662
except ValueError as e:
663
print(f"UID validation error: {e}")
664
```
665
666
### VR Property Checking
667
668
```python
669
from pydicom.valuerep import is_string_VR, is_binary_VR, allows_multiple_values, max_length
670
671
# Check VR properties
672
vr_types = ["PN", "DA", "OB", "SQ", "US", "LT"]
673
674
for vr in vr_types:
675
print(f"\nVR: {vr}")
676
print(f" String VR: {is_string_VR(vr)}")
677
print(f" Binary VR: {is_binary_VR(vr)}")
678
print(f" Multi-value: {allows_multiple_values(vr)}")
679
print(f" Max length: {max_length(vr)}")
680
```
681
682
### Type Conversion
683
684
```python
685
from pydicom.valuerep import convert_text, convert_numbers
686
687
# Convert encoded text
688
encoded_text = b"Patient Name"
689
converted = convert_text(encoded_text, encodings=["iso8859", "utf-8"])
690
print(f"Converted text: {converted}")
691
692
# Convert binary numbers (little endian unsigned short)
693
binary_data = b"\x00\x01\x00\x02" # Two 16-bit values: 256, 512
694
numbers = convert_numbers(binary_data, "US", is_little_endian=True)
695
print(f"Converted numbers: {numbers}")
696
697
# Convert big endian
698
numbers_be = convert_numbers(binary_data, "US", is_little_endian=False)
699
print(f"Big endian numbers: {numbers_be}")
700
```
701
702
### Advanced Person Name Handling
703
704
```python
705
from pydicom.valuerep import PersonName
706
707
# International names with encoding
708
encodings = ['iso8859', 'utf-8']
709
710
# Name with special characters
711
international_name = PersonName("Müller^Hans^Josef", encodings=encodings)
712
print(f"International name: {international_name}")
713
714
# Access components
715
components = international_name.components
716
print(f"Components: {components}")
717
718
# Empty components
719
partial_name = PersonName("Smith^^John") # Missing middle name
720
print(f"Family: '{partial_name.family_name}'")
721
print(f"Given: '{partial_name.given_name}'")
722
print(f"Middle: '{partial_name.middle_name}'") # Empty string
723
```
724
725
### Custom Validation Configuration
726
727
```python
728
from pydicom.valuerep import validate_value
729
import pydicom.config
730
731
# Configure validation mode
732
pydicom.config.settings.reading_validation_mode = "warn" # or "raise", "ignore"
733
734
# Validate with different modes
735
test_values = [
736
("DS", "123.456789012345678"), # Too many digits
737
("IS", "999999999999"), # Potentially too large
738
("DA", "20231301"), # Invalid date
739
]
740
741
for vr, value in test_values:
742
try:
743
result = validate_value(vr, value)
744
print(f"VR {vr}, value '{value}': {result}")
745
except ValueError as e:
746
print(f"VR {vr}, value '{value}': ERROR - {e}")
747
```