obffile

Read Imspector object binary format files (OBF and MSR).

Obffile is a Python library to read image and metadata from Object Binary Format (OBF) and Measurement Summary Record (MSR) image files. These files are written by Imspector software to store image and metadata from microscopy experiments.

Author:

Christoph Gohlke

License:

BSD-3-Clause

Version:

2026.2.20

Quickstart

Install the obffile package and all dependencies from the Python Package Index:

python -m pip install -U obffile[all]

See Examples for using the programming interface.

Source code and support are available on GitHub.

Requirements

This revision was tested with the following requirements and dependencies (other versions may work):

Revisions

2026.2.20

  • Initial alpha release.

Notes

Imspector is a software platform for super-resolution and confocal microscopy developed by Abberior Instruments.

This library is in its early stages of development. It is not feature-complete. Large, backwards-incompatible changes may occur between revisions.

Specifically, the following features are not supported: writing or modifying OBF/MSR files, non-OBF based MSR files, reading MSR-specific non-image data (window positions, hardware configuration), and compression types other than zlib.

The library has been tested with a limited number of files only.

The Imspector image file formats are documented at https://imspectordocs.readthedocs.io/en/latest/fileformat.html.

Other implementations for reading Imspector image files are msr-reader, obf_support.py, and bio-formats.

Examples

Read an image stack and metadata from a OBF file:

>>> with ObfFile('tests/data/Test.obf') as obf:
...     assert obf.header.metadata['ome_xml'].startswith('<?xml')
...     for stack in obf.stacks:
...         _ = stack.name, stack.dims, stack.shape, stack.dtype
...     obf.stacks[0].asxarray()
...
<xarray.DataArray 'Abberior STAR RED.Confocal' (T: 18, Z: 2, Y: 339, X: 381)...
array([[[[0, 0, 0, ..., 3, 3, 3],
         [0, 0, 0, ..., 4, 3, 3],
         ...,
         [0, 0, 0, ..., 0, 0, 0],
         [0, 0, 0, ..., 0, 0, 0]]]], shape=(18, 2, 339, 381), dtype=int16)
Coordinates:
    * T        (T) float64 144B 0.0 0.0 0.0 0.0 0.0 0.0 ...
    * Z        (Z) float64 16B 1.25e-07 3.75e-07
    * Y        (Y) float64 3kB 0.0 2e-07 4e-07 ...
    * X        (X) float64 3kB 0.0 2.002e-07 4.003e-07 ...
...

View the image stack and metadata in a OBF file from the console:

$ python -m obffile tests/data/Test.obf

License

Copyright (c) 2025-2026, Christoph Gohlke
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

obffile module

obffile.__version__ = '2026.2.20'

Obffile version string.

final class obffile.ObfFile(file, /, *, squeeze=True, mode=None)

Bases: BinaryFile

Object Binary Format file.

ObfFile instances are not thread-safe. All attributes are read-only.

ObfFile instances must be closed with ObfFile.close(), which is automatically called when using the ‘with’ context manager.

Parameters:
  • file (str | os.PathLike[Any] | IO[bytes]) – Name of Object Binary Format file or seekable binary stream.

  • mode (Literal['r', 'r+'] | None) – File open mode if file is file name. The default is ‘r’. Files are always opened in binary mode.

  • squeeze (bool) – Remove dimensions of length one from stacks.

Raises:

ObfFileError – File is not in Object Binary Format or is corrupted.

__init__(file, /, *, squeeze=True, mode=None)
Parameters:
  • file (str | os.PathLike[Any] | IO[bytes])

  • squeeze (bool)

  • mode (Literal['r', 'r+'] | None)

Return type:

None

header: ObfFileHeader

Parsed OBF file header.

property stacks: ObfStackSequence

Sequence of image stacks in file.

__str__()

Return str(self).

Return type:

str

class obffile.ObfFileError

Bases: ValueError

Exception to indicate invalid Object Binary Format file structure.

__weakref__

list of weak references to the object

class obffile.ObfFileHeader(format_version, description, first_stack_pos, meta_data_position, metadata)

Bases: object

OBF file header (OMAS_BF).

Parameters:
  • format_version (int)

  • description (str)

  • first_stack_pos (int)

  • meta_data_position (int | None)

  • metadata (dict[str, str])

