ZEISS / pylibczirw

A simple and easy-to-use Python wrapper for libCZI - a cross-platform C++ library intended for providing read and write access to CZI documents.
https://zeiss.github.io/pylibczirw/
GNU Lesser General Public License v3.0
6 stars 1 forks source link

accessing acquisition tiles using pylibCZIrw #10

Open marius10p opened 3 weeks ago

marius10p commented 3 weeks ago

Describe the bug Cannot access more than one tile using pylibCZIrw. The "V" parameter for the "plane" input contains the correct number of tiles, but only V = 0 returns a non-zero tile. I could not find information about this in the notebook tutorial. I installed pylibCZIrw from pip yesterday.

print(czidoc.total_bounding_box)

{'T': (0, 1), 'Z': (0, 1716), 'C': (0, 2), 'R': (0, 1), 'I': (0, 1), 'H': (0, 1), 
'V': (0, 12), 'B': (0, 1), 'X': (0, 1920), 'Y': (0, 1920)}

To Reproduce

  1. X = czidoc.read(plane={"T": 0, "Z": 0, "C": 0, "V":0}, roi=(0, 0,1920, 1920))
  2. Y = czidoc.read(plane={"T": 0, "Z": 0, "C": 0, "V":1}, roi=(0, 0,1920, 1920))
  3. X contains data from tile 0, Y contains only zeros.

Desktop (please complete the following information):

sebi06 commented 2 weeks ago

Hi @marius10p

the "V" dimension is not for tiles (M-Dimension) but illumination planes. Here are the dimensions:

Information official CZI Dimension Characters: "X":"Width" : width of image [pixel] "Y":"Height" : height of image [pixel] "C":"Channel" : number of channels "Z":"Slice" : number of z-planes "T":"Time" : number of time points "R":"Rotation" "S":"Scene" : contiguous regions of interest in a mosaic image "I":"Illumination" : SPIM direction for LightSheet "B":"Block" : acquisition block (legacy) "M":"Mosaic" : index of tile for compositing a scene "H":"Phase" : e.g. Airy detector fibers "V":"View" : e.g. for SPIM

