Skip to main content

FLIMKit QuPath bridge

DOI

Direct image and ROI exchange between FLIMKit and QuPath.

Status

v0.1.1. Used end to end against real FLIMKit sessions on a Leica SP8 FALCON: images and ROIs move in both directions, the FLIMKit images open in a QuPath project, and co-registration works through the alignment extension.

The endpoint shapes come from flimkit-fiji-bridge, where they were designed first. The two have since diverged and are not interchangeable: they report different protocol identifiers, and this one adds a discovery file for pairing and refuses requests whose Host header is not localhost.

The bigger difference is on the other side. This one ships a QuPath extension that runs inside a live session, so it works with the image you have open and the annotations you have drawn, and it can add the FLIMKit images to the open project. The Fiji bridge drives Fiji through a Groovy script.

Installing

The Python half goes into the environment FLIMKit runs in:

pip install flimkit-qupath-bridge

That pulls FLIMKit with it. The bridge then starts with FLIMKit, and flimkit-bridge is on the path for the headless server.

The QuPath half is a jar. Take qupath-extension-flimkit-bridge-*.jar from the release and drop it in QuPath's extensions directory, normally ~/QuPath/v0.7/extensions. It appears under Extensions > FLIMKit bridge.

Why QuPath as well as Fiji

The FLIM workflow that matters here is drawing ROIs on a co-registered brightfield image and sending them back to FLIMKit for analysis. QuPath is built for that on tissue, and its annotation handling and built-in cell detection are stronger than Fiji's ROI Manager.

QuPath also treats GeoJSON as a first-class format, so the ROI half of the bridge is less work than it was for Fiji.

Pairing

FLIMKit writes its address and a freshly generated token to ~/.flimkit/qupath-bridge.json when it starts, owner-readable only where the platform supports it. QuPath reads that file, so Extensions > FLIMKit bridge > Connect needs nothing typed in.

If the file names a FLIMKit that is no longer running, QuPath says so rather than failing with a connection error. Connect to a different address... is there for the case where the file cannot be reached, such as FLIMKit running in a container or on the other end of an SSH tunnel.

The bridge listens on 127.0.0.1 only and refuses any request whose Host header is not localhost, which stops a web page reaching it by pointing its own hostname at your machine. If port 8765 is busy it takes an ephemeral one and records it in the same file, so nothing needs reconfiguring.

Without the desktop GUI

The bridge does not need the FLIMKit window. flimkit-bridge starts the same server on its own, writes the same discovery file, and serves everything except the routes that read the open session:

flimkit-bridge                 # 127.0.0.1:8765, or an ephemeral port if that is busy
flimkit-bridge --port 9000
flimkit-bridge --no-announce   # do not write the discovery file, print the token instead

It refuses to start if another bridge is already serving, since both would write the same discovery file and QuPath would pair with whichever wrote last. Pass --force to take it over.

What the desktop bridge adds is the live session: the images and ROIs currently on screen. Everything else, opening files, fitting regions, phasor plots and stitching, works the same either way.

Stitching and fitting from QuPath

FLIMKit's own tile pipelines are reachable over the bridge, so a mosaic can be stitched and fitted without touching the FLIMKit window. Point it at the .lif or .xlif that carries the tile positions:

POST /v1/pipeline   {"container": "/path/R 2.xlif", "params": {"n_exp": 2}}
GET  /v1/pipeline/defaults

The tiles do not have to sit beside the container. The bridge looks in the directory you name, then beside the container, then in the directories next to it, which is where Leica puts them.

pipeline chooses between stitch_fit, which stitches the canvas and fits it, and tile_fit, which fits each tile after a global summed fit and assembles the maps. Both run as jobs, so GET /v1/jobs/{id} reports progress and DELETE cancels. Cancelling stops the run at the next tile, or at the next stage boundary once fitting is done.

Outputs are written to disk, and the output directory can be reopened as a dataset:

POST /v1/datasets   {"path": "/path/R_2_flimkit"}

A region drawn on that canvas is then fitted from the photons in the stitched cube, not from the displayed image.

Acknowledgement