format_version: int

File format version.

description: str

File-level XML description string.

first_stack_pos: int

File offset of first stack header.

meta_data_position: int | None

File offset of file-level tag dictionary, or None.

metadata: dict[str, str]

File-level tag dictionary (for example, 'ome_xml').

__str__()

Return str(self).

Return type:

str

classmethod fromfile(fh)

Read and validate OBF file header from open file.

Parameters:

fh (IO[bytes])

Return type:

Self

__delattr__(name)

Implement delattr(self, name).

__eq__(other)

Return self==value.

__getstate__()

Helper for pickle.

__hash__()

Return hash(self).

__init__(format_version, description, first_stack_pos, meta_data_position, metadata)
Parameters:
  • format_version (int)

  • description (str)

  • first_stack_pos (int)

  • meta_data_position (int | None)

  • metadata (dict[str, str])

Return type:

None

__repr__()

Return repr(self).

__setattr__(name, value)

Implement setattr(self, name, value).

class obffile.ObfSiUnit(meters, kilograms, seconds, amperes, kelvin, moles, candela, radian, steradian, scale_factor)

Bases: object

SI unit stored as rational exponents and scale factor.

Each base-unit field is a (numerator, denominator) int32 pair.

Parameters:
  • meters (tuple[int, int])

  • kilograms (tuple[int, int])

  • seconds (tuple[int, int])

  • amperes (tuple[int, int])

  • kelvin (tuple[int, int])

  • moles (tuple[int, int])

  • candela (tuple[int, int])

  • radian (tuple[int, int])

  • steradian (tuple[int, int])

  • scale_factor (float)

__delattr__(name)

Implement delattr(self, name).

__eq__(other)

Return self==value.

__getstate__()

Helper for pickle.

__hash__()

Return hash(self).

__init__(meters, kilograms, seconds, amperes, kelvin, moles, candela, radian, steradian, scale_factor)
Parameters:
  • meters (tuple[int, int])

  • kilograms (tuple[int, int])

  • seconds (tuple[int, int])

  • amperes (tuple[int, int])

  • kelvin (tuple[int, int])

  • moles (tuple[int, int])

  • candela (tuple[int, int])

  • radian (tuple[int, int])

  • steradian (tuple[int, int])

  • scale_factor (float)

Return type:

None

__repr__()

Return repr(self).

__setattr__(name, value)

Implement setattr(self, name, value).

__str__()

Return str(self).

Return type:

str

classmethod fromfile(fh)

Read one SI unit record from fh.

Parameters:

fh (IO[bytes])

Return type:

ObfSiUnit

class obffile.ObfStack(fh, *, squeeze)

Bases: object

Image stack inside OBF file.

Parameters:
  • fh (IO[bytes])

  • squeeze (bool)

__init__(fh, *, squeeze)
Parameters:
  • fh (IO[bytes])

  • squeeze (bool)

Return type:

None

header: ObfStackHeader

Parsed stack header.

footer: ObfStackFooter

Parsed stack footer.

property name: str

Stack name.

property dtype: numpy.dtype[Any]

NumPy data type of image stack.

property sizes: dict[str, int]

Ordered mapping of dimension name to length.

property shape: tuple[int, ...]

Shape of image stack.

property dims: tuple[str, ...]

Dimension names of image stack.

property ndim: int

Number of image stack dimensions.

property nbytes: int

Number of bytes consumed by image stack.

property size: int

Number of elements in image stack.

property coords: dict[str, NDArray[Any]]

Mapping of dimension names to physical coordinate arrays.

property attrs: dict[str, Any]

Image stack metadata as dict.

asarray()

Return image stack data as NumPy array.

Return type:

NDArray[Any]

asxarray()

Return image stack as xarray DataArray.

Return type:

DataArray

__str__()

Return str(self).

Return type:

str

__repr__()

Return repr(self).

Return type:

str

__weakref__

list of weak references to the object

class obffile.ObfStackFooter(size=0, has_col_positions=<factory>, has_col_labels=<factory>, metadata_length=0, si_value=None, si_dimensions=<factory>, num_flush_points=0, flush_block_size=None, tag_dictionary_length=None, stack_end_disk=None, min_format_version=None, stack_end_used_disk=None, samples_written=None, num_chunk_positions=None, labels=<factory>, col_positions=<factory>, col_labels=<factory>, metadata='', flush_positions=<factory>, tag_dictionary=<factory>, chunk_positions=<factory>)

