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, andmd5sum- 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:
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.