API reference

The package exports two classes:

BdvWriter

class npy2bdv.BdvWriter(filename, subsamp=((1, 1, 1),), blockdim=((4, 256, 256),), compression=None, nilluminations=1, nchannels=1, ntiles=1, nangles=1, overwrite=False, dtype='uint16')[source]

Write numpy arrays into a new HDF5/XML file pair readable by Fiji BigDataViewer and BigStitcher.

A dataset consists of views: 3d stacks, each identified by its time point and four attributes (illumination, channel, tile, angle). The number of each attribute is fixed when the writer is created; views are then added with append_view in any order, and missing views are allowed.

Typical workflow: create the writer, call append_view for every view, then write_xml and close.

Parameters:
  • filename (str) – Path of the .h5 file to create (or of the .xml file; the other file of the pair gets the same name). The XML file is written by write_xml.

  • subsamp (tuple of tuples) – Resolution levels as subsampling factors in (z, y, x) order, integers >= 1. The first level is normally full resolution. Default ((1, 1, 1),): full resolution only. Example with two downsampled levels: ((1, 1, 1), (2, 4, 4), (4, 8, 8)).

  • blockdim (tuple of tuples) – HDF5 block (chunk) size of each level, in pixels, (z, y, x) order. If fewer entries than subsamp are given, the first one is used for all levels. Default ((4, 256, 256),).

  • compression ({None, 'gzip', 'lzf'}) – HDF5 compression. Default None, the fastest for writing.

  • nilluminations (int) – Number of illuminations, channels, tiles and angles, each >= 1. Default 1.

  • nchannels (int) – Number of illuminations, channels, tiles and angles, each >= 1. Default 1.

  • ntiles (int) – Number of illuminations, channels, tiles and angles, each >= 1. Default 1.

  • nangles (int) – Number of illuminations, channels, tiles and angles, each >= 1. Default 1.

  • overwrite (bool) – If True, an existing file is replaced. If False (default), an existing file raises FileExistsError.

  • dtype ({'uint16', 'uint8', 'float32'}) – Pixel type of all views, default ‘uint16’. Input arrays are cast to this type. If that changes values (out of range, or fractions lost), a UserWarning is issued. Types other than uint16 need BigDataViewer-core >= 10.4.6 (any Fiji updated since 2023).

Notes

Recommended HDF5 block size is between 10 KB and 1 MB: e.g. (4, 256, 256) px of uint16 is 0.5 MB and writes fast. Blocks can be larger than the stack.

Examples

>>> import numpy as np, npy2bdv
>>> stack = np.random.randint(0, 1000, (64, 512, 512), dtype=np.uint16)
>>> writer = npy2bdv.BdvWriter("dataset.h5", nchannels=2)
>>> writer.append_view(stack, time=0, channel=0)
>>> writer.append_view(stack, time=0, channel=1)
>>> writer.write_xml()
>>> writer.close()
append_affine(m_affine, name_affine='Appended affine transformation using npy2bdv.', time=0, illumination=0, channel=0, tile=0, angle=0)

Append an affine transformation to a view, on top of the existing ones.

The new transformation is placed at the top of the list, so BigDataViewer/BigStitcher applies it last. The XML file is written immediately. With BdvWriter, call BdvWriter.write_xml first, so that the XML file exists.

Parameters:
  • m_affine (numpy.ndarray) – Array of shape (3, 4). The first three columns are the images of the x, y, z unit vectors (rotation, scaling, shear), the last column is the translation (x, y, z), in pixels.

  • name_affine (str, optional) – Name of the transformation, shown in BigStitcher.

  • time (int) – Time point index, >= 0.

  • illumination (int) – Indices of the view attributes, >= 0.

  • channel (int) – Indices of the view attributes, >= 0.

  • tile (int) – Indices of the view attributes, >= 0.

  • angle (int) – Indices of the view attributes, >= 0.

Examples

