5
5
import gzip
6
6
from hashlib import sha1
7
7
from decimal import Decimal
8
- from copy import copy
8
+ from copy import copy
9
9
10
10
import numpy as np
11
11
@@ -379,54 +379,54 @@ class Fake(object):
379
379
setattr (fake_frame , seq_name , [fake_element ])
380
380
frames .append (fake_frame )
381
381
return frames
382
-
383
-
384
- def fake_shape_dependents (div_seq , sid_seq = None , sid_dim = None ):
385
- """ Make a fake dictionary of data that ``image_shape`` is dependent on.
386
-
387
- Parameters
388
- ----------
389
- div_seq : list of tuples
390
- list of values to use for the `DimensionIndexValues` of each frame.
391
- sid_seq : list of int
392
- list of values to use for the `StackID` of each frame.
393
- sid_dim : int
394
- the index of the column in 'div_seq' to use as 'sid_seq'
395
- """
396
- class DimIdxSeqElem (object ):
397
- def __init__ (self , dip = (0 , 0 ), fgp = None ):
398
- self .DimensionIndexPointer = dip
399
- if fgp is not None :
400
- self .FunctionalGroupPointer = fgp
401
- class FrmContSeqElem (object ):
402
- def __init__ (self , div , sid ):
403
- self .DimensionIndexValues = div
404
- self .StackID = sid
405
- class PerFrmFuncGrpSeqElem (object ):
406
- def __init__ (self , div , sid ):
407
- self .FrameContentSequence = [FrmContSeqElem (div , sid )]
408
- # if no StackID values passed in then use the values at index 'sid_dim' in
409
- # the value for DimensionIndexValues for it
410
- if sid_seq is None :
411
- if sid_dim is None :
412
- sid_dim = 0
413
- sid_seq = [div [sid_dim ] for div in div_seq ]
414
- # create the DimensionIndexSequence
415
- num_of_frames = len (div_seq )
416
- dim_idx_seq = [DimIdxSeqElem ()] * num_of_frames
417
- # add an entry for StackID into the DimensionIndexSequence
418
- if sid_dim is not None :
419
- sid_tag = pydicom .datadict .tag_for_name ('StackID' )
420
- fcs_tag = pydicom .datadict .tag_for_name ('FrameContentSequence' )
421
- dim_idx_seq [sid_dim ] = DimIdxSeqElem (sid_tag , fcs_tag )
422
- # create the PerFrameFunctionalGroupsSequence
423
- frames = [PerFrmFuncGrpSeqElem (div , sid )
424
- for div , sid in zip (div_seq , sid_seq )]
425
- return {'NumberOfFrames' : num_of_frames ,
426
- 'DimensionIndexSequence' : dim_idx_seq ,
427
- 'PerFrameFunctionalGroupsSequence' : frames }
428
-
429
-
382
+
383
+
384
+ def fake_shape_dependents (div_seq , sid_seq = None , sid_dim = None ):
385
+ """ Make a fake dictionary of data that ``image_shape`` is dependent on.
386
+
387
+ Parameters
388
+ ----------
389
+ div_seq : list of tuples
390
+ list of values to use for the `DimensionIndexValues` of each frame.
391
+ sid_seq : list of int
392
+ list of values to use for the `StackID` of each frame.
393
+ sid_dim : int
394
+ the index of the column in 'div_seq' to use as 'sid_seq'
395
+ """
396
+ class DimIdxSeqElem (object ):
397
+ def __init__ (self , dip = (0 , 0 ), fgp = None ):
398
+ self .DimensionIndexPointer = dip
399
+ if fgp is not None :
400
+ self .FunctionalGroupPointer = fgp
401
+ class FrmContSeqElem (object ):
402
+ def __init__ (self , div , sid ):
403
+ self .DimensionIndexValues = div
404
+ self .StackID = sid
405
+ class PerFrmFuncGrpSeqElem (object ):
406
+ def __init__ (self , div , sid ):
407
+ self .FrameContentSequence = [FrmContSeqElem (div , sid )]
408
+ # if no StackID values passed in then use the values at index 'sid_dim' in
409
+ # the value for DimensionIndexValues for it
410
+ if sid_seq is None :
411
+ if sid_dim is None :
412
+ sid_dim = 0
413
+ sid_seq = [div [sid_dim ] for div in div_seq ]
414
+ # create the DimensionIndexSequence
415
+ num_of_frames = len (div_seq )
416
+ dim_idx_seq = [DimIdxSeqElem ()] * num_of_frames
417
+ # add an entry for StackID into the DimensionIndexSequence
418
+ if sid_dim is not None :
419
+ sid_tag = pydicom .datadict .tag_for_name ('StackID' )
420
+ fcs_tag = pydicom .datadict .tag_for_name ('FrameContentSequence' )
421
+ dim_idx_seq [sid_dim ] = DimIdxSeqElem (sid_tag , fcs_tag )
422
+ # create the PerFrameFunctionalGroupsSequence
423
+ frames = [PerFrmFuncGrpSeqElem (div , sid )
424
+ for div , sid in zip (div_seq , sid_seq )]
425
+ return {'NumberOfFrames' : num_of_frames ,
426
+ 'DimensionIndexSequence' : dim_idx_seq ,
427
+ 'PerFrameFunctionalGroupsSequence' : frames }
428
+
429
+
430
430
class TestMultiFrameWrapper (TestCase ):
431
431
# Test MultiframeWrapper
432
432
MINIMAL_MF = {
@@ -435,6 +435,7 @@ class TestMultiFrameWrapper(TestCase):
435
435
'SharedFunctionalGroupsSequence' : [None ]}
436
436
WRAPCLASS = didw .MultiframeWrapper
437
437
438
+ @dicom_test
438
439
def test_shape (self ):
439
440
# Check the shape algorithm
440
441
fake_mf = copy (self .MINIMAL_MF )
@@ -452,65 +453,65 @@ def test_shape(self):
452
453
assert_raises (AssertionError , getattr , dw , 'image_shape' )
453
454
fake_mf ['NumberOfFrames' ] = 4
454
455
# PerFrameFunctionalGroupsSequence does not match NumberOfFrames
455
- assert_raises (AssertionError , getattr , dw , 'image_shape' )
456
- # check 3D shape when StackID index is 0
457
- div_seq = ((1 , 1 ), (1 , 2 ), (1 , 3 ), (1 , 4 ))
458
- fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 0 ))
456
+ assert_raises (AssertionError , getattr , dw , 'image_shape' )
457
+ # check 3D shape when StackID index is 0
458
+ div_seq = ((1 , 1 ), (1 , 2 ), (1 , 3 ), (1 , 4 ))
459
+ fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 0 ))
459
460
assert_equal (MFW (fake_mf ).image_shape , (32 , 64 , 4 ))
460
461
# Check stack number matching when StackID index is 0
461
462
div_seq = ((1 , 1 ), (1 , 2 ), (1 , 3 ), (2 , 4 ))
462
- fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 0 ))
463
+ fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 0 ))
463
464
assert_raises (didw .WrapperError , getattr , MFW (fake_mf ), 'image_shape' )
464
- # Make some fake frame data for 4D when StackID index is 0
465
+ # Make some fake frame data for 4D when StackID index is 0
465
466
div_seq = ((1 , 1 , 1 ), (1 , 2 , 1 ), (1 , 1 , 2 ), (1 , 2 , 2 ),
466
467
(1 , 1 , 3 ), (1 , 2 , 3 ))
467
- fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 0 ))
468
+ fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 0 ))
468
469
assert_equal (MFW (fake_mf ).image_shape , (32 , 64 , 2 , 3 ))
469
470
# Check stack number matching for 4D when StackID index is 0
470
471
div_seq = ((1 , 1 , 1 ), (1 , 2 , 1 ), (1 , 1 , 2 ), (1 , 2 , 2 ),
471
472
(1 , 1 , 3 ), (2 , 2 , 3 ))
472
- fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 0 ))
473
+ fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 0 ))
473
474
assert_raises (didw .WrapperError , getattr , MFW (fake_mf ), 'image_shape' )
474
475
# Check indices can be non-contiguous when StackID index is 0
475
476
div_seq = ((1 , 1 , 1 ), (1 , 2 , 1 ), (1 , 1 , 3 ), (1 , 2 , 3 ))
476
- fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 0 ))
477
+ fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 0 ))
477
478
assert_equal (MFW (fake_mf ).image_shape , (32 , 64 , 2 , 2 ))
478
479
# Check indices can include zero when StackID index is 0
479
480
div_seq = ((1 , 1 , 0 ), (1 , 2 , 0 ), (1 , 1 , 3 ), (1 , 2 , 3 ))
480
- fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 0 ))
481
+ fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 0 ))
481
482
assert_equal (MFW (fake_mf ).image_shape , (32 , 64 , 2 , 2 ))
482
- # check 3D shape when there is no StackID index
483
+ # check 3D shape when there is no StackID index
483
484
div_seq = ((1 ,), (2 ,), (3 ,), (4 ,))
484
485
sid_seq = (1 , 1 , 1 , 1 )
485
- fake_mf .update (fake_shape_dependents (div_seq , sid_seq = sid_seq ))
486
+ fake_mf .update (fake_shape_dependents (div_seq , sid_seq = sid_seq ))
486
487
assert_equal (MFW (fake_mf ).image_shape , (32 , 64 , 4 ))
487
488
# check 3D stack number matching when there is no StackID index
488
489
div_seq = ((1 ,), (2 ,), (3 ,), (4 ,))
489
490
sid_seq = (1 , 1 , 1 , 2 )
490
- fake_mf .update (fake_shape_dependents (div_seq , sid_seq = sid_seq ))
491
+ fake_mf .update (fake_shape_dependents (div_seq , sid_seq = sid_seq ))
491
492
assert_raises (didw .WrapperError , getattr , MFW (fake_mf ), 'image_shape' )
492
- # check 4D shape when there is no StackID index
493
+ # check 4D shape when there is no StackID index
493
494
div_seq = ((1 , 1 ), (2 , 1 ), (1 , 2 ), (2 , 2 ), (1 , 3 ), (2 , 3 ))
494
495
sid_seq = (1 , 1 , 1 , 1 , 1 , 1 )
495
- fake_mf .update (fake_shape_dependents (div_seq , sid_seq = sid_seq ))
496
+ fake_mf .update (fake_shape_dependents (div_seq , sid_seq = sid_seq ))
496
497
assert_equal (MFW (fake_mf ).image_shape , (32 , 64 , 2 , 3 ))
497
498
# check 4D stack number matching when there is no StackID index
498
499
div_seq = ((1 , 1 ), (2 , 1 ), (1 , 2 ), (2 , 2 ), (1 , 3 ), (2 , 3 ))
499
500
sid_seq = (1 , 1 , 1 , 1 , 1 , 2 )
500
- fake_mf .update (fake_shape_dependents (div_seq , sid_seq = sid_seq ))
501
+ fake_mf .update (fake_shape_dependents (div_seq , sid_seq = sid_seq ))
501
502
assert_raises (didw .WrapperError , getattr , MFW (fake_mf ), 'image_shape' )
502
- # check 3D shape when StackID index is 1
503
+ # check 3D shape when StackID index is 1
503
504
div_seq = ((1 , 1 ), (2 , 1 ), (3 , 1 ), (4 , 1 ))
504
- fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 1 ))
505
+ fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 1 ))
505
506
assert_equal (MFW (fake_mf ).image_shape , (32 , 64 , 4 ))
506
507
# Check stack number matching when StackID index is 1
507
- div_seq = ((1 , 1 ), (2 , 1 ), (3 , 2 ), (4 , 1 ))
508
- fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 1 ))
508
+ div_seq = ((1 , 1 ), (2 , 1 ), (3 , 2 ), (4 , 1 ))
509
+ fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 1 ))
509
510
assert_raises (didw .WrapperError , getattr , MFW (fake_mf ), 'image_shape' )
510
- # Make some fake frame data for 4D when StackID index is 1
511
+ # Make some fake frame data for 4D when StackID index is 1
511
512
div_seq = ((1 , 1 , 1 ), (2 , 1 , 1 ), (1 , 1 , 2 ), (2 , 1 , 2 ),
512
513
(1 , 1 , 3 ), (2 , 1 , 3 ))
513
- fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 1 ))
514
+ fake_mf .update (fake_shape_dependents (div_seq , sid_dim = 1 ))
514
515
assert_equal (MFW (fake_mf ).image_shape , (32 , 64 , 2 , 3 ))
515
516
516
517
def test_iop (self ):
@@ -614,6 +615,7 @@ def test_data_real(self):
614
615
assert_equal (sha1 (dat_str ).hexdigest (),
615
616
'149323269b0af92baa7508e19ca315240f77fa8c' )
616
617
618
+ @dicom_test
617
619
def test_data_fake (self ):
618
620
# Test algorithm for get_data
619
621
fake_mf = copy (self .MINIMAL_MF )
@@ -627,9 +629,9 @@ def test_data_fake(self):
627
629
assert_raises (didw .WrapperError , dw .get_data )
628
630
# Make shape and indices
629
631
fake_mf ['Rows' ] = 2
630
- fake_mf ['Columns' ] = 3
631
- dim_idxs = ((1 , 1 ), (1 , 2 ), (1 , 3 ), (1 , 4 ))
632
- fake_mf .update (fake_shape_dependents (dim_idxs , sid_dim = 0 ))
632
+ fake_mf ['Columns' ] = 3
633
+ dim_idxs = ((1 , 1 ), (1 , 2 ), (1 , 3 ), (1 , 4 ))
634
+ fake_mf .update (fake_shape_dependents (dim_idxs , sid_dim = 0 ))
633
635
assert_equal (MFW (fake_mf ).image_shape , (2 , 3 , 4 ))
634
636
# Still fails - no data
635
637
assert_raises (didw .WrapperError , dw .get_data )
@@ -644,9 +646,9 @@ def test_data_fake(self):
644
646
fake_mf ['RescaleSlope' ] = 2.0
645
647
fake_mf ['RescaleIntercept' ] = - 1
646
648
assert_array_equal (MFW (fake_mf ).get_data (), data * 2.0 - 1 )
647
- # Check slice sorting
648
- dim_idxs = ((1 , 4 ), (1 , 2 ), (1 , 3 ), (1 , 1 ))
649
- fake_mf .update (fake_shape_dependents (dim_idxs , sid_dim = 0 ))
649
+ # Check slice sorting
650
+ dim_idxs = ((1 , 4 ), (1 , 2 ), (1 , 3 ), (1 , 1 ))
651
+ fake_mf .update (fake_shape_dependents (dim_idxs , sid_dim = 0 ))
650
652
sorted_data = data [..., [3 , 1 , 2 , 0 ]]
651
653
fake_mf ['pixel_array' ] = np .rollaxis (sorted_data , 2 )
652
654
assert_array_equal (MFW (fake_mf ).get_data (), data * 2.0 - 1 )
@@ -668,7 +670,7 @@ def test_data_fake(self):
668
670
[1 , 2 , 1 , 2 ],
669
671
[1 , 3 , 1 , 2 ],
670
672
[1 , 1 , 1 , 2 ]]
671
- fake_mf .update (fake_shape_dependents (dim_idxs , sid_dim = 0 ))
673
+ fake_mf .update (fake_shape_dependents (dim_idxs , sid_dim = 0 ))
672
674
shape = (2 , 3 , 4 , 2 , 2 )
673
675
data = np .arange (np .prod (shape )).reshape (shape )
674
676
sorted_data = data .reshape (shape [:2 ] + (- 1 ,), order = 'F' )
0 commit comments