Bases: object

OBF stack footer (version-incremental).

Parameters:
  • size (int)

  • has_col_positions (tuple[int, ...])

  • has_col_labels (tuple[int, ...])

  • metadata_length (int)

  • si_value (ObfSiUnit | None)

  • si_dimensions (list[ObfSiUnit])

  • num_flush_points (int)

  • flush_block_size (int | None)

  • tag_dictionary_length (int | None)

  • stack_end_disk (int | None)

  • min_format_version (int | None)

  • stack_end_used_disk (int | None)

  • samples_written (int | None)

  • num_chunk_positions (int | None)

  • labels (list[str])

  • col_positions (dict[int, tuple[float, ...]])

  • col_labels (dict[int, list[str]])

  • metadata (str)

  • flush_positions (list[int])

  • tag_dictionary (dict[str, str])

  • chunk_positions (list[tuple[int, int]])

__eq__(other)

Return self==value.

__init__(size=0, has_col_positions=<factory>, has_col_labels=<factory>, metadata_length=0, si_value=None, si_dimensions=<factory>, num_flush_points=0, flush_block_size=None, tag_dictionary_length=None, stack_end_disk=None, min_format_version=None, stack_end_used_disk=None, samples_written=None, num_chunk_positions=None, labels=<factory>, col_positions=<factory>, col_labels=<factory>, metadata='', flush_positions=<factory>, tag_dictionary=<factory>, chunk_positions=<factory>)
Parameters:
  • size (int)

  • has_col_positions (tuple[int, ...])

  • has_col_labels (tuple[int, ...])

  • metadata_length (int)

  • si_value (ObfSiUnit | None)

  • si_dimensions (list[ObfSiUnit])

  • num_flush_points (int)

  • flush_block_size (int | None)

  • tag_dictionary_length (int | None)

  • stack_end_disk (int | None)

  • min_format_version (int | None)

  • stack_end_used_disk (int | None)

  • samples_written (int | None)

  • num_chunk_positions (int | None)

  • labels (list[str])

  • col_positions (dict[int, tuple[float, ...]])

  • col_labels (dict[int, list[str]])

  • metadata (str)

  • flush_positions (list[int])

  • tag_dictionary (dict[str, str])

  • chunk_positions (list[tuple[int, int]])

Return type:

None

__repr__()

Return repr(self).

size: int

Total size of fixed footer region in bytes.

has_col_positions: tuple[int, ...]

non-zero if physical column positions are stored.

Type:

Per-axis flag

has_col_labels: tuple[int, ...]

non-zero if column label strings are stored.

Type:

Per-axis flag

metadata_length: int

Length in bytes of legacy metadata string.

si_value: ObfSiUnit | None

SI unit of pixel (sample) values.

si_dimensions: list[ObfSiUnit]

SI units of coordinate axes.

num_flush_points: int

Number of zlib flush points.

flush_block_size: int | None

Block size between flush points.

tag_dictionary_length: int | None

Byte length of stack-level tag dictionary.

stack_end_disk: int | None

File offset past end of complete stack.

min_format_version: int | None

Minimum format version required to read this stack.

stack_end_used_disk: int | None

File offset past actually written data.

samples_written: int | None

Number of samples actually written (0 = all expected).

num_chunk_positions: int | None

Number of interleaved-chunk position entries.

labels: list[str]

Axis label strings for each dimension.

col_positions: dict[int, tuple[float, ...]]

Physical position arrays keyed by axis index.

col_labels: dict[int, list[str]]

Column label strings keyed by axis index.

metadata: str

Legacy metadata string.

flush_positions: list[int]

File offsets of zlib flush points.

tag_dictionary: dict[str, str]

Stack-level tag dictionary.

chunk_positions: list[tuple[int, int]]

Interleaved-chunk entries as (logical_offset, file_offset) pairs.

__str__()

Return str(self).

Return type:

str

classmethod fromfile(fh, header)

Read OBF stack footer from open file.

Parameters:
Return type:

Self

class obffile.ObfStackHeader(format_version, rank, res, lengths, offsets, data_type, compression_type, compression_level, name, description, data_pos, data_length, next_stack_pos)

