pyglmGamPoi#

A native Python replacement for R glmGamPoi in SCTransform v2

pyglmGamPoi reimplements sctransform::fit_glmGamPoi_offset — the per-gene negative-binomial offset model at the heart of Seurat SCTransform v2 — in pure Python/C++, with no R runtime required.

It is designed as a drop-in backend for trackcell single-cell pipelines, replacing Rscript subprocess calls to glmGamPoi while preserving numerical parity with R.

Why pyglmGamPoi?#

R glmGamPoi (before)

pyglmGamPoi (after)

Runtime

BiocManager::install("glmGamPoi")

pip install pyglmGamPoi

Integration

Rscript subprocess per fit

Native Python call

theta parity (real data)

reference

med |Δ| ≈ 10-7

Inf theta (Poisson genes)

reference

exact match

Speed (2000×2000 step1, 8 threads)

~15 s

~2.2 s (~7× vs R)

Memory (10x CSR)

dense toarray()

native CSR (no densify)

Quick start#

import numpy as np
from pyglmGamPoi import fit_glmGamPoi_offset

umi = np.random.poisson(3, size=(100, 50)).astype(float)
log10_umi = np.log10(umi.sum(axis=0) + 1e-9)
model_pars = fit_glmGamPoi_offset(umi, log10_umi)
# columns: theta, Intercept, log_umi

Architecture#

pyglmGamPoi/offset.py          Python API (AnnData-friendly)
        │
pyglmGamPoi/_core.so           pybind11 binding
        │
src/glm_gp_offset.cpp          per-gene glm_gp loop
src/offset_fit.cpp             Newton-Raphson + Brent fallback
src/overdispersion.cpp         Cox-Reid overdispersion MLE

Algorithms follow glmGamPoi but are rewritten without R/Rcpp dependencies.

Indices#