|
46 | 46 | MAX_NGFF_VERSION = Version("0.4") |
47 | 47 |
|
48 | 48 |
|
49 | | -def is_zarr_tiff_fsspec(path: Path) -> bool: |
50 | | - """Check if the input path ends with a .json extension. |
51 | | -
|
52 | | - Args: |
53 | | - path (Path): Path to the file to check. |
54 | | -
|
55 | | - # TODO extend logic and verify that json file is a fsspec tiff file |
56 | | - Returns: |
57 | | - bool: True if the file ends with a .json extension. |
58 | | - """ |
59 | | - path = Path(path) |
60 | | - return path.suffix.lower() in ".json" |
61 | | - |
62 | | - |
63 | 49 | def is_dicom(path: Path) -> bool: |
64 | 50 | """Check if the input is a DICOM file. |
65 | 51 |
|
@@ -378,16 +364,19 @@ def open( # noqa: PLR0911 |
378 | 364 | input_path = Path(input_img) |
379 | 365 | WSIReader.verify_supported_wsi(input_path) |
380 | 366 |
|
381 | | - if is_zarr_tiff_fsspec(input_path): |
382 | | - return FsspecJsonWSIReader(input_path, mpp=mpp, power=power) |
383 | | - |
384 | 367 | # Handle special cases first (DICOM, Zarr/NGFF, OME-TIFF) |
385 | 368 | if is_dicom(input_path): |
386 | 369 | return DICOMWSIReader(input_path, mpp=mpp, power=power) |
387 | 370 |
|
388 | 371 | _, _, suffixes = utils.misc.split_path_name_ext(input_path) |
389 | 372 | last_suffix = suffixes[-1] |
390 | 373 |
|
| 374 | + if WSIReader.is_valid_zarr_fsspec(input_path): |
| 375 | + msg = f"File {input_path} should be a valid fsspec JSON zarr v2." |
| 376 | + raise FileNotSupportedError(msg) |
| 377 | + |
| 378 | + return FsspecJsonWSIReader(input_path, mpp=mpp, power=power) |
| 379 | + |
391 | 380 | if last_suffix == ".db": |
392 | 381 | return AnnotationStoreReader(input_path, **kwargs) |
393 | 382 |
|
@@ -419,6 +408,49 @@ def open( # noqa: PLR0911 |
419 | 408 | # Try openslide last |
420 | 409 | return OpenSlideWSIReader(input_path, mpp=mpp, power=power) |
421 | 410 |
|
| 411 | + @staticmethod |
| 412 | + def is_valid_zarr_fsspec(path: Path) -> bool: |
| 413 | + """Check if the input path is a valid Zarr fsspec JSON file. |
| 414 | +
|
| 415 | + Check if the file is a valid Zarr fsspec JSON file with Zarr format version 2. |
| 416 | +
|
| 417 | + Args: |
| 418 | + path (Path): Path to the file to check. |
| 419 | +
|
| 420 | + Returns: |
| 421 | + bool: True if the file is a valid Zarr fsspec JSON file |
| 422 | + with Zarr format version 2. |
| 423 | + """ |
| 424 | + path = Path(path) |
| 425 | + |
| 426 | + if path.suffix.lower() != ".json": |
| 427 | + logger.error("File does not have a .json extension.") |
| 428 | + return False |
| 429 | + |
| 430 | + try: |
| 431 | + with path.open("r") as file: |
| 432 | + data = json.load(file) |
| 433 | + |
| 434 | + # Check if ".zgroup" exists and is a valid JSON string |
| 435 | + if ".zgroup" not in data: |
| 436 | + logger.error("Missing .zgroup key.") |
| 437 | + return False |
| 438 | + |
| 439 | + zgroup_content = json.loads(data[".zgroup"]) |
| 440 | + zarr_format_version = 2 |
| 441 | + if zgroup_content.get("zarr_format") != zarr_format_version: |
| 442 | + logger.error("zarr_format is not %d.", zarr_format_version) |
| 443 | + return False |
| 444 | + |
| 445 | + return True # noqa: TRY300 |
| 446 | + |
| 447 | + except json.JSONDecodeError as e: |
| 448 | + logger.error("Invalid JSON file: %s", e) |
| 449 | + return False |
| 450 | + except (OSError, ValueError) as e: |
| 451 | + logger.error("An error occurred: %s", e) |
| 452 | + return False |
| 453 | + |
422 | 454 | @staticmethod |
423 | 455 | def verify_supported_wsi(input_path: Path) -> None: |
424 | 456 | """Verify that an input image is supported. |
|
0 commit comments