Bases: object

OBF stack header (OMAS_BF_STACK).

Parameters:
  • format_version (int)

  • rank (int)

  • res (tuple[int, ...])

  • lengths (tuple[float, ...])

  • offsets (tuple[float, ...])

  • data_type (int)

  • compression_type (int)

  • compression_level (int)

  • name (str)

  • description (str)

  • data_pos (int)

  • data_length (int)

  • next_stack_pos (int)

format_version: int

Stack format version.

rank: int

Number of active dimensions.

res: tuple[int, ...]

Number of pixels along each dimension (first rank values).

lengths: tuple[float, ...]

Physical length along each dimension in metres.

offsets: tuple[float, ...]

Physical offset along each dimension in metres.

data_type: int

OMAS_DT flags encoding element type.

compression_type: int

0 = uncompressed, 1 = zlib.

compression_level: int

Zlib compression level.

name: str

Stack name.

description: str

Stack XML description string.

data_pos: int

File offset of first data byte.

data_length: int

Number of data bytes on disk.

next_stack_pos: int

File offset of next stack header, or 0 if last stack.

__str__()

Return str(self).

Return type:

str

classmethod fromfile(fh)

Read OBF stack header from open file.

Parameters:

fh (IO[bytes])

Return type:

Self

__delattr__(name)

Implement delattr(self, name).

__eq__(other)

Return self==value.

__getstate__()

Helper for pickle.

__hash__()

Return hash(self).

__init__(format_version, rank, res, lengths, offsets, data_type, compression_type, compression_level, name, description, data_pos, data_length, next_stack_pos)
Parameters:
  • format_version (int)

  • rank (int)

  • res (tuple[int, ...])

  • lengths (tuple[float, ...])

  • offsets (tuple[float, ...])

  • data_type (int)

  • compression_type (int)

  • compression_level (int)

  • name (str)

  • description (str)

  • data_pos (int)

  • data_length (int)

  • next_stack_pos (int)

Return type:

None

__repr__()

Return repr(self).

__setattr__(name, value)

Implement setattr(self, name, value).

final class obffile.ObfStackSequence(parent, /)

Bases: Sequence[ObfStack]

Sequence of stacks in OBF file.

Parameters:

parent (ObfFile)

__init__(parent, /)
Parameters:

parent (ObfFile)

Return type:

None

find(key, /, *, flags=re.IGNORECASE, default=None)

Return first stack with name matching pattern, if any.

Parameters:
  • key (str) – Regular expression pattern to match ObfStack name.

  • flags (int) – Regular expression flags.

  • default (Any) – Value to return if no stack with matching name found.

Return type:

ObfStack | None

findall(key, /, *, flags=re.IGNORECASE)

Return all stacks with name matching pattern.

Parameters:
  • key (str) – Regular expression pattern to match ObfStack name.

  • flags (int) – Regular expression flags.

Return type:

tuple[ObfStack, …]

__getitem__(key, /)

Return stack at index or first stack with name matching pattern.

Raises:
  • IndexError – if integer index out of range.

  • KeyError – if no stack with matching name pattern found.

Parameters:

key (int | str)

Return type:

ObfStack

__repr__()

Return repr(self).

Return type:

str

__str__()

Return str(self).

Return type:

str

obffile.imread(file: str | os.PathLike[Any] | IO[bytes], /, stack: int = 0, *, squeeze: bool = True, asxarray: Literal[False] = False) NDArray[Any]
obffile.imread(file: str | os.PathLike[Any] | IO[bytes], /, stack: int = 0, *, squeeze: bool = True, asxarray: Literal[True] = False) DataArray

Return image stack from Object Binary Format file.

Dimensions are returned in order stored in file.

Parameters:
  • file (str | os.PathLike[Any] | IO[bytes]) – Name of Object Binary Format file or seekable binary stream.

  • stack (int) – Index of image stack to read.

  • squeeze (bool) – Remove dimensions of length one from stacks.

  • asxarray (bool) – Return image data as xarray.DataArray instead of numpy.ndarray.

Returns:

Image stack data as numpy array or xarray DataArray.

Return type:

NDArray[Any] | DataArray

obffile.FILE_EXTENSIONS