Moirai
August 4, 2026 · View on GitHub
Moirai is a graph-based method that utilizes gene expression patterns sampled across the developmental continuum to predict pseudotime. Underlying Moirai are two key assumptions, which are (1) the expression of (a subset of) genes involved in cell fate specification changes gradually across pseudotime, and (2) these expression patterns can be captured across a population of cells. To capture these expression patterns, we embed single cells in a lower dimensional space which is used to construct a graph that captures the developmental topology. Here, we perform random walks from among which we identify expression patterns that change dynamically across the graph. We assume that these expression patterns belong to genes involved in cell fate specification. By defining a common pseudotime axis based on the expression patterns sampled across the graph, we finally infer pseudotime for all cells represented in the data.
Contents
moirai_core.py — Steps 1–6 of the pipeline: embedding and k-NN graph construction,
transition-matrix biasing, random walks, gene-dynamics scoring and alignment, and iterative
transition updates. Entry point: run_moirai().
moirai_downstream.py — Step 7: alignment of seed-specific matrices into a single
pseudotime axis, including approximate-match alignment and k-NN imputation for unaligned cells.
Entry point: pseudotime_pred().
Usage
run_moirai()'s return values feed directly into pseudotime_pred() and knn_impute() by name:
import scanpy as sc
from moirai_core import run_moirai
from moirai_downstream import pseudotime_pred, knn_impute
ad = sc.read("data.h5ad")
adj_upd, align, al_seeds, seeds, seed_upd = run_moirai(
ad,
start_cell=start_cell_indices, # list of starting-cell indices
normalize=True,
log_transform=True,
)
final_pseud, pseud_norm, pseud_std, pseud_std_mean, na_all = pseudotime_pred(
shift=40, # keep consistent with the value passed to run_moirai
max_steps=250, # keep consistent with the value passed to run_moirai
align=align,
seeds=seeds,
al_seeds=al_seeds,
N=ad.shape[0],
m_match=1, # number of repeat pseudotime runs over different guide walks
out_file="pseudotime_run",
)
# Optional: impute pseudotime for cells left out of the alignment
pseud_norm_imp = knn_impute(pseud_norm, adj_upd)
See the docstrings in each function for the full parameter list and defaults.
Dependencies
See requirements.txt.