Shift tile 1 by 100 px in x:

>>> shift = np.array([[1., 0, 0, 100], [0, 1, 0, 0], [0, 0, 1, 0]])
>>> editor.append_affine(shift, name_affine="tile shift", tile=1)
append_plane(plane, z, time=0, illumination=0, channel=0, tile=0, angle=0)[source]

Write one plane into a virtual stack.

The virtual stack must first be allocated with append_view(stack=None, virtual_stack_dim=(nz, ny, nx), ...) for the same view. Planes can be written in any order. Downsampled levels are computed per plane, so all subsampling factors in z must be 1, e.g. subsamp=((1, 1, 1), (1, 4, 4)).

Parameters:
  • plane (numpy.ndarray) – 2d array of shape (ny, nx), equal to the (y, x) size of the virtual stack.

  • z (int) – Plane index in the virtual stack, 0 <= z < nz.

  • time (int) – Time point index, >= 0.

  • illumination (int) – Indices of the view attributes, >= 0.

  • channel (int) – Indices of the view attributes, >= 0.

  • tile (int) – Indices of the view attributes, >= 0.

  • angle (int) – Indices of the view attributes, >= 0.

Examples

>>> writer.append_view(stack=None, virtual_stack_dim=(1000, 2048, 2048))
>>> for z in range(1000):
...     writer.append_plane(camera.get_frame(), z=z)
append_substack(substack, z_start, y_start=0, x_start=0, time=0, illumination=0, channel=0, tile=0, angle=0)[source]

Write a 3d block (substack) into a virtual stack.

The virtual stack must first be allocated with append_view(stack=None, virtual_stack_dim=(nz, ny, nx), ...) for the same view. Substacks can be written in any order and need not align with the subsampling factors: downsampled levels are recomputed from the full-resolution data, so the final pyramid is the same as for append_view with the whole stack. Unlike append_plane, subsampling in z is allowed.

Parameters:
  • substack (numpy.ndarray) – 3d array in (z, y, x) order. It must fit inside the virtual stack at the given offsets.

  • z_start (int) – Offsets of the substack in the virtual stack, in pixels. y_start and x_start default to 0.

  • y_start (int) – Offsets of the substack in the virtual stack, in pixels. y_start and x_start default to 0.

  • x_start (int) – Offsets of the substack in the virtual stack, in pixels. y_start and x_start default to 0.

  • time (int) – Time point index, >= 0.

  • illumination (int) – Indices of the view attributes, >= 0.

  • channel (int) – Indices of the view attributes, >= 0.

  • tile (int) – Indices of the view attributes, >= 0.

  • angle (int) – Indices of the view attributes, >= 0.

Examples

>>> writer.append_view(stack=None, virtual_stack_dim=(400, 2048, 2048))
>>> for z0 in range(0, 400, 100):
...     writer.append_substack(load_chunk(z0), z_start=z0)
append_view(stack, virtual_stack_dim=None, time=0, illumination=0, channel=0, tile=0, angle=0, m_affine=None, name_affine='manually defined', voxel_size_xyz=(1, 1, 1), voxel_units='px', calibration=(1, 1, 1), exposure_time=0, exposure_units='s')[source]

Write a 3d stack as one view, or allocate a virtual stack to be filled later.

A view is identified by time and the attribute indices. Writing the same view twice replaces it. All resolution levels given in subsamp are computed and written immediately.

