PyStemFinder
PyStemFinder estimates how far single cells have progressed through differentiation from scRNA-seq data. Less differentiated cells vary more in their expression of cell cycle genes than their neighbors do, and stemFinder scores that heterogeneity within each cell's k-nearest-neighbor neighborhood.
PyStemFinder is a Python port of the R package stemFinder
that works on AnnData objects and
scanpy neighbor graphs. Given the same inputs, its scores match R's
to within floating point precision (checked in tests/test_r_parity.py against the R vignette's
bone marrow data).
Installation
pystemfinder requires Python 3.11 or newer.
pip install pystemfinder
The development version installs with pip install git+https://github.com/CahanLab/PyStemFinder.git.
To run the tutorials or the tests, clone the repository and install into the conda environment
defined in environment.yml:
git clone https://github.com/CahanLab/PyStemFinder.git
cd PyStemFinder
conda env create -f environment.yml
conda activate pystemfinder
pip install -e .
Usage
import numpy as np
import scanpy as sc
import pystemfinder as psf
# adata: raw counts (cells x genes)
markers = psf.cell_cycle_genes("mouse") # S and G2M phase genes; also "human", "celegans"
# normalize, log-transform, scale, and run PCA, leaving the markers out of the highly variable genes
psf.recipe_stemfinder(adata, exclude=markers, n_comps=50)
sc.pp.neighbors(adata, n_neighbors=int(round(np.sqrt(adata.n_obs))), n_pcs=32)
psf.stemfinder(adata, markers)
# adata.obs["stemfinder_raw"]: higher = less differentiated
# adata.obs["stemfinder"]: 1 - raw / max(raw), oriented like pseudotime
With ground truth differentiation stages in adata.obs["Ground_truth"] and cell types in
adata.obs["Phenotype"], psf.compute_performance(adata) and psf.pct_recover(adata) benchmark the
scores as in the R package.
The documentation includes notebooks (in docs/notebooks) that
walk through a toy dataset (quickstart.ipynb) and reproduce the R vignette (benchmarking.ipynb).
Coming from the R package
| R stemFinder | pystemfinder |
|---|---|
run_stemFinder(adata, nn, k, thresh, markers, method) |
stemfinder(adata, markers, threshold, method) |
compute_performance_single(adata, competitor, comp.inverted) |
compute_performance(adata, competitor_key=..., competitor_inverted=...) |
pct_recover(adata) |
pct_recover(adata) |
gene_set_score(gene.set, adata) |
gene_set_score(adata, genes) |
c(s_genes_mouse, g2m_genes_mouse), mmTFs |
cell_cycle_genes("mouse"), transcription_factors("mouse") |
Differences:
compute_performancecomputes the AUC over every pair of most and least differentiated cells. R'sauc_probabilitycompares only the first most differentiated cell with the least differentiated ones.- The phenotype-level correlation is Spearman, as its name says; R's uses Pearson. Pass
pheno_method="pearson"to reproduce R's value. stemfinderreads the neighborhood size from the kNN graph, so it takes nokargument.- E2f8 (E2F8 in human) is an S phase gene only. The R package also lists it under G2M, so the R vignette counts it twice, and R counts any repeated marker once per occurrence; pystemfinder counts each marker once. Scores on the vignette's data therefore differ slightly from the published ones (rank correlation 0.9999).
See CHANGELOG.md for details.
Documentation
https://pystemfinder.readthedocs.io
To build the docs locally:
pip install -r docs/requirements.txt
sphinx-build docs docs/_build/html
Tests
pytest
Citation
Noller K, Cahan P. Cell cycle expression heterogeneity predicts degree of differentiation. Briefings in Bioinformatics 25(6):bbae536 (2024). https://doi.org/10.1093/bib/bbae536
License
MIT; see LICENSE.
Metadata
Release files for pystemfinder 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pystemfinder-0.5.0.tar.gz | 1.4 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pystemfinder-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.5 MB
Release files / pystemfinder-0.5.0.tar.gz
| Download URL | pystemfinder-0.5.0.tar.gz |
|---|---|
| Size | 1.4 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f3f704e905f9732e58c2a1afbefd496fb4f384bfa914e3f9535289c5bf813291
|
|
BLAKE2b-256 checksum How to use checksums |
b825a306928d4fd8113ef7ae60c0db12b08d7ccde0406c87dc1ec07d67f309bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency logRelease files / pystemfinder-0.5.0-py3-none-any.whl
| Download URL | pystemfinder-0.5.0-py3-none-any.whl |
|---|---|
| Size | 28.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6493b28a314a9a19c5737c8b05908793dfa90092c08ad3bdaaf0769ef36446e6
|
|
BLAKE2b-256 checksum How to use checksums |
1023d99ccacd2a1680efcbb94f536fb4472d618f5b1664c20c8b4b2434e16bc3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency log