File: bench_handler_numpy.py

package info (click to toggle)
pydicom 2.4.3-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,700 kB
  • sloc: python: 129,337; makefile: 198; sh: 121
file content (234 lines) | stat: -rw-r--r-- 7,943 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# Copyright 2008-2018 pydicom authors. See LICENSE file for details.
"""Benchmarks for the numpy_handler module.

Requires asv and numpy.
"""

from platform import python_implementation
from tempfile import TemporaryFile

import numpy as np

from pydicom import dcmread
from pydicom.data import get_testdata_file
from pydicom.dataset import Dataset, FileMetaDataset
from pydicom.pixel_data_handlers.numpy_handler import (
    get_pixeldata, unpack_bits, pack_bits
)
from pydicom.uid import ExplicitVRLittleEndian, generate_uid

# 1/1, 1 sample/pixel, 1 frame
EXPL_1_1_1F = get_testdata_file("liver_1frame.dcm")
# 1/1, 1 sample/pixel, 3 frame
EXPL_1_1_3F = get_testdata_file("liver.dcm")
# 8/8, 1 sample/pixel, 1 frame
EXPL_8_1_1F = get_testdata_file("OBXXXX1A.dcm")
# 8/8, 1 sample/pixel, 2 frame
EXPL_8_1_2F = get_testdata_file("OBXXXX1A_2frame.dcm")
# 8/8, 3 sample/pixel, 1 frame
EXPL_8_3_1F = get_testdata_file("SC_rgb.dcm")
# 8/8, 3 sample/pixel, 1 frame, YBR_FULL_422
EXPL_8_3_1F_YBR422 = get_testdata_file('SC_ybr_full_422_uncompressed.dcm')
# 8/8, 3 sample/pixel, 2 frame
EXPL_8_3_2F = get_testdata_file("SC_rgb_2frame.dcm")
# 16/16, 1 sample/pixel, 1 frame
EXPL_16_1_1F = get_testdata_file("MR_small.dcm")
# 16/12, 1 sample/pixel, 10 frame
EXPL_16_1_10F = get_testdata_file("emri_small.dcm")
# 16/16, 3 sample/pixel, 1 frame
EXPL_16_3_1F = get_testdata_file("SC_rgb_16bit.dcm")
# 16/16, 3 sample/pixel, 2 frame
EXPL_16_3_2F = get_testdata_file("SC_rgb_16bit_2frame.dcm")
# 32/32, 1 sample/pixel, 1 frame
IMPL_32_1_1F = get_testdata_file("rtdose_1frame.dcm")
# 32/32, 1 sample/pixel, 15 frame
IMPL_32_1_15F = get_testdata_file("rtdose.dcm")
# 32/32, 3 sample/pixel, 1 frame
EXPL_32_3_1F = get_testdata_file("SC_rgb_32bit.dcm")
# 32/32, 3 sample/pixel, 2 frame
EXPL_32_3_2F = get_testdata_file("SC_rgb_32bit_2frame.dcm")


def _create_temporary_dataset(shape=(100, 1024, 1024, 3), bit_depth=16):
    """Function to create a temporary dataset for use in testing.

    Parameters
    ----------
    shape : 4-tuple
        The (frames, rows, columns, channels) of the test dataset.
    bit_depth : int
        The BitsAllocated value to use for the dataset, one of 8, 16, 32, 64.

    Returns
    -------
    tempfile.TemporaryFile
        A created DICOM File Format conformant dataset.
    """
    ds = Dataset()
    ds.is_little_endian = True
    ds.is_implicit_VR = False
    ds.file_meta = FileMetaDataset()
    ds.file_meta.TransferSyntaxUID = ExplicitVRLittleEndian
    ds.SOPClassUID = '1.2.3.4'
    ds.SOPInstanceUID = generate_uid()
    ds.BitsAllocated = bit_depth
    ds.PixelRepresentation = 0
    ds.PlanarConfiguration = 0
    ds.Rows = shape[1]
    ds.Columns = shape[2]
    ds.NumberOfFrames = shape[0]
    ds.SamplesPerPixel = shape[3]
    if shape[3] == 1:
        ds.PhotometricInterpretation = 'MONOCHROME2'
    elif shape[3] == 3:
        ds.PhotometricInterpretation = 'RGB'

    arr = np.zeros(shape, dtype='uint{}'.format(bit_depth))
    ds.PixelData = arr.tobytes()

    if len(ds.PixelData) % 2:
        ds.PixelData += b'\x00'

    tfile = TemporaryFile(mode='w+b')
    ds.save_as(tfile, write_like_original=False)
    tfile.seek(0)

    return tfile


class TimeGetPixelData_LargeDataset:
    """Time tests for numpy_handler.get_pixeldata with large datasets."""
    def setup(self):
        """Setup the tests."""
        self.no_runs = 100

        self.ds_16_3_100 = dcmread(_create_temporary_dataset())

    def time_large_dataset(self):
        """Time reading pixel data from a large dataset."""
        for ii in range(self.no_runs):
            get_pixeldata(self.ds_16_3_100)