Parameters:
  • stack (numpy.ndarray or None) – 3d array in (z, y, x) order. It is cast to the writer’s dtype, with a UserWarning if that changes values. If None, an empty virtual stack of shape virtual_stack_dim is allocated, to be filled with append_plane or append_substack (for data larger than RAM).

  • virtual_stack_dim (tuple of int, optional) – (nz, ny, nx) shape of the virtual stack. Required if stack is None.

  • time (int) – Time point index, >= 0.

  • illumination (int) – Indices of the view attributes, >= 0 and below the numbers given to the writer.

  • channel (int) – Indices of the view attributes, >= 0 and below the numbers given to the writer.

  • tile (int) – Indices of the view attributes, >= 0 and below the numbers given to the writer.

  • angle (int) – Indices of the view attributes, >= 0 and below the numbers given to the writer.

  • m_affine (numpy.ndarray, optional) – Affine transformation of shape (3, 4) applied to this view in BigDataViewer, e.g. the tile position (last column: translation x, y, z in pixels) or a shear correction.

  • name_affine (str, optional) – Name of the affine transformation, shown in BigStitcher.

  • voxel_size_xyz (tuple of float) – Physical voxel size (x, y, z) in voxel_units. Default (1, 1, 1).

  • voxel_units (str) – Unit of the voxel size, e.g. ‘um’. Default ‘px’.

  • calibration (tuple of float) – Scaling (x, y, z) written as the ‘calibration’ transform. Default (1, 1, 1). To display anisotropic voxels at the correct aspect ratio, set e.g. (1, 1, 4) for z-steps 4x larger than the pixel size.

  • exposure_time (float) – Camera exposure time, stored as metadata. Default 0.

  • exposure_units (str) – Unit of the exposure time. Default ‘s’.

Raises:

ValueError – If the shape differs from the shape of the same setup at another time point: the XML file stores one shape per setup.

Examples

>>> writer.append_view(stack, time=0, channel=1, voxel_size_xyz=(0.5, 0.5, 2), voxel_units='um')
close()[source]

Flush and close the H5 file. Call it last, after write_xml.

create_pyramids(subsamp=((4, 8, 8),), blockdim=((8, 128, 128),), compression=None) → None

Compute and write downsampled resolution levels (pyramids) of all views already written.

Use it for “lazy” downsampling: write raw full-resolution data at full speed during acquisition, then call this method once before write_xml. The writer must have been created with a single resolution level (the default subsamp).

Parameters:
  • subsamp (tuple of tuples) – Additional subsampling levels in (z, y, x) order, integers >= 1, e.g. ((2, 4, 4), (4, 8, 8)). The full-resolution level is kept and does not need to be listed.

  • blockdim (tuple of tuples) – HDF5 block (chunk) size of each new level, in (z, y, x) order, same length as subsamp.

  • compression ({None, 'gzip', 'lzf'}) – HDF5 compression of the new levels. Default None.

Examples

>>> writer = npy2bdv.BdvWriter("raw.h5")
>>> writer.append_view(stack)
>>> writer.create_pyramids(subsamp=((2, 4, 4),), blockdim=((16, 64, 64),))
>>> writer.write_xml()
>>> writer.close()
read_affine(time=0, illumination=0, channel=0, tile=0, angle=0, index=0)

Read an affine transformation of a view from the XML file.

A view can have several transformations (e.g. calibration, then registration). They are stored as a list in the XML file; BigDataViewer applies them bottom to top.

Parameters:
  • time (int) – Time point index, >= 0.

  • illumination (int) – Indices of the view attributes, >= 0.

  • channel (int) – Indices of the view attributes, >= 0.

  • tile (int) – Indices of the view attributes, >= 0.

  • angle (int) – Indices of the view attributes, >= 0.

  • index (int) – Index of the transformation in the list. Default 0 is the top one, which is applied last.

Returns:

Float array of shape (3, 4). The first three columns are the linear part, the last column is the translation (x, y, z).

Return type:

numpy.ndarray

Examples

>>> editor = npy2bdv.BdvEditor("dataset.xml")
>>> affine = editor.read_affine(time=0, tile=1)
set_attribute_labels(attribute: str, labels: tuple) → None[source]

Set names of attribute values, shown in BigDataViewer/BigStitcher instead of 0, 1, 2…

Call before write_xml.

