Hierarchical unsupervised cell type annotation from consensus markers
Project description
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", ...
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cellconsensus-1.2.0.tar.gz.
File metadata
- Download URL: cellconsensus-1.2.0.tar.gz
- Upload date:
- Size: 5.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8814760d4c3fedf012287320df3c180b34473e9f0c2a1edd69824cf1f632f8e5
|
|
| MD5 |
3845bf3fb9546b3e2e75a38c41626db2
|
|
| BLAKE2b-256 |
0b41f941d83d1e5e0fa831b0d84e999ed73f790c4005c6bd06459bc36765addf
|
File details
Details for the file cellconsensus-1.2.0-py3-none-any.whl.
File metadata
- Download URL: cellconsensus-1.2.0-py3-none-any.whl
- Upload date:
- Size: 5.5 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11c909d4f333c211972dfdf19d9f6998878c4cd2e1715fe3c2877e2ea616ea3d
|
|
| MD5 |
7f46a7a3e8819619abd96557c69cfe53
|
|
| BLAKE2b-256 |
99a09f78ab863a2da52c0afc4dbfae5e3940583fc33a2c4a69fd586ae5492ce7
|