Bayesian inference of organoid morphogenesis parameters from single static microscopy images, using a multi-cell phase-field model, the SampEuler shape descriptor (a sampled Euler characteristic transform), and approximate Bayesian computation (ABC) by rejection.
This repository contains the code needed to regenerate the simulations,
descriptors, and posteriors. The experimental microscopy images used as
inference targets are in data/experimental_images/; all simulator output and
intermediate caches are regenerated by the scripts below rather than shipped.
We infer the triple (tauV, xi, t): the cell-volume relaxation time, the lumen
osmotic pressure, and the developmental time, from a single snapshot of
unknown developmental age:
- Draw
(tauV, xi)uniformly from the prior and simulate the phase-field model forward. Each run writes a frame at a fixed model-time cadence until its (parameter-dependent) stopping criterion is met. Pooling every frame across all runs gives a candidate set that is uniform over the reachable region{(tauV, xi, t) : 0 <= t <= T(tauV, xi)}. - Featurise every candidate and each observation with the SampEuler descriptor.
- ABC rejection: for each observation, accept the candidates closest under the SampEuler–Wasserstein distance. The candidate pool is built once and reused across all observations.
scripts/
abc_rej/ ABC-rejection pipeline (the main method)
generate_sims.py Stage A1: draw the prior grid, simulate, cache metadata
sample_and_featurise.py Stage A2: pool-sample frames, compute SampEuler descriptors
compute_distances.py Stage B: SampEuler–Wasserstein distances + acceptance
featurise_temporal.py Trajectory (multi-frame) featurisation
featurise_diamnorm.py Size-normalised featurisation for the experimental targets
observations.py Load and featurise the experimental images
exp_distances.py Distances and acceptance for the experimental targets
sim_worker.py, config.py Per-theta workers and configuration
plot_posterior.py, plot_posterior_3p.py, plot_exp_corner.py
core.py Simulator wrapper, ECTComputer, Wasserstein distance
sampeuler.py SampEuler descriptor (sampled Euler characteristic transform)
paths.py Project path configuration (edit for your machine)
launch_abc_rej_gen.sh Stage A1 dispatch across hosts
launch_abc_rej_featurise.sh Stage A2 dispatch across hosts
launch_abc_rej_dist.sh Stage B dispatch, one observation per host
launch_abc_rej_temporal.sh Trajectory-cache dispatch across hosts
compute_sampeuler_bounds.py Regenerate data/sampeuler_bounds.npz (run first)
sweep.py (tauV, xi) sweep driver for the phase-field simulator
gen_fakexp_one.py Generate a synthetic validation organoid
recovery_wasserstein_cuda.py GPU frame-recovery under the Wasserstein distance
abc_rej_distance_cuda.py GPU SampEuler–Wasserstein distance computation
regress_morphometrics.py Ridge regression of morphometrics on SampEuler
plot_recovery_cdf.py Cumulative recovery-error distribution
plot_recovery_per_param.py Per-parameter recovery error versus true time
data/
experimental_images/ Experimental organoid microscopy (.tif), inference targets
- Python 3.9+
numpy,scipy,pandas,scikit-learn,matplotlib,seaborn,Pillow,tqdm,numba,joblib(seerequirements.txt).eucalc, the Euler-characteristic library used by the descriptor. It is made importable throughscripts/paths.py:ensure_eucalc(), which adds a locallib/directory to the path; build/installeucalcand point that helper at it.- MCPFM phase-field solver (C++), not included here. It is the model of
Tanida et al. (2025) and Lee et al. (2026); set
scripts/paths.py:MODEL_REPOto your local build. - A CUDA GPU is required only for the
*_cuda.pyscripts.
This repository is the code behind the published results. It was run across a small cluster with shared storage, so the paths and host allocations are specific to that setup. Adapt them before running anything:
scripts/paths.pyfor the project, data and library locationsscripts/abc_rej/config.pyfor the cache and output directories- the
HOSTSarrays inscripts/launch_abc_rej_*.sh, andABC_REJ_REMOTE_DIR, for the machines that jobs are dispatched to
Copyright (C) 2026 Haochen Yang.
This project is licensed under the GNU General Public License v3.0 or later
(GPL-3.0-or-later), the same licence as the
sampeuler package. You may
redistribute and/or modify it under the terms of the GNU GPL as published by the
Free Software Foundation, either version 3 of the License, or (at your option)
any later version; see LICENSE. GPL is a copyleft licence: any
distributed work derived from this code must also be released as open source
under the same terms.