fbdfile

Read FLIMbox data and related files (FBD, FBF, and FBS.XML).

Fbdfile is a Python library to read FLIMbox data (FBD), firmware (FBF), and setting (FBS.XML) files. The FLIMbox is an FPGA-based device for high bandwidth, multi-channel data collection for fluorescence lifetime-resolved imaging (FLIM) from a pulsed laser scanning confocal microscope. The files are written by SimFCS and ISS VistaVision software.

Author:

Christoph Gohlke

License:

BSD-3-Clause

Version:

2026.3.20

DOI:

10.5281/zenodo.17136073

Quickstart

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

python -m pip install -U fbdfile[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.3.20

  • Frames and asimage methods always refine laser_factor by default (breaking).

  • Add tri-state refine option to frames and asimage methods.

  • Add refine_settings method to refine pixel_dwell_time and laser_factor.

  • Add more decoder settings (not tested).

  • Fix decode to read all bytes from streams and fix skip/count guard.

  • Fix cluster-to-frame-marker mapping in frames fallback path.

  • Fix from_fbs header detection to use fbf_parse_header.

  • Fix decoder_settings to not swallow errors from valid decoders.

  • Use fbd_decode return value to trim markers array.

  • Drop support for Python 3.11.

2026.2.6

  • Fix code review issues.

2026.1.14

  • Improve code quality.

2025.12.12

  • Add attrs property to FbdFile.

  • Improve code quality.

2025.11.8

  • Allow to override FbdFile decoder, firmware, and settings.

  • Always try to load settings from .fbs.xml file.

  • Factor out BinaryFile base class.

  • Derive FbdFileError from ValueError.

  • Build ABI3 wheels.

2025.9.18

  • Fix reading FBF and FBS files from streams.

2025.9.17

  • Make frame_markers a numpy array.

  • Add options to specify number of OpenMP threads.

2025.9.16

  • Initial alpha release based on lfdfiles 2025.7.31.

Notes

The API is not stable yet and might change between revisions.

Python <= 3.11 is no longer supported. 32-bit versions are deprecated.

The latest Microsoft Visual C++ Redistributable for Visual Studio 2015-2022 is required on Windows.

The FLIMbox formats are not documented and might change arbitrarily. This implementation is based on reverse engineering existing files. No guarantee can be made as to the correctness of code and documentation.

SimFCS, a.k.a. Globals for Images, is software for fluorescence image acquisition, analysis, and simulation, developed by Enrico Gratton at UCI.

VistaVision is commercial software for instrument control, data acquisition, and data processing by ISS Inc (Champaign, IL).

Examples

Read a FLIM lifetime image and metadata from an FBD file:

>>> with FbdFile(
...     'tests/data/flimbox_data$CBCO.fbd', pixel_dwell_time=0.937
... ) as fbd:
...     bins, times, markers = fbd.decode()
...     image = fbd.asimage()
>>> image.shape
(1, 2, 256, 256, 64)
>>> print(bins[0, :2], times[:2], markers[:2])
[50 58] [ 0 32] [1944097 2024815]
>>> import numpy
>>> hist = [numpy.bincount(b[b >= 0]) for b in bins]
>>> int(hist[0].argmax())
53

View the histogram and metadata in a FLIMbox data file from the console:

$ python -m fbdfile tests/data/flimbox_data$CBCO.fbd

License

Copyright (c) 2012-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.

fbdfile module

fbdfile.__version__ = '2026.3.20'

Fbdfile version string.

final class fbdfile.FbdFile(file, /, *, mode=None, code='', decoder=None, fbf=None, fbs=None, frame_size=-1, windows=-1, channels=-1, harmonics=-1, pdiv=-1, pixel_dwell_time=-1.0, laser_frequency=-1.0, laser_factor=-1.0, scanner_line_length=-1, scanner_line_start=-1, scanner_frame_start=-1, scanner='', synthesizer='')

Bases: BinaryFile

FLIMbox data file.

FBD files contain encoded data from the FLIMbox device, storing a stream of 16-bit or 32-bit integers (data words) that can be decoded to photon arrival windows, channels, and times.

The measurement’s frame size, pixel dwell time, number of sampling windows, and scanner type are encoded in the last four characters of the file name. Newer FBD files, where the 3rd character in the file name tag is 0, may contain embedded firmware and measurement headers before the encoded data stream. FBD files written by VistaVision are accompanied by FBS.XML setting files.

It depends on the application and its settings how to interpret the decoded data, for example, as time series, line scans, or image frames of FCS or digital frequency domain fluorescence lifetime measurements.

The data word format depends on the device’s firmware. A common layout is:

|F|E|D|C|B|A|9|8|7|6|5|4|3|2|1|0|  data word bits
                    |-----------|  pcc (cross correlation phase)
                |---------------|  tcc (cross correlation time)
              |-|                  marker (indicates start of frame)
|-------------|                    index into decoder table

The data word can be decoded into a cross correlation phase histogram index (shown for the 1st harmonics):

bin = (pmax-1 - (pcc + win * (pmax//windows)) % pmax) // pdiv
  • bin, cross correlation phase index (phase histogram bin number).

  • pcc, cross correlation phase (counter).

  • pmax, number of entries in cross correlation phase histogram.

  • pdiv, divisor to reduce number of entries in phase histogram.

  • win, arrival window.

  • windows, number of sampling windows.

The current implementation uses a decoder table to decode arrival windows for each channel. This method is inefficient for 32-bit FLIMbox data with large number of windows and channels.

Parameters:
  • file (str | os.PathLike[str] | IO[bytes]) – File name or seekable binary stream.

  • code (str) – Four-character string, encoding frame size (1st char), pixel dwell time (2nd char), number of sampling windows (3rd char), and scanner type (4th char). By default, the code is extracted from the file name.

  • decoder (str | None) – Name of decoder settings function.

  • fbf (dict[str, Any] | None) – FLIMbox firmware header settings. By default, firmware settings are loaded from the file header, if any.

  • fbs (dict[str, Any] | None) – FLIMbox settings from FBS.XML file. By default, settings are loaded from companion file, if any.

  • frame_size (int) – Number of pixels in one line scan, excluding retrace.

  • windows (int) – Number of sampling windows used by FLIMbox.

  • channels (int) – Number of channels used by FLIMbox.

  • harmonics (int) – First or second harmonics.

  • pdiv (int) – Divisor to reduce number of entries in phase histogram.

  • pixel_dwell_time (float) – Number of microseconds the scanner remains at each pixel.

  • laser_frequency (float) – Laser frequency in Hz. The default is 20000000 Hz (or 40000000 Hz for second harmonics), the internal FLIMbox frequency.

  • laser_factor (float) – Factor to correct dwell_time/laser_frequency. Use when the scanner clock is not known exactly.

  • scanner_line_length (int) – Number of pixels in each line, including retrace.

  • scanner_line_start (int) – Index of first valid pixel in scan line.

  • scanner_frame_start (int) – Index of first valid pixel after marker.

  • scanner (str) – Scanner software or hardware.

  • synthesizer (str) – Synthesizer software or hardware.

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

__init__(file, /, *, mode=None, code='', decoder=None, fbf=None, fbs=None, frame_size=-1, windows=-1, channels=-1, harmonics=-1, pdiv=-1, pixel_dwell_time=-1.0, laser_frequency=-1.0, laser_factor=-1.0, scanner_line_length=-1, scanner_line_start=-1, scanner_frame_start=-1, scanner='', synthesizer='')
Parameters:
  • file (str | os.PathLike[str] | IO[bytes])

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

  • code (str)

  • decoder (str | None)

  • fbf (dict[str, Any] | None)

  • fbs (dict[str, Any] | None)

  • frame_size (int)

  • windows (int)

  • channels (int)

  • harmonics (int)

  • pdiv (int)

  • pixel_dwell_time (float)

  • laser_frequency (float)

  • laser_factor (float)

  • scanner_line_length (int)

  • scanner_line_start (int)

  • scanner_frame_start (int)

  • scanner (str)

  • synthesizer (str)

Return type:

None

header: numpy.recarray[Any, Any] | None

File header, if any.

fbf: dict[str, Any] | None

Firmware header settings, if any.

fbs: dict[str, Any] | None

Settings from FBS.XML file, if any.

frame_size: int

Number of pixels in one line scan, excluding retrace.

windows: int

Number of sampling windows.

channels: int

Number of channels.

harmonics: int

First or second harmonics.

pixel_dwell_time: float

Number of microseconds the scanner remains at each pixel.

laser_frequency: float

Laser frequency in Hz.

laser_factor: float

Factor to correct dwell_time/laser_frequency.

scanner_line_length: int

Number of pixels in each line, including retrace.

scanner_line_start: int

Index of first valid pixel in scan line.

scanner_frame_start: int

Index of first valid pixel after marker.

scanner: str

Scanner software or hardware.

synthesizer: str

Synthesizer software or hardware.

is_32bit: bool

Data words are 32-bit.

code: str

Four-character string from file name, if any.

decoder: str | None

Decoder settings function.

pdiv: int

Divisor to reduce number of entries in phase histogram.

property pmax: int

Number of entries in cross correlation phase histogram.

property scanner_line_add: int

Number of pixels added to each line (for retrace).

property units_per_sample: float

Number of FLIMbox units per scanner sample.

property attrs: dict[str, Any]

Selected metadata as dict.

property decoder_settings: dict[str, NDArray[numpy.int16] | int | bool]

Return parameters to decode FLIMbox data stream.

Returns:

  • ‘decoder_table’ - Decoder table mapping channel and window indices to actual arrival windows. The shape is (channels, window indices) and dtype is int16.

  • ’tcc_mask’, ‘tcc_shr’ - Binary mask and number of bits to right shift to extract cross correlation time from data word.

  • ’pcc_mask’, ‘pcc_shr’ - Binary mask and number of bits to right shift to extract cross correlation phase from data word.

  • ’marker_mask’, ‘marker_shr’ - Binary mask and number of bits to right shift to extract markers from data word.

  • ’win_mask’, ‘win_shr’ - Binary mask and number of bits to right shift to extract index into lookup table from data word.

  • ’swap_words’ - If True, swap the two 16-bit halves of each 32-bit data word before decoding. Optional, defaults to False.

decode(data=None, *, word_count=-1, skip_words=0, max_markers=65536, num_threads=0, **kwargs)

Return decoded records from FLIMbox data stream.

Parameters:
  • data (NDArray[Any] | None) – FLIMbox data stream. By default, the data is read from file.

  • word_count (int) – Number of data words to process. By default, all words are processed.

  • skip_words (int) – Number of data words to skip at beginning of stream.

  • max_markers (int) – Maximum number of markers expected in data stream.

  • num_threads (int) – Number of OpenMP threads to use for parallelization.

  • kwargs (Any)

Returns:

Cross correlation phase index for all channels and data points.

An int8 or int16 array of shape (channels, size). A value of -1 means no photon was counted.

times:

The times in FLIMbox counter units at each data point. An array of type uint64, potentially huge.

markers:

The indices of up markers in the data stream, usually indicating frame starts. An array of type ssize_t.

Return type:

bins

refine_settings(records=None, /, *, aspect_range=(0.8, 1.2), **kwargs)

Refine pixel_dwell_time and laser_factor from frame durations.

First evaluate the current pixel_dwell_time against the frame data. Then, only when pixel_dwell_time was originally derived from the header’s pixel_dwell_time_index (i.e. not from computed timing metadata, XML/FBS settings, or user input), search _header_pixel_dwell_time for a value that produces more valid frames and replace pixel_dwell_time if found. Always refine laser_factor from the median of detected frame durations. Update attributes in-place and issue warnings.

Parameters:
  • records (tuple[NDArray[Any], NDArray[Any], NDArray[Any]] | None) – Bins, times, and markers from decode function. By default, call FbdFile.decode().

  • aspect_range (tuple[float, float]) – Minimum and maximum aspect ratios of valid frames.

  • **kwargs (Any) – Additional arguments passed to FbdFile.decode().

Returns:

True if any setting was changed, False if settings are already optimal, and None if no valid frames could be found.

Return type:

bool | None

frames(records=None, /, *, select_frames=None, aspect_range=(0.8, 1.2), frame_cluster=0, refine=True, **kwargs)

Return shape and start/stop indices of scanner frames.

If unable to detect any frames using the default settings, try to determine a correction factor from clusters of frame durations.

Parameters:
  • records (tuple[NDArray[Any], NDArray[Any], NDArray[Any]] | None) – Bins, times, and markers from decode function. By default, call FbdFile.decode().

  • select_frames (slice | None) – Specifies which image frames to return. By default, all frames are returned.

  • aspect_range (tuple[float, float]) – Minimum and maximum aspect ratios of valid frames. The default lets 1:1 aspect pass.

  • frame_cluster (int) – Index of the frame duration cluster to use when calculating the correction factor.

  • refine (bool | None) – Refine settings: True=always, None=if needed, False=never.

  • **kwargs (Any) – Additional arguments passed to FbdFile.decode().

Returns:

Dimensions of scanner frame. 2. frame_markers: Start and stop indices of detected image frames.

Return type:

  1. shape

asimage(records=None, frames=None, /, *, integrate_frames=1, square_frame=True, num_threads=0, **kwargs)

Return image histograms from decoded records and detected frames.

This function may fail to produce expected results when settings were recorded incorrectly, scanner and FLIMbox frequencies were out of sync, or scanner settings were changed during acquisition.

Parameters:
  • records (tuple[NDArray[Any], NDArray[Any], NDArray[Any]] | None) – Bins, times, and markers from decode function. By default, call FbdFile.decode().

  • frames (tuple[tuple[int, int], NDArray[Any]] | None) – scanner_shape and frame_markers returned by FbdFile.frames(). By default, call FbdFile.frames().

  • integrate_frames (int) – Specifies which frames to sum. By default, all frames are summed into one. If 0, no frames are summed.

  • square_frame (bool) – If True, return square image (frame_size x frame_size), else return full scanner frame.

  • num_threads (int) – Number of OpenMP threads to use for parallelization.

  • **kwargs (Any) – Additional arguments passed to FbdFile.decode() and FbdFile.frames(), including refine (True=always, None=if needed, False=never).

Returns:

Image histogram of shape (number of frames, channels in bins array, lines per frame, scanner samples per line, histogram bins). If square_frame is True, both lines per frame and scanner samples per line equal frame_size; otherwise they equal the detected line count and scanner_line_length respectively.

Return type:

NDArray[numpy.uint16]

__str__()

Return str(self).

Return type:

str

plot(*, show=True)

Plot histogram and image for all channels.

Parameters:

show (bool)

Return type:

None

class fbdfile.FbdFileError

Bases: ValueError

Exception to indicate invalid FLIMbox data file.

__weakref__

list of weak references to the object

fbdfile.fbd_decode(data, bins_out, times_out, markers_out, windows, pdiv, harmonics, decoder_table, tcc_mask, tcc_shr, pcc_mask, pcc_shr, marker_mask, marker_shr, win_mask, win_shr, swap_words=False, num_threads=1)

Decode FLIMbox data stream.

Parameters:
  • data (numpy.ndarray) – FLIMbox data stream without header. An uint16 (16-bit FLIMbox) or uint32 (32-bit FLIMbox) array.

  • bins_out (numpy.ndarray) – Cross correlation phase index for all channels and data points. A int8 or int16 array of shape (channels, data.size), where decoded cross correlation phase indices are returned. A value of -1 means no photon was counted. A value of -2 means the window index exceeded the decoder_table (should not occur with valid input).

  • times_out (numpy.ndarray) – uint32 or uint64 array of length data.size, where times in FLIMbox counter units at each data point are returned.

  • markers_out (numpy.ndarray) – A ssize_t array of appropriate length, where indices into times_out are returned for all data words with markers enabled.

  • windows (int) – Number of sampling windows.

  • pdiv (int) – Divisor to reduce number of entries in phase histogram.

  • harmonics (int) – Decode first or second harmonics.

  • decoder_table (numpy.ndarray) – Mapping of channel and window indices to actual arrival windows. An int16 array of shape (channels, max of cross correlation phase).

  • tcc_mask (int) – Binary mask to extract cross correlation time from data word.

  • tcc_shr (int) – Number of bits to right shift masked cross correlation time.

  • pcc_mask (int) – Binary mask to extract cross correlation phase from data word.

  • pcc_shr (int) – Number of bits to right shift masked cross correlation phase.

  • marker_mask (int) – Binary mask to extract markers from data word.

  • marker_shr (int) – Number of bits to right shift masked marker.

  • win_mask (int) – Binary mask to extract index into decoder_table from data word.

  • win_shr (int) – Number of bits to right shift masked index into decoder_table.

  • swap_words (bool) – Swap words of uint32 data.

  • num_threads (int) – Number of OpenMP threads to use for parallelization.

Returns:

Number of markers written to markers_out.

fbdfile.fbd_histogram(bins, times, frame_markers, units_per_sample, scanner_frame_start, hist_out, num_threads=1)

Calculate histograms from decoded FLIMbox data and frame markers.

Parameters:
  • bins (numpy.ndarray) – Cross correlation phase index for all channels and data points. A int8 or int16 array of shape (channels, data.size). A value of -1 means no photon was counted.

  • times (numpy.ndarray) – Times in FLIMbox counter units at each data point. An uint64 or uint32 array of length data.size.

  • frame_markers (numpy.ndarray) – Start and stop indices of detected image frames.

  • units_per_sample (float) – Number of FLIMbox units per scanner sample.

  • scanner_frame_start (int) – Index of first valid pixel/sample after marker.

  • hist_out (numpy.ndarray) – Initialized uint16 array of shape (number of frames, channels, frame_size, histogram bins), where computed histogram will be stored.

  • num_threads (int) – Number of OpenMP threads to use for parallelization.

fbdfile.fbd_to_b64(fbdfile, /, b64files='{filename}_c{channel:02}t{frame:04}.b64', *, integrate_frames=0, square_frame=True, pdiv=-1, laser_frequency=-1, laser_factor=-1.0, pixel_dwell_time=-1.0, frame_size=-1, scanner_line_length=-1, scanner_line_start=-1, scanner_frame_start=-1, cmap='turbo', verbose=True, show=True)

Convert SimFCS FLIMbox data file to B64 files.

Parameters:
  • fbdfile (str | os.PathLike[Any]) – FLIMbox data file to convert.

  • b64files (str) – Format string for B64 output file names.

  • integrate_frames (int) – Specifies which frames to sum. By default, no frames are summed.

  • square_frame (bool) – If True, crop to square image (frame_size x frame_size). Else keep the full scanner frame.

  • pdiv (int) – Divisor to reduce number of entries in phase histogram.

  • laser_frequency (float) – Laser frequency in Hz.

  • laser_factor (float) – Factor to correct dwell_time/laser_frequency.

  • pixel_dwell_time (float) – Number of microseconds the scanner remains at each pixel.

  • frame_size (int) – Number of pixels in one line scan, excluding retrace.

  • scanner_line_length (int) – Number of pixels in each line, including retrace.

  • scanner_line_start (int) – Index of first valid pixel in scan line.

  • scanner_frame_start (int) – Index of first valid pixel after marker.

  • cmap (str) – Matplotlib colormap for plotting images.

  • verbose (bool) – Print detailed information about file and conversion.

  • show (bool) – If True, plot (but do not write) the decoded frames. If False, one B64 files is written for each frame and channel.

Return type:

None

fbdfile.fbf_read(file, /, *, firmware=False, maxheaderlength=1024)

Return metadata from FLIMbox device firmware (FBF) file.

FBF files contain FLIMbox device firmwares, stored in binary form following a NULL terminated ASCII string containing properties and description.

Parameters:
  • file (str | os.PathLike[str] | IO[bytes]) – Name of FBF file to open, or seekable binary stream.

  • firmware (bool) – Include the firmware binary data.

  • maxheaderlength (int) – Maximum length of ASCII header.

Return type:

dict[str, Any]

Examples

>>> header = fbf_read('tests/data/flimbox_firmware.fbf')
>>> header['windows']
16
>>> header['channels']
2
>>> header['secondharmonic']
0
>>> 'extclk' in header
True
fbdfile.fbs_read(file, /)

Return metadata from FLIMbox settings (FBS.XML) file.

VistaVision FBS.XML files contain FLIMbox acquisition settings in XML format.

Parameters:

file (str | os.PathLike[str] | IO[str]) – Name of file to open, or seekable text stream.

Return type:

dict[str, Any]

Examples

>>> fbs = fbs_read('tests/data/flimbox_settings.fbs.xml')
>>> fbs['ScanParams']['ExcitationFrequency']
20000000
fbdfile.sflim_decode(data, sflim, pixeltime, enabletime=0, maxframes=-1, num_threads=1)

Decode Kintex FLIMbox data to SLIM image array.

Parameters:
  • data (numpy.ndarray) – Data stream from Kintex FLIMbox. A uint32 array.

  • sflim (numpy.ndarray) – Initialized uint8 or uint16 array of shape (channels=32, phasebins=256, height, width) to which photon counts are added.

  • pixeltime (int) – Pixel dwell time in FLIMbox units. math.ceil(dwelltime * 256 / 255 * frequency_factor * frequency)

  • enabletime (int) – Time in FLIMbox units to wait after detecting enable bit before detecting next enable bit.

  • maxframes (int) – Maximum number of image frames to decode.

  • num_threads (int) – Number of OpenMP threads to use for parallelization.

Returns:

Number of image frames decoded.

Examples

>>> import numpy, math
>>> data = numpy.fromfile(
...     'tests/data/20210123488_100x_NSC_166_TMRM_4_zoom4000_L115.bin',
...      dtype=numpy.uint32
... )
>>> frequency = 78e6
>>> frequency_factor = 0.9976
>>> dwelltime = 16e-6
>>> pixeltime = math.ceil(
...     dwelltime * 256 / 255 * frequency_factor * frequency
... )
>>> sflim = numpy.zeros((32, 256, 256, 342), dtype=numpy.uint8)
>>> sflim_decode(
...     data, sflim, pixeltime=pixeltime, maxframes=20, num_threads=6
... )
>>> numpy.unravel_index(numpy.argmax(sflim), sflim.shape)
(np.int64(24), np.int64(178), np.int64(132), np.int64(248))