Parameters:
  • attribute ({'illumination', 'channel', 'tile', 'angle'}) – The view attribute to label.

  • labels (tuple of str) – One label per attribute value, e.g. ('488', '561') for 2 channels or ('left', 'right') for 2 illuminations. Length must equal the number of values of this attribute.

Examples

>>> writer.set_attribute_labels('channel', ('488', '561'))
write_xml(camera_name='default', microscope_name='default', microscope_version='0.0', user_name='user')[source]

Write the XML file that describes the dataset. Call it after all views are written.

The XML file lists views, their attributes, voxel sizes, transformations and missing views, and points to the .h5 file by relative path. Fiji opens the dataset via this file.

Parameters:
  • camera_name (str) – Camera name, stored as metadata for all views.

  • microscope_name (str) – Stored as metadata in the <generatedBy> element.

  • microscope_version (str) – Stored as metadata in the <generatedBy> element.

  • user_name (str) – Stored as metadata in the <generatedBy> element.

BdvEditor

class npy2bdv.BdvEditor(filename, mode='r+')[source]

Read and edit an existing BigDataViewer HDF5/XML file pair.

Works with files written by npy2bdv, Fiji/BigStitcher, or any other tool using the BigDataViewer HDF5 format. The pixel type (uint16, uint8, float32) is detected from the H5 file.

Warning

Edits (crop_view, append_affine) change the files in place, without undo. finalize keeps a backup of the previous XML file as <name>.xml~1.

Parameters:
  • filename (str) – Path to the .xml or the .h5 file. Both files must exist. Given an .xml file, the .h5 file it points to is used, so several XML files sharing one H5 file are supported.

  • mode ({'r+', 'r'}) – ‘r+’ (default) for reading and editing, ‘r’ for read-only access.

ntimes, nilluminations, nchannels, ntiles, nangles

Number of time points and view attributes, read from the XML file.

Type:

int

dtype

Pixel type of the views.

Type:

numpy.dtype

Examples

>>> editor = npy2bdv.BdvEditor("dataset.xml", mode='r')
>>> stack = editor.read_view(time=0, channel=1)
>>> editor.finalize()
append_affine(m_affine, name_affine='Appended affine transformation using npy2bdv.', time=0, illumination=0, channel=0, tile=0, angle=0)

Append an affine transformation to a view, on top of the existing ones.

The new transformation is placed at the top of the list, so BigDataViewer/BigStitcher applies it last. The XML file is written immediately. With BdvWriter, call BdvWriter.write_xml first, so that the XML file exists.

Parameters:
  • m_affine (numpy.ndarray) – Array of shape (3, 4). The first three columns are the images of the x, y, z unit vectors (rotation, scaling, shear), the last column is the translation (x, y, z), in pixels.

  • name_affine (str, optional) – Name of the transformation, shown in BigStitcher.

  • time (int) – Time point index, >= 0.

  • illumination (int) – Indices of the view attributes, >= 0.

  • channel (int) – Indices of the view attributes, >= 0.

  • tile (int) – Indices of the view attributes, >= 0.

  • angle (int) – Indices of the view attributes, >= 0.

Examples

Shift tile 1 by 100 px in x:

>>> shift = np.array([[1., 0, 0, 100], [0, 1, 0, 0], [0, 0, 1, 0]])
>>> editor.append_affine(shift, name_affine="tile shift", tile=1)
crop_view(bbox_xyz=((1, -1), (1, -1), None), illumination=0, channel=0, tile=0, angle=0, ilevel=0)[source]

Crop a view in place, for all time points, in the H5 file and the XML file.

The H5 data is cropped immediately; the new view size is written to the XML file by finalize. Only the given resolution level is cropped.

