0
# Data Elements
1
2
Individual DICOM data element handling with comprehensive support for all Value Representations (VRs), proper type conversion, validation, and element manipulation within the DICOM standard framework.
3
4
## Capabilities
5
6
### DataElement Class
7
8
The fundamental building block of DICOM datasets, representing individual data elements with tag, VR, and value components.
9
10
```python { .api }
11
class DataElement:
12
"""
13
Represents a single DICOM data element with tag, VR, and value.
14
15
The basic unit of DICOM data storage containing a tag identifier,
16
Value Representation (VR), and the actual data value.
17
"""
18
19
def __init__(self, tag, VR, value, file_value_tell=None, is_undefined_length=False, already_converted=False):
20
"""
21
Initialize DataElement.
22
23
Parameters:
24
- tag: int or Tag - DICOM tag identifying the element
25
- VR: str - Value Representation (2-character string)
26
- value: Any - The element's value
27
- file_value_tell: int - File position of value (for lazy loading)
28
- is_undefined_length: bool - Whether element has undefined length
29
- already_converted: bool - Whether value has been converted from raw
30
"""
31
32
@property
33
def tag(self):
34
"""Tag: DICOM tag for this element."""
35
36
@property
37
def VR(self):
38
"""str: Value Representation for this element."""
39
40
@property
41
def value(self):
42
"""Any: The element's value."""
43
44
@value.setter
45
def value(self, val):
46
"""Set the element's value."""
47
48
@property
49
def keyword(self):
50
"""str: DICOM keyword for this element's tag."""
51
52
@property
53
def description(self):
54
"""str: DICOM description for this element's tag."""
55
56
@property
57
def repval(self):
58
"""str: String representation of the value for display."""
59
60
def __str__(self):
61
"""Return string representation of element."""
62
63
def __repr__(self):
64
"""Return detailed string representation of element."""
65
66
def __eq__(self, other):
67
"""Compare elements for equality."""
68
69
def __ne__(self, other):
70
"""Compare elements for inequality."""
71
```
72
73
### RawDataElement Class
74
75
Represents unprocessed data elements as read from DICOM files, before value conversion and interpretation.
76
77
```python { .api }
78
class RawDataElement:
79
"""
80
Represents raw data element before processing and value conversion.
81
82
Used during file reading to store element information before
83
the value is processed and converted to appropriate Python types.
84
"""
85
86
def __init__(self, tag, VR, length, value, value_tell, is_implicit_VR, is_little_endian):
87
"""
88
Initialize RawDataElement.
89
90
Parameters:
91
- tag: int - DICOM tag
92
- VR: str - Value Representation
93
- length: int - Value length in bytes
94
- value: bytes or file-like - Raw value data
95
- value_tell: int - File position of value
96
- is_implicit_VR: bool - Whether VR was implicit in file
97
- is_little_endian: bool - Byte order of source file
98
"""
99
100
@property
101
def tag(self):
102
"""int: DICOM tag."""
103
104
@property
105
def VR(self):
106
"""str: Value Representation."""
107
108
@property
109
def length(self):
110
"""int: Value length in bytes."""
111
112
@property
113
def value(self):
114
"""bytes or file-like: Raw value data."""
115
116
@property
117
def value_tell(self):
118
"""int: File position where value data starts."""
119
120
@property
121
def is_implicit_VR(self):
122
"""bool: Whether VR was implicit in source."""
123
124
@property
125
def is_little_endian(self):
126
"""bool: Byte order of source file."""
127
```
128
129
### Element Conversion Functions
130
131
Functions for converting between raw and processed data elements with proper value interpretation.
132
133
```python { .api }
134
def convert_raw_data_element(raw_data_element):
135
"""
136
Convert RawDataElement to DataElement with processed value.
137
138
Parameters:
139
- raw_data_element: RawDataElement - Raw element to convert
140
141
Returns:
142
DataElement - Processed element with converted value
143
"""
144
145
def convert_value(VR, raw_value, encoding=None):
146
"""
147
Convert raw bytes to appropriate Python type based on VR.
148
149
Parameters:
150
- VR: str - Value Representation
151
- raw_value: bytes - Raw value data
152
- encoding: str - Character encoding for text VRs
153
154
Returns:
155
Any - Converted value in appropriate Python type
156
"""
157
```
158
159
### VR-Specific Value Handling
160
161
Functions for creating appropriate empty values and handling VR-specific requirements.
162
163
```python { .api }
164
def empty_value_for_VR(VR, raw=False):
165
"""
166
Return appropriate empty value for given VR.
167
168
Parameters:
169
- VR: str - Value Representation
170
- raw: bool - Whether to return raw bytes or processed value
171
172
Returns:
173
Any - Appropriate empty value for the VR type
174
"""
175
176
def isMultiValue(VR):
177
"""
178
Check if VR can contain multiple values.
179
180
Parameters:
181
- VR: str - Value Representation
182
183
Returns:
184
bool - True if VR supports multiple values
185
"""
186
187
def can_contain_sequences(VR):
188
"""
189
Check if VR can contain sequence data.
190
191
Parameters:
192
- VR: str - Value Representation
193
194
Returns:
195
bool - True if VR can contain sequences
196
"""
197
```
198
199
### Element Factory Functions
200
201
Convenience functions for creating data elements with proper validation and type handling.
202
203
```python { .api }
204
def DataElementFactory(tag, VR, value):
205
"""
206
Factory function to create appropriate DataElement.
207
208
Parameters:
209
- tag: int, tuple, or str - DICOM tag or keyword
210
- VR: str - Value Representation
211
- value: Any - Element value
212
213
Returns:
214
DataElement - Created element with proper typing
215
"""
216
217
def create_element(tag, VR, value, validate=True):
218
"""
219
Create DataElement with validation.
220
221
Parameters:
222
- tag: int, tuple, or str - DICOM tag or keyword
223
- VR: str - Value Representation
224
- value: Any - Element value
225
- validate: bool - Whether to validate value against VR
226
227
Returns:
228
DataElement - Created and validated element
229
"""
230
```
231
232
### Element Validation Functions
233
234
Functions for validating data elements according to DICOM standards and VR requirements.
235
236
```python { .api }
237
def validate_element(data_element):
238
"""
239
Validate DataElement against DICOM standards.
240
241
Parameters:
242
- data_element: DataElement - Element to validate
243
244
Returns:
245
list - List of validation errors/warnings
246
"""
247
248
def validate_element_value(VR, value):
249
"""
250
Validate element value against VR requirements.
251
252
Parameters:
253
- VR: str - Value Representation
254
- value: Any - Value to validate
255
256
Returns:
257
bool - True if value is valid for VR
258
259
Raises:
260
ValueError - If value is invalid for VR
261
"""
262
```
263
264
### Element Comparison and Utilities
265
266
Utility functions for comparing and manipulating data elements.
267
268
```python { .api }
269
def element_comparison_key(data_element):
270
"""
271
Generate comparison key for element sorting.
272
273
Parameters:
274
- data_element: DataElement - Element to generate key for
275
276
Returns:
277
tuple - Sortable comparison key
278
"""
279
280
def copy_element(data_element, deep=True):
281
"""
282
Create copy of DataElement.
283
284
Parameters:
285
- data_element: DataElement - Element to copy
286
- deep: bool - Whether to perform deep copy
287
288
Returns:
289
DataElement - Copied element
290
"""
291
292
def element_byte_size(data_element, encoding=None):
293
"""
294
Calculate byte size of element when serialized.
295
296
Parameters:
297
- data_element: DataElement - Element to measure
298
- encoding: str - Character encoding for text elements
299
300
Returns:
301
int - Size in bytes
302
"""
303
```
304
305
## Usage Examples
306
307
### Creating Data Elements
308
309
```python
310
from pydicom.dataelem import DataElement
311
from pydicom.tag import Tag
312
313
# Create element with tag as integer
314
patient_name_elem = DataElement(0x00100010, "PN", "Doe^John")
315
316
# Create element with Tag object
317
study_date_elem = DataElement(Tag(0x0008, 0x0020), "DA", "20231215")
318
319
# Create element with keyword (requires dictionary lookup)
320
patient_id_elem = DataElement("PatientID", "LO", "12345")
321
322
# Access element properties
323
print(f"Tag: {patient_name_elem.tag}")
324
print(f"VR: {patient_name_elem.VR}")
325
print(f"Value: {patient_name_elem.value}")
326
print(f"Keyword: {patient_name_elem.keyword}")
327
print(f"Description: {patient_name_elem.description}")
328
```
329
330
### Working with Raw Elements
331
332
```python
333
from pydicom.dataelem import RawDataElement, convert_raw_data_element
334
335
# Create raw element (as typically done during file reading)
336
raw_elem = RawDataElement(
337
tag=0x00100010,
338
VR="PN",
339
length=8,
340
value=b"Doe^John",
341
value_tell=1024,
342
is_implicit_VR=False,
343
is_little_endian=True
344
)
345
346
# Convert to processed element
347
processed_elem = convert_raw_data_element(raw_elem)
348
print(f"Converted value: {processed_elem.value}")
349
```
350
351
### Element Validation
352
353
```python
354
from pydicom.dataelem import DataElement, validate_element_value
355
356
# Create element
357
elem = DataElement(0x00100010, "PN", "Doe^John^Middle^^Dr")
358
359
# Validate element value
360
try:
361
is_valid = validate_element_value(elem.VR, elem.value)
362
print(f"Element is valid: {is_valid}")
363
except ValueError as e:
364
print(f"Validation error: {e}")
365
366
# Validate complete element
367
errors = validate_element(elem)
368
if errors:
369
print("Validation issues:")
370
for error in errors:
371
print(f" {error}")
372
```
373
374
### Empty Values and Defaults
375
376
```python
377
from pydicom.dataelem import empty_value_for_VR
378
379
# Get appropriate empty values for different VRs
380
empty_pn = empty_value_for_VR("PN") # ""
381
empty_da = empty_value_for_VR("DA") # ""
382
empty_ds = empty_value_for_VR("DS") # ""
383
empty_sq = empty_value_for_VR("SQ") # Sequence()
384
385
print(f"Empty PN: '{empty_pn}'")
386
print(f"Empty DA: '{empty_da}'")
387
print(f"Empty SQ type: {type(empty_sq)}")
388
389
# Raw empty values (bytes)
390
empty_raw = empty_value_for_VR("PN", raw=True) # b""
391
```
392
393
### Element Comparison and Sorting
394
395
```python
396
from pydicom.dataelem import DataElement, element_comparison_key
397
398
# Create multiple elements
399
elements = [
400
DataElement(0x00200010, "SH", "Study1"), # Study ID
401
DataElement(0x00100010, "PN", "Patient"), # Patient Name
402
DataElement(0x00080020, "DA", "20231215"), # Study Date
403
]
404
405
# Sort elements by tag
406
sorted_elements = sorted(elements, key=element_comparison_key)
407
408
for elem in sorted_elements:
409
print(f"{elem.tag}: {elem.keyword} = {elem.value}")
410
```
411
412
### Element Size Calculation
413
414
```python
415
from pydicom.dataelem import DataElement, element_byte_size
416
417
# Create element with text value
418
elem = DataElement(0x00100010, "PN", "Doe^John^Middle")
419
420
# Calculate size when serialized
421
size = element_byte_size(elem, encoding="utf-8")
422
print(f"Element will occupy {size} bytes when written to file")
423
424
# Size includes tag, VR, length, and value
425
```
426
427
### Element Copying
428
429
```python
430
from pydicom.dataelem import DataElement, copy_element
431
432
# Create original element
433
original = DataElement(0x00100010, "PN", "Doe^John")
434
435
# Create shallow copy
436
shallow_copy = copy_element(original, deep=False)
437
438
# Create deep copy
439
deep_copy = copy_element(original, deep=True)
440
441
# Modify original
442
original.value = "Smith^Jane"
443
444
print(f"Original: {original.value}")
445
print(f"Shallow copy: {shallow_copy.value}") # May or may not change
446
print(f"Deep copy: {deep_copy.value}") # Won't change
447
```
448
449
### Working with Multi-Value Elements
450
451
```python
452
from pydicom.dataelem import DataElement
453
from pydicom.multival import MultiValue
454
455
# Create element with multiple values
456
# WindowCenter can have multiple values
457
window_centers = DataElement(0x00281050, "DS", ["200", "400", "600"])
458
459
# Access individual values
460
first_center = window_centers.value[0] # "200"
461
all_centers = list(window_centers.value)
462
463
print(f"Number of window centers: {len(window_centers.value)}")
464
print(f"Centers: {window_centers.value}")
465
```