Skip to main content

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 scanpy as sc

adata = sc.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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cellconsensus-1.1.0.tar.gz (5.4 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cellconsensus-1.1.0-py3-none-any.whl (5.5 MB view details)

Uploaded Python 3

File details

Details for the file cellconsensus-1.1.0.tar.gz.

File metadata

  • Download URL: cellconsensus-1.1.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

Hashes for cellconsensus-1.1.0.tar.gz
Algorithm Hash digest
SHA256 f73387ca1d795dc6ca5a8fe8436b0669b8a19584fea7040212e3c1be315b5f79
MD5 78891495fb31a00e42e30ea03aa29fd1
BLAKE2b-256 fa4755e7d5134fd0c29aa04c920d1ead77135c9fc154a5ec92165dc0a40e3fec

See more details on using hashes here.

File details

Details for the file cellconsensus-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: cellconsensus-1.1.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

Hashes for cellconsensus-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b3517c18bd0dfc07c4e23402e1f1e71e3aa056c4d8d0aeeb418860aa43aacd8f
MD5 c58e854919c4368b65194ed3082d13af
BLAKE2b-256 5edacc657c4b6a499378b30eff65c09b811cb90a404b63876c08d506123a549d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page