The wire protocol used here was designed and first implemented in flimkit-fiji-bridge by Zhen Yuan Yeo (https://doi.org/10.5281/zenodo.21951612). This bridge reuses it unchanged, so a client written against one works against the other.

Licensing

Two licences, because the two halves link against different things. The Python package is MIT. The QuPath extension is GPL-3.0, because it links QuPath, which is GPL-3.0. See LICENSING.md.

Requirements

  • QuPath 0.7.0 or newer.
  • FLIMKit 0.12.0 or newer, which pip pulls in.
  • Python 3.12 or newer.
  • The QuPath alignment extension, for co-registration.

Align on the intensity image, not the lifetime map. Photon counts are integers, so intensity crosses as 16-bit whenever it fits losslessly, which the alignment extension can open. The lifetime map has to stay 32-bit float to carry real nanoseconds, and the alignment extension throws on 32-bit float rather than declining politely. The transform you get from the intensity image is valid for the lifetime map anyway, because they share one pixel grid.

The alignment extension is not optional for the intended workflow and it does not ship with QuPath. QuPath 0.7.0 does not bundle interactive image alignment, and neither did 0.6.0, so it has to be downloaded and dropped into QuPath's extensions directory separately.

Without it you can still move images and ROIs, but only between images that already share a coordinate system. Aligning a brightfield or histology image to the FLIM field of view, which is the reason this bridge exists, needs that extension installed.

Co-registration

FLIMKit receives ROIs in FLIM image-pixel coordinates. Anything drawn on another image has to be transformed into that space before it is sent, and the transform is produced on the QuPath side, the same division of labour the Fiji bridge uses.

The intended sequence:

  1. Open the brightfield image and add the FLIM intensity map to the same QuPath project.
  2. Align them with the alignment extension and transfer the annotations onto the FLIM image.
  3. Send the annotations on the FLIM image to FLIMKit.

This bridge deliberately contains no alignment code of its own. Reimplementing it would mean maintaining a copy of something QuPath's own developers already maintain.

Verified against QuPath 0.7.0

The plan is built on API behaviour confirmed by running it on 2026-08-15, not on documentation alone:

  • Headless Groovy scripts run with no image and no project.
  • GsonTools.getInstance().toJson(obj) emits a GeoJSON Feature, and GsonTools.parseObjectsFromGeoJSON(String) reads one back.
  • Float32 TIFF opens through Bio-Formats with pixel values intact.
  • Script arguments arrive as a positional String[] named args.
  • QuPath 0.7.0 runs on Java 25, so there is no Java 8 problem of the kind the Fiji bridge hit.

Two behaviours shape the design. QuPath reads images from a path rather than a stream, so the client writes fetched bytes to a temporary file first. QuPath also normalises polygon winding order, so tests compare geometry rather than an exact coordinate sequence.

Release files for flimkit-qupath-bridge 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for flimkit-qupath-bridge 0.2.0
File Size Uploaded
flimkit_qupath_bridge-0.2.0.tar.gz 56.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for flimkit-qupath-bridge 0.2.0
File Interpreter ABI Platform
flimkit_qupath_bridge-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 89.3 kB

Release files / flimkit_qupath_bridge-0.2.0.tar.gz

Download URL flimkit_qupath_bridge-0.2.0.tar.gz
Size 56.0 kB
Tags Source
SHA-256 checksum
How to use checksums
4fc27a7da8893c21ee3c24463c4c0b2b99b4ebc495c2665b8d9b111d0f5f8604
BLAKE2b-256 checksum
How to use checksums
e22d3c3c9518a821b2249ca4f3b4708716f9dfe4d78d1ebfe4061db0f7b8a390
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.

Transparency log

Release files / flimkit_qupath_bridge-0.2.0-py3-none-any.whl

Download URL flimkit_qupath_bridge-0.2.0-py3-none-any.whl
Size 33.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
20b7087bfd89b966a9a4137170968d88c1e68a0e6134216cc78c6920bfa2abfe
BLAKE2b-256 checksum
How to use checksums
6e87eee41a2e6762155b4ed5c55fd0ea2aa393d562fa5cbceded67a919677dab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 19, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

This release

0.2.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page