Parameters:
  • bbox_xyz (tuple) – Crop ranges ((x_start, x_stop), (y_start, y_stop), (z_start, z_stop)), each used as a Python slice (negative values count from the end). None leaves that axis uncropped. Default ((1, -1), (1, -1), None) removes a 1-px border in x and y.

  • illumination (int) – Indices of the view attributes, >= 0.

  • channel (int) – Indices of the view attributes, >= 0.

  • tile (int) – Indices of the view attributes, >= 0.

  • angle (int) – Indices of the view attributes, >= 0.

  • ilevel (int) – Resolution level to crop, default 0.

Examples

>>> editor = npy2bdv.BdvEditor("dataset.xml")
>>> editor.crop_view(bbox_xyz=((100, -100), None, (10, 200)), channel=0)
>>> editor.finalize()
finalize()[source]

Save pending changes and close the files. Call it when done with the editor.

The H5 file is flushed and closed. If the XML tree was loaded (by read_affine, append_affine, crop_view or get_view_property), the XML file is rewritten, and the previous version is kept as <name>.xml~1.

get_attribute_count()[source]

Count time points and view attributes in the XML file.

Returns:

(ntimes, nilluminations, nchannels, ntiles, nangles). The same values are available as editor attributes.

Return type:

tuple of int

get_view_property(key, illumination=0, channel=0, tile=0, angle=0) → tuple[source]

Read a property of a view setup from the XML file.

Setups do not change over time, so no time index is needed.

Parameters:
  • key ({'voxel_size', 'view_shape'}) – ‘voxel_size’: physical voxel size (floats); ‘view_shape’: view size in pixels (ints).

  • illumination (int) – Indices of the view attributes, >= 0.

  • channel (int) – Indices of the view attributes, >= 0.

  • tile (int) – Indices of the view attributes, >= 0.

  • angle (int) – Indices of the view attributes, >= 0.

Returns:

Value in (x, y, z) order, as stored in the XML file. Note that read_view returns arrays in (z, y, x) order.

Return type:

tuple

Examples

>>> editor.get_view_property('voxel_size')
(0.5, 0.5, 2.0)
read_affine(time=0, illumination=0, channel=0, tile=0, angle=0, index=0)

Read an affine transformation of a view from the XML file.

A view can have several transformations (e.g. calibration, then registration). They are stored as a list in the XML file; BigDataViewer applies them bottom to top.

Parameters:
  • time (int) – Time point index, >= 0.

  • illumination (int) – Indices of the view attributes, >= 0.

  • channel (int) – Indices of the view attributes, >= 0.

  • tile (int) – Indices of the view attributes, >= 0.

  • angle (int) – Indices of the view attributes, >= 0.

  • index (int) – Index of the transformation in the list. Default 0 is the top one, which is applied last.

Returns:

Float array of shape (3, 4). The first three columns are the linear part, the last column is the translation (x, y, z).

Return type:

numpy.ndarray

Examples

>>> editor = npy2bdv.BdvEditor("dataset.xml")
>>> affine = editor.read_affine(time=0, tile=1)
read_view(time=0, illumination=0, channel=0, tile=0, angle=0, ilevel=0, z=None)[source]

Read a view, or a single plane of it, into a numpy array.

Parameters:
  • time (int) – Time point index, >= 0.

  • illumination (int) – Indices of the view attributes, >= 0.

  • channel (int) – Indices of the view attributes, >= 0.

  • tile (int) – Indices of the view attributes, >= 0.

  • angle (int) – Indices of the view attributes, >= 0.

  • ilevel (int) – Resolution level: 0 (default) is full resolution, 1, 2… are the downsampled levels.

  • z (int, optional) – If given, read only this plane (faster than reading the whole stack).

Returns:

3d array (z, y, x), or 2d array (y, x) if z is given, of type dtype.

Return type:

numpy.ndarray

Raises:

KeyError – If the view or level does not exist in the H5 file (e.g. a missing view).

Examples

>>> stack = editor.read_view(time=0, channel=1)
>>> preview = editor.read_view(ilevel=2)
>>> plane = editor.read_view(z=100)