mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge pull request #21385 from kostrykin/feat/dicom
Add initial support for the DICOM format
This commit is contained in:
@@ -316,6 +316,7 @@
|
||||
<datatype extension="ome.tiff" type="galaxy.datatypes.images:OMETiff" display_in_upload="true">
|
||||
<display file="image/avivator.xml"/>
|
||||
</datatype>
|
||||
<datatype extension="dcm" type="galaxy.datatypes.images:Dicom" mimetype="application/dicom" subclass="true" display_in_upload="true" description_url="https://formats.kaitai.io/dicom"/>
|
||||
<datatype extension="vms" type="galaxy.datatypes.images:Hamamatsu" mimetype="image/hamamatsu"/>
|
||||
<datatype extension="vmu" type="galaxy.datatypes.images:Hamamatsu" subclass="true" display_in_upload="false"/>
|
||||
<datatype extension="ndpi" type="galaxy.datatypes.images:Hamamatsu" subclass="true" display_in_upload="false"/>
|
||||
@@ -1453,6 +1454,7 @@
|
||||
<sniffer type="galaxy.datatypes.images:Png"/>
|
||||
<sniffer type="galaxy.datatypes.images:OMETiff"/>
|
||||
<sniffer type="galaxy.datatypes.images:Tiff"/>
|
||||
<sniffer type="galaxy.datatypes.images:Dicom"/>
|
||||
<sniffer type="galaxy.datatypes.images:Bmp"/>
|
||||
<sniffer type="galaxy.datatypes.images:Gif"/>
|
||||
<sniffer type="galaxy.datatypes.images:Im"/>
|
||||
|
||||
@@ -3,6 +3,7 @@ Image classes
|
||||
"""
|
||||
|
||||
import base64
|
||||
import io
|
||||
import json
|
||||
import logging
|
||||
import math
|
||||
@@ -18,6 +19,7 @@ from typing import (
|
||||
import mrcfile
|
||||
import numpy as np
|
||||
import png
|
||||
import pydicom
|
||||
import tifffile
|
||||
|
||||
try:
|
||||
@@ -225,10 +227,12 @@ class Png(Image):
|
||||
dataset.metadata.num_unique_values = len(unique_values)
|
||||
|
||||
|
||||
@build_sniff_from_prefix
|
||||
class Tiff(Image):
|
||||
edam_format = "format_3591"
|
||||
file_ext = "tiff"
|
||||
display_behavior = "download" # TIFF files trigger browser downloads
|
||||
|
||||
MetadataElement(
|
||||
name="offsets",
|
||||
desc="Offsets File",
|
||||
@@ -239,6 +243,27 @@ class Tiff(Image):
|
||||
optional=True,
|
||||
)
|
||||
|
||||
def sniff_prefix(self, file_prefix: FilePrefix) -> bool:
|
||||
"""
|
||||
Determine if the file is in TIFF format by checking the file header.
|
||||
|
||||
For a successful check, the first 4 bytes must be the TIFF magic number. See [1] for a list of magic numbers.
|
||||
|
||||
Manual checking of the file header, as opposed to trying to read the file with tifffile, is required due to an
|
||||
ambiguity with DICOM files. This is because the DICOM standard allows *any content* for the first 128 bytes of
|
||||
the file, followed by the DICOM prefix (see §7.1 in [2] for details).
|
||||
|
||||
[1] https://gist.github.com/leommoore/f9e57ba2aa4bf197ebc5
|
||||
[2] https://dicom.nema.org/medical/dicom/current/output/html/part10.html
|
||||
"""
|
||||
return file_prefix.contents_header_bytes[:4] in (
|
||||
b"\x4d\x4d\x00\x2a", # TIFF format (Motorola - big endian)
|
||||
b"\x49\x49\x2a\x00", # TIFF format (Intel - little endian)
|
||||
) and (
|
||||
len(file_prefix.contents_header_bytes) < 132 # file is too short to be a DICOM
|
||||
or file_prefix.contents_header_bytes[128:132] != b"DICM" # file does not contain the DICOM prefix
|
||||
)
|
||||
|
||||
def set_meta(
|
||||
self, dataset: DatasetProtocol, overwrite: bool = True, metadata_tmp_files_dir: Optional[str] = None, **kwd
|
||||
) -> None:
|
||||
@@ -385,19 +410,14 @@ class Tiff(Image):
|
||||
|
||||
yield segment
|
||||
|
||||
def sniff(self, filename: str) -> bool:
|
||||
with tifffile.TiffFile(filename):
|
||||
return True
|
||||
|
||||
|
||||
class OMETiff(Tiff):
|
||||
file_ext = "ome.tiff"
|
||||
|
||||
def sniff(self, filename: str) -> bool:
|
||||
with tifffile.TiffFile(filename) as tif:
|
||||
if tif.is_ome:
|
||||
return True
|
||||
return False
|
||||
def sniff_prefix(self, file_prefix: FilePrefix) -> bool:
|
||||
buf = io.BytesIO(file_prefix.contents_header_bytes)
|
||||
with tifffile.TiffFile(buf) as tif:
|
||||
return tif.is_ome
|
||||
|
||||
|
||||
class OMEZarr(data.ZarrDirectory):
|
||||
@@ -519,6 +539,117 @@ class Pdf(Image):
|
||||
return fh.read(4) == b"%PDF"
|
||||
|
||||
|
||||
@build_sniff_from_prefix
|
||||
class Dicom(Image):
|
||||
"""
|
||||
DICOM medical imaging format (.dcm)
|
||||
|
||||
>>> from galaxy.datatypes.sniff import get_test_fname
|
||||
>>> fname = get_test_fname('ct_image.dcm')
|
||||
>>> Dicom().sniff(fname)
|
||||
True
|
||||
"""
|
||||
|
||||
MetadataElement(
|
||||
name="is_tiled",
|
||||
desc="Is this a WSI DICOM?",
|
||||
readonly=True,
|
||||
visible=True,
|
||||
optional=True,
|
||||
)
|
||||
|
||||
edam_format = "format_3548"
|
||||
file_ext = "dcm"
|
||||
|
||||
def sniff_prefix(self, file_prefix: FilePrefix) -> bool:
|
||||
"""
|
||||
Determine if the file is in DICOM format according to §7.1 in [1].
|
||||
|
||||
[1] https://dicom.nema.org/medical/dicom/current/output/html/part10.html
|
||||
"""
|
||||
return len(file_prefix.contents_header_bytes) >= 132 and file_prefix.contents_header_bytes[128:132] == b"DICM"
|
||||
|
||||
def get_mime(self) -> str:
|
||||
"""
|
||||
Returns the mime type of the datatype.
|
||||
"""
|
||||
return "application/dicom"
|
||||
|
||||
def set_meta(
|
||||
self, dataset: DatasetProtocol, overwrite: bool = True, metadata_tmp_files_dir: Optional[str] = None, **kwd
|
||||
) -> None:
|
||||
"""
|
||||
Populate the metadata of the DICOM file using the pydicom library.
|
||||
|
||||
The following metadata fields are populated, if possible:
|
||||
- `width`
|
||||
- `height`
|
||||
- `channels`
|
||||
- `dtype`
|
||||
- `num_unique_values` in some cases
|
||||
- `is_tiled`
|
||||
|
||||
Currently, `frames` and `depth` are not populated. This is because "frames" in DICOM are a generic entity,
|
||||
that can be used for different purposes, including slices in 3-D images, frames in temporal sequences, and
|
||||
tiles of a mosaic or pyramid (WSI DICOM). Distinguishing these cases is not straight-forward (and, as a
|
||||
consequence, neither is determining the `axes` of the image). This can be implemented in the future.
|
||||
"""
|
||||
try:
|
||||
dcm = pydicom.dcmread(dataset.get_file_name(), stop_before_pixels=True)
|
||||
except pydicom.errors.InvalidDicomError:
|
||||
return # Ignore errors if metadata cannot be read
|
||||
|
||||
# Determine the number of channels (0 if no channel info is present)
|
||||
dataset.metadata.channels = dcm.get("SamplesPerPixel", 0)
|
||||
|
||||
# Determine if the DICOM file is tiled (likely WSI DICOM)
|
||||
dataset.metadata.is_tiled = hasattr(dcm, "TotalPixelMatrixColumns") and hasattr(dcm, "TotalPixelMatrixRows")
|
||||
|
||||
# Determine the width and height of the dataset. If the DICOM file is not tiled, the width and height
|
||||
# directly. For tiled DICOM, these values correspond to the size of the tiles.
|
||||
if dataset.metadata.is_tiled:
|
||||
dataset.metadata.width = dcm.TotalPixelMatrixColumns
|
||||
dataset.metadata.height = dcm.TotalPixelMatrixRows
|
||||
else:
|
||||
dataset.metadata.width = dcm.get("Columns")
|
||||
dataset.metadata.height = dcm.get("Rows")
|
||||
|
||||
# Try to infer the `dtype` from metadata
|
||||
if dcm.BitsAllocated == 1:
|
||||
dataset.metadata.dtype = "bool" # 1bit
|
||||
else:
|
||||
dtype_lut = [
|
||||
["uint8", "int8"],
|
||||
["uint16", "int16"],
|
||||
["uint32", "int32"],
|
||||
]
|
||||
dtype_lut_pos = (
|
||||
round(math.log2(dcm.BitsAllocated) - 3), # 8bit -> 0, 16bit -> 1, 32bit -> 2
|
||||
dcm.PixelRepresentation,
|
||||
)
|
||||
if 0 <= dtype_lut_pos[0] < len(dtype_lut):
|
||||
dataset.metadata.dtype = dtype_lut[dtype_lut_pos[0]][dtype_lut_pos[1]]
|
||||
else:
|
||||
dataset.metadata.dtype = None # unknown `dtype`
|
||||
|
||||
# Try to infer `num_unique_values` from metadata
|
||||
try:
|
||||
if dcm.SOPClassUID == "1.2.840.10008.5.1.4.1.1.66.4": # https://www.dicomlibrary.com/dicom/sop
|
||||
|
||||
# The DICOM file contains segmentation, count +1 for the image background
|
||||
dataset.metadata.num_unique_values = 1 + len(dcm.SegmentSequence)
|
||||
|
||||
else:
|
||||
|
||||
# Otherwise, `num_unique_values` is not available from metadata
|
||||
dataset.metadata.num_unique_values = None
|
||||
|
||||
except AttributeError:
|
||||
|
||||
# Ignore errors if metadata cannot be read
|
||||
dataset.metadata.num_unique_values = None
|
||||
|
||||
|
||||
@build_sniff_from_prefix
|
||||
class Tck(Binary):
|
||||
"""
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../../test-data/highdicom/ct_image.dcm
|
||||
@@ -0,0 +1 @@
|
||||
../../../../test-data/highdicom/seg_image_ct_binary.dcm
|
||||
+1
@@ -0,0 +1 @@
|
||||
../../../../test-data/highdicom/sm_image.dcm
|
||||
@@ -215,6 +215,8 @@ pydantic-graph==1.44.0
|
||||
pydantic-settings==2.12.0
|
||||
pydantic-tes==0.2.0
|
||||
pydocket==0.16.6
|
||||
pydicom==2.4.4 ; python_full_version < '3.10'
|
||||
pydicom==3.0.1 ; python_full_version >= '3.10'
|
||||
pydot==4.0.1
|
||||
pyeventsystem==0.1.0
|
||||
pyfaidx==0.9.0.3
|
||||
|
||||
@@ -55,6 +55,7 @@ install_requires =
|
||||
parsley
|
||||
pycryptodome
|
||||
pydantic[email]>=2.7.4
|
||||
pydicom
|
||||
pylibmagic
|
||||
pypng
|
||||
python-magic
|
||||
|
||||
@@ -77,6 +77,7 @@ dependencies = [
|
||||
"pycryptodome",
|
||||
"pydantic[email]>=2.7.4", # https://github.com/pydantic/pydantic/pull/9639
|
||||
"pydantic-ai>=0.1.16", # AI agent framework
|
||||
"pydicom; python_version >= '3.10'",
|
||||
"PyJWT",
|
||||
"pykwalify",
|
||||
"pylibmagic",
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
Copyright 2020 MGH Computational Pathology
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,13 +1,14 @@
|
||||
from typing import (
|
||||
Any,
|
||||
)
|
||||
from typing import Any
|
||||
|
||||
from galaxy.datatypes.images import (
|
||||
Dicom,
|
||||
Image,
|
||||
OMETiff,
|
||||
Pdf,
|
||||
Png,
|
||||
Tiff,
|
||||
)
|
||||
from galaxy.datatypes.sniff import get_test_fname
|
||||
from .util import (
|
||||
get_dataset,
|
||||
MockDatasetDataset,
|
||||
@@ -35,11 +36,18 @@ def __test(image_cls: type[Image], input_filename: str):
|
||||
# Define test factory
|
||||
|
||||
|
||||
def __create_test(image_cls: type[Image], input_filename: str, metadata_key: str, expected_value: Any):
|
||||
def __create_test(image_cls: type[Image], input_filename: str, **expected_metadata: Any):
|
||||
|
||||
@__test(image_cls, input_filename)
|
||||
def test(metadata):
|
||||
assert getattr(metadata, metadata_key) == expected_value
|
||||
for metadata_key, expected_value in expected_metadata.items():
|
||||
metadata_value = getattr(metadata, metadata_key)
|
||||
cond = (
|
||||
(metadata_value is expected_value)
|
||||
if expected_value is None or type(expected_value) is bool
|
||||
else (metadata_value == expected_value)
|
||||
)
|
||||
assert cond, f"expected: {repr(expected_value)}, actual: {repr(metadata_value)}"
|
||||
|
||||
return test
|
||||
|
||||
@@ -63,24 +71,24 @@ def __assert_empty_metadata(metadata):
|
||||
|
||||
# Tests for `Tiff` class
|
||||
|
||||
test_tiff_axes_yx = __create_test(Tiff, "im1_uint8.tif", "axes", "YX")
|
||||
test_tiff_axes_zcyx = __create_test(Tiff, "im6_uint8.tif", "axes", "ZCYX")
|
||||
test_tiff_dtype_uint8 = __create_test(Tiff, "im6_uint8.tif", "dtype", "uint8")
|
||||
test_tiff_dtype_uint16 = __create_test(Tiff, "im8_uint16.tif", "dtype", "uint16")
|
||||
test_tiff_dtype_float64 = __create_test(Tiff, "im4_float.tif", "dtype", "float64")
|
||||
test_tiff_num_unique_values_2 = __create_test(Tiff, "im3_b.tif", "num_unique_values", 2)
|
||||
test_tiff_num_unique_values_618 = __create_test(Tiff, "im4_float.tif", "num_unique_values", 618)
|
||||
test_tiff_width_16 = __create_test(Tiff, "im7_uint8.tif", "width", 16) # axes: ZYX
|
||||
test_tiff_width_32 = __create_test(Tiff, "im3_b.tif", "width", 32) # axes: YXS
|
||||
test_tiff_height_8 = __create_test(Tiff, "im7_uint8.tif", "height", 8) # axes: ZYX
|
||||
test_tiff_height_32 = __create_test(Tiff, "im3_b.tif", "height", 32) # axes: YXS
|
||||
test_tiff_channels_0 = __create_test(Tiff, "im1_uint8.tif", "channels", 0)
|
||||
test_tiff_channels_2 = __create_test(Tiff, "im5_uint8.tif", "channels", 2) # axes: CYX
|
||||
test_tiff_channels_3 = __create_test(Tiff, "im3_b.tif", "channels", 3) # axes: YXS
|
||||
test_tiff_depth_0 = __create_test(Tiff, "im1_uint8.tif", "depth", 0) # axes: YXS
|
||||
test_tiff_depth_25 = __create_test(Tiff, "im7_uint8.tif", "depth", 25) # axes: ZYX
|
||||
test_tiff_frames_0 = __create_test(Tiff, "im1_uint8.tif", "frames", 0) # axes: YXS
|
||||
test_tiff_frames_5 = __create_test(Tiff, "im8_uint16.tif", "frames", 5) # axes: TYX
|
||||
test_tiff_axes_yx = __create_test(Tiff, "im1_uint8.tif", axes="YX")
|
||||
test_tiff_axes_zcyx = __create_test(Tiff, "im6_uint8.tif", axes="ZCYX")
|
||||
test_tiff_dtype_uint8 = __create_test(Tiff, "im6_uint8.tif", dtype="uint8")
|
||||
test_tiff_dtype_uint16 = __create_test(Tiff, "im8_uint16.tif", dtype="uint16")
|
||||
test_tiff_dtype_float64 = __create_test(Tiff, "im4_float.tif", dtype="float64")
|
||||
test_tiff_num_unique_values_2 = __create_test(Tiff, "im3_b.tif", num_unique_values=2)
|
||||
test_tiff_num_unique_values_618 = __create_test(Tiff, "im4_float.tif", num_unique_values=618)
|
||||
test_tiff_width_16 = __create_test(Tiff, "im7_uint8.tif", width=16) # axes: ZYX
|
||||
test_tiff_width_32 = __create_test(Tiff, "im3_b.tif", width=32) # axes: YXS
|
||||
test_tiff_height_8 = __create_test(Tiff, "im7_uint8.tif", height=8) # axes: ZYX
|
||||
test_tiff_height_32 = __create_test(Tiff, "im3_b.tif", height=32) # axes: YXS
|
||||
test_tiff_channels_0 = __create_test(Tiff, "im1_uint8.tif", channels=0)
|
||||
test_tiff_channels_2 = __create_test(Tiff, "im5_uint8.tif", channels=2) # axes: CYX
|
||||
test_tiff_channels_3 = __create_test(Tiff, "im3_b.tif", channels=3) # axes: YXS
|
||||
test_tiff_depth_0 = __create_test(Tiff, "im1_uint8.tif", depth=0) # axes: YXS
|
||||
test_tiff_depth_25 = __create_test(Tiff, "im7_uint8.tif", depth=25) # axes: ZYX
|
||||
test_tiff_frames_0 = __create_test(Tiff, "im1_uint8.tif", frames=0) # axes: YXS
|
||||
test_tiff_frames_5 = __create_test(Tiff, "im8_uint16.tif", frames=5) # axes: TYX
|
||||
|
||||
|
||||
@__test(Tiff, "im_empty.tif")
|
||||
@@ -88,64 +96,144 @@ def test_tiff_empty(metadata):
|
||||
__assert_empty_metadata(metadata)
|
||||
|
||||
|
||||
@__test(Tiff, "1.tiff")
|
||||
def test_tiff_unsupported_compression(metadata):
|
||||
test_tiff_unsupported_compression = __create_test(
|
||||
Tiff,
|
||||
"1.tiff",
|
||||
# If the compression of a TIFF is unsupported, some fields should still be there
|
||||
assert metadata.axes == "YX"
|
||||
assert metadata.dtype == "bool"
|
||||
assert metadata.width == 1728
|
||||
assert metadata.height == 2376
|
||||
assert metadata.channels == 0
|
||||
assert metadata.depth == 0
|
||||
assert metadata.frames == 0
|
||||
|
||||
axes="YX",
|
||||
dtype="bool",
|
||||
width=1728,
|
||||
height=2376,
|
||||
channels=0,
|
||||
depth=0,
|
||||
frames=0,
|
||||
# The other fields should be missing
|
||||
assert getattr(metadata, "num_unique_values", None) is None
|
||||
num_unique_values=None,
|
||||
)
|
||||
|
||||
|
||||
@__test(Tiff, "im9_multiseries.tif")
|
||||
def test_tiff_multiseries(metadata):
|
||||
assert metadata.axes == ["YXS", "YX"]
|
||||
assert metadata.dtype == ["uint8", "uint16"]
|
||||
assert metadata.num_unique_values == [2, 255]
|
||||
assert metadata.width == [32, 256]
|
||||
assert metadata.height == [32, 256]
|
||||
assert metadata.channels == [3, 0]
|
||||
assert metadata.depth == [0, 0]
|
||||
assert metadata.frames == [0, 0]
|
||||
test_tiff_unsupported_multiseries = __create_test(
|
||||
Tiff,
|
||||
"im9_multiseries.tif", # TODO: rename to .tiff
|
||||
axes=["YXS", "YX"],
|
||||
dtype=["uint8", "uint16"],
|
||||
num_unique_values=[2, 255],
|
||||
width=[32, 256],
|
||||
height=[32, 256],
|
||||
channels=[3, 0],
|
||||
depth=[0, 0],
|
||||
frames=[0, 0],
|
||||
)
|
||||
|
||||
|
||||
def test_tiff_sniff():
|
||||
for filename in (
|
||||
"im4_float.tif",
|
||||
"im1_uint8.tif",
|
||||
"im_empty.tif",
|
||||
"im7_uint8.tif",
|
||||
"im5_uint8.tif",
|
||||
"1.tiff",
|
||||
"im9_multiseries.tif",
|
||||
"im8_uint16.tif",
|
||||
"im6_uint8.tif",
|
||||
"im3_b.tif",
|
||||
):
|
||||
fname = get_test_fname(filename)
|
||||
assert not Dicom().sniff(fname), f"filename: {filename}"
|
||||
assert not Png().sniff(fname), f"filename: {filename}"
|
||||
assert not OMETiff().sniff(fname), f"filename: {filename}"
|
||||
assert Tiff().sniff(fname), f"filename: {filename}"
|
||||
|
||||
|
||||
# Tests for `OMETiff` class
|
||||
|
||||
|
||||
def test_ome_tiff_sniff():
|
||||
fname = get_test_fname("1.ome.tiff")
|
||||
assert not Dicom().sniff(fname)
|
||||
assert not Png().sniff(fname)
|
||||
assert Tiff().sniff(fname)
|
||||
assert OMETiff().sniff(fname)
|
||||
|
||||
|
||||
# Tests for `Image` class
|
||||
|
||||
test_png_axes_yx = __create_test(Image, "im1_uint8.png", "axes", "YX")
|
||||
test_png_axes_yxc = __create_test(Image, "im3_a.png", "axes", "YXC")
|
||||
test_png_dtype_uint8 = __create_test(Image, "im1_uint8.png", "dtype", "uint8")
|
||||
test_png_num_unique_values_1 = __create_test(Image, "im2_a.png", "num_unique_values", None)
|
||||
test_png_num_unique_values_2 = __create_test(Image, "im2_b.png", "num_unique_values", None)
|
||||
test_png_width_32 = __create_test(Image, "im2_b.png", "width", 32)
|
||||
test_png_height_32 = __create_test(Image, "im2_b.png", "height", 32)
|
||||
test_png_channels_0 = __create_test(Image, "im1_uint8.png", "channels", 0)
|
||||
test_png_channels_3 = __create_test(Image, "im3_a.png", "channels", 3)
|
||||
test_png_depth_0 = __create_test(Image, "im1_uint8.png", "depth", 0)
|
||||
test_png_frames_1 = __create_test(Image, "im1_uint8.png", "frames", 1)
|
||||
test_png_axes_yx = __create_test(Image, "im1_uint8.png", axes="YX")
|
||||
test_png_axes_yxc = __create_test(Image, "im3_a.png", axes="YXC")
|
||||
test_png_dtype_uint8 = __create_test(Image, "im1_uint8.png", dtype="uint8")
|
||||
test_png_num_unique_values_1 = __create_test(Image, "im2_a.png", num_unique_values=None)
|
||||
test_png_num_unique_values_2 = __create_test(Image, "im2_b.png", num_unique_values=None)
|
||||
test_png_width_32 = __create_test(Image, "im2_b.png", width=32)
|
||||
test_png_height_32 = __create_test(Image, "im2_b.png", height=32)
|
||||
test_png_channels_0 = __create_test(Image, "im1_uint8.png", channels=0)
|
||||
test_png_channels_3 = __create_test(Image, "im3_a.png", channels=3)
|
||||
test_png_depth_0 = __create_test(Image, "im1_uint8.png", depth=0)
|
||||
test_png_frames_1 = __create_test(Image, "im1_uint8.png", frames=1)
|
||||
|
||||
|
||||
# Tests for `Png` class
|
||||
|
||||
test_png_axes_yx = __create_test(Png, "im1_uint8.png", "axes", "YX")
|
||||
test_png_axes_yxc = __create_test(Png, "im3_a.png", "axes", "YXC")
|
||||
test_png_dtype_uint8 = __create_test(Png, "im1_uint8.png", "dtype", "uint8")
|
||||
test_png_num_unique_values_1 = __create_test(Png, "im2_a.png", "num_unique_values", 1)
|
||||
test_png_num_unique_values_2 = __create_test(Png, "im2_b.png", "num_unique_values", 2)
|
||||
test_png_width_32 = __create_test(Png, "im2_b.png", "width", 32)
|
||||
test_png_height_32 = __create_test(Png, "im2_b.png", "height", 32)
|
||||
test_png_channels_0 = __create_test(Png, "im1_uint8.png", "channels", 0)
|
||||
test_png_channels_3 = __create_test(Png, "im3_a.png", "channels", 3)
|
||||
test_png_depth_0 = __create_test(Png, "im1_uint8.png", "depth", 0)
|
||||
test_png_frames_1 = __create_test(Png, "im1_uint8.png", "frames", 1)
|
||||
test_png_axes_yx = __create_test(Png, "im1_uint8.png", axes="YX")
|
||||
test_png_axes_yxc = __create_test(Png, "im3_a.png", axes="YXC")
|
||||
test_png_dtype_uint8 = __create_test(Png, "im1_uint8.png", dtype="uint8")
|
||||
test_png_num_unique_values_1 = __create_test(Png, "im2_a.png", num_unique_values=1)
|
||||
test_png_num_unique_values_2 = __create_test(Png, "im2_b.png", num_unique_values=2)
|
||||
test_png_width_32 = __create_test(Png, "im2_b.png", width=32)
|
||||
test_png_height_32 = __create_test(Png, "im2_b.png", height=32)
|
||||
test_png_channels_0 = __create_test(Png, "im1_uint8.png", channels=0)
|
||||
test_png_channels_3 = __create_test(Png, "im3_a.png", channels=3)
|
||||
test_png_depth_0 = __create_test(Png, "im1_uint8.png", depth=0)
|
||||
test_png_frames_1 = __create_test(Png, "im1_uint8.png", frames=1)
|
||||
|
||||
|
||||
# Test with files that neither Pillow nor tifffile can open
|
||||
# Tests for `Dicom` class
|
||||
|
||||
test_2d_singlechannel = __create_test(
|
||||
Dicom,
|
||||
"ct_image.dcm",
|
||||
width=128,
|
||||
height=128,
|
||||
channels=1,
|
||||
dtype="int16",
|
||||
num_unique_values=None,
|
||||
is_tiled=False,
|
||||
)
|
||||
|
||||
|
||||
test_tiled_multichannel = __create_test(
|
||||
Dicom,
|
||||
"sm_image.dcm",
|
||||
width=50,
|
||||
height=50,
|
||||
channels=3,
|
||||
dtype="uint8",
|
||||
num_unique_values=None,
|
||||
is_tiled=True,
|
||||
)
|
||||
|
||||
|
||||
test_3d_binary = __create_test(
|
||||
Dicom,
|
||||
"seg_image_ct_binary.dcm",
|
||||
width=16,
|
||||
height=16,
|
||||
channels=1,
|
||||
dtype="bool",
|
||||
num_unique_values=2,
|
||||
is_tiled=False,
|
||||
)
|
||||
|
||||
|
||||
def test_dicom_sniff():
|
||||
fname = get_test_fname("ct_image.dcm")
|
||||
assert Dicom().sniff(fname)
|
||||
assert not OMETiff().sniff(fname)
|
||||
assert not Tiff().sniff(fname)
|
||||
assert not Png().sniff(fname)
|
||||
|
||||
|
||||
# Test with files that neither Pillow, tifffile, nor pydicom can open
|
||||
|
||||
|
||||
@__test(Pdf, "454Score.pdf")
|
||||
|
||||
Reference in New Issue
Block a user