Skip to content

Commit b7022e0

Browse files
Merge pull request #1228 from matthew-brett/refactor-find-private
RF: refactor find_private_element Refactor find_private_element and extend tests.
2 parents 8e53d69 + 77b7a33 commit b7022e0

File tree

2 files changed

+45
-36
lines changed

2 files changed

+45
-36
lines changed

nibabel/nicom/tests/test_utils.py

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from nibabel.optpkg import optional_package
66

7-
from ..utils import find_private_section
7+
from ..utils import find_private_section as fps
88
from .test_dicomwrappers import DATA, DATA_PHILIPS
99

1010
pydicom, _, setup_module = optional_package('pydicom')
@@ -13,37 +13,53 @@
1313
def test_find_private_section_real():
1414
# Find section containing named private creator information
1515
# On real data first
16-
assert find_private_section(DATA, 0x29, 'SIEMENS CSA HEADER') == 0x1000
17-
assert find_private_section(DATA, 0x29, 'SIEMENS MEDCOM HEADER2') == 0x1100
18-
assert find_private_section(DATA_PHILIPS, 0x29, 'SIEMENS CSA HEADER') == None
19-
# Make fake datasets
16+
assert fps(DATA, 0x29, 'SIEMENS CSA HEADER') == 0x1000
17+
assert fps(DATA, 0x29, b'SIEMENS CSA HEADER') == 0x1000
18+
assert fps(DATA, 0x29, re.compile('SIEMENS CSA HEADER')) == 0x1000
19+
assert fps(DATA, 0x29, 'NOT A HEADER') is None
20+
assert fps(DATA, 0x29, 'SIEMENS MEDCOM HEADER2') == 0x1100
21+
assert fps(DATA_PHILIPS, 0x29, 'SIEMENS CSA HEADER') == None
22+
23+
24+
def test_find_private_section_fake():
25+
# Make and test fake datasets
2026
ds = pydicom.dataset.Dataset({})
27+
assert fps(ds, 0x11, 'some section') is None
2128
ds.add_new((0x11, 0x10), 'LO', b'some section')
22-
assert find_private_section(ds, 0x11, 'some section') == 0x1000
23-
ds.add_new((0x11, 0x11), 'LO', b'anther section')
29+
assert fps(ds, 0x11, 'some section') == 0x1000
30+
ds.add_new((0x11, 0x11), 'LO', b'another section')
2431
ds.add_new((0x11, 0x12), 'LO', b'third section')
25-
assert find_private_section(ds, 0x11, 'third section') == 0x1200
26-
# Wrong 'OB' is acceptable for VM (should be 'LO')
32+
assert fps(ds, 0x11, 'third section') == 0x1200
33+
# Technically incorrect 'OB' is acceptable for VM (should be 'LO')
2734
ds.add_new((0x11, 0x12), 'OB', b'third section')
28-
assert find_private_section(ds, 0x11, 'third section') == 0x1200
35+
assert fps(ds, 0x11, 'third section') == 0x1200
2936
# Anything else not acceptable
3037
ds.add_new((0x11, 0x12), 'PN', b'third section')
31-
assert find_private_section(ds, 0x11, 'third section') is None
38+
assert fps(ds, 0x11, 'third section') is None
3239
# The input (DICOM value) can be a string insteal of bytes
3340
ds.add_new((0x11, 0x12), 'LO', 'third section')
34-
assert find_private_section(ds, 0x11, 'third section') == 0x1200
41+
assert fps(ds, 0x11, 'third section') == 0x1200
3542
# Search can be bytes as well as string
3643
ds.add_new((0x11, 0x12), 'LO', b'third section')
37-
assert find_private_section(ds, 0x11, b'third section') == 0x1200
44+
assert fps(ds, 0x11, b'third section') == 0x1200
3845
# Search with string or bytes must be exact
39-
assert find_private_section(ds, 0x11, b'third sectio') is None
40-
assert find_private_section(ds, 0x11, 'hird sectio') is None
46+
assert fps(ds, 0x11, b'third sectio') is None
47+
assert fps(ds, 0x11, 'hird sectio') is None
4148
# The search can be a regexp
42-
assert find_private_section(ds, 0x11, re.compile(r'third\Wsectio[nN]')) == 0x1200
49+
assert fps(ds, 0x11, re.compile(r'third\Wsectio[nN]')) == 0x1200
4350
# No match -> None
44-
assert find_private_section(ds, 0x11, re.compile(r'not third\Wsectio[nN]')) is None
51+
assert fps(ds, 0x11, re.compile(r'not third\Wsectio[nN]')) is None
4552
# If there are gaps in the sequence before the one we want, that is OK
4653
ds.add_new((0x11, 0x13), 'LO', b'near section')
47-
assert find_private_section(ds, 0x11, 'near section') == 0x1300
54+
assert fps(ds, 0x11, 'near section') == 0x1300
4855
ds.add_new((0x11, 0x15), 'LO', b'far section')
49-
assert find_private_section(ds, 0x11, 'far section') == 0x1500
56+
assert fps(ds, 0x11, 'far section') == 0x1500
57+
# More than one match - find the first.
58+
assert fps(ds, 0x11, re.compile('(another|third) section')) == 0x1100
59+
# The signalling element number must be <= 0xFF
60+
ds = pydicom.dataset.Dataset({})
61+
ds.add_new((0x11, 0xFF), 'LO', b'some section')
62+
assert fps(ds, 0x11, 'some section') == 0xFF00
63+
ds = pydicom.dataset.Dataset({})
64+
ds.add_new((0x11, 0x100), 'LO', b'some section')
65+
assert fps(ds, 0x11, 'some section') is None

nibabel/nicom/utils.py

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,19 @@ def find_private_section(dcm_data, group_no, creator):
2727
Returns
2828
-------
2929
element_start : int
30-
Element number at which named section starts
30+
Element number at which named section starts.
3131
"""
32-
is_regex = hasattr(creator, 'search')
33-
if not is_regex: # assume string / bytes
34-
creator = asstr(creator)
35-
for element in dcm_data: # Assumed ordered by tag (groupno, elno)
36-
grpno, elno = element.tag.group, element.tag.elem
37-
if grpno > group_no:
38-
break
39-
if grpno != group_no:
40-
continue
32+
if hasattr(creator, 'search'):
33+
match_func = creator.search
34+
else: # assume string / bytes
35+
match_func = asstr(creator).__eq__
36+
# Group elements assumed ordered by tag (groupno, elno)
37+
for element in dcm_data.group_dataset(group_no):
38+
elno = element.tag.elem
4139
if elno > 0xFF:
4240
break
4341
if element.VR not in ('LO', 'OB'):
4442
continue
45-
name = asstr(element.value)
46-
if is_regex:
47-
if creator.search(name) is not None:
48-
return elno * 0x100
49-
else: # string - needs exact match
50-
if creator == name:
51-
return elno * 0x100
43+
if match_func(asstr(element.value)):
44+
return elno * 0x100
5245
return None

0 commit comments

Comments
 (0)