Skip to content

Commit 7ffd22e

Browse files
committed
Added a test to compare decoded data between CPU and GPU decoding if deps are installed
Signed-off-by: M Q <mingmelvinq@nvidia.com>
1 parent 65c1161 commit 7ffd22e

1 file changed

Lines changed: 83 additions & 0 deletions

File tree

tests/data/test_nvimgcodec_pydicom_reader.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import unittest
1616
from unittest.mock import patch
1717

18+
import numpy as np
19+
1820
from monai.data.image_reader import DICOM_READER_ENV_MAP, get_preferred_dicom_reader_key, is_dicom_path
1921
from monai.transforms import LoadImage
2022
from monai.transforms.io.array import SUPPORTED_READERS, get_default_reader_registration_order
@@ -216,6 +218,87 @@ def test_is_nvimgcodec_available_with_cuda(self):
216218

217219

218220
class TestNvImgCodecPydicomReaderIntegration(unittest.TestCase):
221+
@SkipIfNoModule("pydicom")
222+
@SkipIfNoModule("pylibjpeg")
223+
@SkipIfNoModule("openjpeg") # pylibjpeg-openjpeg
224+
@SkipIfNoModule("jpeg_ls") # pyjpegls
225+
@SkipIfNoModule("gdcm") # python-gdcm
226+
@SkipIfNoModule("nvidia.nvimgcodec.tools.dicom.pydicom_plugin")
227+
def test_pixels_match_pydicom_reader(self):
228+
from pydicom import dcmread
229+
from pydicom.data import get_testdata_file
230+
231+
from monai.data import NvImgCodecPydicomReader, PydicomReader
232+
from monai.data.nvimgcodec_pydicom_plugin import (
233+
NVIMGCODEC_PLUGIN_LABEL,
234+
SUPPORTED_DECODER_CLASSES,
235+
SUPPORTED_TRANSFER_SYNTAXES,
236+
is_nvimgcodec_available,
237+
unregister_as_decoder_plugin,
238+
)
239+
240+
if not is_nvimgcodec_available():
241+
self.skipTest("nvImageCodec with CUDA support is not available.")
242+
243+
# One bundled pydicom decoder test file for each nvImageCodec-supported
244+
# transfer syntax for which pydicom ships a local sample.
245+
test_files = (
246+
"SC_rgb_jpeg_lossy_gdcm.dcm", # JPEG Baseline
247+
"SC_rgb_jpeg_gdcm.dcm", # JPEG Lossless SV1
248+
"MR_small_jp2klossless.dcm", # JPEG 2000 Lossless
249+
"JPEG2000.dcm", # JPEG 2000 Lossy
250+
)
251+
supported_uids = {str(uid) for uid in SUPPORTED_TRANSFER_SYNTAXES}
252+
tested = 0
253+
pydicom_failures = []
254+
255+
for filename in test_files:
256+
path = get_testdata_file(filename, download=False)
257+
self.assertIsNotNone(path, f"{filename} is not bundled with pydicom")
258+
transfer_syntax = str(dcmread(path, stop_before_pixels=True).file_meta.TransferSyntaxUID)
259+
if transfer_syntax not in supported_uids:
260+
continue
261+
262+
with self.subTest(filename=filename, transfer_syntax=transfer_syntax):
263+
# Decode the reference before registering nvImageCodec, ensuring
264+
# pydicom uses one of its standard compressed-pixel decoders.
265+
unregister_as_decoder_plugin()
266+
pydicom_reader = PydicomReader()
267+
try:
268+
expected, _ = pydicom_reader.get_data(pydicom_reader.read(path))
269+
except Exception as error:
270+
pydicom_failures.append(f"{filename}: {error}")
271+
continue
272+
273+
# Force nvImageCodec to be the only available plugin for its
274+
# supported decoder classes, then restore the registry afterward.
275+
old_available = {decoder.UID: decoder._available for decoder in SUPPORTED_DECODER_CLASSES}
276+
try:
277+
for decoder in SUPPORTED_DECODER_CLASSES:
278+
decoder._available = {}
279+
280+
nvimgcodec_reader = NvImgCodecPydicomReader()
281+
decoder = next(
282+
decoder for decoder in SUPPORTED_DECODER_CLASSES if str(decoder.UID) == transfer_syntax
283+
)
284+
self.assertIn(NVIMGCODEC_PLUGIN_LABEL, decoder._available)
285+
actual, _ = nvimgcodec_reader.get_data(nvimgcodec_reader.read(path))
286+
287+
self.assertEqual(actual.shape, expected.shape)
288+
np.testing.assert_allclose(actual, expected, rtol=0.0, atol=2)
289+
finally:
290+
unregister_as_decoder_plugin()
291+
for decoder in SUPPORTED_DECODER_CLASSES:
292+
decoder._available = old_available[decoder.UID]
293+
tested += 1
294+
295+
if not tested:
296+
failure_details = "; ".join(pydicom_failures)
297+
self.skipTest(
298+
"pydicom could not decode any bundled samples for nvImageCodec-supported transfer syntaxes."
299+
f" Failures: {failure_details}"
300+
)
301+
219302
@SkipIfNoModule("pydicom")
220303
@SkipIfNoModule("nvidia.nvimgcodec.tools.dicom.pydicom_plugin")
221304
def test_load_dicom_with_pydicom_env(self):

0 commit comments

Comments
 (0)