WARNING: under active development. Please expect breaking changes.
GPU accelerated post-processing for 2D / 3D iterative barcoded FISH data. This package is currently NVIDIA only and Linux only. Documentation, including examples, is available at https://qi2lab.github.io/merfish3d-analysis/.
GPU-accelerated, self-optimizing processing for 3D multiplexed iterative RNA-FISH experiments.
You can try out the package in the cloud on simulated data using a Google Colab notebook that demonstrates data preprocessing and decoding.
The GPU integration test workflow uses the StatPhysBio MERFISH simulations archived on Zenodo. Download the simulation test data or follow the complete synthetic-data example for checksum verification, extraction, model setup, and test commands.
This project uses one uv environment based on CUDA 12.9 runtime/toolkit. You need a compatible NVIDIA driver installed on the machine.
Install uv if needed:
curl -LsSf https://astral.sh/uv/install.sh | shClone the repository and enter it:
git clone https://github.com/QI2lab/merfish3d-analysis
cd merfish3d-analysisCreate and sync the environment:
uv syncFor development tools, include the dev group:
uv sync --group devFor documentation tools, include the docs group:
uv sync --group docsRun package entry points through uv run, for example:
uv run qi2lab-preprocess /path/to/experimentLocal fiducial registration uses the qi2lab GPU registration path: lateral XY registration on max-Z projections, XYZ registration, and optional SOFIMA residual flow fields after affine fiducial alignment. Global registration and fused fiducial OME-Zarr creation follow the multiview-stitcher workflow, using CPU registration and CPU direct-to-Zarr fusion.
After local and global registration, fuse the first-round fiducial and codebook
bits into qi2labdatastore/fused/full_dataset.ome.zarr:
uv run qi2lab-fuseall /path/to/experiment \
--output-chunk-zyx 32,2048,2048 \
--fusion-workers 30 \
--compression blosc-lz4 \
--compression-level 1All output levels use lossless compression. The shared default for fiducial
and all-channel fusion is blosc-zstd with bitshuffle at level 1. The example
selects blosc-lz4 with bitshuffle for faster encoding; compression ratio and
speed depend on the data. zstd is also available. Levels 1 through 9 are
accepted; compression cannot be disabled. Changing compression preserves the
pixel values produced by fusion.
The output is OME-Zarr v0.5, with the fiducial first and then bits in numeric codebook order. The command uses stored chromatic, local-round, stage and global transforms; SOFIMA is omitted. See the fusion workflow for resource settings and restart behavior.
The standard uv sync install includes the NDV, VisPy, and PyQt dependencies
for the view-only datastore GUI.
Open an experiment root:
uv run viewer /path/to/experimentor open a datastore directly:
uv run viewer /path/to/experiment/qi2labdatastoreThe viewer only reads existing datastore contents. It uses NDV for Zarr-backed image channels and VisPy for sparse transcript and cell-boundary overlays. It can inspect local native tiles, local tiles warped with selected chromatic, stage/round affine, and SOFIMA components, and global fused views. Transcript sources are mutually exclusive: datastore transcripts, Proseg transcripts, or Baysor transcripts. Cell boundaries can be shown from Cellpose, Proseg, or Baysor when those outputs are present.
The documentation includes a viewer guide with screenshots and a current API notes page covering the current RLGC, PSF, and U-FISH defaults.
Follow the installation instructions at proseg.
Example calls to proseg:
2D segmentation optimization (ignore z coordinate)
mkdir /path/to/qi2labdatastore/proseg/2D
/path/to/proseg --gene-column gene_id -x global_x -y global_y -z global_z --fov-column tile_idx --cell-id-column cell_id --cell-id-unassigned 0 --excluded-genes ^[Bb]lank.*$ --ignore-z-coord --density-bins 1 --burnin-samples 1000 --samples 2000 --voxel-size 1.0 --burnin-voxel-size 4.0 --enforce-connectivity --diffusion-probability 0.0 --output-spatialdata /path/to/data/qi2labdatastore/proseg/2D/spatialdata_2D.zarr --output-counts /path/to/data/qi2labdatastore/proseg/2D/counts_2D.mtx.gz --output-cell-polygons /path/to/data/qi2labdatastore/proseg/2D/cell_polygons_2D.geojson.gz --output-transcript-metadata /path/to/data/qi2labdatastore/proseg/2D/transcript_metadata_2D.csv.gz /path/to/data/qi2labdatastore/all_tiles_filtered_decoded_features/decoded_features.csv.gz3D segmentation optimization. Here --voxel-layers should be roughly set to the height of the imaged volume in microns. For example, a 15 micron thick sample should have --voxel-layers 15.
mkdir /path/to/qi2labdatastore/proseg/3D
/path/to/proseg --gene-column gene_id -x global_x -y global_y -z global_z --fov-column tile_idx --cell-id-column cell_id --cell-id-unassigned 0 --excluded-genes ^[Bb]lank.*$ --voxel-layers 15 --density-bins 1 --burnin-samples 1000 --samples 2000 --voxel-size 1.0 --burnin-voxel-size 4.0 --enforce-connectivity --diffusion-probability 0.0 --output-spatialdata /path/to/data/qi2labdatastore/proseg/3D/spatialdata_3D.zarr --output-counts /path/to/data/qi2labdatastore/proseg/3D/counts_3D.mtx.gz --output-cell-polygons-layers /path/to/data/qi2labdatastore/proseg/3D/cell_polygons_3D.geojson.gz --output-transcript-metadata /path/to/data/qi2labdatastore/proseg/3D/transcript_metadata_3D.csv.gz /path/to/data/qi2labdatastore/all_tiles_filtered_decoded_features/decoded_features.csv.gzTo build the documentation, install using uv sync --group docs.
Then execute uv run mkdocs build --clean or uv run mkdocs serve. The
documentation is available in your web browser at http://127.0.0.1:8000/.
Pushes to main automatically build and deploy the documentation through the
Documentation GitHub Actions workflow. The workflow installs only the
documentation dependency group and runs on a standard CPU runner; it does not
require CUDA or GPU hardware. Configure the repository's Pages source as
GitHub Actions under Settings → Pages.
The suite consists of unit tests and integration tests. Every test has exactly one of these markers. Run either category with:
uv run pytest -m unit
uv run pytest -m integrationSee the testing guidelines for the required assertions and how to classify tests.
The simulation tests require an NVIDIA GPU, the extracted Zenodo sample data,
and the default simfish U-FISH weights cached by U-FISH. Pass the extracted
dataset directory with --simulation-data-root. See the
synthetic-data example
for setup instructions.
Standard simulation matrix:
uv run pytest tests/test_simulation_example_pipeline.py -vv \
--simulation-data-root simulation-data/merfish3d_analysis-simulationFull repository suite, including the exhaustive simulation matrix:
uv run pytest -vv --run-simulation-exhaustive \
--simulation-data-root simulation-data/merfish3d_analysis-simulationThe standard simulation matrix uses CUDA device 0 and runs paired affine and
SOFIMA preprocessing for every default dataset, axial spacing, and
chromatic-aberration setting. The exhaustive mode adds deconvolution-on and
deconvolution-off coverage using SOFIMA and synthetic chromatic aberration. It
writes measured performance records to
tests/data/simulation_performance.json. The tests verify the Zenodo image
fingerprints and enforce the documented F1 baselines with an absolute tolerance
of 0.02.