cellxgene-context
Guide for integrating CellxGene Census single-cell data with ENCODE bulk experiments. Use when users need cell-type-specific expression context for ENCODE regulatory data, want to deconvolve bulk ENCODE signals, or validate regulatory elements at single-cell resolution. Trigger o
Install
npx skills add https://github.com/ammawla/encode-toolkit/tree/main/skills/cellxgene-context
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install ammawla-encode-toolkit@llmmart
git clone https://github.com/ammawla/encode-toolkit.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole ammawla/encode-toolkit collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Integrating CellxGene Census Single-Cell Data with ENCODE Bulk Experiments
Bridge bulk ENCODE functional genomics data with cell-type-specific expression from the CellxGene Census, the largest unified single-cell RNA-seq atlas, to resolve cell-type contributions to regulatory element activity.
Scientific Rationale
The question: "Which specific cell types within my tissue drive the regulatory signals I see in bulk ENCODE data?"
ENCODE provides deeply sequenced bulk functional genomics (ChIP-seq, ATAC-seq, Hi-C) across hundreds of biosamples. But bulk data from a tissue like "pancreas" is a mixture of acinar cells (~80%), duct cells (~10%), endocrine cells (~5%), and others. An H3K27ac peak in bulk pancreas could be driven by any of these cell types. CellxGene Census provides cell-type-resolved expression data from 50M+ single-cell observations across thousands of datasets, enabling deconvolution of bulk ENCODE signals.
The Bulk-to-Single-Cell Bridge
| Bulk ENCODE Signal | Single-Cell Question | CellxGene Answer |
|---|---|---|
| H3K27ac peak near INS gene in pancreas | Which cell type expresses INS? | Beta cells (>500 TPM), not acinar (<1 TPM) |
| ATAC-seq peak in liver near ALB | Is this hepatocyte-specific? | Yes — ALB expressed only in hepatocytes |
| Enhancer active in brain cortex | Neurons or glia? | CellxGene resolves excitatory neurons vs. astrocytes vs. oligodendrocytes |
| Broad H3K27ac domain in blood | Which immune cell type? | Can distinguish T cells, B cells, monocytes, NK cells |
What CellxGene Census Provides
- 50M+ single-cell observations from thousands of published datasets
- Standardized cell ontology (Cell Ontology terms) across all datasets
- Unified gene expression in a consistent format
- Metadata: tissue, disease status, sex, ethnicity, developmental stage
- API access via Python (
cellxgene-census) or R (cellxgene.census) - No authentication required for public data
Key Literature
- Megill et al. 2021 "cellxgene: a performant, scalable exploration platform for high dimensional sparse matrices" (bioRxiv preprint). Describes the CellxGene platform architecture and exploration capabilities. DOI: 10.1101/2021.04.05.438318
- CZ CELLxGENE Discover (Chan Zuckerberg Initiative, 2023). CellxGene Census provides programmatic access to the entire CellxGene data corpus as a single unified dataset. https://cellxgene.cziscience.com/
- Regev et al. 2017 "The Human Cell Atlas" (eLife, ~1,500 citations). The vision paper for comprehensive single-cell reference maps of all human cells. CellxGene Census is the largest realization of this vision. DOI: 10.7554/eLife.27041
- Tabula Sapiens Consortium 2022 "The Tabula Sapiens: A multiple-organ, single-cell transcriptomic atlas of humans" (Science, ~800 citations). Multi-organ human cell atlas contributing to CellxGene Census. DOI: 10.1126/science.abl4896
- ENCODE Project Consortium 2020 (Nature, ~1,656 citations). The bulk regulatory element catalog that CellxGene single-cell data contextualizes. DOI: 10.1038/s41586-020-2493-4
When to Use This Skill
| Scenario | How CellxGene Helps |
|---|---|
| Bulk ENCODE peak near a gene — which cell type? | Query gene expression by cell type in matching tissue |
| ENCODE enhancer active in tissue X — cell-type-specific? | Check if enhancer target gene is restricted to one cell type |
| Choosing ENCODE cell line as proxy | Verify which primary cell type the cell line best represents |
| Interpreting differential peaks between tissues | Determine if difference is due to cell-type composition |
| Validating ENCODE scATAC-seq findings | Cross-reference with CellxGene scRNA-seq for same cell types |
| Designing follow-up experiments | Identify which cell types to isolate for validation |
Python API Reference
Installation
pip install cellxgene-census
Requires Python 3.8+. The package uses TileDB-SOMA for efficient data access.
Core API Pattern
import cellxgene_census
# Open the Census (reads metadata, does not download all data)
with cellxgene_census.open_soma() as census:
# Access human data
human = census["census_data"]["homo_sapiens"]
# Query specific genes in specific tissues/cell types
# This is where filtering happens — be specific to control memory
Step 1: Identify the ENCODE Target Gene
Start from an ENCODE finding — a regulatory element near a gene of interest:
# Find enhancers in pancreas
encode_search_experiments(
assay_title="Histone ChIP-seq",
target="H3K27ac",
organ="pancreas",
biosample_type="tissue"
)
# Get peaks
encode_list_files(
experiment_accession="ENCSR...",
file_format="bed",
output_type="IDR thresholded peaks",
assembly="GRCh38"
)
From peaks, identify the nearest gene(s). You need the gene symbol or Ensembl ID.
Step 2: Query CellxGene Census for Cell-Type Expression
Basic Gene Expression Query
import cellxgene_census
import pandas as pd
gene_symbol = "INS" # Insulin — example for pancreas
with cellxgene_census.open_soma() as census:
human = census["census_data"]["homo_sapiens"]
# Get expression for INS in pancreas tissue
# Use obs_value_filter to restrict to pancreas
# Use var_value_filter to restrict to the gene
adata = cellxgene_census.get_anndata(
census,
organism="Homo sapiens",
var_value_filter=f"feature_name == '{gene_symbol}'",
obs_value_filter="tissue_general == 'pancreas'",
obs_column_names=["cell_type", "tissue", "disease", "dataset_id"]
)
# Summarize expression by cell type
expr_by_celltype = adata.to_df().join(adata.obs["cell_type"])
summary = expr_by_celltype.groupby("cell_type").agg(
mean_expr=(gene_symbol, "mean"),
pct_expressed=(gene_symbol, lambda x: (x > 0).mean() * 100),
n_cells=(gene_symbol, "count")
).sort_values("mean_expr", ascending=False)
print(summary.head(10))
Multi-Gene Query
genes_of_interest = ["INS", "GCG", "SST", "PPY"] # Islet hormones
with cellxgene_census.open_soma() as census:
gene_filter = " or ".join([f"feature_name == '{g}'" for g in genes_of_interest])
adata = cellxgene_census.get_anndata(
census,
organism="Homo sapiens",
var_value_filter=gene_filter,
obs_value_filter="tissue_general == 'pancreas'",
obs_column_names=["cell_type", "tissue", "disease"]
)
Query by Cell Ontology Term
# More precise than tissue — query specific cell types
with cellxgene_census.open_soma() as census:
adata = cellxgene_census.get_anndata(
census,
organism="Homo sapiens",
var_value_filter="feature_name == 'INS'",
obs_value_filter="cell_type == 'type B pancreatic cell'", # Cell Ontology term for beta cells
obs_column_names=["cell_type", "tissue", "disease", "sex"]
)
Step 3: Map CellxGene Cell Types to ENCODE Biosamples
CellxGene uses Cell Ontology (CL) terms. ENCODE uses its own biosample ontology. Key mappings:
| CellxGene Cell Type (CL term) | ENCODE Biosample | Notes |
|---|---|---|
| type B pancreatic cell | pancreatic beta cell | Beta cells |
| hepatocyte | hepatocyte | Direct match |
| CD4-positive, alpha-beta T cell | CD4+ T cell | ENCODE may have more specific subtypes |
| monocyte | monocyte | Direct match |
| excitatory neuron | neuron | ENCODE may use broader category |
| oligodendrocyte | oligodendrocyte | Direct match |
| fibroblast | fibroblast | Direct match |
| endothelial cell | endothelial cell of umbilical vein (HUVEC) | ENCODE often uses HUVEC cell line |
| erythrocyte | K562 (CML, erythroid features) | K562 is a proxy, not primary |
Getting Available Cell Types for a Tissue
with cellxgene_census.open_soma() as census:
# Get all cell types observed in pancreas
obs_df = cellxgene_census.get_obs(
census,
organism="Homo sapiens",
value_filter="tissue_general == 'pancreas'",
column_names=["cell_type"]
)
cell_types = obs_df["cell_type"].value_counts()
print(cell_types)
Step 4: Interpret Cell-Type Expression in ENCODE Context
Interpretation Framework
IF gene is expressed in only ONE cell type in the tissue:
-> Bulk ENCODE peak near that gene likely reflects that cell type
-> Example: INS expressed only in beta cells -> pancreas H3K27ac peak at INS is beta-cell-driven
IF gene is expressed in MULTIPLE cell types:
-> Bulk ENCODE peak could be from any contributing cell type
-> Need additional evidence (cell-type-specific TF, scATAC-seq) to resolve
IF gene is expressed at low levels in the dominant cell type:
-> Bulk signal may be weak despite real expression
-> Example: A gene at 100 TPM in beta cells (2% of pancreas) shows ~2 TPM in bulk
IF gene is NOT expressed in any cell type in the tissue:
-> ENCODE peak near that gene likely regulates a DIFFERENT gene
-> Check other nearby genes, or consider long-range regulation
Estimating Bulk Signal Contribution
# Simple deconvolution estimate
# If beta cells = 2% of pancreas, and INS = 500 TPM in beta cells:
# Expected bulk signal contribution = 0.02 * 500 = 10 TPM
# This matches GTEx pancreas INS ~400 TPM (higher due to actual beta cell fraction ~5-10%)
cell_fraction = 0.05 # estimated fraction of cell type in tissue
sc_expression = 500 # TPM in the specific cell type
estimated_bulk = cell_fraction * sc_expression
Step 5: Cross-Reference with ENCODE scATAC-seq
ENCODE has single-cell ATAC-seq data for some tissues. These provide cell-type-resolved chromatin accessibility that directly complements CellxGene scRNA-seq.
# Find ENCODE single-cell data
encode_search_experiments(
assay_title="snATAC-seq",
organ="pancreas"
)
encode_search_experiments(
assay_title="scRNA-seq",
organ="pancreas"
)
When both ENCODE scATAC-seq and CellxGene scRNA-seq are available for the same tissue:
- Use CellxGene to identify which cell types express the gene
- Use ENCODE scATAC-seq to confirm chromatin accessibility at the regulatory element in those cell types
- Convergent evidence (expression + accessibility in same cell type) is strongest
Step 6: Present Results
Cell-Type Expression Summary Table
| Cell Type | N Cells | Mean Expression | % Expressing | ENCODE Biosample Available | Bulk Contribution |
|---|---|---|---|---|---|
| type B pancreatic cell | 12,456 | 487.3 | 92% | pancreatic beta cell (limited) | ~24 TPM (5% fraction) |
| acinar cell | 45,678 | 0.1 | 2% | pancreas tissue (bulk) | ~0.08 TPM |
| ductal cell | 8,901 | 0.0 | 0% | — | 0 TPM |
| alpha cell | 9,234 | 0.0 | 0% | — | 0 TPM |
Key Numbers to Report
- Gene queried and tissue
- Total cells analyzed and number of datasets
- Number of cell types with expression (> threshold)
- Dominant cell type and its expression level
- Estimated contribution to bulk ENCODE signal
- Whether ENCODE has cell-type-specific data for validation
Pitfalls & Edge Cases
- Cell type ontology inconsistency: Different datasets in CellxGene use different cell type annotation schemes. "Macrophage" in one dataset may be labeled "M1 macrophage" or "tissue-resident macrophage" in another. Use Cell Ontology IDs for consistent matching.
- Batch effects across studies: CellxGene aggregates data from many labs. Direct comparison of expression values across datasets requires batch correction (Harmony, scVI). Raw counts are NOT comparable.
- Sparse single-cell data: scRNA-seq has high dropout rates. A gene showing 0 expression in a cell may still be expressed — zero does not mean absent. Use imputation cautiously.
- Species mismatch with ENCODE: CellxGene contains both human and mouse data. Ensure you match the species when cross-referencing with ENCODE experiments. Gene symbols may differ between species.
- Dataset size affects resolution: Large datasets (>100K cells) can resolve rare cell types that small datasets miss. Check dataset size before concluding a cell type is absent.
Walkthrough: Single-Cell Resolution for ENCODE Bulk Epigenomic Data
Goal: Use CellxGene single-cell RNA-seq atlases to deconvolve which cell types within a tissue contribute to ENCODE bulk epigenomic signals. Context: ENCODE bulk ChIP-seq/ATAC-seq captures signals from all cell types in a tissue. CellxGene reveals the cellular composition.
Step 1: Find ENCODE bulk experiments for a tissue
encode_search_experiments(assay_title="ATAC-seq", organ="lung", organism="Homo sapiens")
Expected output:
{
"results": [
{"accession": "ENCSR500LNG", "assay_title": "ATAC-seq", "biosample_summary": "lung", "organ": "lung", "status": "released"}
],
"total": 14,
"limit": 25,
"offset": 0,
"has_more": false,
"next_offset": null
}
Step 2: Query CellxGene for lung cell types
Using CellxGene Census API (via skill guidance):
import cellxgene_census
census = cellxgene_census.open_soma()
lung_cells = census["census_data"]["homo_sapiens"].obs.read(
value_filter="tissue_general == 'lung'",
column_names=["cell_type", "tissue"]
).concat().to_pandas()
lung_cells["cell_type"].value_counts().head(10)
Expected output:
AT2 cell 45,230
macrophage 32,100
endothelial cell 28,450
AT1 cell 22,890
fibroblast 18,670
ciliated cell 15,320
basal cell 9,850
club cell 7,200
NK cell 6,100
dendritic cell 4,800
Interpretation: AT2 cells dominate (45K cells) — bulk ATAC-seq signal likely reflects AT2 accessibility primarily. Immune cells (macrophages, NK, dendritic) contribute ~25% of cells.
Step 3: Identify cell-type markers for deconvolution
For each cell type, identify marker genes with high expression specificity. Use these to estimate which fraction of the ENCODE bulk signal comes from each cell type.
Step 4: Cross-reference with ENCODE single-cell data
encode_search_experiments(assay_title="snATAC-seq", organ="lung", organism="Homo sapiens")
Expected output:
{
"results": [
{"accession": "ENCSR600SCA", "assay_title": "snATAC-seq", "biosample_summary": "lung", "organ": "lung", "status": "released"}
],
"total": 4,
"limit": 25,
"offset": 0,
"has_more": false,
"next_offset": null
}
Interpretation: 4 snATAC-seq experiments available in lung. Compare cell-type accessibility profiles from snATAC-seq with the bulk ATAC-seq to validate deconvolution estimates.
Integration with downstream skills
- Cell-type composition informs compare-biosamples interpretation of tissue differences
- Cell-type markers feed into gtex-expression for bulk deconvolution validation
- Cell-type-specific peaks from scATAC-seq integrate with regulatory-elements
- Cell-type proportions inform disease-research for cell-type-specific disease mechanisms
Code Examples
1. Find ENCODE single-cell experiments for CellxGene comparison
encode_search_experiments(assay_title="scRNA-seq", organ="brain", organism="Homo sapiens")
Expected output:
{
"results": [
{"accession": "ENCSR700SCR", "assay_title": "scRNA-seq", "biosample_summary": "brain", "organ": "brain", "status": "released"}
],
"total": 22,
"limit": 25,
"offset": 0,
"has_more": false,
"next_offset": null
}
2. Survey single-cell data availability
encode_get_facets(assay_title="scRNA-seq", organism="Homo sapiens")
Expected output:
{
"biosample_ontology.organ_slims": [
{"term": "brain", "count": 22},
{"term": "blood", "count": 15},
{"term": "lung", "count": 8}
]
}
3. Compare bulk vs single-cell experiments
encode_compare_experiments(accession1="ENCSR500LNG", accession2="ENCSR600SCA")
Expected output:
{
"experiment_1": {
"accession": "ENCSR500LNG",
"assay": "ATAC-seq",
"biosample": "lung"
},
"experiment_2": {
"accession": "ENCSR600SCA",
"assay": "snATAC-seq",
"biosample": "lung"
},
"verdict": "COMPATIBLE_WITH_CAVEATS",
"recommendation": "These experiments can be compared, but the warnings should be addressed in your analysis.",
"compatible_aspects": [
"Same organism: Homo sapiens",
"Same organ: lung"
],
"issues": [],
"warnings": [
"Different assay types: ATAC-seq vs snATAC-seq. Multi-omic integration may be needed."
]
}
Integration
| This skill produces... | Feed into... | Purpose |
|---|---|---|
| Cell-type composition estimates | compare-biosamples | Explain tissue differences by cellular composition |
| Cell-type marker genes | gtex-expression | Validate markers against GTEx bulk expression |
| Cell-type-specific gene sets | peak-annotation | Assign peaks to cell-type-specific genes |
| Deconvolution proportions | disease-research | Identify disease-relevant cell types within tissues |
| Single-cell expression matrix | scrna-meta-analysis | Integrate CellxGene data with ENCODE scRNA-seq |
| Cell-type-resolved enhancers | regulatory-elements | Map cCREs to specific cell types |
| Cell-type abundance data | visualization-workflow | Generate UMAP/t-SNE plots alongside epigenomic data |
Presenting Results
When reporting CellxGene expression context:
- Expression table: Present a table with columns: cell_type, mean_expression, pct_expressing, n_cells, and tissue_source for the queried gene(s)
- Dataset metadata: Report the CellxGene Census version/snapshot date, organism, tissue filter applied, and whether disease samples were included or excluded
- Key fields to include: Gene symbol, Ensembl ID, tissue of origin, number of datasets contributing, and total cells queried
- Always report: Whether expression values are raw counts or normalized (log1p), the
obs_value_filterused, and any cell type ontology terms (CL IDs) for reproducibility - Context to provide: Note that cross-dataset expression comparisons are affected by protocol differences (10x v2 vs v3 vs Smart-seq2) and that presence/absence is more robust than quantitative levels across studies
- Next steps: Suggest
single-cell-encodefor ENCODE-specific scRNA-seq data, orgtex-expressionfor complementary bulk tissue expression context
Related Skills
single-cell-encode— Working with ENCODE's own single-cell data (scATAC-seq, scRNA-seq)regulatory-elements— Characterizing the bulk ENCODE regulatory elements that CellxGene contextualizesgtex-expression— Bulk tissue expression from GTEx (complements CellxGene single-cell)cross-reference— Linking ENCODE experiments to external databasescompare-biosamples— Comparing ENCODE data across biosamples informed by cell-type compositionepigenome-profiling— Building tissue epigenomic profiles informed by cell-type contextpublication-trust— Verify literature claims backing analytical decisions
For the request: "$ARGUMENTS"
Files (encode-toolkit)
-
references
-
literature.md 10.9 KB
# CellxGene Context — Literature References **Last updated:** 2026-03-07 **Purpose:** Reference catalog for the cellxgene-context skill — key papers informing single-cell atlas resources, cell type annotation, and cross-tissue reference datasets for contextualizing ENCODE functional genomic data at cell-type resolution. --- ## Atlas Vision & Infrastructure --- ### Regev et al. 2017 — The Human Cell Atlas: a strategic overview - **Citation:** Regev A, Teichmann SA, Lander ES, Amit I, Benoist C, Birney E, Bodenmiller B, Campbell P, Carninci P, Clatworthy M, et al. The Human Cell Atlas. eLife, 6:e27041, 2017. - **DOI:** [10.7554/eLife.27041](https://doi.org/10.7554/eLife.27041) - **PMID:** 29206104 | **PMC:** PMC5762154 - **Citations:** ~2,500 - **Key findings:** Outlined the vision and scientific strategy for the Human Cell Atlas (HCA), an international consortium to create comprehensive reference maps of all human cell types and states using single-cell and spatial genomics technologies. Formally defined a "cell type" as a stable transcriptional program reproducibly observed across individuals and experimental conditions, distinguishing it from transient "cell states" driven by activation signals, cell cycle position, or environmental stimuli. Proposed a hierarchical annotation framework from coarse lineages (immune, epithelial, stromal, endothelial, neural) through intermediate classes to fine-grained subtypes and states, establishing the ontological structure that CellxGene uses for organizing and querying atlas data. The HCA vision directly motivates the CellxGene platform as the primary portal for discovering reference cell type profiles and contextualizing bulk ENCODE chromatin data within the cellular composition of profiled tissues. --- ### Megill et al. 2021 — CellxGene: interactive exploration of single-cell datasets - **Citation:** Megill C, Martin B, Weaver C, Bell S, Dedber L, Badajoz S, Heumos L, Pisco AO, et al. CellxGene: a performant, scalable exploration platform for high dimensional sparse matrices. bioRxiv, 2021. - **DOI:** [10.1101/2021.04.05.438318](https://doi.org/10.1101/2021.04.05.438318) - **PMID:** N/A | **PMC:** N/A - **Citations:** ~300 - **Key findings:** Described the CellxGene platform architecture for interactive visualization and exploration of single-cell datasets supporting millions of cells with sub-second query response times through sparse matrix compression and server-side rendering. The platform enables real-time gene expression queries across cell types, on-the-fly differential expression between user-defined cell groups, and embedding visualization (UMAP/t-SNE) with multi-metadata overlays. CellxGene Census provides a programmatic Python/R API for querying across all hosted datasets simultaneously by cell type ontology, tissue, disease status, and gene expression — enabling cross- dataset meta-analyses without downloading individual h5ad files. As of 2025, the platform hosts >1,200 datasets with >80 million cells, making it the de facto portal for Human Cell Atlas data and the richest resource for cell- type-specific expression context. --- ## Reference Atlases --- ### Tabula Sapiens Consortium 2022 — Multi-organ human cell atlas - **Citation:** The Tabula Sapiens Consortium. The Tabula Sapiens: a multiple- organ, single-cell transcriptomic atlas of humans. Science, 376(6594):eabl4896, 2022. - **DOI:** [10.1126/science.abl4896](https://doi.org/10.1126/science.abl4896) - **PMID:** 35549404 | **PMC:** PMC9812015 - **Citations:** ~1,500 - **Key findings:** Profiled ~500,000 cells from 24 tissues of a small cohort of donors using standardized protocols, enabling direct cross-tissue cell type comparison without inter-individual batch confounds. Identified 475 distinct cell types with tissue-shared and tissue-specific transcriptional programs, revealing that resident immune, endothelial, and fibroblast populations acquire tissue-adapted transcriptional signatures distinct from their circulating or generic counterparts — for example, liver sinusoidal endothelial cells express scavenger receptors absent from lung capillary endothelium, reflecting tissue-specific functional specialization. Discovered widespread alternative splicing differences between cell types, with ~40% of genes showing cell-type-specific isoform usage invisible in gene-level expression analysis — suggesting that ENCODE RNA-seq from heterogeneous tissues may mask important isoform dynamics. Tabula Sapiens is a key CellxGene reference atlas for label transfer: annotating cell types in user scRNA-seq datasets by projecting them onto the Tabula Sapiens reference embedding, and for deconvolving bulk ENCODE profiles into estimated cell type proportions to determine which cell populations contribute most to observed chromatin signals. --- ### Tabula Muris Consortium 2018 — Single-cell atlas of the mouse - **Citation:** Tabula Muris Consortium. Single-cell transcriptomics of 20 mouse organs creates a Tabula Muris. Nature, 562(7727):367-372, 2018. - **DOI:** [10.1038/s41586-018-0590-4](https://doi.org/10.1038/s41586-018-0590-4) - **PMID:** 30283141 | **PMC:** PMC6642641 - **Citations:** ~3,000 - **Key findings:** Generated single-cell transcriptomes from >100,000 cells across 20 mouse organs using dual protocols — FACS-sorted Smart-seq2 (full- length, deeper coverage per cell) and 10x Chromium (droplet-based, higher cell throughput). The dual-protocol design enabled rigorous assessment of platform-specific biases: Smart-seq2 detected ~4,000 genes per cell vs. ~1,500 for 10x, but cell type identification was consistent across both platforms when using appropriate integration methods, confirming that major cell populations are robustly identifiable regardless of technology choice. Established a standardized cell type ontology for mouse tissues that maps to ENCODE biosample terms (e.g., ENCODE's "pancreas" tissue corresponds to Tabula Muris acinar, ductal, alpha, beta, delta, epsilon, and stellate cells), enabling deconvolution of bulk ENCODE profiles into cell-type contributions. Tabula Muris serves as the primary reference for mouse cell type annotation in CellxGene, and its cross-species comparisons with human atlases reveal conserved and divergent cell type programs relevant for interpreting mouse ENCODE experiments in human disease context. --- ### Dominguez Conde et al. 2022 — Cross-tissue human immune cell atlas - **Citation:** Dominguez Conde C, Xu C, Jarvis LB, Rainbow DB, Wells SB, Gomes T, Howlett SK, Sherber O, Gould J, Conde CD, et al. Cross-tissue immune cell analysis reveals tissue-specific features in humans. Science, 376(6594):eabl5197, 2022. - **DOI:** [10.1126/science.abl5197](https://doi.org/10.1126/science.abl5197) - **PMID:** 35549406 | **PMC:** PMC7613554 - **Citations:** ~800 - **Key findings:** Profiled 330,000 immune cells from 16 tissues of 12 donors, revealing that tissue-resident immune populations diverge substantially from circulating blood counterparts in gene expression, surface markers, and inferred transcription factor activity. Identified tissue-specific macrophage states (alveolar macrophages in lung, Kupffer cells in liver, microglia in brain, Langerhans cells in skin) with distinct regulatory programs driven by tissue-specific enhancer landscapes detectable by ENCODE ChIP-seq and ATAC-seq. Found that cross-tissue immune cell integration requires particularly careful batch correction because tissue processing artifacts (enzymatic digestion, mechanical dissociation) can be confounded with genuine tissue adaptation signatures. This atlas is essential for interpreting ENCODE immune cell profiling data in tissue context — a K562 or GM12878 ChIP-seq experiment captures only one state of one hematopoietic lineage, while the immune atlas reveals the full spectrum of immune cell diversity across tissues. --- ## Integration Methods --- ### Luecken et al. 2022 — Benchmarking atlas-level single-cell integration - **Citation:** Luecken MD, Buttner M, Chaichoompu K, Danese A, Grote M, Herbst P, Erber W, Pineau J, Schulte-Schrepping J, Sikkema L, et al. Benchmarking atlas-level data integration in single-cell genomics. Nature Methods, 19(1):41-50, 2022. - **DOI:** [10.1038/s41592-021-01336-8](https://doi.org/10.1038/s41592-021-01336-8) - **PMID:** 34949812 | **PMC:** PMC8762698 - **Citations:** ~1,500 - **Key findings:** Systematically benchmarked 16 single-cell integration methods across 85 integration tasks spanning different biological and technical scenarios using the scIB (single-cell Integration Benchmarking) framework. Evaluated methods on two fundamentally competing objectives: batch correction quality (kBET statistic, batch-ASW, graph connectivity) and biological conservation (cell type ASW, NMI, ARI, isolated label score, trajectory conservation). ScVI, scANVI, and Harmony consistently ranked among the top methods for atlas-scale integration tasks, while BBKNN and Combat performed competitively for simpler within-tissue integration. The key insight was that batch correction and biological conservation are inherently in tension — methods that perfectly mix batches often merge biologically distinct but transcriptionally similar cell types, particularly rare populations. This benchmark directly informs method selection when building or querying CellxGene atlases and when deconvolving ENCODE bulk data using single-cell references. --- ### Chazarra-Gil et al. 2021 — Flexible comparison of batch correction methods - **Citation:** Chazarra-Gil R, van Dongen S, Kiselev VY, Hemberger M. Flexible comparison of batch correction methods for single-cell RNA-seq using BatchBench. Genome Biology, 22(1):189, 2021. - **DOI:** [10.1186/s13059-021-02393-y](https://doi.org/10.1186/s13059-021-02393-y) - **PMID:** 34183031 - **Citations:** ~500 - **Key findings:** Introduced BatchBench, a modular Nextflow pipeline for standardized comparison of batch correction methods across diverse single- cell datasets with reproducible metrics. Evaluated 8 methods (Harmony, Scanorama, MNN, ComBat, limma, LIGER, Seurat v3 CCA, BBKNN) across 5 real- world datasets with varying batch complexity. Found that the optimal method depends critically on the nature of the batch effect: same- protocol/different-donor designs (simple batch effects) were correctable by most methods, while cross-platform batch effects (10x vs. Smart-seq2) or cross-species comparisons required embedding-based approaches. Critically demonstrated that integration quality should be assessed at the cell-type level rather than globally, because global metrics can mask complete failure to integrate rare cell populations — a particularly important concern for ENCODE cell type deconvolution where rare cell types like delta cells in islets or stellate cells in liver may be the populations of interest. ---
-
-
SKILL.md 19.6 KB
--- name: cellxgene-context description: "Guide for integrating CellxGene Census single-cell data with ENCODE bulk experiments. Use when users need cell-type-specific expression context for ENCODE regulatory data, want to deconvolve bulk ENCODE signals, or validate regulatory elements at single-cell resolution. Trigger on: CellxGene, single-cell atlas, cell type expression, Census, cell type specificity, single-cell context, scRNA-seq atlas." --- # Integrating CellxGene Census Single-Cell Data with ENCODE Bulk Experiments Bridge bulk ENCODE functional genomics data with cell-type-specific expression from the CellxGene Census, the largest unified single-cell RNA-seq atlas, to resolve cell-type contributions to regulatory element activity. ## Scientific Rationale **The question**: "Which specific cell types within my tissue drive the regulatory signals I see in bulk ENCODE data?" ENCODE provides deeply sequenced bulk functional genomics (ChIP-seq, ATAC-seq, Hi-C) across hundreds of biosamples. But bulk data from a tissue like "pancreas" is a mixture of acinar cells (~80%), duct cells (~10%), endocrine cells (~5%), and others. An H3K27ac peak in bulk pancreas could be driven by any of these cell types. CellxGene Census provides cell-type-resolved expression data from 50M+ single-cell observations across thousands of datasets, enabling deconvolution of bulk ENCODE signals. ### The Bulk-to-Single-Cell Bridge | Bulk ENCODE Signal | Single-Cell Question | CellxGene Answer | |-------------------|---------------------|-----------------| | H3K27ac peak near INS gene in pancreas | Which cell type expresses INS? | Beta cells (>500 TPM), not acinar (<1 TPM) | | ATAC-seq peak in liver near ALB | Is this hepatocyte-specific? | Yes — ALB expressed only in hepatocytes | | Enhancer active in brain cortex | Neurons or glia? | CellxGene resolves excitatory neurons vs. astrocytes vs. oligodendrocytes | | Broad H3K27ac domain in blood | Which immune cell type? | Can distinguish T cells, B cells, monocytes, NK cells | ### What CellxGene Census Provides - **50M+ single-cell observations** from thousands of published datasets - **Standardized cell ontology** (Cell Ontology terms) across all datasets - **Unified gene expression** in a consistent format - **Metadata**: tissue, disease status, sex, ethnicity, developmental stage - **API access** via Python (`cellxgene-census`) or R (`cellxgene.census`) - **No authentication required** for public data ## Key Literature - **Megill et al. 2021** "cellxgene: a performant, scalable exploration platform for high dimensional sparse matrices" (bioRxiv preprint). Describes the CellxGene platform architecture and exploration capabilities. [DOI: 10.1101/2021.04.05.438318](https://doi.org/10.1101/2021.04.05.438318) - **CZ CELLxGENE Discover** (Chan Zuckerberg Initiative, 2023). CellxGene Census provides programmatic access to the entire CellxGene data corpus as a single unified dataset. [https://cellxgene.cziscience.com/](https://cellxgene.cziscience.com/) - **Regev et al. 2017** "The Human Cell Atlas" (eLife, ~1,500 citations). The vision paper for comprehensive single-cell reference maps of all human cells. CellxGene Census is the largest realization of this vision. [DOI: 10.7554/eLife.27041](https://doi.org/10.7554/eLife.27041) - **Tabula Sapiens Consortium 2022** "The Tabula Sapiens: A multiple-organ, single-cell transcriptomic atlas of humans" (Science, ~800 citations). Multi-organ human cell atlas contributing to CellxGene Census. [DOI: 10.1126/science.abl4896](https://doi.org/10.1126/science.abl4896) - **ENCODE Project Consortium 2020** (Nature, ~1,656 citations). The bulk regulatory element catalog that CellxGene single-cell data contextualizes. [DOI: 10.1038/s41586-020-2493-4](https://doi.org/10.1038/s41586-020-2493-4) ## When to Use This Skill | Scenario | How CellxGene Helps | |---------|-------------------| | Bulk ENCODE peak near a gene — which cell type? | Query gene expression by cell type in matching tissue | | ENCODE enhancer active in tissue X — cell-type-specific? | Check if enhancer target gene is restricted to one cell type | | Choosing ENCODE cell line as proxy | Verify which primary cell type the cell line best represents | | Interpreting differential peaks between tissues | Determine if difference is due to cell-type composition | | Validating ENCODE scATAC-seq findings | Cross-reference with CellxGene scRNA-seq for same cell types | | Designing follow-up experiments | Identify which cell types to isolate for validation | ## Python API Reference ### Installation ```bash pip install cellxgene-census ``` Requires Python 3.8+. The package uses TileDB-SOMA for efficient data access. ### Core API Pattern ```python import cellxgene_census # Open the Census (reads metadata, does not download all data) with cellxgene_census.open_soma() as census: # Access human data human = census["census_data"]["homo_sapiens"] # Query specific genes in specific tissues/cell types # This is where filtering happens — be specific to control memory ``` ## Step 1: Identify the ENCODE Target Gene Start from an ENCODE finding — a regulatory element near a gene of interest: ``` # Find enhancers in pancreas encode_search_experiments( assay_title="Histone ChIP-seq", target="H3K27ac", organ="pancreas", biosample_type="tissue" ) # Get peaks encode_list_files( experiment_accession="ENCSR...", file_format="bed", output_type="IDR thresholded peaks", assembly="GRCh38" ) ``` From peaks, identify the nearest gene(s). You need the gene symbol or Ensembl ID. ## Step 2: Query CellxGene Census for Cell-Type Expression ### Basic Gene Expression Query ```python import cellxgene_census import pandas as pd gene_symbol = "INS" # Insulin — example for pancreas with cellxgene_census.open_soma() as census: human = census["census_data"]["homo_sapiens"] # Get expression for INS in pancreas tissue # Use obs_value_filter to restrict to pancreas # Use var_value_filter to restrict to the gene adata = cellxgene_census.get_anndata( census, organism="Homo sapiens", var_value_filter=f"feature_name == '{gene_symbol}'", obs_value_filter="tissue_general == 'pancreas'", obs_column_names=["cell_type", "tissue", "disease", "dataset_id"] ) # Summarize expression by cell type expr_by_celltype = adata.to_df().join(adata.obs["cell_type"]) summary = expr_by_celltype.groupby("cell_type").agg( mean_expr=(gene_symbol, "mean"), pct_expressed=(gene_symbol, lambda x: (x > 0).mean() * 100), n_cells=(gene_symbol, "count") ).sort_values("mean_expr", ascending=False) print(summary.head(10)) ``` ### Multi-Gene Query ```python genes_of_interest = ["INS", "GCG", "SST", "PPY"] # Islet hormones with cellxgene_census.open_soma() as census: gene_filter = " or ".join([f"feature_name == '{g}'" for g in genes_of_interest]) adata = cellxgene_census.get_anndata( census, organism="Homo sapiens", var_value_filter=gene_filter, obs_value_filter="tissue_general == 'pancreas'", obs_column_names=["cell_type", "tissue", "disease"] ) ``` ### Query by Cell Ontology Term ```python # More precise than tissue — query specific cell types with cellxgene_census.open_soma() as census: adata = cellxgene_census.get_anndata( census, organism="Homo sapiens", var_value_filter="feature_name == 'INS'", obs_value_filter="cell_type == 'type B pancreatic cell'", # Cell Ontology term for beta cells obs_column_names=["cell_type", "tissue", "disease", "sex"] ) ``` ## Step 3: Map CellxGene Cell Types to ENCODE Biosamples CellxGene uses Cell Ontology (CL) terms. ENCODE uses its own biosample ontology. Key mappings: | CellxGene Cell Type (CL term) | ENCODE Biosample | Notes | |-------------------------------|-----------------|-------| | type B pancreatic cell | pancreatic beta cell | Beta cells | | hepatocyte | hepatocyte | Direct match | | CD4-positive, alpha-beta T cell | CD4+ T cell | ENCODE may have more specific subtypes | | monocyte | monocyte | Direct match | | excitatory neuron | neuron | ENCODE may use broader category | | oligodendrocyte | oligodendrocyte | Direct match | | fibroblast | fibroblast | Direct match | | endothelial cell | endothelial cell of umbilical vein (HUVEC) | ENCODE often uses HUVEC cell line | | erythrocyte | K562 (CML, erythroid features) | K562 is a proxy, not primary | ### Getting Available Cell Types for a Tissue ```python with cellxgene_census.open_soma() as census: # Get all cell types observed in pancreas obs_df = cellxgene_census.get_obs( census, organism="Homo sapiens", value_filter="tissue_general == 'pancreas'", column_names=["cell_type"] ) cell_types = obs_df["cell_type"].value_counts() print(cell_types) ``` ## Step 4: Interpret Cell-Type Expression in ENCODE Context ### Interpretation Framework ``` IF gene is expressed in only ONE cell type in the tissue: -> Bulk ENCODE peak near that gene likely reflects that cell type -> Example: INS expressed only in beta cells -> pancreas H3K27ac peak at INS is beta-cell-driven IF gene is expressed in MULTIPLE cell types: -> Bulk ENCODE peak could be from any contributing cell type -> Need additional evidence (cell-type-specific TF, scATAC-seq) to resolve IF gene is expressed at low levels in the dominant cell type: -> Bulk signal may be weak despite real expression -> Example: A gene at 100 TPM in beta cells (2% of pancreas) shows ~2 TPM in bulk IF gene is NOT expressed in any cell type in the tissue: -> ENCODE peak near that gene likely regulates a DIFFERENT gene -> Check other nearby genes, or consider long-range regulation ``` ### Estimating Bulk Signal Contribution ```python # Simple deconvolution estimate # If beta cells = 2% of pancreas, and INS = 500 TPM in beta cells: # Expected bulk signal contribution = 0.02 * 500 = 10 TPM # This matches GTEx pancreas INS ~400 TPM (higher due to actual beta cell fraction ~5-10%) cell_fraction = 0.05 # estimated fraction of cell type in tissue sc_expression = 500 # TPM in the specific cell type estimated_bulk = cell_fraction * sc_expression ``` ## Step 5: Cross-Reference with ENCODE scATAC-seq ENCODE has single-cell ATAC-seq data for some tissues. These provide cell-type-resolved chromatin accessibility that directly complements CellxGene scRNA-seq. ``` # Find ENCODE single-cell data encode_search_experiments( assay_title="snATAC-seq", organ="pancreas" ) encode_search_experiments( assay_title="scRNA-seq", organ="pancreas" ) ``` When both ENCODE scATAC-seq and CellxGene scRNA-seq are available for the same tissue: 1. Use CellxGene to identify which cell types express the gene 2. Use ENCODE scATAC-seq to confirm chromatin accessibility at the regulatory element in those cell types 3. Convergent evidence (expression + accessibility in same cell type) is strongest ## Step 6: Present Results ### Cell-Type Expression Summary Table | Cell Type | N Cells | Mean Expression | % Expressing | ENCODE Biosample Available | Bulk Contribution | |-----------|---------|----------------|-------------|---------------------------|-------------------| | type B pancreatic cell | 12,456 | 487.3 | 92% | pancreatic beta cell (limited) | ~24 TPM (5% fraction) | | acinar cell | 45,678 | 0.1 | 2% | pancreas tissue (bulk) | ~0.08 TPM | | ductal cell | 8,901 | 0.0 | 0% | — | 0 TPM | | alpha cell | 9,234 | 0.0 | 0% | — | 0 TPM | ### Key Numbers to Report - Gene queried and tissue - Total cells analyzed and number of datasets - Number of cell types with expression (> threshold) - Dominant cell type and its expression level - Estimated contribution to bulk ENCODE signal - Whether ENCODE has cell-type-specific data for validation ## Pitfalls & Edge Cases - **Cell type ontology inconsistency**: Different datasets in CellxGene use different cell type annotation schemes. "Macrophage" in one dataset may be labeled "M1 macrophage" or "tissue-resident macrophage" in another. Use Cell Ontology IDs for consistent matching. - **Batch effects across studies**: CellxGene aggregates data from many labs. Direct comparison of expression values across datasets requires batch correction (Harmony, scVI). Raw counts are NOT comparable. - **Sparse single-cell data**: scRNA-seq has high dropout rates. A gene showing 0 expression in a cell may still be expressed — zero does not mean absent. Use imputation cautiously. - **Species mismatch with ENCODE**: CellxGene contains both human and mouse data. Ensure you match the species when cross-referencing with ENCODE experiments. Gene symbols may differ between species. - **Dataset size affects resolution**: Large datasets (>100K cells) can resolve rare cell types that small datasets miss. Check dataset size before concluding a cell type is absent. ## Walkthrough: Single-Cell Resolution for ENCODE Bulk Epigenomic Data **Goal**: Use CellxGene single-cell RNA-seq atlases to deconvolve which cell types within a tissue contribute to ENCODE bulk epigenomic signals. **Context**: ENCODE bulk ChIP-seq/ATAC-seq captures signals from all cell types in a tissue. CellxGene reveals the cellular composition. ### Step 1: Find ENCODE bulk experiments for a tissue ``` encode_search_experiments(assay_title="ATAC-seq", organ="lung", organism="Homo sapiens") ``` Expected output: ```json { "results": [ {"accession": "ENCSR500LNG", "assay_title": "ATAC-seq", "biosample_summary": "lung", "organ": "lung", "status": "released"} ], "total": 14, "limit": 25, "offset": 0, "has_more": false, "next_offset": null } ``` ### Step 2: Query CellxGene for lung cell types Using CellxGene Census API (via skill guidance): ```python import cellxgene_census census = cellxgene_census.open_soma() lung_cells = census["census_data"]["homo_sapiens"].obs.read( value_filter="tissue_general == 'lung'", column_names=["cell_type", "tissue"] ).concat().to_pandas() lung_cells["cell_type"].value_counts().head(10) ``` Expected output: ``` AT2 cell 45,230 macrophage 32,100 endothelial cell 28,450 AT1 cell 22,890 fibroblast 18,670 ciliated cell 15,320 basal cell 9,850 club cell 7,200 NK cell 6,100 dendritic cell 4,800 ``` **Interpretation**: AT2 cells dominate (45K cells) — bulk ATAC-seq signal likely reflects AT2 accessibility primarily. Immune cells (macrophages, NK, dendritic) contribute ~25% of cells. ### Step 3: Identify cell-type markers for deconvolution For each cell type, identify marker genes with high expression specificity. Use these to estimate which fraction of the ENCODE bulk signal comes from each cell type. ### Step 4: Cross-reference with ENCODE single-cell data ``` encode_search_experiments(assay_title="snATAC-seq", organ="lung", organism="Homo sapiens") ``` Expected output: ```json { "results": [ {"accession": "ENCSR600SCA", "assay_title": "snATAC-seq", "biosample_summary": "lung", "organ": "lung", "status": "released"} ], "total": 4, "limit": 25, "offset": 0, "has_more": false, "next_offset": null } ``` **Interpretation**: 4 snATAC-seq experiments available in lung. Compare cell-type accessibility profiles from snATAC-seq with the bulk ATAC-seq to validate deconvolution estimates. ### Integration with downstream skills - Cell-type composition informs **compare-biosamples** interpretation of tissue differences - Cell-type markers feed into **gtex-expression** for bulk deconvolution validation - Cell-type-specific peaks from scATAC-seq integrate with **regulatory-elements** - Cell-type proportions inform **disease-research** for cell-type-specific disease mechanisms ## Code Examples ### 1. Find ENCODE single-cell experiments for CellxGene comparison ``` encode_search_experiments(assay_title="scRNA-seq", organ="brain", organism="Homo sapiens") ``` Expected output: ```json { "results": [ {"accession": "ENCSR700SCR", "assay_title": "scRNA-seq", "biosample_summary": "brain", "organ": "brain", "status": "released"} ], "total": 22, "limit": 25, "offset": 0, "has_more": false, "next_offset": null } ``` ### 2. Survey single-cell data availability ``` encode_get_facets(assay_title="scRNA-seq", organism="Homo sapiens") ``` Expected output: ```json { "biosample_ontology.organ_slims": [ {"term": "brain", "count": 22}, {"term": "blood", "count": 15}, {"term": "lung", "count": 8} ] } ``` ### 3. Compare bulk vs single-cell experiments ``` encode_compare_experiments(accession1="ENCSR500LNG", accession2="ENCSR600SCA") ``` Expected output: ```json { "experiment_1": { "accession": "ENCSR500LNG", "assay": "ATAC-seq", "biosample": "lung" }, "experiment_2": { "accession": "ENCSR600SCA", "assay": "snATAC-seq", "biosample": "lung" }, "verdict": "COMPATIBLE_WITH_CAVEATS", "recommendation": "These experiments can be compared, but the warnings should be addressed in your analysis.", "compatible_aspects": [ "Same organism: Homo sapiens", "Same organ: lung" ], "issues": [], "warnings": [ "Different assay types: ATAC-seq vs snATAC-seq. Multi-omic integration may be needed." ] } ``` ## Integration | This skill produces... | Feed into... | Purpose | |---|---|---| | Cell-type composition estimates | **compare-biosamples** | Explain tissue differences by cellular composition | | Cell-type marker genes | **gtex-expression** | Validate markers against GTEx bulk expression | | Cell-type-specific gene sets | **peak-annotation** | Assign peaks to cell-type-specific genes | | Deconvolution proportions | **disease-research** | Identify disease-relevant cell types within tissues | | Single-cell expression matrix | **scrna-meta-analysis** | Integrate CellxGene data with ENCODE scRNA-seq | | Cell-type-resolved enhancers | **regulatory-elements** | Map cCREs to specific cell types | | Cell-type abundance data | **visualization-workflow** | Generate UMAP/t-SNE plots alongside epigenomic data | ## Presenting Results When reporting CellxGene expression context: - **Expression table**: Present a table with columns: cell_type, mean_expression, pct_expressing, n_cells, and tissue_source for the queried gene(s) - **Dataset metadata**: Report the CellxGene Census version/snapshot date, organism, tissue filter applied, and whether disease samples were included or excluded - **Key fields to include**: Gene symbol, Ensembl ID, tissue of origin, number of datasets contributing, and total cells queried - **Always report**: Whether expression values are raw counts or normalized (log1p), the `obs_value_filter` used, and any cell type ontology terms (CL IDs) for reproducibility - **Context to provide**: Note that cross-dataset expression comparisons are affected by protocol differences (10x v2 vs v3 vs Smart-seq2) and that presence/absence is more robust than quantitative levels across studies - **Next steps**: Suggest `single-cell-encode` for ENCODE-specific scRNA-seq data, or `gtex-expression` for complementary bulk tissue expression context ## Related Skills - `single-cell-encode` — Working with ENCODE's own single-cell data (scATAC-seq, scRNA-seq) - `regulatory-elements` — Characterizing the bulk ENCODE regulatory elements that CellxGene contextualizes - `gtex-expression` — Bulk tissue expression from GTEx (complements CellxGene single-cell) - `cross-reference` — Linking ENCODE experiments to external databases - `compare-biosamples` — Comparing ENCODE data across biosamples informed by cell-type composition - `epigenome-profiling` — Building tissue epigenomic profiles informed by cell-type context - `publication-trust` — Verify literature claims backing analytical decisions ## For the request: "$ARGUMENTS"
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.