11
11
import numpy as np
12
12
import pytest
13
13
from numpy .testing import assert_array_almost_equal , assert_array_equal
14
- from pydicom .dataset import Dataset
15
14
16
15
from ...tests .nibabel_data import get_nibabel_data , needs_nibabel_data
17
16
from ...volumeutils import endian_codes
@@ -64,8 +63,8 @@ def test_wrappers():
64
63
# test direct wrapper calls
65
64
# first with empty or minimal data
66
65
multi_minimal = {
67
- 'PerFrameFunctionalGroupsSequence' : [Dataset ()],
68
- 'SharedFunctionalGroupsSequence' : [Dataset ()],
66
+ 'PerFrameFunctionalGroupsSequence' : [pydicom . Dataset ()],
67
+ 'SharedFunctionalGroupsSequence' : [pydicom . Dataset ()],
69
68
}
70
69
for maker , args in (
71
70
(didw .Wrapper , ({},)),
@@ -164,10 +163,10 @@ def test_wrapper_from_data():
164
163
fake_data ['SOPClassUID' ] = '1.2.840.10008.5.1.4.1.1.4.1'
165
164
with pytest .raises (didw .WrapperError ):
166
165
didw .wrapper_from_data (fake_data )
167
- fake_data ['PerFrameFunctionalGroupsSequence' ] = [Dataset ()]
166
+ fake_data ['PerFrameFunctionalGroupsSequence' ] = [pydicom . Dataset ()]
168
167
with pytest .raises (didw .WrapperError ):
169
168
didw .wrapper_from_data (fake_data )
170
- fake_data ['SharedFunctionalGroupsSequence' ] = [Dataset ()]
169
+ fake_data ['SharedFunctionalGroupsSequence' ] = [pydicom . Dataset ()]
171
170
# minimal set should now be met
172
171
dw = didw .wrapper_from_data (fake_data )
173
172
assert dw .is_multiframe
@@ -386,14 +385,14 @@ def fake_frames(seq_name, field_name, value_seq, frame_seq=None):
386
385
value_seq[n] for n in range(N)
387
386
"""
388
387
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 ))]
390
389
for value , fake_frame in zip (value_seq , frame_seq ):
391
390
if value is None :
392
391
continue
393
392
if hasattr (fake_frame , seq_name ):
394
393
fake_element = getattr (fake_frame , seq_name )[0 ]
395
394
else :
396
- fake_element = Dataset ()
395
+ fake_element = pydicom . Dataset ()
397
396
setattr (fake_frame , seq_name , [fake_element ])
398
397
setattr (fake_element , field_name , value )
399
398
return frame_seq
@@ -436,30 +435,30 @@ def __repr__(self):
436
435
attr_strs .append (f'{ attr } ={ getattr (self , attr )} ' )
437
436
return f"{ self .__class__ .__name__ } ({ ', ' .join (attr_strs )} )"
438
437
439
- class DimIdxSeqElem (Dataset ):
438
+ class DimIdxSeqElem (pydicom . Dataset ):
440
439
def __init__ (self , dip = (0 , 0 ), fgp = None ):
441
440
super ().__init__ ()
442
441
self .DimensionIndexPointer = dip
443
442
if fgp is not None :
444
443
self .FunctionalGroupPointer = fgp
445
444
446
- class FrmContSeqElem (Dataset ):
445
+ class FrmContSeqElem (pydicom . Dataset ):
447
446
def __init__ (self , div , sid ):
448
447
super ().__init__ ()
449
448
self .DimensionIndexValues = div
450
449
self .StackID = sid
451
450
452
- class PlnPosSeqElem (Dataset ):
451
+ class PlnPosSeqElem (pydicom . Dataset ):
453
452
def __init__ (self , ipp ):
454
453
super ().__init__ ()
455
454
self .ImagePositionPatient = ipp
456
455
457
- class PlnOrientSeqElem (Dataset ):
456
+ class PlnOrientSeqElem (pydicom . Dataset ):
458
457
def __init__ (self , iop ):
459
458
super ().__init__ ()
460
459
self .ImageOrientationPatient = iop
461
460
462
- class PerFrmFuncGrpSeqElem (Dataset ):
461
+ class PerFrmFuncGrpSeqElem (pydicom . Dataset ):
463
462
def __init__ (self , div , sid , ipp , iop ):
464
463
super ().__init__ ()
465
464
self .FrameContentSequence = [FrmContSeqElem (div , sid )]
@@ -514,17 +513,21 @@ def __init__(self, div, sid, ipp, iop):
514
513
}
515
514
516
515
517
- class FakeDataset (Dataset ):
518
- pixel_array = None
516
+ if have_dicom :
517
+
518
+ class FakeDataset (pydicom .Dataset ):
519
+ pixel_array = None
519
520
520
521
521
522
class TestMultiFrameWrapper (TestCase ):
522
523
# 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
528
531
529
532
@dicom_test
530
533
def test_shape (self ):
@@ -719,6 +722,7 @@ def test_shape(self):
719
722
fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 0 ))
720
723
assert MFW (fake_mf ).image_shape == (32 , 64 , 3 )
721
724
725
+ @dicom_test
722
726
def test_iop (self ):
723
727
# Test Image orient patient for multiframe
724
728
fake_mf = deepcopy (self .MINIMAL_MF )
@@ -732,12 +736,13 @@ def test_iop(self):
732
736
)[0 ]
733
737
fake_mf .SharedFunctionalGroupsSequence = [fake_frame ]
734
738
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 ()]
736
740
with pytest .raises (didw .WrapperError ):
737
741
MFW (fake_mf ).image_orient_patient
738
742
fake_mf .PerFrameFunctionalGroupsSequence = [fake_frame ]
739
743
assert_array_equal (MFW (fake_mf ).image_orient_patient , [[0 , 1 ], [1 , 0 ], [0 , 0 ]])
740
744
745
+ @dicom_test
741
746
def test_voxel_sizes (self ):
742
747
# Test voxel size calculation
743
748
fake_mf = deepcopy (self .MINIMAL_MF )
@@ -761,7 +766,7 @@ def test_voxel_sizes(self):
761
766
del fake_mf .SpacingBetweenSlices
762
767
assert_array_equal (MFW (fake_mf ).voxel_sizes , [2.1 , 3.2 , 5.4 ])
763
768
# Removing shared leads to error again
764
- fake_mf .SharedFunctionalGroupsSequence = [Dataset ()]
769
+ fake_mf .SharedFunctionalGroupsSequence = [pydicom . Dataset ()]
765
770
with pytest .raises (didw .WrapperError ):
766
771
MFW (fake_mf ).voxel_sizes
767
772
# Restoring to frames makes it work again
@@ -777,6 +782,7 @@ def test_voxel_sizes(self):
777
782
fake_frame .PixelMeasuresSequence [0 ].SliceThickness = Decimal ('5.4' )
778
783
assert_array_equal (MFW (fake_mf ).voxel_sizes , [2.1 , 3.2 , 5.4 ])
779
784
785
+ @dicom_test
780
786
def test_image_position (self ):
781
787
# Test image_position property for multiframe
782
788
fake_mf = deepcopy (self .MINIMAL_MF )
@@ -792,7 +798,7 @@ def test_image_position(self):
792
798
)
793
799
fake_mf .SharedFunctionalGroupsSequence = frames
794
800
assert_array_equal (MFW (fake_mf ).image_position , [- 2 , 3 , 7 ])
795
- fake_mf .SharedFunctionalGroupsSequence = [Dataset ()]
801
+ fake_mf .SharedFunctionalGroupsSequence = [pydicom . Dataset ()]
796
802
with pytest .raises (didw .WrapperError ):
797
803
MFW (fake_mf ).image_position
798
804
fake_mf .PerFrameFunctionalGroupsSequence = frames
@@ -933,12 +939,13 @@ def test_data_fake(self):
933
939
fake_mf .pixel_array = np .rollaxis (sorted_data , 2 )
934
940
assert_array_equal (MFW (fake_mf ).get_data (), data * 2.0 - 1 )
935
941
942
+ @dicom_test
936
943
def test_scale_data (self ):
937
944
# Test data scaling
938
945
fake_mf = deepcopy (self .MINIMAL_MF )
939
946
fake_mf .Rows = 2
940
947
fake_mf .Columns = 3
941
- fake_mf .PerFrameFunctionalGroupsSequence = [Dataset () for _ in range (4 )]
948
+ fake_mf .PerFrameFunctionalGroupsSequence = [pydicom . Dataset () for _ in range (4 )]
942
949
MFW = self .WRAPCLASS
943
950
data = np .arange (24 ).reshape ((2 , 3 , 4 ), order = 'F' )
944
951
assert_array_equal (data , MFW (fake_mf )._scale_data (data ))
@@ -947,22 +954,24 @@ def test_scale_data(self):
947
954
fake_mf .RescaleIntercept = - 1.0
948
955
assert_array_equal (data * 2 - 1 , MFW (fake_mf )._scale_data (data ))
949
956
# RealWorldValueMapping takes precedence, but only with defined units
950
- fake_mf .RealWorldValueMappingSequence = [Dataset ()]
957
+ fake_mf .RealWorldValueMappingSequence = [pydicom . Dataset ()]
951
958
fake_mf .RealWorldValueMappingSequence [0 ].RealWorldValueSlope = 10.0
952
959
fake_mf .RealWorldValueMappingSequence [0 ].RealWorldValueIntercept = - 5.0
953
960
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 ()]
955
962
fake_mf .RealWorldValueMappingSequence [0 ].MeasurementUnitsCodeSequence [0 ].CodeMeaning = '%'
956
963
assert_array_equal (data * 10 - 5 , MFW (fake_mf )._scale_data (data ))
957
964
fake_mf .RealWorldValueMappingSequence [0 ].MeasurementUnitsCodeSequence [
958
965
0
959
966
].CodeMeaning = 'no units'
960
967
assert_array_equal (data * 2 - 1 , MFW (fake_mf )._scale_data (data ))
961
968
# 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 ())
963
970
fake_mf .RealWorldValueMappingSequence [- 1 ].RealWorldValueSlope = 15.0
964
971
fake_mf .RealWorldValueMappingSequence [- 1 ].RealWorldValueIntercept = - 3.0
965
- fake_mf .RealWorldValueMappingSequence [- 1 ].MeasurementUnitsCodeSequence = [Dataset ()]
972
+ fake_mf .RealWorldValueMappingSequence [- 1 ].MeasurementUnitsCodeSequence = [
973
+ pydicom .Dataset ()
974
+ ]
966
975
fake_mf .RealWorldValueMappingSequence [- 1 ].MeasurementUnitsCodeSequence [0 ].CodeMeaning = '%'
967
976
assert_array_equal (data * 15 - 3 , MFW (fake_mf )._scale_data (data ))
968
977
# A global RWV scale takes precedence over per-frame PixelValueTransformation
@@ -988,10 +997,12 @@ def test_scale_data(self):
988
997
assert_array_equal (data * 3 - 2 , MFW (fake_mf )._scale_data (data ))
989
998
# A per-frame RWV scaling takes precedence over per-frame PixelValueTransformation
990
999
for frame in frames :
991
- frame .RealWorldValueMappingSequence = [Dataset ()]
1000
+ frame .RealWorldValueMappingSequence = [pydicom . Dataset ()]
992
1001
frame .RealWorldValueMappingSequence [0 ].RealWorldValueSlope = 10.0
993
1002
frame .RealWorldValueMappingSequence [0 ].RealWorldValueIntercept = - 5.0
994
- frame .RealWorldValueMappingSequence [0 ].MeasurementUnitsCodeSequence = [Dataset ()]
1003
+ frame .RealWorldValueMappingSequence [0 ].MeasurementUnitsCodeSequence = [
1004
+ pydicom .Dataset ()
1005
+ ]
995
1006
frame .RealWorldValueMappingSequence [0 ].MeasurementUnitsCodeSequence [
996
1007
0
997
1008
].CodeMeaning = '%'
@@ -1005,12 +1016,13 @@ def test_scale_data(self):
1005
1016
MFW (fake_mf )._scale_data (data ),
1006
1017
)
1007
1018
1019
+ @dicom_test
1008
1020
def test_philips_scale_data (self ):
1009
1021
fake_mf = deepcopy (self .MINIMAL_MF )
1010
1022
fake_mf .Manufacturer = 'Philips'
1011
1023
fake_mf .Rows = 2
1012
1024
fake_mf .Columns = 3
1013
- fake_mf .PerFrameFunctionalGroupsSequence = [Dataset () for _ in range (4 )]
1025
+ fake_mf .PerFrameFunctionalGroupsSequence = [pydicom . Dataset () for _ in range (4 )]
1014
1026
MFW = self .WRAPCLASS
1015
1027
data = np .arange (24 ).reshape ((2 , 3 , 4 ), order = 'F' )
1016
1028
# Unlike other manufacturers, public scale factors from Philips without defined
@@ -1040,12 +1052,12 @@ def test_philips_scale_data(self):
1040
1052
fake_mf .RescaleType = 'mrad'
1041
1053
assert_array_equal (data * 2 - 1 , MFW (fake_mf )._scale_data (data ))
1042
1054
# A RWV scale factor with defined units takes precdence
1043
- shared = Dataset ()
1055
+ shared = pydicom . Dataset ()
1044
1056
fake_mf .SharedFunctionalGroupsSequence = [shared ]
1045
- rwv_map = Dataset ()
1057
+ rwv_map = pydicom . Dataset ()
1046
1058
rwv_map .RealWorldValueSlope = 10.0
1047
1059
rwv_map .RealWorldValueIntercept = - 5.0
1048
- rwv_map .MeasurementUnitsCodeSequence = [Dataset ()]
1060
+ rwv_map .MeasurementUnitsCodeSequence = [pydicom . Dataset ()]
1049
1061
rwv_map .MeasurementUnitsCodeSequence [0 ].CodeMeaning = '%'
1050
1062
shared .RealWorldValueMappingSequence = [rwv_map ]
1051
1063
assert_array_equal (data * 10 - 5 , MFW (fake_mf )._scale_data (data ))
@@ -1057,7 +1069,7 @@ def test_philips_scale_data(self):
1057
1069
fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 0 ))
1058
1070
# Simplest case is all frames have same (valid) scale factor
1059
1071
for frame in fake_mf .PerFrameFunctionalGroupsSequence :
1060
- pix_trans = Dataset ()
1072
+ pix_trans = pydicom . Dataset ()
1061
1073
pix_trans .RescaleSlope = 2.5
1062
1074
pix_trans .RescaleIntercept = - 4
1063
1075
pix_trans .RescaleType = 'mrad'
@@ -1084,10 +1096,10 @@ def test_philips_scale_data(self):
1084
1096
)
1085
1097
# Again RWV scale factors take precedence
1086
1098
for frame_idx , frame in enumerate (fake_mf .PerFrameFunctionalGroupsSequence ):
1087
- rwv_map = Dataset ()
1099
+ rwv_map = pydicom . Dataset ()
1088
1100
rwv_map .RealWorldValueSlope = 14.0 - frame_idx
1089
1101
rwv_map .RealWorldValueIntercept = 5.0
1090
- rwv_map .MeasurementUnitsCodeSequence = [Dataset ()]
1102
+ rwv_map .MeasurementUnitsCodeSequence = [pydicom . Dataset ()]
1091
1103
rwv_map .MeasurementUnitsCodeSequence [0 ].CodeMeaning = '%'
1092
1104
frame .RealWorldValueMappingSequence = [rwv_map ]
1093
1105
assert_array_equal (
0 commit comments