Skip to main content

Read and browse nested images in Leica LIF, LOF, and XLEF files

Project description

ConvertLeica-Docker

ConvertLeica-Docker is a toolset and web interface for converting Leica LIF, LOF, and XLEF microscopy image files to OME-TIFF or OME-Zarr, with special handling for certain file types and image configurations. It is designed for command-line, web-based, and Qt desktop workflows, supporting batch conversion and interactive browsing/conversion of large microscopy datasets.

The reusable Leica file-browser modules are also distributed separately as convertleica-file-browser. This lets Python applications consume the readers without copying source files from this repository:

pip install convertleica-file-browser
from convertleica_file_browser.ci_leica_converters_helpers import read_leica_file

contents_json = read_leica_file("example.lif")

Preview generation additionally needs OpenCV and can be installed with pip install "convertleica-file-browser[preview]".

Package versions are derived from this repository's Git tags. Publishing a GitHub Release builds and publishes the matching wheel and source distribution to PyPI, alongside the Docker image release workflow.

Before the first release, configure a PyPI Trusted Publisher with owner NL-BioImaging, repository ConvertLeica-Docker, workflow publish-to-pypi.yml, and GitHub environment pypi. Create the matching GitHub environment and protect it with required reviewer approval. No PyPI API token is needed.


Table of Contents


Features

  • Convert Leica LIF, LOF, and XLEF files to OME-TIFF or OME-Zarr (multi-channel, multi-Z, RGB, tilescans, etc.)
  • Automatic handling of special cases: returns .LOF or single-image .LIF files when OME-TIFF is not appropriate
  • Batch and single-image conversion
  • Web interface and Qt desktop GUI for browsing, previewing, and converting files
  • Progress reporting and metadata inspection
  • Robust file saving: Uses a temp-first approach with automatic retry logic for reliable saving to network drives
  • Dual progress bars: Separate progress indicators for data processing and file saving phases

Installation

Requirements

  • Python 3.13
  • pip
  • (Optional) Docker for containerized usage

Python packages

Different requirements files are provided for different scenarios:

  • requirements-docker.txt — Core dependencies for Docker container (numpy, tifffile, imagecodecs, opencv-python)
  • requirements-server.txt — For running the web server (same core deps; server uses stdlib only)
  • requirements-qt6ui.txt — For running Qt6 desktop GUIs (core deps + PyQt6)

Core packages (all scenarios):

  • numpy>=2.0.0
  • tifffile>=2024.1.30
  • imagecodecs>=2024.1.1
  • opencv-python==4.13.0.90
  • numcodecs>=0.12
  • zarr>=3.0.0

Qt Desktop GUI

The desktop application can be launched directly:

python ConvertLeicaQT.py
python ConvertLeicaQT.py --debug
  • The GUI always converts the selected image; there is no LOF/XLEF size-threshold toggle in the desktop app.
  • Use the Convert to: row to choose OME-TIFF or OME-Zarr.
  • --debug shows the Folder JSON and Image JSON buttons for raw metadata inspection.

Install with:

# For Docker/CLI usage:
pip install -r requirements-docker.txt

# For web server:
pip install -r requirements-server.txt

# For Qt6 GUI applications:
pip install -r requirements-qt6ui.txt

(Optional) Build and run with Docker

# Build the Docker image
# (from the root of this repository)
docker build -t convertleica-docker .

# Run the container, mounting your data directory
# (replace L:/data with your data path)
docker run --rm -v "L:/data:/data" convertleica-docker --inputfile /data/myfile.lif --outputfolder /data/.processed

# With custom temp folder (useful when output is on a slow network mount)
docker run --rm \
  -v "L:/data:/data" \
  -v "/tmp/leica:/temp" \
  convertleica-docker \
  --inputfile /data/myfile.lif \
  --outputfolder /data/.processed \
  --tempfolder /temp \
  --show_progress

Usage (Command Line)

Basic Command

python main.py --inputfile <path-to-LIF/LOF/XLEF> --outputfolder <output-folder> [--image_uuid <uuid>] [--show_progress] [--altoutputfolder <alt-folder>] [--xy_check_value <int>]

