Skip to content

Commit 9406332

Browse files
authored
bug: Fix UID lookup and sequence field handling (#292)
* bug: Fix UID lookup and sequence field handling Fix UID lookup for nested sequence fields in DICOM datasets Previously, when processing DICOM sequence fields (VR=SQ), the UID lookup logic incorrectly handled nested items within sequences. This caused issues when trying to remove or manipulate specific nested fields using the field specification syntax like (0018,9346)__0__(0008,0104). The fix ensures that: Sequence fields with VR=SQ are properly identified and their items are correctly indexed Each item within a sequence receives a proper UID that includes the parent sequence tag and item index Nested fields can be targeted using the double-underscore notation with index (e.g., SequenceTag__ItemIndex__NestedTag) * Update changelog and bump version
1 parent ef902be commit 9406332

File tree

4 files changed

+38
-1
lines changed

4 files changed

+38
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ and **Merged pull requests**. Critical items to know are:
1414
Referenced versions in headers are tagged on Github, in parentheses are for pypi.
1515

1616
## [vxx](https://github.com/pydicom/deid/tree/master) (master)
17+
- Fix UID lookup for nested sequence fields in DICOM datasets [#292](https://github.com/pydicom/deid/pull/292) (0.4.8)
1718
- Allow saving with a compressed transfer syntax [#290](https://github.com/pydicom/deid/pull/290) (0.4.7)
1819
- Improve performance of header deid with caching and lookup tables [#289](https://github.com/pydicom/deid/pull/289)
1920
- Fix REMOVE action to respect REPLACE or JITTER priority [#283](https://github.com/pydicom/deid/pull/283) (0.4.6)

deid/dicom/fields.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ def __init__(self, fields):
329329
"stripped_tag": defaultdict(list),
330330
"element_name": defaultdict(list),
331331
"element_keyword": defaultdict(list),
332+
"uid": defaultdict(list),
332333
}
333334
for uid, field in fields.items():
334335
self._add_field_to_lookup(field)
@@ -347,6 +348,7 @@ def get_exact_matches(self, field):
347348
+ self.lookup_tables["stripped_tag"][field]
348349
+ self.lookup_tables["element_name"][field]
349350
+ self.lookup_tables["element_keyword"][field]
351+
+ self.lookup_tables["uid"][field]
350352
)
351353
return exact_match_contenders
352354

@@ -387,6 +389,8 @@ def _get_field_lookup_keys(self, field):
387389
lookup_keys["element_name"] = [field.element.name.lower()]
388390
if field.element.keyword:
389391
lookup_keys["element_keyword"] = [field.element.keyword.lower()]
392+
if field.uid:
393+
lookup_keys["uid"] = [field.uid.lower()]
390394
if field.element.is_private:
391395
lookup_keys["name"] = lookup_keys.get("name", []) + [
392396
f'({field.element.tag.group:04X},"{field.element.private_creator}",{(field.element.tag.element & 0x00FF):02X})'.lower(),

deid/tests/test_remove_action.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,38 @@ def test_remove_single_tag_private_creator_no_match(self):
239239
# Tag should still exist because private creator didn't match
240240
self.assertEqual(currentValue, outputfile[field_dicom].value)
241241

242+
def test_remove_specific_nested_sequence_tag(self):
243+
"""RECIPE RULE
244+
REMOVE (0018,9346)__0__(0008,0104)
245+
"""
246+
print("Test REMOVE specific nested sequence tag")
247+
dicom_file = get_file(self.dataset)
248+
249+
Field = "(0018,9346)__0__(0008,0104)" # Referenced SOP Instance UID inside Referenced Series Sequence
250+
actions = [
251+
{"action": "REMOVE", "field": Field},
252+
]
253+
recipe = create_recipe(actions)
254+
255+
inputfile = utils.dcmread(dicom_file)
256+
currentValue = inputfile["00189346"][0]["00080104"].value
257+
258+
self.assertNotEqual(None, currentValue)
259+
self.assertNotEqual("", currentValue)
260+
261+
result = replace_identifiers(
262+
dicom_files=dicom_file,
263+
deid=recipe,
264+
save=True,
265+
remove_private=False,
266+
strip_sequences=False,
267+
)
268+
outputfile = utils.dcmread(result[0])
269+
270+
self.assertEqual(1, len(result))
271+
with self.assertRaises(KeyError):
272+
_ = outputfile["00189346"][0]["00080104"].value
273+
242274

243275
if __name__ == "__main__":
244276
unittest.main()

deid/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
__copyright__ = "Copyright 2016-2025, Vanessa Sochat"
33
__license__ = "MIT"
44

5-
__version__ = "0.4.7"
5+
__version__ = "0.4.8"
66
AUTHOR = "Vanessa Sochat"
77
AUTHOR_EMAIL = "[email protected]"
88
NAME = "deid"

0 commit comments

Comments
 (0)