I have whole slide images (WSIs) scanned with a Zeiss scanner in file format .czi. I converted them to .ome.tiff with Bioformats (bfconvert) to be compatible with the pyvips library that Slideflow relies on. However, when I loaded in the WSI with sf.WSI() (with libvips backend) and tried WSI.otsu() or WSI.preview() I ran into an error with pyvips. I then used tiffinfo to examine the converted TIFF structure and realized that some sublayers of the .ome.tiff file did not have tile width present in their metadata. This revealed a fault during conversion with bfconvert where the default tile width was too large for the smaller subfiles. I resolved the issue by specifying the tilex and tiley sizes during conversion.
To Reproduce
I used the following code in the command line to convert the .czi file to .tiff: ./bfconvert 2023_11_01__8855.czi 2023_11_01__8855.ome.tiff
I then tried to load in the new .ome.tiff Slideflow code which caused an error:
import os
import slideflow as sf
os.environ['SF_SLIDE_BACKEND'] = 'libvips'
WSI_img = sf.WSI(path=slidepath,
tile_px=299,
tile_um=302,
mpp=0.5,
)
WSI_img.preview()
The error message:
Traceback (most recent call last):
File "/home/pearsonlab/anaconda3/envs/sf/lib/python3.8/multiprocessing/pool.py", line 125, in worker
result = (True, func(*args, **kwds))
File "/home/pearsonlab/anaconda3/envs/sf/lib/python3.8/multiprocessing/pool.py", line 48, in mapstar
return list(map(*args))
File "/home/pearsonlab/anaconda3/envs/sf/lib/python3.8/site-packages/slideflow/slide/backends/__init__.py", line 12, in tile_worker
return tile_worker(*args, **kwargs)
File "/home/pearsonlab/anaconda3/envs/sf/lib/python3.8/site-packages/slideflow/slide/backends/vips.py", line 277, in tile_worker
gs_fraction = hsv_region[1].relational_const(
File "/home/pearsonlab/anaconda3/envs/sf/lib/python3.8/site-packages/pyvips/vimage.py", line 919, in call_function
return pyvips.Operation.call(name, self, *args, **kwargs)
File "/home/pearsonlab/anaconda3/envs/sf/lib/python3.8/site-packages/pyvips/voperation.py", line 282, in call
raise Error('unable to call {0}'.format(operation_name))
pyvips.error.Error: unable to call avg
tiff2vips: out of order read -- at line 711, but line 506 requested
The key difference being that for lower resolution, higher layer sub-images of the .ome.tiff pyramid, there was no "Tile Width" tag in the metadata. Given that the pyvips error occurred during a step with calling tile workers, I realized there was something wrong with subtiling of the OME-TIFF file during conversion with bfconvert.
After playing around with a few options, I realized that I could manually set the tilex and tiley during conversion (I also made sure to set only one timepoint to be used for all layers). I chose tilex=512 and tiley=512, which is smaller than the total x & y dimensions of all sublayers of the WSI. This allows all sublayers to be saved in a tiled format (see Bioformats docs for more info on this option). Ultimately, the following code worked to successfully convert the files:
Description
I have whole slide images (WSIs) scanned with a Zeiss scanner in file format
.czi
. I converted them to.ome.tiff
with Bioformats (bfconvert
) to be compatible with the pyvips library that Slideflow relies on. However, when I loaded in the WSI withsf.WSI()
(with libvips backend) and triedWSI.otsu()
orWSI.preview()
I ran into an error with pyvips. I then usedtiffinfo
to examine the converted TIFF structure and realized that some sublayers of the.ome.tiff
file did not have tile width present in their metadata. This revealed a fault during conversion withbfconvert
where the default tile width was too large for the smaller subfiles. I resolved the issue by specifying thetilex
andtiley
sizes during conversion.To Reproduce
I used the following code in the command line to convert the .czi file to .tiff:
./bfconvert 2023_11_01__8855.czi 2023_11_01__8855.ome.tiff
I then tried to load in the new .ome.tiff Slideflow code which caused an error:
The error message:
Environment
sf.about()
output:Version: 2.2.0
Backend: torch
Slide Backend: libvips (8.12.2)
Resolution
I examined the converted
.ome.tiff
file with tiffinfo on the command line and compared it other TIFF files I had.tiffinfo
output from non-CZI converted tiff (from the first downsample layer):Compared to
tiffinfo
output from CZI converted.ome.tiff
:The key difference being that for lower resolution, higher layer sub-images of the .ome.tiff pyramid, there was no "Tile Width" tag in the metadata. Given that the pyvips error occurred during a step with calling tile workers, I realized there was something wrong with subtiling of the OME-TIFF file during conversion with
bfconvert
.After playing around with a few options, I realized that I could manually set the
tilex
andtiley
during conversion (I also made sure to set only one timepoint to be used for all layers). I chosetilex=512
andtiley=512
, which is smaller than the total x & y dimensions of all sublayers of the WSI. This allows all sublayers to be saved in a tiled format (see Bioformats docs for more info on this option). Ultimately, the following code worked to successfully convert the files:./bfconvert -timepoint 0 -tilex 512 -tiley 512 2023_11_01__8855.czi 2023_11_01__8855_t0_tiles.ome.tiff
Loading with
sf.WSI()
and thenWSI.preview()
worked!