Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.tif file from Ventana scanner is not parsed properly with WSIReader; openslide works well on its own #804

Closed
GeorgeBatch opened this issue Apr 8, 2024 · 5 comments · Fixed by #807

Comments

@GeorgeBatch
Copy link
Contributor

  • TIA Toolbox version: 1.5.1
  • Python version: 3.11.8
  • Operating System: CentOS Linux 7 (Core)

Description

I have slides scanned with a Ventana DP200 scanner and saved as .tif files.

What I Did

slide_path = "sample_slide_path.tif"

Open with tiatoolbox WSIReader and print the extracted metadata:

from tiatoolbox.wsicore.wsireader import WSIReader

reader = WSIReader.open(input_img=slide_path)
print(reader)

info_dict = reader.info.as_dict()
pprint(info_dict)  # noqa: T203

Result:

<tiatoolbox.wsicore.wsireader.VirtualWSIReader object at 0xABCDEFGHIJK>
{'axes': 'YSX',
 'file_path': PosixPath('sample_slide_path.tif'),
 'level_count': 1,
 'level_dimensions': ((1251, 3685),),
 'level_downsamples': [1.0],
 'mpp': (None, None),
 'objective_power': None,
 'slide_dimensions': (1251, 3685),
 'vendor': 'None'}

The result did not seem right, so I checked with openslide

slide_openslide = openslide.open_slide(slide_path)

print("openslide.level_downsamples", slide_openslide.level_downsamples)
print("openslide.level_dimensions", slide_openslide.level_dimensions)
print("openslide.mpp-x", slide_openslide.properties[openslide.PROPERTY_NAME_MPP_X])
print("openslide.mpp-y", slide_openslide.properties[openslide.PROPERTY_NAME_MPP_Y])
print("openslide.objective-power", slide_openslide.properties[openslide.PROPERTY_NAME_OBJECTIVE_POWER])

Result:

openslide.level_downsamples (1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0)
openslide.level_dimensions ((90112, 134144), (45056, 67072), (22528, 33536), (11264, 16768), (5632, 8384), (2816, 4192), (1408, 2096), (704, 1048), (352, 524), (176, 262), (88, 131))
openslide.mpp-x 0.25
openslide.mpp-y 0.25
openslide.objective-power 40

For some reason, instead of using OpenSlideWSIReader or TIFFWSIReader, VirtualWSIReader is used. I will investigate further and add my findings in the comments below.

@GeorgeBatch
Copy link
Contributor Author

I checked, last_suffix is ".tif", but is_tiled_tiff(slide_path) is False, so neither OpenSlideWSIReader nor TIFFWSIReader gets to be tried.

if last_suffix in (".tif", ".tiff") and is_tiled_tiff(input_path):
try:
return OpenSlideWSIReader(input_path, mpp=mpp, power=power)
except openslide.OpenSlideError:
return TIFFWSIReader(input_path, mpp=mpp, power=power)

I checked what happens in is_tiled_tiff when passing my slide_path. In the try-except block, a tif is successfully made with tif = tifffile.TiffFile(path), but tif.pages[0].is_tiled is False for my slide, so is_tiled_tiff(slide_path) is False.

def is_tiled_tiff(path: Path) -> bool:
"""Check if the input is a tiled TIFF file.
Args:
path (Path):
Path to the file to check.
Returns:
bool:
True if the file is a tiled TIFF file.
"""
path = Path(path)
try:
tif = tifffile.TiffFile(path)
except tifffile.TiffFileError:
return False
return tif.pages[0].is_tiled

Given that openslide opens the image and successfully parses metadata, I think the requirement of is_tiled_tiff() to be true is too strict.


Finally, I checked out the develop branch with the tiatoolbox-dev environment created and activated as described in the README. The results are the same, which is as expected since the relevant parts of the code did not change:

if last_suffix in (".tif", ".tiff") and is_tiled_tiff(input_path):
try:
return OpenSlideWSIReader(input_path, mpp=mpp, power=power)
except openslide.OpenSlideError:
return TIFFWSIReader(input_path, mpp=mpp, power=power)

and

def is_tiled_tiff(path: Path) -> bool:
"""Check if the input is a tiled TIFF file.
Args:
path (Path):
Path to the file to check.
Returns:
bool:
True if the file is a tiled TIFF file.
"""
path = Path(path)
try:
tif = tifffile.TiffFile(path)
except tifffile.TiffFileError:
return False
return tif.pages[0].is_tiled

@GeorgeBatch
Copy link
Contributor Author

I made a workaround that I will make into a pull-request. Please let me know what you think of it:

Add an argument ignore_is_tiled_tiff: bool = False to wsicore.wsireader.WSIReader.open():

def open( # noqa: PLR0911
input_img: str | Path | np.ndarray | WSIReader,
mpp: tuple[Number, Number] | None = None,
power: Number | None = None,
**kwargs: dict,
) -> WSIReader:

Change

if last_suffix in (".tif", ".tiff") and is_tiled_tiff(input_path):

to be

if last_suffix in (".tif", ".tiff") and (ignore_is_tiled_tiff or is_tiled_tiff(input_path)):

@shaneahmed shaneahmed linked a pull request Apr 26, 2024 that will close this issue
shaneahmed added a commit that referenced this issue May 3, 2024
A possible solution for the issue #804

Checks if openslide is able to detect tiff format. In this case, OpenSlide opens the tiff file, otherwise falls back to tifffile or opencv.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Shan E Ahmed Raza <13048456+shaneahmed@users.noreply.github.com>
@GeorgeBatch
Copy link
Contributor Author

GeorgeBatch commented Jul 4, 2024

@Abdol @shaneahmed, do you have an estimate of when you will release v1.5.2?

@shaneahmed
Copy link
Member

Hi @GeorgeBatch , we plan to make a release v 1.6.0 as soon as #825 or #716 are ready. Probably by end of July/early Aug.

@GeorgeBatch
Copy link
Contributor Author

@shaneahmed, thank you for the update!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants