| name | cellxgene-census-query |
| description | Query CZ CELLxGENE Census (61M+ cells). Filter by cell type/tissue/disease, retrieve expression data, and integrate with scanpy/PyTorch for population-scale single-cell analysis. Use this skill when: (1) Querying single-cell expression data by cell type, tissue, or disease, (2) Exploring available single-cell datasets and metadata, (3) Training machine learning models on single-cell data, (4) Performing large-scale cross-dataset analyses.
|
| license | MIT |
| category | bioinformatics |
| tags | ["single-cell","transcriptomics","genomics","scanpy","machine-learning","pytorch"] |
CZ CELLxGENE Census
The CZ CELLxGENE Census provides programmatic access to a comprehensive, versioned collection of standardized single-cell genomics data from CZ CELLxGENE Discover. This skill enables efficient querying and analysis of millions of cells across thousands of datasets.
The Census includes:
- 61+ million cells from human and mouse
- Standardized metadata (cell types, tissues, diseases, donors)
- Raw gene expression matrices
- Pre-calculated embeddings and statistics
- Integration with PyTorch, scanpy, and other analysis tools
What it does
- Querying single-cell expression data by cell type, tissue, or disease
- Exploring available single-cell datasets and metadata
- Training machine learning models on single-cell data
- Performing large-scale cross-dataset analyses
- Integrating Census data with scanpy or other analysis frameworks
- Computing statistics across millions of cells
- Accessing pre-calculated embeddings or model predictions
Why this exists
This skill encodes the correct, scalable methodological decisions for population-level single-cell data:
- Uses the official
tiledbsoma backend to query data remotely without downloading massive files.
- Automatically handles out-of-core processing (
axis_query) for datasets larger than your available RAM.
- Always enforces
is_primary_data == True to prevent statistical inflation from duplicate cells.
- Native, memory-efficient integration directly into PyTorch DataLoaders and Scanpy objects.
Usage
1. Opening the Census
Always use the context manager to ensure proper resource cleanup:
import cellxgene_census
with cellxgene_census.open_soma() as census:
with cellxgene_census.open_soma(census_version="2023-07-25") as census:
Key points:
- Use context manager (
with statement) for automatic cleanup
- Specify
census_version for reproducible analyses
- Default opens latest "stable" release
2. Exploring Census Information
Before querying expression data, explore available datasets and metadata.
Access summary information:
summary = census["census_info"]["summary"].read().concat().to_pandas()
print(f"Total cells: {summary['total_cell_count'][0]}")
datasets = census["census_info"]["datasets"].read().concat().to_pandas()
covid_datasets = datasets[datasets["disease"].str.contains("COVID", na=False)]
Query cell metadata to understand available data:
cell_metadata = cellxgene_census.get_obs(
census,
"homo_sapiens",
value_filter="tissue_general == 'brain' and is_primary_data == True",
column_names=["cell_type"]
)
unique_cell_types = cell_metadata["cell_type"].unique()
print(f"Found {len(unique_cell_types)} cell types in brain")
tissue_counts = cell_metadata.groupby("tissue_general").size()
Important: Always filter for is_primary_data == True to avoid counting duplicate cells unless specifically analyzing duplicates.
3. Querying Expression Data (Small to Medium Scale)
For queries returning < 100k cells that fit in memory, use get_anndata():
adata = cellxgene_census.get_anndata(
census=census,
organism="Homo sapiens",
obs_value_filter="cell_type == 'B cell' and tissue_general == 'lung' and is_primary_data == True",
obs_column_names=["assay", "disease", "sex", "donor_id"],
)
adata = cellxgene_census.get_anndata(
census=census,
organism="Homo sapiens",
var_value_filter="feature_name in ['CD4', 'CD8A', 'CD19', 'FOXP3']",
obs_value_filter="cell_type == 'T cell' and disease == 'COVID-19' and is_primary_data == True",
obs_column_names=["cell_type", "tissue_general", "donor_id"],
)
Filter syntax:
- Use
obs_value_filter for cell filtering
- Use
var_value_filter for gene filtering
- Combine conditions with
and, or
- Use
in for multiple values: tissue in ['lung', 'liver']
- Select only needed columns with
obs_column_names
Getting metadata separately:
cell_metadata = cellxgene_census.get_obs(
census, "homo_sapiens",
value_filter="disease == 'COVID-19' and is_primary_data == True",
column_names=["cell_type", "tissue_general", "donor_id"]
)
gene_metadata = cellxgene_census.get_var(
census, "homo_sapiens",
value_filter="feature_name in ['CD4', 'CD8A']",
column_names=["feature_id", "feature_name", "feature_length"]
)
4. Large-Scale Queries (Out-of-Core Processing)
For queries exceeding available RAM, use axis_query() with iterative processing:
import tiledbsoma as soma
query = census["census_data"]["homo_sapiens"].axis_query(
measurement_name="RNA",
obs_query=soma.AxisQuery(
value_filter="tissue_general == 'brain' and is_primary_data == True"
),
var_query=soma.AxisQuery(
value_filter="feature_name in ['FOXP2', 'TBR1', 'SATB2']"
)
)
iterator = query.X("raw").tables()
for batch in iterator:
process_batch(batch)
Computing incremental statistics:
n_observations = 0
sum_values = 0.0
iterator = query.X("raw").tables()
for batch in iterator:
values = batch["soma_data"].to_numpy()
n_observations += len(values)
sum_values += values.sum()
mean_expression = sum_values / n_observations
5. Machine Learning with PyTorch
For training models, use the experimental PyTorch integration:
from cellxgene_census.experimental.ml import experiment_dataloader
with cellxgene_census.open_soma() as census:
dataloader = experiment_dataloader(
census["census_data"]["homo_sapiens"],
measurement_name="RNA",
X_name="raw",
obs_value_filter="tissue_general == 'liver' and is_primary_data == True",
obs_column_names=["cell_type"],
batch_size=128,
shuffle=True,
)
for epoch in range(num_epochs):
for batch in dataloader:
X = batch["X"]
labels = batch["obs"]["cell_type"]
outputs = model(X)
loss = criterion(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
Train/test splitting:
from cellxgene_census.experimental.ml import ExperimentDataset
dataset = ExperimentDataset(
experiment_axis_query,
layer_name="raw",
obs_column_names=["cell_type"],
batch_size=128,
)
train_dataset, test_dataset = dataset.random_split(
split=[0.8, 0.2],
seed=42
)
6. Integration with Scanpy
Seamlessly integrate Census data with scanpy workflows:
import scanpy as sc
adata = cellxgene_census.get_anndata(
census=census,
organism="Homo sapiens",
obs_value_filter="cell_type == 'neuron' and tissue_general == 'cortex' and is_primary_data == True",
)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, n_top_genes=2000)
sc.pp.pca(adata, n_comps=50)
sc.pp.neighbors(adata)
sc.tl.umap(adata)
sc.pl.umap(adata, color=["cell_type", "tissue", "disease"])
7. Multi-Dataset Integration
Query and integrate multiple datasets:
tissues = ["lung", "liver", "kidney"]
adatas = []
for tissue in tissues:
adata = cellxgene_census.get_anndata(
census=census,
organism="Homo sapiens",
obs_value_filter=f"tissue_general == '{tissue}' and is_primary_data == True",
)
adata.obs["tissue"] = tissue
adatas.append(adata)
combined = adatas[0].concatenate(adatas[1:])
adata = cellxgene_census.get_anndata(
census=census,
organism="Homo sapiens",
obs_value_filter="tissue_general in ['lung', 'liver', 'kidney'] and is_primary_data == True",
)
Use Case 1: Explore Cell Types in a Tissue
with cellxgene_census.open_soma() as census:
cells = cellxgene_census.get_obs(
census, "homo_sapiens",
value_filter="tissue_general == 'lung' and is_primary_data == True",
column_names=["cell_type"]
)
print(cells["cell_type"].value_counts())
Use Case 2: Query Marker Gene Expression
with cellxgene_census.open_soma() as census:
adata = cellxgene_census.get_anndata(
census=census,
organism="Homo sapiens",
var_value_filter="feature_name in ['CD4', 'CD8A', 'CD19']",
obs_value_filter="cell_type in ['T cell', 'B cell'] and is_primary_data == True",
)
Use Case 3: Train Cell Type Classifier
from cellxgene_census.experimental.ml import experiment_dataloader
with cellxgene_census.open_soma() as census:
dataloader = experiment_dataloader(
census["census_data"]["homo_sapiens"],
measurement_name="RNA",
X_name="raw",
obs_value_filter="is_primary_data == True",
obs_column_names=["cell_type"],
batch_size=128,
shuffle=True,
)
for epoch in range(epochs):
for batch in dataloader:
pass
Use Case 4: Cross-Tissue Analysis
with cellxgene_census.open_soma() as census:
adata = cellxgene_census.get_anndata(
census=census,
organism="Homo sapiens",
obs_value_filter="cell_type == 'macrophage' and tissue_general in ['lung', 'liver', 'brain'] and is_primary_data == True",
)
sc.tl.rank_genes_groups(adata, groupby="tissue_general")
Example Output
CZ CELLxGENE Census Query
==========================
Census Version: 2023-07-25 (Stable)
Organism: Homo sapiens
Filters: tissue_general == 'lung' AND is_primary_data == True
Query Summary:
Found 382,194 unique cells across 14 datasets.
Retrieved 2,000 highly variable genes.
Expression Data Loaded:
AnnData object with n_obs × n_vars = 382194 × 2000
obs: 'assay', 'cell_type', 'disease', 'tissue', 'donor_id'
var: 'feature_id', 'feature_name', 'feature_length'
Downstream Ready:
Memory footprint: ~3.1 GB
Matrix format: scipy.sparse.csr_matrix
Bundled Resources
This skill includes detailed reference documentation:
references/census_schema.md
Comprehensive documentation of:
- Census data structure and organization
- All available metadata fields
- Value filter syntax and operators
- SOMA object types
- Data inclusion criteria
When to read: When you need detailed schema information, full list of metadata fields, or complex filter syntax.
references/common_patterns.md
Examples and patterns for:
- Exploratory queries (metadata only)
- Small-to-medium queries (AnnData)
- Large queries (out-of-core processing)
- PyTorch integration
- Scanpy integration workflows
- Multi-dataset integration
- Best practices and common pitfalls
When to read: When implementing specific query patterns, looking for code examples, or troubleshooting common issues.
Requirements
| Requirement | Version |
|---|
| Python | 3.9+ |
| cellxgene-census | latest |
| tiledbsoma | latest |
| scanpy | latest |
| pyarrow | latest |
| pandas | latest |
| numpy | latest |
Inputs
| Name | Type | Format | Description |
|---|
| query_parameters | parameters | string | Filters for cell type, tissue, disease, genes (e.g., obs_value_filter, var_value_filter) |
Outputs
| Name | Type | Format | Description |
|---|
| expression_data | object | anndata, h5ad | Single-cell expression matrices and metadata loaded into memory or saved to disk |
| ml_dataloader | object | pytorch-dataloader | Iterative dataloader for machine learning model training |
Citations
https://github.com/FreedomIntelligence/OpenClaw-Medical-Skills/blob/main/skills/cellxgene-census