pydicom Primer
pydicom is a python module for working with DICOM files. We provide a primer here for things we think might be particularly useful for users of the ProKnow Python SDK. We encourage you to consult the full documentation for more in-depth coverage of the package.
Reading Files
Reading a DICOM file using pydicom is simple:
import pydicom
dataset = pydicom.dcmread('./plan.dcm')
Sometimes, however, you might receive an error message like this:
pydicom.errors.InvalidDicomError: File is missing DICOM File Meta Information header or the ‘DICM’ prefix is missing from the header. Use force=True to force reading.
If this happens, you will have to use force=True to force pydicom to read the file.
Accessing Sequence Data
Let’s say you wish to access the TargetPrescriptionDose located in the DoseReferenceSequence for a plan. Here’s a quite example showing how this can be done:
import pydicom
dataset = pydicom.dcmread('./plan.dcm')
print("Number of Items in Dose Reference Sequence:", len(dataset.DoseReferenceSequence))
item = dataset.DoseReferenceSequence[0] # Get first item in sequence
print("Dose Reference Type:", item.DoseReferenceType)
print("Target Prescription Dose:", item.TargetPrescriptionDose)
Note that this example uses optional tags (DoseReferenceSequence and TargetPrescriptionDose). In your code, you should ensure that you’re not attempting to access attribute values that do not exist.
Attribute Dump
If you don’t know the name of the attribute you’re looking for, it might be helpful to output a recursive dump of the dataset with the available attributes and values. Use the following code as a guide:
import pydicom
def print_dataset(dataset, depth, max_depth=None):
for name in dataset.dir():
value = getattr(dataset, name)
if isinstance(value, pydicom.Sequence):
if max_depth is not None and depth + 1 < max_depth:
print('{:40} => ['.format(' ' * depth + name))
print_sequence(value, depth + 1, max_depth=max_depth)
print('{}]'.format(' ' * depth))
else:
print('{:40} => [...]'.format(' ' * depth + name))
else:
print('{:40} => {}'.format(' ' * depth + name, value))
def print_sequence(sequence, depth, max_depth=None):
if max_depth is not None and depth + 1 < max_depth:
print(' ' * depth + '{')
for dataset in sequence:
print_dataset(dataset, depth + 1, max_depth=max_depth)
print(' ' * depth + '}')
else:
print(' ' * depth + '{...}')
########################################
# Read and output root dataset
dataset = pydicom.dcmread('./plan.dcm', force=True)
print_dataset(dataset, 0, max_depth=1) # root dataset
print_dataset(dataset.DoseReferenceSequence[0], 0, max_depth=1) # sequency
You can adjust max_depth up and down to control the depth of the recursion or omit it entirely for no recursion limits.