So what you are looking for is the "M" dimension. But the current API we provide is a "2D Plane-based API" which does not expose the concept of "tiles" to the user (see also: pylibCZIrw.

"At the moment, pylibCZIrw completely abstracts away the subblock concept, both in the reading and in the writing APIs."

So right now pylibCZIrw does not allow you to read "acquisition tiles", but only regions from a 2D plane. What you ask for makes sense and would be a new feature. May I ask what the exact use case is?

marius10p commented 2 weeks ago

Thanks for the explanation, much appreciated. I have acquisitions of 3x4 or 4x4 tiles and I can only get the data out from the top left tile. Is there a way to get the rest of the data out using the current API? It's possible that I just don't understand how scenes work.

zeissmicroscopy commented 2 weeks ago

Hi @marius10p

You can get all tiles at once as one 2D plane if you just leave out the ROI parameter I think.

Scenes are just "tags" for TileRegions and positions. So if you have 2 TileRegions of any size that will give you to scenes, but the "S" dimension is not really an orthogonal dimension like "T" or "Z".

Or image a wellplate with 96 wells where you add 2 positions per well --> 192 scenes

image

marius10p commented 2 weeks ago

Thanks @zeissmicroscopy. If I leave out the roi parameter, I still only get a single tile, 1920x1920x1. I have tried extending the roi region beyond 1920x1920, but the rest comes out black.

zeissmicroscopy commented 2 weeks ago

HI @marius10p

ok, can you share the CZI somewhere? Was it acquired with ZEN Black?

marius10p commented 1 week ago

here is a substack of 1x3 tiles. Thanks for looking into this.

It was acquired with Zen 3.1 (black edition) for Lightsheet.

sebi06 commented 3 days ago

Hi @marius10p

I check the file you send me that this does not contain any tile (no M-Index) but 3 views (V-Index)

{'T': (0, 1), 'Z': (0, 51), 'C': (0, 2), 'R': (0, 1), 'I': (0, 1), 'H': (0, 1), 'V': (0, 3), 'B': (0, 1), 'X': (0, 1920), 'Y': (0, 1920)}

Therefore using the "roi" beyond 1920 x 1920 does not make sense. I think the issue is that you are using the old ZEN Black, which not really writing "official" CZI according to the specs for pylibCZIrw.

So what you know as tiles is treated the the V-Dimension in pylibCZIrw and therefore cannot be addressed with the "roi" parameter.

image

marius10p commented 3 days ago

Thanks, yes I had noticed that, but I also cannot access the data using different V values. I get all zeros when V>0.

marius10p commented 3 days ago

Also, I confirmed with our imaging core that we are in fact running the latest 3.1 version of Zen black (like I said above), and we're only 1 or 2 "hotfixes" behind.

sebi06 commented 3 days ago

meanwhile I think this really might be a bug inside pylibCZIrw, because I can get it to work with aicslibczi, which is also based on our libCZI.

from aicspylibczi import CziFile
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np
from pylibCZIrw import czi as pyczi

filepath = r"F:\Downloads\Gland_1x_3substack.czi"
cmap = "inferno"

# read via aicspylibCZI
czi = CziFile(filepath)

# Get the shape of the data, the coordinate pairs are (start index, size)
print(f"aicspylibCZI - Dimensions: {czi.get_dims_shape()}")

# Load the image slice I want from the file
img1_v0, shp = czi.read_image(Z=13, C=0, V=0)
img1_v1, shp = czi.read_image(Z=13, C=0, V=1)

# read via pylibCZIrw
with pyczi.open_czi(filepath) as czidoc:

    # get the image dimensions as a dictionary, where the key identifies the dimension
    print(f"pylibCZIrw - TotalBoundingBox: {czidoc.total_bounding_box}")

    img2_v0 = czidoc.read(plane={"Z": 13, "C": 0, "V": 0})
    img2_v1 = czidoc.read(plane={"Z": 13, "C": 0, "V": 1})

# show the 2D image plane
fig, ax = plt.subplots(2, 2, figsize=(12, 12))
ax[0, 0].imshow(np.squeeze(img1_v0), cmap=cmap, vmin=img1_v0.min(), vmax=img1_v0.max())
ax[0, 1].imshow(img2_v0[..., 0], cmap=cmap, vmin=img2_v0.min(), vmax=img2_v0.max())
ax[0, 0].set_title("Z=13, C=0, V=0 by aicspylibczi")
ax[0, 1].set_title("Z=13, C=0, V=0 by pylibczirw")

ax[1, 0].imshow(np.squeeze(img1_v1), cmap=cmap, vmin=img1_v1.min(), vmax=img1_v1.max())
ax[1, 1].imshow(img2_v1[..., 0], cmap=cmap, vmin=img2_v1.min(), vmax=img2_v1.max())
ax[1, 0].set_title("Z=13, C=0, V=1 by aicspylibczi")
ax[1, 1].set_title("Z=13, C=0, V=1 by pylibczirw")
plt.show()

gives me this:

aicspylibCZI - Dimensions: [{'X': (0, 1920), 'Y': (0, 1920), 'Z': (0, 51), 'C': (0, 2), 'T': (0, 1), 'R': (0, 1), 'S': (0, 1), 'I': (0, 1), 'H': (0, 1), 'V': (0, 3), 'B': (0, 1)}]
pylibCZIrw - TotalBoundingBox: {'T': (0, 1), 'Z': (0, 51), 'C': (0, 2), 'R': (0, 1), 'I': (0, 1), 'H': (0, 1), 'V': (0, 3), 'B': (0, 1), 'X': (0, 1920), 'Y': (0, 1920)}

image