Skip to content

omero/tiles.py

OmeroPy tile helpers

create_full_tile_list(z_indexes, channels, timepoints, width, height, tile_size, weave=False)

Creates a list of all tiles for given dimensions.

Parameters:

Name Type Description Default
z_indexes list[int]

list containing z_indexes to gather

required
channels list[int]

list containing channels to gather

required
timepoints list[int]

list containing timepoints to gather

required
width int

width of full image in pixels

required
height int

height of full image in pixels

required
tile_size tuple[int, int]
required
weave

Interlace tiles from each channel vs default seperate channels.

False

Returns:

Type Description
list

list of (z,c,t,(x,y,w,h)) tiles for use in getTiles

Examples:

>>> createFullTileList((0),(0,2),(0),1000,1000,10,10)
list[
(0,0,0,(0,0,10,10)), (0,0,0,(10,0,10,10))...
(0,2,0,(0,0,10,10)), (0,2,0,(10,0,10,10))...
]

Default will gather each channel separately.

>>> createFullTileList((0),(0,2),(0),1000,1000,10,10, weave=True)
list[
(0,0,0,(0,0,10,10)), (0,2,0,(0,0,10,10)),
(0,0,0,(10,0,10,10)), (0,2,0,(10,0,10,10))...
]

Setting weave True will mix the channels together. Used  for writing RGB images
Source code in lavlab/omero/tiles.py
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
def create_full_tile_list(  # pylint: disable=R0913
    z_indexes: list[int],
    channels: list[int],
    timepoints: list[int],
    width: int,
    height: int,
    tile_size: tuple[int, int],
    weave=False,
) -> list[tuple[int, int, int, tuple[int, int, int, int]]]:
    """
    Creates a list of all tiles for given dimensions.

    Parameters
    ----------
    z_indexes: list[int]
        list containing z_indexes to gather
    channels: list[int]
        list containing channels to gather
    timepoints: list[int]
        list containing timepoints to gather
    width: int
        width of full image in pixels
    height: int
        height of full image in pixels
    tile_size: tuple(int, int)
    weave: bool, Default: False
        Interlace tiles from each channel vs default seperate channels.

    Returns
    -------
    list
        list of (z,c,t,(x,y,w,h)) tiles for use in getTiles


    Examples
    --------
    ```
    >>> createFullTileList((0),(0,2),(0),1000,1000,10,10)
    list[
    (0,0,0,(0,0,10,10)), (0,0,0,(10,0,10,10))...
    (0,2,0,(0,0,10,10)), (0,2,0,(10,0,10,10))...
    ]

    Default will gather each channel separately.

    >>> createFullTileList((0),(0,2),(0),1000,1000,10,10, weave=True)
    list[
    (0,0,0,(0,0,10,10)), (0,2,0,(0,0,10,10)),
    (0,0,0,(10,0,10,10)), (0,2,0,(10,0,10,10))...
    ]

    Setting weave True will mix the channels together. Used  for writing RGB images
    ```
    """
    tile_list = []
    if weave is True:
        orig_c = channels
        channels = [
            0,
        ]
    for z in z_indexes:
        for c in channels:
            for t in timepoints:
                if weave is True:
                    tile_channels = []
                    for channel in orig_c:
                        tile_channels.append(
                            create_tile_list_2d(z, channel, t, width, height, tile_size)
                        )
                    tile_list.extend(interlace_lists(tile_channels))
                else:
                    tile_list.extend(
                        create_tile_list_2d(z, c, t, width, height, tile_size)
                    )

    return tile_list

create_tile_list_2d(z, c, t, size_x, size_y, tile_size)

Creates a list of tile coords for a given 2D plane (z,c,t)

Notes

Tiles are outputed as (z,c,t,(x,y,w,h)) as this is the expected format by omero python bindings. This may cause confusion as numpy uses rows,cols (y,x) instead of x,y.

Parameters:

Name Type Description Default
z int

z index

required
c int

channel

required
t int

timepoint

required
size_x int

width of full image in pixels

required
size_y int

height of full image in pixels

required
tile_size tuple[int, int]

size of tile to gather (x,y)

required

Returns:

Type Description
list

list of (z,c,t,(x,y,w,h)) tiles for use in getTiles

Source code in lavlab/omero/tiles.py
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
def create_tile_list_2d(  # pylint: disable=R0913
    z: int,
    c: int,
    t: int,
    size_x: int,
    size_y: int,  # pylint: disable=R0913
    tile_size: tuple[int, int],
) -> list[tuple[int, int, int, tuple[int, int, int, int]]]:
    """
    Creates a list of tile coords for a given 2D plane (z,c,t)

    Notes
    -----
    Tiles are outputed as (z,c,t,(x,y,w,h)) as this is the expected format by omero python bindings.
    This may cause confusion as numpy uses rows,cols (y,x) instead of x,y.

    Parameters
    ----------
    z: int
        z index
    c: int
        channel
    t: int
        timepoint
    size_x: int
        width of full image in pixels
    size_y: int
        height of full image in pixels
    tile_size: tuple(int, int)
        size of tile to gather (x,y)

    Returns
    -------
    list
        list of (z,c,t,(x,y,w,h)) tiles for use in getTiles
    """
    tile_list = []
    width, height = tile_size
    for y in range(0, size_y, height):
        width, height = tile_size  # reset tile size
        # if tileheight is greater than remaining pixels, get remaining pixels
        height = min(height, size_y - y)
        for x in range(0, size_x, width):
            # if tilewidth is greater than remaining pixels, get remaining pixels
            width = min(width, size_x - x)
            tile_list.append((z, c, t, (x, y, width, height)))
    return tile_list

