Skip to content

Synthetic data example

Overview

This example downloads simulated iterative RNA-FISH experiments generated by the StatPhysBio lab at ASU and runs the repository's GPU integration tests without modifying the test code. The tests convert the simulations to the qi2lab acquisition format, create datastores, preprocess the images, decode transcripts, and compare the results with ground truth.

You can also run the same workflow in the linked Google Colab notebook.

Requirements

  • Linux with a CUDA-compatible NVIDIA GPU and driver
  • git, curl, unzip, and md5sum
  • enough space for the 2.3 GB archive, its extracted contents, and temporary datastores created by pytest

Clone the repository, create the project environment, and include the test dependencies:

git clone https://github.com/QI2lab/merfish3d-analysis
cd merfish3d-analysis
uv sync --group dev

Download the test data

Create a data directory, download the archived simulation data, verify the Zenodo checksum, and extract it:

mkdir -p simulation-data

curl -L \
  "https://zenodo.org/records/17274305/files/merfish3d_analysis-simulation.zip?download=1" \
  -o simulation-data/merfish3d_analysis-simulation.zip

echo "3c415493ca37bd19af14464badc45fae  simulation-data/merfish3d_analysis-simulation.zip" \
  | md5sum --check -

unzip simulation-data/merfish3d_analysis-simulation.zip -d simulation-data

At session startup, the tests verify the SHA-256 fingerprints of all six aligned_1.tiff inputs against Zenodo record 17274305. A different local or server-side dataset fails before GPU processing begins.

After extraction, the two dataset variants used by the standard test should have this structure:

merfish3d_analysis-simulation/
├── example_16bit_cells/
│   ├── 0.315/
│   │   ├── aligned_1.tiff
│   │   ├── bit_order.csv
│   │   ├── codebook.csv
│   │   ├── GT_spots.csv
│   │   └── scan_metadata.csv
│   ├── 1.0/
│   └── 1.5/
└── example_16bit_flat/
    ├── 0.315/
    ├── 1.0/
    └── 1.5/

Cache the default U-FISH model

The test matrix discovers locally cached U-FISH models during test collection. Cache the default simfish weights once before invoking pytest:

uv run python -c "from ufish.api import UFish; UFish(device='cuda:0').load_weights(weights_file='finetune_models/v1.0.1-simfish_model.onnx')"

The expected cached file is ~/.ufish/finetune_models/v1.0.1-simfish_model.onnx. If it is absent, the standard matrix has no default-model parameter to collect and is skipped.

Run the standard GPU integration test

Run the test module as-is from the repository root:

uv run pytest tests/test_simulation_example_pipeline.py -vv \
  --simulation-data-root simulation-data/merfish3d_analysis-simulation

No separate pytest GPU option is required. The test constructs the processing classes with num_gpus=1, so CUDA device 0 performs preprocessing and decoding. The standard matrix covers both dataset variants, all three axial spacings, and chromatic-aberration estimation enabled and disabled. Each case compares an affine-only run with a SOFIMA-enabled run and stops if the rounded SOFIMA F1 score is lower. Both results must meet the documented reference F1 minus 0.02. Higher accuracy is accepted, and precision, recall and F1 are also checked against the measured true-positive, false-positive and false-negative counts.

The complete run on 2026-09-17 produced the following standard F1 scores (affine and SOFIMA were identical):

Dataset Axial spacing (µm) No chromatic aberration Chromatic aberration
Cells 0.315 0.9848 0.9823
Cells 1.0 0.9623 0.9483
Cells 1.5 0.3867 0.3352
Uniform 0.315 0.9899 0.9891
Uniform 1.0 0.9669 0.9641
Uniform 1.5 0.6090 0.5370

Optional full matrix

The longer deconvolution matrix is excluded by default. It uses SOFIMA, synthetic chromatic aberration, the default simfish model, and both deconvolution modes. Enable it explicitly with:

uv run pytest tests/test_simulation_example_pipeline.py -vv \
  --run-simulation-exhaustive \
  --simulation-data-root simulation-data/merfish3d_analysis-simulation

The exhaustive run writes performance records to tests/data/simulation_performance.json unless MERFISH3D_PERFORMANCE_REPORT selects another output path.

The full repository suite, including this matrix, is:

uv run pytest -vv --run-simulation-exhaustive \
  --simulation-data-root simulation-data/merfish3d_analysis-simulation

The same run produced these reference F1 scores for the additional matrix:

Dataset Axial spacing (µm) Deconvolution No deconvolution
Cells 0.315 0.9823 0.9899
Cells 1.0 0.9483 0.9379
Cells 1.5 0.3352 0.8308
Uniform 0.315 0.9891 0.9865
Uniform 1.0 0.9641 0.9500
Uniform 1.5 0.5370 0.7914

feature_predictor_threshold remains fixed at 0.5 for compatibility. The decoder currently weights readout images by the feature-predictor image rather than thresholding them, so sweeping this legacy argument produced identical F1 scores and is not a useful test-matrix dimension.