Skip to content

Instantly share code, notes, and snippets.

@jstorrs
Last active September 21, 2022 15:53
Show Gist options
  • Save jstorrs/4d8e22b53cbb6412e5355e0c7754efee to your computer and use it in GitHub Desktop.
Save jstorrs/4d8e22b53cbb6412e5355e0c7754efee to your computer and use it in GitHub Desktop.
A decorator to trace pydicom.dataset.Dataset's walk()
from pydicom import DataElement, Dataset
def trace_sequences(walk_callback):
stacks = {}
contexts = []
def add_items(parent: Dataset, elem: DataElement) -> None:
for item in range(elem.VM):
contexts.append((parent, elem, item))
def add_dataset(ds: Dataset) -> None:
if stacks:
if id(ds) not in stacks:
context = contexts.pop(0)
parent_stack = stacks[id(context[0])]
if parent_stack:
stack = (*parent_stack, context)
else:
stack = (context,)
stacks[id(ds)] = stack
else:
stacks[id(ds)] = None
def trace_walk(ds: Dataset, elem: DataElement):
add_dataset(ds)
if elem.VR == 'SQ':
add_items(ds, elem)
trace = stacks[id(ds)]
walk_callback(ds, elem, trace)
return trace_walk
@jstorrs
Copy link
Author

jstorrs commented Sep 21, 2022

Example use:

import pydicom

@trace_sequences
def callback(ds, elem, trace):
    if trace:
        prefix = '.'.join([f"{i[1].keyword}[{i[2]}]" for i in trace]) + '.'
    else:
        prefix = ''
    print(prefix + str(elem.keyword))
    
dcm = pydicom.dcmread('dicom.dcm')
dcm.walk(callback)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment