Convert Micromanager multidimensional tiff data into zarr format

This notebook explains how to use Pycromanger to readout the multi-dimensional data saved by Micro-manager and convert it into zarr format.

This is useful when the multi-dimensional data is large (more than hundreds of GBs). Currently there is no python reader that can directly readout the large multi-dimensional data saved by Micromanger. Therefore, Pycromanger can be used as a reader to bridge this gap.

To run this notebook, first open Micromanger, then load the multi-dimensional data into Micromanger using virtual stack. Pycromanger will then be able to read out that data via a Java-Python bridge.

After the data is converted to zarr, one can easier load the data into Python and perform downsteam processing.

[19]:
import numpy as np
import zarr

from pycromanager import Bridge

Construct java objects

[20]:
bridge = Bridge()
mm = bridge.get_studio()
ds = mm.displays().get_active_data_viewer().get_data_provider()

Set parameters

[24]:
nb_tp = 500  # number of time points
nb_ch = 2  # number of channels
nz = 600  # number of z slices
ny = 2048  # number of y pixels in each image
nx = 2048  # number of x pixels in each image
save_to = r"D:\zarr_data\data.zarr"  # save to this directory

Create Zarr folder

[22]:
if not os.path.isdir(save_to):
    # create new zarr folder
    root = zarr.open(save_to, mode="w")
    ch0 = root.zeros(
        "ch0", shape=(nb_tp, nz, ny, nx), chunks=(1, 64, 512, 512), dtype="i2"
    )
    ch1 = root.zeros(
        "ch1", shape=(nb_ch, nz, ny, nx), chunks=(1, 64, 512, 512), dtype="i2"
    )
    print(root.tree())
[23]:
# open the zarr folder to save data into it
root = zarr.open(save_to, mode="rw")
ch0 = root["ch0"]
ch1 = root["ch1"]

Readout data from MM and save to zarr

[ ]:
data_stack = np.zeros((nz, ny, nx))  # initialize nparray to store a z-stack
for t in range(nb_tp):
    for ch in range(nb_ch):
        for z in range(nb_slices):
            coords_string = "t={0},p=0,c={1},z={2}".format(t, ch, z)
            coords = mm.data().create_coords(coords_string)
            mimg = ds.get_image(coords)
            data_stack[z, :, :] = np.reshape(
                mimg.get_raw_pixels(), newshape=[mimg.get_height(), mimg.get_width()]
            )
        if ch == 0:
            ch0[t, :, :, :] = data_stack
        else:
            ch1[t, :, :, :] = data_stack

bridge.close()