CellConsensus
⚠️ Heavy development. API and outputs are evolving rapidly — breaking changes between versions should be expected. Pin a specific version if you need stability.
Hierarchical unsupervised cell type annotation from consensus marker genes — three levels of granularity, no reference atlas required, plus user-defined gene-set and cell-type scoring.
📖 Full README with figures and demo video: https://github.com/tansey-lab/cellconsensus
Explore the database
Browse the underlying consensus marker database — per-cell-type marker lists, sources, and gene rankings — at http://cellconsensus.org/.
The same database is exposed as an MCP server so AI assistants can query it conversationally (e.g. "what are the markers for memory CD8+ T cells?", "what is the cell type for this set of marker genes: LST1, FCER1G, AIF1, FTH1, IFITM2?"):
https://wrbcaolmpdeefznfkqpj.supabase.co/functions/v1/mcp
Claude: Settings → Connectors → Add custom connector → paste the URL above. ChatGPT: Settings → Apps → Advanced settings → enable Developer mode → Create Connector → paste the URL above.
Installation
pip install cellconsensus
Or the latest development version from GitHub:
pip install git+https://github.com/tansey-lab/cellconsensus.git
Usage
from cellconsensus import CellConsensus
import anndata as ad
adata = ad.read_h5ad("my_data.h5ad")
cc = CellConsensus()
cc.fit(adata, include_cancer=True, cancer_types=["lung_adenocarcinoma"])
labels_lvl1 = cc.predict(level=1) # "T cell", "myeloid cell", ...
labels_lvl2 = cc.predict(level=2) # "CD4+ T cell", "macrophage", ...
labels_lvl3 = cc.predict(level=3) # "memory CD4+ T cell", ...
# Per-cell × per-type score matrix (DataFrame, n_cells x n_lvl1_types)
S = cc.score_matrix(level=1)
# Save / reload
cc.save("model.pkl")
cc2 = CellConsensus.load("model.pkl")
cancer_types accepts any key from cellconsensus.list_cancer_types() (120 entries including lung_adenocarcinoma, breast_carcinoma, melanoma, …). Omit include_cancer for normal-tissue-only fits. The available cell-type keys at each level are listed by cellconsensus.load_cell_type(level=1|2|3).
Per-cell-type scores
predict_score returns the continuous score for any cell type (at any level) or any cancer type, reduced the same way as fit (NN smoothing for ccc, per-cluster averaging for precomputed). Use load_cell_type(level=N) to see the available cell-type keys; list_cancer_types() for cancer keys.
from cellconsensus import load_cell_type, list_cancer_types
load_cell_type(level=1) # {'t_cell': 'T cell', 'myeloid_cell': 'myeloid cell', ...}
load_cell_type(level=2) # 44 subtypes
load_cell_type(level=3) # 76 fine-grained types
# Single key, list, or mixed cell type + cancer in one call:
cc.predict_score("t_cell") # L1 T-cell score per cell
cc.predict_score(["nk", "monocyte"], level=2) # two L2 scores
cc.predict_score(["t_cell", "melanoma"]) # mixed; cancer auto-detected
Custom gene signatures
Score cells against any user-supplied marker list — pooled the same way as the built-in references (NN-graph smoothing for ccc, per-cluster averaging for precomputed), so the result is directly comparable to entries of score_matrix.
sig = {"WT1": 10, "CCND1": 8, "CD99": 7, "NCAM1": 6, "MKI67": 5}
df = cc.predict_gene_set(list(sig.keys()), weights=sig, name="my_sig")
adata.obs["my_sig_score"] = df["my_sig"].values
weights accepts a list, a dict (missing entries default to 1.0), or None for uniform. Negative weights are allowed (anti-markers).
Bringing your own clusters
Already have clusters (Leiden, or anything else)? Pass clustering="precomputed" with the obs column that holds the labels. CellConsensus uses the same three-level taxonomy as the default ccc mode — it just averages the marker scores across all cells in each cluster (no NN smoothing) and labels every cluster by the argmax. Clusters are never split: each one gets a single label per level, gaining precision from level 1 to level 3.
import scanpy as sc
sc.pp.neighbors(adata)
sc.tl.leiden(adata, key_added="my_clusters") # your clustering, your way
cc = CellConsensus(clustering="precomputed", cluster_key="my_clusters")
cc.fit(adata)
cc.predict(level=1) # "T cell", "myeloid cell", ...
cc.predict(level=3) # "memory CD4+ T cell", ...
Metadata
Release files for cellconsensus 1.2.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 | |
|---|---|---|---|
| cellconsensus-1.2.0.tar.gz | 5.4 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cellconsensus-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 10.9 MB
Release files / cellconsensus-1.2.0.tar.gz
| Download URL | cellconsensus-1.2.0.tar.gz |
|---|---|
| Size | 5.4 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8814760d4c3fedf012287320df3c180b34473e9f0c2a1edd69824cf1f632f8e5
|
|
BLAKE2b-256 checksum How to use checksums |
0b41f941d83d1e5e0fa831b0d84e999ed73f790c4005c6bd06459bc36765addf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Release files / cellconsensus-1.2.0-py3-none-any.whl
| Download URL | cellconsensus-1.2.0-py3-none-any.whl |
|---|---|
| Size | 5.5 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
11c909d4f333c211972dfdf19d9f6998878c4cd2e1715fe3c2877e2ea616ea3d
|
|
BLAKE2b-256 checksum How to use checksums |
99a09f78ab863a2da52c0afc4dbfae5e3940583fc33a2c4a69fd586ae5492ce7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|