|
37 | 37 | has_tiff = has_tiff and has_codec |
38 | 38 |
|
39 | 39 | TESTS_PATH = Path(__file__).parents[2] |
40 | | -WSI_GENERIC_TIFF_KEY = "wsi_generic_tiff" |
| 40 | +WSI_GENERIC_TIFF_KEY = "wsi_generic_tiff" # TIFF image with incorrect mpp values |
41 | 41 | WSI_GENERIC_TIFF_PATH = os.path.join(TESTS_PATH, "testing_data", f"temp_{WSI_GENERIC_TIFF_KEY}.tiff") |
42 | 42 |
|
| 43 | +WSI_GENERIC_TIFF_CORRECT_MPP_KEY = "wsi_generic_tiff_corrected" |
| 44 | +WSI_GENERIC_TIFF_CORRECT_MPP_PATH = os.path.join(TESTS_PATH, "testing_data", f"temp_{WSI_GENERIC_TIFF_CORRECT_MPP_KEY}.tiff") |
| 45 | + |
43 | 46 | WSI_APERIO_SVS_KEY = "wsi_aperio_svs" |
44 | 47 | WSI_APERIO_SVS_PATH = os.path.join(TESTS_PATH, "testing_data", f"temp_{WSI_APERIO_SVS_KEY}.svs") |
45 | 48 |
|
|
256 | 259 | "cpu", |
257 | 260 | ] |
258 | 261 |
|
| 262 | +TEST_CASE_SVS_MPP_1 = [ |
| 263 | + WSI_APERIO_SVS_PATH, |
| 264 | + {"mpp": (4.0, 4.0), "atol": 0.0, "rtol": 0.1}, |
| 265 | + {"openslide": (4106, 5739, 4), "cucim": (4106, 5739, 3)}, |
| 266 | +] |
| 267 | + |
| 268 | +TEST_CASE_SVS_MPP_2 = [ |
| 269 | + WSI_APERIO_SVS_PATH, |
| 270 | + {"mpp": (8.0, 8.0)}, |
| 271 | + {"openslide": (2057, 2875, 4), "cucim": (2057, 2875, 3)}, |
| 272 | +] |
| 273 | + |
| 274 | +TEST_CASE_SVS_MPP_3 = [ |
| 275 | + WSI_APERIO_SVS_PATH, |
| 276 | + {"mpp": (3.0, 3.0)}, |
| 277 | + {"openslide": (5475, 7652, 4), "cucim": (5475, 7652, 3)}, |
| 278 | +] |
| 279 | + |
| 280 | +TEST_CASE_SVS_MPP_4 = [ |
| 281 | + WSI_APERIO_SVS_PATH, |
| 282 | + {"mpp": (1.5, 1.5)}, |
| 283 | + {"openslide": (10949, 15303, 4), "cucim": (10949, 15303, 3)}, |
| 284 | +] |
| 285 | + |
| 286 | +TEST_CASE_TIFF_MPP_1 = [ |
| 287 | + WSI_GENERIC_TIFF_CORRECT_MPP_PATH, |
| 288 | + {"mpp": (4.0, 4.0), "atol": 0.0, "rtol": 0.1}, |
| 289 | + {"openslide": (4114, 5750, 4), "cucim": (4114, 5750, 3), "tifffile": (4106, 5739, 3)}, |
| 290 | +] |
| 291 | + |
| 292 | +TEST_CASE_TIFF_MPP_2 = [ |
| 293 | + WSI_GENERIC_TIFF_CORRECT_MPP_PATH, |
| 294 | + {"mpp": (8.0, 8.0)}, |
| 295 | + {"openslide": (2057, 2875, 4), "cucim": (2057, 2875, 3), "tifffile": (2053, 2869, 3)}, |
| 296 | +] |
| 297 | + |
| 298 | +TEST_CASE_TIFF_MPP_3 = [ |
| 299 | + WSI_GENERIC_TIFF_CORRECT_MPP_PATH, |
| 300 | + {"mpp": (3.0, 3.0)}, |
| 301 | + {"openslide": (5475, 7652, 4), "cucim": (5475, 7652, 3), "tifffile": (5475, 7651, 3)}, |
| 302 | +] |
| 303 | + |
| 304 | +TEST_CASE_TIFF_MPP_4 = [ |
| 305 | + WSI_GENERIC_TIFF_CORRECT_MPP_PATH, |
| 306 | + {"mpp": (1.5, 1.5)}, |
| 307 | + {"openslide": (10949, 15303, 4), "cucim": (10949, 15303, 3), "tifffile": (10949, 15303, 3)}, |
| 308 | +] |
| 309 | + |
259 | 310 | TEST_CASE_DEVICE_2 = [ |
260 | 311 | WSI_GENERIC_TIFF_PATH, |
261 | 312 | {"level": 8, "dtype": torch.float32, "device": "cuda"}, |
@@ -407,17 +458,45 @@ class WSIReaderTests: |
407 | 458 | class Tests(unittest.TestCase): |
408 | 459 | backend = None |
409 | 460 |
|
410 | | - @parameterized.expand([TEST_CASE_WHOLE_0]) |
411 | | - def test_read_whole_image(self, file_path, level, expected_shape): |
412 | | - reader = WSIReader(self.backend, level=level) |
413 | | - with reader.read(file_path) as img_obj: |
414 | | - img, meta = reader.get_data(img_obj) |
415 | | - self.assertTupleEqual(img.shape, expected_shape) |
416 | | - self.assertEqual(meta["backend"], self.backend) |
417 | | - self.assertEqual(meta[WSIPatchKeys.PATH].lower(), str(os.path.abspath(file_path)).lower()) |
418 | | - self.assertEqual(meta[WSIPatchKeys.LEVEL], level) |
419 | | - assert_allclose(meta[WSIPatchKeys.SIZE], expected_shape[1:], type_test=False) |
420 | | - assert_allclose(meta[WSIPatchKeys.LOCATION], (0, 0), type_test=False) |
| 461 | + # @parameterized.expand([TEST_CASE_WHOLE_0]) |
| 462 | + # def test_read_whole_image(self, file_path, level, expected_shape): |
| 463 | + # reader = WSIReader(self.backend, level=level) |
| 464 | + # with reader.read(file_path) as img_obj: |
| 465 | + # img, meta = reader.get_data(img_obj) |
| 466 | + # self.assertTupleEqual(img.shape, expected_shape) |
| 467 | + # self.assertEqual(meta["backend"], self.backend) |
| 468 | + # self.assertEqual(meta[WSIPatchKeys.PATH].lower(), str(os.path.abspath(file_path)).lower()) |
| 469 | + # self.assertEqual(meta[WSIPatchKeys.LEVEL], level) |
| 470 | + # assert_allclose(meta[WSIPatchKeys.SIZE], expected_shape[1:], type_test=False) |
| 471 | + # assert_allclose(meta[WSIPatchKeys.LOCATION], (0, 0), type_test=False) |
| 472 | + |
| 473 | + @parameterized.expand( |
| 474 | + [ |
| 475 | + TEST_CASE_SVS_MPP_1, |
| 476 | + TEST_CASE_SVS_MPP_2, |
| 477 | + TEST_CASE_SVS_MPP_3, |
| 478 | + TEST_CASE_SVS_MPP_4, |
| 479 | + TEST_CASE_TIFF_MPP_1, |
| 480 | + TEST_CASE_TIFF_MPP_2, |
| 481 | + TEST_CASE_TIFF_MPP_3, |
| 482 | + TEST_CASE_TIFF_MPP_4 |
| 483 | + ] |
| 484 | + ) |
| 485 | + def test_get_wsi_at_mpp(self, file_path, func_kwargs, expected_shape): |
| 486 | + # Tifffile backend cannot read MPP from the SVS file, so skip. |
| 487 | + if self.backend == "tifffile" and file_path == WSI_APERIO_SVS_PATH: |
| 488 | + self.skipTest("TiffFileWSIReader cannot extract MPP from SVS files.") |
| 489 | + |
| 490 | + # Look up the expected shape for the current backend |
| 491 | + if self.backend not in expected_shape: |
| 492 | + self.skipTest(f"No expected shape defined for backend '{self.backend}' in this test case.") |
| 493 | + expected_shape = expected_shape[self.backend] |
| 494 | + |
| 495 | + reader = WSIReader(self.backend) |
| 496 | + with reader.read(file_path) as wsi: |
| 497 | + wsi_arr = reader.get_wsi_at_mpp(wsi, **func_kwargs) |
| 498 | + |
| 499 | + self.assertTupleEqual(wsi_arr.shape, expected_shape) |
421 | 500 |
|
422 | 501 | @parameterized.expand( |
423 | 502 | [ |
|
0 commit comments