class TimeGetPixelData:
    """Time tests for numpy_handler.get_pixeldata."""
    def setup(self):
        """Setup the tests."""
        self.no_runs = 100

        self.ds_1_1_1 = dcmread(EXPL_1_1_1F)
        self.ds_1_1_3 = dcmread(EXPL_1_1_3F)
        self.ds_8_1_1 = dcmread(EXPL_8_1_1F)
        self.ds_8_1_2 = dcmread(EXPL_8_1_2F)
        self.ds_8_3_1 = dcmread(EXPL_8_3_1F)
        self.ds_8_3_2 = dcmread(EXPL_8_3_2F)
        self.ds_16_1_1 = dcmread(EXPL_16_1_1F)
        self.ds_16_1_10 = dcmread(EXPL_16_1_10F)
        self.ds_16_3_1 = dcmread(EXPL_16_3_1F)
        self.ds_16_3_2 = dcmread(EXPL_16_3_2F)
        self.ds_32_1_1 = dcmread(IMPL_32_1_1F)
        self.ds_32_1_15 = dcmread(IMPL_32_1_15F)
        self.ds_32_3_1 = dcmread(EXPL_32_3_1F)
        self.ds_32_3_2 = dcmread(EXPL_32_3_2F)
        self.ds_ybr_422 = dcmread(EXPL_8_3_1F_YBR422)

    def time_1bit_1sample_1frame(self):
        """Time retrieval of 1-bit, 1 sample/pixel, 1 frame."""
        no_runs = self.no_runs
        if 'PyPy' in python_implementation():
            no_runs = 1

        for ii in range(no_runs):
            get_pixeldata(self.ds_1_1_1)

    def time_1bit_1sample_3frame(self):
        """Time retrieval of 1-bit, 1 sample/pixel, 3 frame."""
        no_runs = self.no_runs
        if 'PyPy' in python_implementation():
            no_runs = 1

        for ii in range(no_runs):
            get_pixeldata(self.ds_1_1_3)

    def time_8bit_1sample_1frame(self):
        """Time retrieval of 8-bit, 1 sample/pixel, 1 frame."""
        for ii in range(self.no_runs):
            get_pixeldata(self.ds_8_1_1)

    def time_8bit_1sample_2frame(self):
        """Time retrieval of 8-bit, 1 sample/pixel, 2 frame."""
        for ii in range(self.no_runs):
            get_pixeldata(self.ds_8_1_2)

    def time_8bit_3sample_1frame(self):
        """Time retrieval of 8-bit, 3 sample/pixel, 1 frame."""
        for ii in range(self.no_runs):
            get_pixeldata(self.ds_8_3_1)

    def time_8bit_3sample_2frame(self):
        """Time retrieval of 8-bit, 3 sample/pixel, 2 frame."""
        for ii in range(self.no_runs):
            get_pixeldata(self.ds_8_3_2)

    def time_16bit_1sample_1frame(self):
        """Time retrieval of 16-bit, 1 sample/pixel, 1 frame."""
        for ii in range(self.no_runs):
            get_pixeldata(self.ds_16_1_1)

    def time_16bit_1sample_10frame(self):
        """Time retrieval of 16-bit, 1 sample/pixel, 10 frame."""
        for ii in range(self.no_runs):
            get_pixeldata(self.ds_16_1_10)

    def time_16bit_3sample_1frame(self):
        """Time retrieval of 16-bit, 3 sample/pixel, 1 frame."""
        for ii in range(self.no_runs):
            get_pixeldata(self.ds_16_3_1)

    def time_16bit_3sample_2frame(self):
        """Time retrieval of 16-bit, 3 sample/pixel, 2 frame."""
        for ii in range(self.no_runs):
            get_pixeldata(self.ds_16_3_2)

    def time_32bit_1sample_1frame(self):
        """Time retrieval of 32-bit, 1 sample/pixel, 1 frame."""
        for ii in range(self.no_runs):
            get_pixeldata(self.ds_32_1_1)

    def time_32bit_1sample_15frame(self):
        """Time retrieval of 32-bit, 1 sample/pixel, 15 frame."""
        for ii in range(self.no_runs):
            get_pixeldata(self.ds_32_1_15)

    def time_32bit_3sample_1frame(self):
        """Time retrieval of 32-bit, 3 sample/pixel, 1 frame."""
        for ii in range(self.no_runs):
            get_pixeldata(self.ds_32_3_1)

    def time_32bit_3sample_2frame(self):
        """Time retrieval of 32-bit, 3 sample/pixel, 2 frame."""
        for ii in range(self.no_runs):
            get_pixeldata(self.ds_32_3_2)

    def time_ybr_422(self):
        """Time retrieval of YBR_FULL_422 data."""
        for ii in range(self.no_runs):
            get_pixeldata(self.ds_ybr_422)


class TimePackUnpack:
    def setup(self):
        """Setup the tests."""
        self.no_runs = 100
        self.ds_1_1_1 = dcmread(EXPL_1_1_1F)
        self.unpacked = unpack_bits(self.ds_1_1_1.PixelData)

    def time_unpack(self):
        """Time unpacking"""
        for ii in range(self.no_runs):
            unpack_bits(self.ds_1_1_1.PixelData)

    def time_pack(self):
        """Time packing."""
        for ii in range(self.no_runs):
            pack_bits(self.unpacked)