Arguments

  • --inputfile (required): Path to the input Leica file (.lif, .lof, .xlef)
  • --outputfolder (required): Output directory for converted files
  • --image_uuid: UUID of the image to extract (for multi-image files)
  • --show_progress: Show progress bar during conversion
  • --altoutputfolder: Optional second output directory
  • --tempfolder: Custom temp folder for intermediate files (useful for Docker or network scenarios). If not set, uses system temp directory.
  • --xy_check_value: XY size threshold for special handling (default: 3192)
  • --get_image_metadata: Also include full image metadata JSON in the result under keyvalues.image_metadata_json
  • --get_image_xml: Also include the raw image XML (when available) under keyvalues.image_xml

Inputs

  • LIF: Leica Image File (may contain multiple images, folders, tilescans, etc.)
  • LOF: Leica Object File (single image, often exported from LIF)
  • XLEF: Leica Experiment File (may reference multiple images, often RGB)

List nested image IDs

Use extract_nested_leica_items to enumerate every image before submitting individual conversion jobs. It expands nested LIF and XLEF folders lazily and also supports single-image LOF files and legacy SP5 MemoryBlockID values.

from ci_leica_converters_helpers import extract_nested_leica_items

images = extract_nested_leica_items("/data/experiment.lif")
for image in images:
    print(image["uuid"], image["name"])

Each result has the import-compatible shape introduced by OMERO.biomero:

{
  "localPath": "/data/experiment.lif",
  "uuid": "image-or-memory-block-id",
  "name": "Image name"
}

Outputs

  • OME-TIFF: Standard output for most images (multi-channel, multi-Z, tiled, etc.)
  • .LOF: Returned for certain LOF files or when conversion to OME-TIFF is not needed
  • Single-image .LIF: Returned for special cases (e.g., negative overlap tilescans)

Function Output Format

The function returns a JSON array string describing the conversion result(s). Each element has:

  • name: base name of the created or relevant file (without extension)
  • full_path: absolute path to the output file (OME-TIFF, .LOF, or .LIF)
  • alt_path: absolute path to the file in altoutputfolder (if used and file exists), else null
  • keyvalues: a single-item list with a dictionary containing per-channel intensity stats and optional metadata

Per-channel intensity stats (always present when readable):

  • channel_mins: list[int] per channel, minimum pixel value observed (container units)
  • channel_maxs: list[int] per channel, maximum pixel value observed (container units)
  • channel_display_black_values: list[int] per channel, display black levels scaled to the container range
  • channel_display_white_values: list[int] per channel, display white levels scaled to the container range

Optional metadata fields (included only when flags are used):

  • image_metadata_json: full parsed image metadata JSON (when --get_image_metadata)
  • image_xml: raw image XML string if available, else empty string (when --get_image_xml)

If no conversion is applicable or an error occurs, an empty JSON array string ([]) is returned.

Example result:

[
  {
    "name": "Swiss Rolls GM1748 LEX277AD",
    "full_path": "L:/Archief/active/cellular_imaging/OMERO_test/Leica-LIF/.processed/Swiss Rolls GM1748 LEX277AD.ome.tiff",
    "alt_path": "U:/cc/Swiss Rolls GM1748 LEX277AD.ome.tiff",
    "keyvalues": [
      {
        "channel_mins": [1097, 2257, 335, 175],
        "channel_maxs": [7423, 5907, 10261, 3716],
        "channel_display_black_values": [1179, 2357, 372, 202],
        "channel_display_white_values": [6798, 5641, 7002, 2969]
      },
      "experiment_name": "Cells in mouse brain",
      "experiment_date": "2025-05-01"
    ]
  }
]

You can parse this output in Python using json.loads() to access the result programmatically.


Conversion Scenarios

  • LIF file: RGB and multi-channel images are converted to OME-TIFF. If the image is a tilescan with negative overlap, a single-image .LIF is returned instead.
  • LOF file: RGB and multi-channel images are converted to OME-TIFF. If not needed, the original .LOF is returned.
  • XLEF file: RGB and multi-channel images are converted to OME-TIFF. Special cases (e.g., negative overlap or unsupported structure) may return the original LOF file.

WSL/Windows Example Usage

See Tests/test_convertleica.py and Tests/test_ometiff_RGB.py for real-world examples:

lif_file_path = 'L:/Archief/active/cellular_imaging/OMERO_test/Leica-LIF/Swiss Rolls GM1748 LEX277AD.lif'
image_uuid = "ad7b9384-0466-11e9-8a36-8cec4b8a9866"
outputfolder = 'L:/Archief/active/cellular_imaging/OMERO_test/Leica-LIF/.processed'
altoutputfolder = 'U:/cc'

status = convert_leica(
    inputfile=lif_file_path,
    image_uuid=image_uuid,
    show_progress=True,
    outputfolder=outputfolder,
    altoutputfolder=altoutputfolder
)
print(status)

Special Cases

  • Tilescan with Negative Overlap (LIF): Instead of OME-TIFF, a single-image .LIF is returned
  • LOF/XLEF: If conversion is not needed, the original LOF file is returned

Robust File Saving

The converter uses a temp-first approach for reliable saving to network-mounted drives:

  1. Save to temp: The TIFF is first written to a local temp folder (system temp or custom --tempfolder)
  2. Copy with verification: The file is copied to the destination with size verification
  3. Automatic retry: On failure, retries up to 10 times with progressive backoff (1 min, 2 min, ... 10 min)
  4. Alt folder support: If --altoutputfolder is specified, the file is also copied there from temp
  5. Cleanup: The temp file is removed only after all copies succeed

This prevents corrupted or partial files on unreliable network connections.

Progress Indicators

When --show_progress is enabled, two distinct progress bars are shown:

Converting to OME-TIFF: |██████████████████████████████████████████████████| 100.0% Processing complete
  Saving: <▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓> 100.0% - Copying to output
  • Processing bar (|███|): Data reading, stitching, and tiled-pyramid creation (0-100%)
  • Saving bar (<▓▓▓>): Verified copying to the requested output locations (0-100%)

Troubleshooting

  • Ensure all dependencies are installed (pip install -r requirements-docker.txt for CLI/Docker)
  • For Docker, ensure your data directory is mounted correctly
  • For large files, ensure sufficient disk space and memory
  • If you encounter errors, check the console output for details

License

Apache License 2.0 — see LICENSE.


References


More documentation

  • Server.md — Web server and website documentation, including progressive preview and disk cache behavior, endpoints, and client flow.
  • ConvertLeicaQT.md — Desktop Qt GUI documentation with browsing, progressive previews (cache parity with server), and conversion workflow.
  • LeicaViewerQT.md — A lightweight Qt desktop image viewer focused on Leica LIF/LOF/XLEF browsing and quick previewing.
  • tools/omero_import_metadata_probe/README.md — Generate tiled/pyramidal TIFF and Zarr fixtures and verify their OMERO/BIOMERO imports.

Note: Requires the same Python dependencies as the converter (see requirements).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

convertleica_file_browser-1.7.3.tar.gz (56.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

convertleica_file_browser-1.7.3-py3-none-any.whl (58.3 kB view details)

Uploaded Python 3

File details

Details for the file convertleica_file_browser-1.7.3.tar.gz.

File metadata

File hashes

Hashes for convertleica_file_browser-1.7.3.tar.gz
Algorithm Hash digest
SHA256 5c011b7ad8507d96784344d8875595e417e1af039ddd6a43cab84b61665aa7b1
MD5 73aa6e30151000858ea0c3eadd8e68b6
BLAKE2b-256 16f339ef77c9c6da2748b8ea16276031ec7c81d8dba7f330d4844c918f952412

See more details on using hashes here.

Provenance

The following attestation bundles were made for convertleica_file_browser-1.7.3.tar.gz:

Publisher: publish-to-pypi.yml on NL-BioImaging/ConvertLeica-Docker

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file convertleica_file_browser-1.7.3-py3-none-any.whl.

File metadata

File hashes

Hashes for convertleica_file_browser-1.7.3-py3-none-any.whl
Algorithm Hash digest
SHA256 f346deea2622a66fdf64524c69200342315a0e449a8b9999dc29189ad133c024
MD5 d48bf05156fa215bd8060f115c48ce76
BLAKE2b-256 aff7a46995863e99de0debaad0ab92542bb56e695226e6a50781efbee73e3a8f

See more details on using hashes here.

Provenance

The following attestation bundles were made for convertleica_file_browser-1.7.3-py3-none-any.whl:

Publisher: publish-to-pypi.yml on NL-BioImaging/ConvertLeica-Docker

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page