create_tile_list_from_image(img, rgb=False, include_z=True, include_t=True)

Generates a list of tiles from an omero.model.Image object.

Parameters:

Name Type Description Default
img ImageWrapper

Omero Image object from conn.getObjects().

required
rgb

Puts tile channels next to each other.

False
include_z

get tiles for z indexes

True
include_t

get tiles for timepoints

True

Returns:

Type Description
list

List of (z,c,t,(x,y,w,h)) tiles for use in getTiles.

Source code in lavlab/omero/tiles.py
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
def create_tile_list_from_image(
    img: ImageWrapper, rgb=False, include_z=True, include_t=True
) -> list[tuple[int, int, int, tuple[int, int, int, int]]]:
    """
    Generates a list of tiles from an omero.model.Image object.

    Parameters
    ----------
    img: omero.gateway.ImageWrapper
        Omero Image object from conn.getObjects().
    rgb: bool, Default: False.
        Puts tile channels next to each other.
    include_z: bool, Default: True
        get tiles for z indexes
    include_t: bool, Default: True
        get tiles for timepoints

    Returns
    -------
    list
        List of (z,c,t,(x,y,w,h)) tiles for use in getTiles.
    """
    width = img.getSizeX()
    height = img.getSizeY()
    z_indexes = list(range(img.getSizeZ()))
    timepoints = list(range(img.getSizeT()))
    channels = list(range(img.getSizeC()))

    img._prepareRenderingEngine()  # pylint: disable=W0212
    tile_size = img._re.getTileSize()  # pylint: disable=W0212
    img._re.close()  # pylint: disable=W0212

    if include_t is False:
        timepoints = [
            0,
        ]
    if include_z is False:
        z_indexes = [
            0,
        ]

    return create_full_tile_list(
        z_indexes, channels, timepoints, width, height, tile_size, rgb
    )

get_tiles(img, tiles, res_lvl=None, rps_bypass=True, conn=None)

Pull tiles from omero faster using a ThreadPoolExecutor!

Parameters:

Name Type Description Default
img Image

Omero image.

required
tiles list of tuple[int, int, int, tuple[int, int, int, int]]

List of tiles to pull.

required
res_lvl int

Resolution level to pull, defaults to None.

None
rps_bypass bool

Passthrough to rps bypass option, defaults to True.

True
conn BlitzGateway

Omero blitz gateway if not using omero image object, defaults to None.

None

Yields:

Type Description
tuple[ndarray, tuple[int, int, int, tuple[int, int, int, int]]]

Tile and coords.

Source code in lavlab/omero/tiles.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
def get_tiles(  # pylint: disable=R0914
    img: omero.gateway.Image,
    tiles: list[tuple[int, int, int, tuple[int, int, int, int]]],
    res_lvl: Optional[int] = None,
    rps_bypass: bool = True,
    conn: omero.gateway.BlitzGateway = None,
) -> Generator[
    tuple[np.ndarray, tuple[int, int, int, tuple[int, int, int, int]]], None, None
]:
    """Pull tiles from omero faster using a ThreadPoolExecutor!

    Parameters
    ----------
    img : omero.gateway.Image
        Omero image.
    tiles : list of tuple[int, int, int, tuple[int, int, int, int]]
        List of tiles to pull.
    res_lvl : int, optional
        Resolution level to pull, defaults to None.
    rps_bypass : bool, optional
        Passthrough to rps bypass option, defaults to True.
    conn : omero.gateway.BlitzGateway, optional
        Omero blitz gateway if not using omero image object, defaults to None.

    Yields
    ------
    tuple[np.ndarray, tuple[int, int, int, tuple[int, int, int, int]]]
        Tile and coords.
    """
    with lavlab.ctx.resources.io_pool as tpe:
        if conn is None:
            conn = img._conn  # pylint: disable=W0212
        local = threading.local()

        def work(pix_id, zct, coord, res_lvl, rps_bypass):
            """runs inside a threadpool to get multiple tiles at a time"""
            if getattr(local, "rps", None) is None:
                # need to prepare a thread-specific rps
                local.rps = conn.c.sf.createRawPixelsStore()
                local.rps.setPixelsId(pix_id, rps_bypass)
                if res_lvl is None:
                    res_lvl = local.rps.getResolutionLevels()
                    res_lvl -= 1
                local.rps.setResolutionLevel(res_lvl)
            return local.rps.getTile(*zct, *coord), (*zct, coord)

        def cleanup():
            """cleans out the raw pixels stores after work is done"""
            if hasattr(local, "rps"):
                local.rps.close()
                delattr(local, "rps")

        futures = [
            tpe.submit(
                work,
                img.getPrimaryPixels().getId(),
                (z, c, t),
                coord,
                res_lvl,
                rps_bypass,
            )
            for z, c, t, coord in tiles
        ]
        try:
            for future in as_completed(futures):
                raw_data, (z, c, t, coord) = future.result()
                processed_data = np.frombuffer(raw_data, dtype=np.uint8).reshape(
                    coord[3], coord[2]
                )
                yield processed_data, (z, c, t, coord)
        finally:
            futures = [
                tpe.submit(cleanup)
                for x in range(tpe._max_workers)  # pylint: disable=W0212
            ]  # pylint: disable=W0212
            for future in as_completed(futures):
                future.result()