Skip to content

Commit f0264ab

Browse files
committed
TST: Don't assume pydicom installed in test_dicomwrappers
1 parent fd56bf4 commit f0264ab

File tree

1 file changed

+48
-36
lines changed

1 file changed

+48
-36
lines changed

nibabel/nicom/tests/test_dicomwrappers.py

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import numpy as np
1212
import pytest
1313
from numpy.testing import assert_array_almost_equal, assert_array_equal
14-
from pydicom.dataset import Dataset
1514

1615
from ...tests.nibabel_data import get_nibabel_data, needs_nibabel_data
1716
from ...volumeutils import endian_codes
@@ -64,8 +63,8 @@ def test_wrappers():
6463
# test direct wrapper calls
6564
# first with empty or minimal data
6665
multi_minimal = {
67-
'PerFrameFunctionalGroupsSequence': [Dataset()],
68-
'SharedFunctionalGroupsSequence': [Dataset()],
66+
'PerFrameFunctionalGroupsSequence': [pydicom.Dataset()],
67+
'SharedFunctionalGroupsSequence': [pydicom.Dataset()],
6968
}
7069
for maker, args in (
7170
(didw.Wrapper, ({},)),
@@ -164,10 +163,10 @@ def test_wrapper_from_data():
164163
fake_data['SOPClassUID'] = '1.2.840.10008.5.1.4.1.1.4.1'
165164
with pytest.raises(didw.WrapperError):
166165
didw.wrapper_from_data(fake_data)
167-
fake_data['PerFrameFunctionalGroupsSequence'] = [Dataset()]
166+
fake_data['PerFrameFunctionalGroupsSequence'] = [pydicom.Dataset()]
168167
with pytest.raises(didw.WrapperError):
169168
didw.wrapper_from_data(fake_data)
170-
fake_data['SharedFunctionalGroupsSequence'] = [Dataset()]
169+
fake_data['SharedFunctionalGroupsSequence'] = [pydicom.Dataset()]
171170
# minimal set should now be met
172171
dw = didw.wrapper_from_data(fake_data)
173172
assert dw.is_multiframe
@@ -386,14 +385,14 @@ def fake_frames(seq_name, field_name, value_seq, frame_seq=None):
386385
value_seq[n] for n in range(N)
387386
"""
388387
if frame_seq is None:
389-
frame_seq = [Dataset() for _ in range(len(value_seq))]
388+
frame_seq = [pydicom.Dataset() for _ in range(len(value_seq))]
390389
for value, fake_frame in zip(value_seq, frame_seq):
391390
if value is None:
392391
continue
393392
if hasattr(fake_frame, seq_name):
394393
fake_element = getattr(fake_frame, seq_name)[0]
395394
else:
396-
fake_element = Dataset()
395+
fake_element = pydicom.Dataset()
397396
setattr(fake_frame, seq_name, [fake_element])
398397
setattr(fake_element, field_name, value)
399398
return frame_seq
@@ -436,30 +435,30 @@ def __repr__(self):
436435
attr_strs.append(f'{attr}={getattr(self, attr)}')
437436
return f"{self.__class__.__name__}({', '.join(attr_strs)})"
438437

439-
class DimIdxSeqElem(Dataset):
438+
class DimIdxSeqElem(pydicom.Dataset):
440439
def __init__(self, dip=(0, 0), fgp=None):
441440
super().__init__()
442441
self.DimensionIndexPointer = dip
443442
if fgp is not None:
444443
self.FunctionalGroupPointer = fgp
445444

446-
class FrmContSeqElem(Dataset):
445+
class FrmContSeqElem(pydicom.Dataset):
447446
def __init__(self, div, sid):
448447
super().__init__()
449448
self.DimensionIndexValues = div
450449
self.StackID = sid
451450

452-
class PlnPosSeqElem(Dataset):
451+
class PlnPosSeqElem(pydicom.Dataset):
453452
def __init__(self, ipp):
454453
super().__init__()
455454
self.ImagePositionPatient = ipp
456455

457-
class PlnOrientSeqElem(Dataset):
456+
class PlnOrientSeqElem(pydicom.Dataset):
458457
def __init__(self, iop):
459458
super().__init__()
460459
self.ImageOrientationPatient = iop
461460

462-
class PerFrmFuncGrpSeqElem(Dataset):
461+
class PerFrmFuncGrpSeqElem(pydicom.Dataset):
463462
def __init__(self, div, sid, ipp, iop):
464463
super().__init__()
465464
self.FrameContentSequence = [FrmContSeqElem(div, sid)]
@@ -514,17 +513,21 @@ def __init__(self, div, sid, ipp, iop):
514513
}
515514

516515

517-
class FakeDataset(Dataset):
518-
pixel_array = None
516+
if have_dicom:
517+
518+
class FakeDataset(pydicom.Dataset):
519+
pixel_array = None
519520

520521

521522
class TestMultiFrameWrapper(TestCase):
522523
# Test MultiframeWrapper
523-
# Minimal contents of dcm_data for this wrapper
524-
MINIMAL_MF = FakeDataset()
525-
MINIMAL_MF.PerFrameFunctionalGroupsSequence = [Dataset()]
526-
MINIMAL_MF.SharedFunctionalGroupsSequence = [Dataset()]
527-
WRAPCLASS = didw.MultiframeWrapper
524+
525+
if have_dicom:
526+
# Minimal contents of dcm_data for this wrapper
527+
MINIMAL_MF = FakeDataset()
528+
MINIMAL_MF.PerFrameFunctionalGroupsSequence = [pydicom.Dataset()]
529+
MINIMAL_MF.SharedFunctionalGroupsSequence = [pydicom.Dataset()]
530+
WRAPCLASS = didw.MultiframeWrapper
528531

529532
@dicom_test
530533
def test_shape(self):
@@ -719,6 +722,7 @@ def test_shape(self):
719722
fake_mf.update(fake_shape_dependents(div_seq, sid_dim=0))
720723
assert MFW(fake_mf).image_shape == (32, 64, 3)
721724

725+
@dicom_test
722726
def test_iop(self):
723727
# Test Image orient patient for multiframe
724728
fake_mf = deepcopy(self.MINIMAL_MF)
@@ -732,12 +736,13 @@ def test_iop(self):
732736
)[0]
733737
fake_mf.SharedFunctionalGroupsSequence = [fake_frame]
734738
assert_array_equal(MFW(fake_mf).image_orient_patient, [[0, 1], [1, 0], [0, 0]])
735-
fake_mf.SharedFunctionalGroupsSequence = [Dataset()]
739+
fake_mf.SharedFunctionalGroupsSequence = [pydicom.Dataset()]
736740
with pytest.raises(didw.WrapperError):
737741
MFW(fake_mf).image_orient_patient
738742
fake_mf.PerFrameFunctionalGroupsSequence = [fake_frame]
739743
assert_array_equal(MFW(fake_mf).image_orient_patient, [[0, 1], [1, 0], [0, 0]])
740744

745+
@dicom_test
741746
def test_voxel_sizes(self):
742747
# Test voxel size calculation
743748
fake_mf = deepcopy(self.MINIMAL_MF)
@@ -761,7 +766,7 @@ def test_voxel_sizes(self):
761766
del fake_mf.SpacingBetweenSlices
762767
assert_array_equal(MFW(fake_mf).voxel_sizes, [2.1, 3.2, 5.4])
763768
# Removing shared leads to error again
764-
fake_mf.SharedFunctionalGroupsSequence = [Dataset()]
769+
fake_mf.SharedFunctionalGroupsSequence = [pydicom.Dataset()]
765770
with pytest.raises(didw.WrapperError):
766771
MFW(fake_mf).voxel_sizes
767772
# Restoring to frames makes it work again
@@ -777,6 +782,7 @@ def test_voxel_sizes(self):
777782
fake_frame.PixelMeasuresSequence[0].SliceThickness = Decimal('5.4')
778783
assert_array_equal(MFW(fake_mf).voxel_sizes, [2.1, 3.2, 5.4])
779784

785+
@dicom_test
780786
def test_image_position(self):
781787
# Test image_position property for multiframe
782788
fake_mf = deepcopy(self.MINIMAL_MF)
@@ -792,7 +798,7 @@ def test_image_position(self):
792798
)
793799
fake_mf.SharedFunctionalGroupsSequence = frames
794800
assert_array_equal(MFW(fake_mf).image_position, [-2, 3, 7])
795-
fake_mf.SharedFunctionalGroupsSequence = [Dataset()]
801+
fake_mf.SharedFunctionalGroupsSequence = [pydicom.Dataset()]
796802
with pytest.raises(didw.WrapperError):
797803
MFW(fake_mf).image_position
798804
fake_mf.PerFrameFunctionalGroupsSequence = frames
@@ -933,12 +939,13 @@ def test_data_fake(self):
933939
fake_mf.pixel_array = np.rollaxis(sorted_data, 2)
934940
assert_array_equal(MFW(fake_mf).get_data(), data * 2.0 - 1)
935941

942+
@dicom_test
936943
def test_scale_data(self):
937944
# Test data scaling
938945
fake_mf = deepcopy(self.MINIMAL_MF)
939946
fake_mf.Rows = 2
940947
fake_mf.Columns = 3
941-
fake_mf.PerFrameFunctionalGroupsSequence = [Dataset() for _ in range(4)]
948+
fake_mf.PerFrameFunctionalGroupsSequence = [pydicom.Dataset() for _ in range(4)]
942949
MFW = self.WRAPCLASS
943950
data = np.arange(24).reshape((2, 3, 4), order='F')
944951
assert_array_equal(data, MFW(fake_mf)._scale_data(data))
@@ -947,22 +954,24 @@ def test_scale_data(self):
947954
fake_mf.RescaleIntercept = -1.0
948955
assert_array_equal(data * 2 - 1, MFW(fake_mf)._scale_data(data))
949956
# RealWorldValueMapping takes precedence, but only with defined units
950-
fake_mf.RealWorldValueMappingSequence = [Dataset()]
957+
fake_mf.RealWorldValueMappingSequence = [pydicom.Dataset()]
951958
fake_mf.RealWorldValueMappingSequence[0].RealWorldValueSlope = 10.0
952959
fake_mf.RealWorldValueMappingSequence[0].RealWorldValueIntercept = -5.0
953960
assert_array_equal(data * 2 - 1, MFW(fake_mf)._scale_data(data))
954-
fake_mf.RealWorldValueMappingSequence[0].MeasurementUnitsCodeSequence = [Dataset()]
961+
fake_mf.RealWorldValueMappingSequence[0].MeasurementUnitsCodeSequence = [pydicom.Dataset()]
955962
fake_mf.RealWorldValueMappingSequence[0].MeasurementUnitsCodeSequence[0].CodeMeaning = '%'
956963
assert_array_equal(data * 10 - 5, MFW(fake_mf)._scale_data(data))
957964
fake_mf.RealWorldValueMappingSequence[0].MeasurementUnitsCodeSequence[
958965
0
959966
].CodeMeaning = 'no units'
960967
assert_array_equal(data * 2 - 1, MFW(fake_mf)._scale_data(data))
961968
# Possible to have more than one RealWorldValueMapping, use first one with defined units
962-
fake_mf.RealWorldValueMappingSequence.append(Dataset())
969+
fake_mf.RealWorldValueMappingSequence.append(pydicom.Dataset())
963970
fake_mf.RealWorldValueMappingSequence[-1].RealWorldValueSlope = 15.0
964971
fake_mf.RealWorldValueMappingSequence[-1].RealWorldValueIntercept = -3.0
965-
fake_mf.RealWorldValueMappingSequence[-1].MeasurementUnitsCodeSequence = [Dataset()]
972+
fake_mf.RealWorldValueMappingSequence[-1].MeasurementUnitsCodeSequence = [
973+
pydicom.Dataset()
974+
]
966975
fake_mf.RealWorldValueMappingSequence[-1].MeasurementUnitsCodeSequence[0].CodeMeaning = '%'
967976
assert_array_equal(data * 15 - 3, MFW(fake_mf)._scale_data(data))
968977
# A global RWV scale takes precedence over per-frame PixelValueTransformation
@@ -988,10 +997,12 @@ def test_scale_data(self):
988997
assert_array_equal(data * 3 - 2, MFW(fake_mf)._scale_data(data))
989998
# A per-frame RWV scaling takes precedence over per-frame PixelValueTransformation
990999
for frame in frames:
991-
frame.RealWorldValueMappingSequence = [Dataset()]
1000+
frame.RealWorldValueMappingSequence = [pydicom.Dataset()]
9921001
frame.RealWorldValueMappingSequence[0].RealWorldValueSlope = 10.0
9931002
frame.RealWorldValueMappingSequence[0].RealWorldValueIntercept = -5.0
994-
frame.RealWorldValueMappingSequence[0].MeasurementUnitsCodeSequence = [Dataset()]
1003+
frame.RealWorldValueMappingSequence[0].MeasurementUnitsCodeSequence = [
1004+
pydicom.Dataset()
1005+
]
9951006
frame.RealWorldValueMappingSequence[0].MeasurementUnitsCodeSequence[
9961007
0
9971008
].CodeMeaning = '%'
@@ -1005,12 +1016,13 @@ def test_scale_data(self):
10051016
MFW(fake_mf)._scale_data(data),
10061017
)
10071018

1019+
@dicom_test
10081020
def test_philips_scale_data(self):
10091021
fake_mf = deepcopy(self.MINIMAL_MF)
10101022
fake_mf.Manufacturer = 'Philips'
10111023
fake_mf.Rows = 2
10121024
fake_mf.Columns = 3
1013-
fake_mf.PerFrameFunctionalGroupsSequence = [Dataset() for _ in range(4)]
1025+
fake_mf.PerFrameFunctionalGroupsSequence = [pydicom.Dataset() for _ in range(4)]
10141026
MFW = self.WRAPCLASS
10151027
data = np.arange(24).reshape((2, 3, 4), order='F')
10161028
# Unlike other manufacturers, public scale factors from Philips without defined
@@ -1040,12 +1052,12 @@ def test_philips_scale_data(self):
10401052
fake_mf.RescaleType = 'mrad'
10411053
assert_array_equal(data * 2 - 1, MFW(fake_mf)._scale_data(data))
10421054
# A RWV scale factor with defined units takes precdence
1043-
shared = Dataset()
1055+
shared = pydicom.Dataset()
10441056
fake_mf.SharedFunctionalGroupsSequence = [shared]
1045-
rwv_map = Dataset()
1057+
rwv_map = pydicom.Dataset()
10461058
rwv_map.RealWorldValueSlope = 10.0
10471059
rwv_map.RealWorldValueIntercept = -5.0
1048-
rwv_map.MeasurementUnitsCodeSequence = [Dataset()]
1060+
rwv_map.MeasurementUnitsCodeSequence = [pydicom.Dataset()]
10491061
rwv_map.MeasurementUnitsCodeSequence[0].CodeMeaning = '%'
10501062
shared.RealWorldValueMappingSequence = [rwv_map]
10511063
assert_array_equal(data * 10 - 5, MFW(fake_mf)._scale_data(data))
@@ -1057,7 +1069,7 @@ def test_philips_scale_data(self):
10571069
fake_mf.update(fake_shape_dependents(div_seq, sid_dim=0))
10581070
# Simplest case is all frames have same (valid) scale factor
10591071
for frame in fake_mf.PerFrameFunctionalGroupsSequence:
1060-
pix_trans = Dataset()
1072+
pix_trans = pydicom.Dataset()
10611073
pix_trans.RescaleSlope = 2.5
10621074
pix_trans.RescaleIntercept = -4
10631075
pix_trans.RescaleType = 'mrad'
@@ -1084,10 +1096,10 @@ def test_philips_scale_data(self):
10841096
)
10851097
# Again RWV scale factors take precedence
10861098
for frame_idx, frame in enumerate(fake_mf.PerFrameFunctionalGroupsSequence):
1087-
rwv_map = Dataset()
1099+
rwv_map = pydicom.Dataset()
10881100
rwv_map.RealWorldValueSlope = 14.0 - frame_idx
10891101
rwv_map.RealWorldValueIntercept = 5.0
1090-
rwv_map.MeasurementUnitsCodeSequence = [Dataset()]
1102+
rwv_map.MeasurementUnitsCodeSequence = [pydicom.Dataset()]
10911103
rwv_map.MeasurementUnitsCodeSequence[0].CodeMeaning = '%'
10921104
frame.RealWorldValueMappingSequence = [rwv_map]
10931105
assert_array_equal(

0 commit comments

Comments
 (0)