Scvi Tools
AnthropicOfficialPublished by Anthropic
- Skill
- Tool integration
- Data and AI
- Apache-2.0
- Low risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
scvi-tools provides a suite of probabilistic models designed for the analysis of single-cell data, including scRNA-seq, scATAC-seq, and multi-modal datasets. It leverages variational autoencoders to handle batch correction, data integration, label transfer, and dimensionality reduction. This skill serves as a guide for utilizing specific models like scVI, scANVI, totalVI, PeakVI, MultiVI, DestVI, and veloVI, offering standardized workflows, CLI scripts for pipeline automation, and best practices for data preparation and model training.
What it does
- Performs batch correction and data integration across different experimental conditions.
- Supports multi-modal analysis for CITE-seq and multiome (RNA+ATAC) data.
- Enables label transfer and reference mapping between query and reference datasets.
- Facilitates spatial transcriptomics deconvolution and RNA velocity estimation.
- Provides modular Python scripts for common analysis pipelines.
- Offers guidance on model selection based on specific data types and research goals.
When to use it
- When integrating multiple single-cell datasets with significant batch effects.
- When analyzing multi-modal data such as CITE-seq or joint RNA+ATAC profiles.
- When performing reference-based label transfer or query-to-reference mapping.
- When conducting deep learning-based dimensionality reduction for clustering and visualization.
- When working with spatial transcriptomics or RNA velocity data.
Advantages
- Standardized approach to complex single-cell deep learning workflows.
- Modular scripts allow for reproducible and scalable analysis pipelines.
- Comprehensive model selection guide for diverse genomic data types.
- Built-in support for advanced tasks like batch correction and multi-modal integration.
- Clear documentation on data preparation requirements for probabilistic models.
Usage examples
- “How do I integrate two scRNA-seq datasets using scVI?”
- The agent provides the workflow for preparing the AnnData objects, selecting highly variable genes, setting up the model with batch keys, and training the scVI model.
- “I have CITE-seq data, which model should I use?”
- The agent identifies totalVI as the appropriate model and directs the user to the corresponding reference file for multi-modal integration.
- “How can I map my new scRNA-seq query data to an existing reference?”
- The agent explains the use of scArches for query-to-reference mapping and provides the necessary steps to configure the model.
- “What are the requirements for input data before training a model?”
- The agent outlines the necessity of raw integer count data, the importance of highly variable gene selection, and how to correctly set up the AnnData object.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/anthropics/scvi-tools/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip scvi-tools.zip -d .agents/skills
Documentation by Anthropic
scvi-tools Deep Learning Skill
This skill provides guidance for deep learning-based single-cell analysis using scvi-tools, the leading framework for probabilistic models in single-cell genomics.
How to Use This Skill
Identify the appropriate workflow from the model/workflow tables below
Read the corresponding reference file for detailed steps and code
Use scripts in
scripts/to avoid rewriting common codeFor installation or GPU issues, consult
references/environment_setup.mdFor debugging, consult
references/troubleshooting.md
When to Use This Skill
When scvi-tools, scVI, scANVI, or related models are mentioned
When deep learning-based batch correction or integration is needed
When working with multi-modal data (CITE-seq, multiome)
When reference mapping or label transfer is required
When analyzing ATAC-seq or spatial transcriptomics data
When learning latent representations of single-cell data
Model Selection Guide
| Data Type | Model | Primary Use Case |
|---|---|---|
| scRNA-seq | scVI | Unsupervised integration, DE, imputation |
| scRNA-seq + labels | scANVI | Label transfer, semi-supervised integration |
| CITE-seq (RNA+protein) | totalVI | Multi-modal integration, protein denoising |
| scATAC-seq | PeakVI | Chromatin accessibility analysis |
| Multiome (RNA+ATAC) | MultiVI | Joint modality analysis |
| Spatial + scRNA reference | DestVI | Cell type deconvolution |
| RNA velocity | veloVI | Transcriptional dynamics |
| Cross-technology | sysVI | System-level batch correction |
Workflow Reference Files
| Workflow | Reference File | Description |
|---|---|---|
| Environment Setup | references/environment_setup.md | Installation, GPU, version info |
| Data Preparation | references/data_preparation.md | Formatting data for any model |
| scRNA Integration | references/scrna_integration.md | scVI/scANVI batch correction |
| ATAC-seq Analysis | references/atac_peakvi.md | PeakVI for accessibility |
| CITE-seq Analysis | references/citeseq_totalvi.md | totalVI for protein+RNA |
| Multiome Analysis | references/multiome_multivi.md | MultiVI for RNA+ATAC |
| Spatial Deconvolution | references/spatial_deconvolution.md | DestVI spatial analysis |
| Label Transfer | references/label_transfer.md | scANVI reference mapping |
| scArches Mapping | references/scarches_mapping.md | Query-to-reference mapping |
| Batch Correction | references/batch_correction_sysvi.md | Advanced batch methods |
| RNA Velocity | references/rna_velocity_velovi.md | veloVI dynamics |
| Troubleshooting | references/troubleshooting.md | Common issues and solutions |
CLI Scripts
Modular scripts for common workflows. Chain together or modify as needed.
Pipeline Scripts
| Script | Purpose | Usage |
|---|---|---|
prepare_data.py | QC, filter, HVG selection | python scripts/prepare_data.py raw.h5ad prepared.h5ad --batch-key batch |
train_model.py | Train any scvi-tools model | python scripts/train_model.py prepared.h5ad results/ --model scvi |
cluster_embed.py | Neighbors, UMAP, Leiden | python scripts/cluster_embed.py adata.h5ad results/ |
differential_expression.py | DE analysis | python scripts/differential_expression.py model/ adata.h5ad de.csv --groupby leiden |
transfer_labels.py | Label transfer with scANVI | python scripts/transfer_labels.py ref_model/ query.h5ad results/ |
integrate_datasets.py | Multi-dataset integration | python scripts/integrate_datasets.py results/ data1.h5ad data2.h5ad |
validate_adata.py | Check data compatibility | python scripts/validate_adata.py data.h5ad --batch-key batch |
Example Workflow
# 1. Validate input data
python scripts/validate_adata.py raw.h5ad --batch-key batch --suggest
# 2. Prepare data (QC, HVG selection)
python scripts/prepare_data.py raw.h5ad prepared.h5ad --batch-key batch --n-hvgs 2000
# 3. Train model
python scripts/train_model.py prepared.h5ad results/ --model scvi --batch-key batch
# 4. Cluster and visualize
python scripts/cluster_embed.py results/adata_trained.h5ad results/ --resolution 0.8
# 5. Differential expression
python scripts/differential_expression.py results/model results/adata_clustered.h5ad results/de.csv --groupby leidenPython Utilities
The scripts/model_utils.py provides importable functions for custom workflows:
| Function | Purpose |
|---|---|
prepare_adata() | Data preparation (QC, HVG, layer setup) |
train_scvi() | Train scVI or scANVI |
evaluate_integration() | Compute integration metrics |
get_marker_genes() | Extract DE markers |
save_results() | Save model, data, plots |
auto_select_model() | Suggest best model |
quick_clustering() | Neighbors + UMAP + Leiden |
Critical Requirements
Raw counts required: scvi-tools models require integer count data
adata.layers["counts"] = adata.X.copy() # Before normalization scvi.model.SCVI.setup_anndata(adata, layer="counts")HVG selection: Use 2000-4000 highly variable genes
sc.pp.highly_variable_genes(adata, n_top_genes=2000, batch_key="batch", layer="counts", flavor="seurat_v3") adata = adata[:, adata.var['highly_variable']].copy()Batch information: Specify batch_key for integration
scvi.model.SCVI.setup_anndata(adata, layer="counts", batch_key="batch")
Quick Decision Tree
Need to integrate scRNA-seq data?
├── Have cell type labels? → scANVI (references/label_transfer.md)
└── No labels? → scVI (references/scrna_integration.md)
Have multi-modal data?
├── CITE-seq (RNA + protein)? → totalVI (references/citeseq_totalvi.md)
├── Multiome (RNA + ATAC)? → MultiVI (references/multiome_multivi.md)
└── scATAC-seq only? → PeakVI (references/atac_peakvi.md)
Have spatial data?
└── Need cell type deconvolution? → DestVI (references/spatial_deconvolution.md)
Have pre-trained reference model?
└── Map query to reference? → scArches (references/scarches_mapping.md)
Need RNA velocity?
└── veloVI (references/rna_velocity_velovi.md)
Strong cross-technology batch effects?
└── sysVI (references/batch_correction_sysvi.md)Key Resources
Files
- ATTRIBUTION.mdAdded by AutoGineer932 B
- LICENSE.txt10.0 KiB
- SKILL.md7.2 KiB
- references/atac_peakvi.md9.3 KiB
- references/batch_correction_sysvi.md10.2 KiB
- references/citeseq_totalvi.md10.1 KiB
- references/data_preparation.md6.2 KiB
- references/environment_setup.md6.3 KiB
- references/label_transfer.md10.2 KiB
- references/multiome_multivi.md8.9 KiB
- references/rna_velocity_velovi.md8.6 KiB
- references/scarches_mapping.md10.8 KiB
- references/scrna_integration.md9.6 KiB
- references/spatial_deconvolution.md11.2 KiB
- references/troubleshooting.md10.8 KiB
- scripts/cluster_embed.pyScript6.3 KiB
- scripts/differential_expression.pyScript6.7 KiB
- scripts/integrate_datasets.pyScript6.9 KiB
- scripts/model_utils.pyScript17.0 KiB
- scripts/prepare_data.pyScript5.1 KiB
- scripts/train_model.pyScript11.3 KiB
- scripts/transfer_labels.pyScript7.2 KiB
- scripts/validate_adata.pyScript11.9 KiB
scripts/validate_adata.py
#!/usr/bin/env python3
"""
Validation utilities for checking AnnData compatibility with scvi-tools.
Usage:
python validate_adata.py data.h5ad
# Or import as module
from validate_adata import validate_for_scvi, ValidationResult
result = validate_for_scvi(adata)
print(result.summary())
"""
import argparse
import sys
from dataclasses import dataclass, field
from typing import Optional, List, Dict, Any
import warnings
@dataclass
class ValidationResult:
"""Results from AnnData validation."""
is_valid: bool = True
errors: List[str] = field(default_factory=list)
warnings: List[str] = field(default_factory=list)
info: Dict[str, Any] = field(default_factory=dict)
recommendations: List[str] = field(default_factory=list)
def add_error(self, msg: str):
"""Add an error (makes validation fail)."""
self.errors.append(msg)
self.is_valid = False
def add_warning(self, msg: str):
"""Add a warning (doesn't fail validation)."""
self.warnings.append(msg)
def add_recommendation(self, msg: str):
"""Add a recommendation for improvement."""
self.recommendations.append(msg)
def summary(self) -> str:
"""Generate summary report."""
lines = []
lines.append("=" * 60)
lines.append("scvi-tools AnnData Validation Report")
lines.append("=" * 60)
# Status
status = "PASSED" if self.is_valid else "FAILED"
lines.append(f"\nStatus: {status}")
# Info
if self.info:
lines.append("\n--- Data Summary ---")
for key, value in self.info.items():
lines.append(f" {key}: {value}")
# Errors
if self.errors:
lines.append(f"\n--- Errors ({len(self.errors)}) ---")
for i, err in enumerate(self.errors, 1):
lines.append(f" {i}. {err}")
# Warnings
if self.warnings:
lines.append(f"\n--- Warnings ({len(self.warnings)}) ---")
for i, warn in enumerate(self.warnings, 1):
lines.append(f" {i}. {warn}")
# Recommendations
if self.recommendations:
lines.append(f"\n--- Recommendations ({len(self.recommendations)}) ---")
for i, rec in enumerate(self.recommendations, 1):
lines.append(f" {i}. {rec}")
lines.append("\n" + "=" * 60)
return "\n".join(lines)
def validate_for_scvi(
adata,
layer: Optional[str] = None,
batch_key: Optional[str] = None,
labels_key: Optional[str] = None,
check_hvg: bool = True
) -> ValidationResult:
"""
Validate AnnData for scvi-tools compatibility.
Parameters
----------
adata : AnnData
Data to validate
layer : str, optional
Layer containing counts (if None, checks X)
batch_key : str, optional
Expected batch column in obs
labels_key : str, optional
Expected labels column in obs
check_hvg : bool
Check for highly variable genes
Returns
-------
ValidationResult with errors, warnings, and recommendations
"""
import numpy as np
from scipy.sparse import issparse
result = ValidationResult()
# Basic info
result.info["shape"] = f"{adata.n_obs} cells x {adata.n_vars} genes"
result.info["layers"] = list(adata.layers.keys()) if adata.layers else "None"
# Get data matrix to check
if layer is not None:
if layer not in adata.layers:
result.add_error(f"Layer '{layer}' not found. Available: {list(adata.layers.keys())}")
return result
X = adata.layers[layer]
result.info["checking"] = f"layer '{layer}'"
else:
X = adata.X
result.info["checking"] = "adata.X"
# Check for None or empty
if X is None:
result.add_error("Data matrix is None")
return result
if X.shape[0] == 0 or X.shape[1] == 0:
result.add_error(f"Data matrix is empty: shape {X.shape}")
return result
# Convert to array for checking
if issparse(X):
result.info["sparse"] = True
X_check = X.data # Just check non-zero values
else:
result.info["sparse"] = False
X_check = X.flatten()
# Check for raw counts (integers)
if len(X_check) > 0:
is_integer = np.allclose(X_check, X_check.astype(int))
result.info["contains_integers"] = is_integer
if not is_integer:
result.add_error(
"Data does not contain integers (raw counts required). "
"Found float values - data may be normalized."
)
result.add_recommendation(
"Use adata.raw.to_adata() to recover raw counts, "
"or specify a layer with raw counts"
)
# Check for negative values
min_val = X.min()
if min_val < 0:
result.add_error(f"Data contains negative values (min={min_val})")
# Check for NaN/Inf
if issparse(X):
has_nan = np.isnan(X.data).any()
has_inf = np.isinf(X.data).any()
else:
has_nan = np.isnan(X).any()
has_inf = np.isinf(X).any()
if has_nan:
result.add_error("Data contains NaN values")
if has_inf:
result.add_error("Data contains Inf values")
# Check data range
max_val = X.max()
result.info["value_range"] = f"[{min_val}, {max_val}]"
if max_val < 10:
result.add_warning(
f"Maximum value is {max_val}, which is very low. "
"Data may be log-transformed or normalized."
)
# Check sparsity
if issparse(X):
sparsity = 1 - (X.nnz / (X.shape[0] * X.shape[1]))
result.info["sparsity"] = f"{sparsity:.1%}"
if sparsity < 0.5:
result.add_warning(
f"Data is only {sparsity:.1%} sparse. "
"Consider if this is expected for your data type."
)
# Check batch key
if batch_key is not None:
if batch_key not in adata.obs.columns:
result.add_error(
f"batch_key '{batch_key}' not found in obs. "
f"Available columns: {list(adata.obs.columns)}"
)
else:
n_batches = adata.obs[batch_key].nunique()
result.info["n_batches"] = n_batches
if n_batches == 1:
result.add_warning(
"Only 1 batch found. Batch correction may not be needed."
)
# Check for small batches
batch_counts = adata.obs[batch_key].value_counts()
small_batches = batch_counts[batch_counts < 50]
if len(small_batches) > 0:
result.add_warning(
f"{len(small_batches)} batches have fewer than 50 cells. "
"Consider merging small batches."
)
# Check labels key
if labels_key is not None:
if labels_key not in adata.obs.columns:
result.add_error(
f"labels_key '{labels_key}' not found in obs. "
f"Available columns: {list(adata.obs.columns)}"
)
else:
n_labels = adata.obs[labels_key].nunique()
result.info["n_labels"] = n_labels
# Check for rare labels
label_counts = adata.obs[labels_key].value_counts()
rare_labels = label_counts[label_counts < 30]
if len(rare_labels) > 0:
result.add_warning(
f"{len(rare_labels)} cell types have fewer than 30 cells. "
"Rare types may not be well learned."
)
# Check HVG
if check_hvg:
if 'highly_variable' not in adata.var.columns:
result.add_recommendation(
"No highly variable genes found. Run sc.pp.highly_variable_genes() "
"and subset to HVGs for better performance."
)
else:
n_hvg = adata.var['highly_variable'].sum()
result.info["n_hvg"] = n_hvg
if n_hvg < 1000:
result.add_warning(
f"Only {n_hvg} HVGs selected. Consider using 2000-4000 for best results."
)
elif n_hvg > 5000:
result.add_warning(
f"{n_hvg} HVGs selected. Consider reducing to 2000-4000 "
"for efficiency."
)
# Check gene count
if adata.n_vars > 30000:
result.add_recommendation(
f"Dataset has {adata.n_vars} genes. Subset to HVGs (2000-4000) "
"for faster training and better results."
)
# Check cell count
if adata.n_obs < 1000:
result.add_warning(
f"Dataset has only {adata.n_obs} cells. "
"Deep learning models work best with >5000 cells."
)
# Check for counts layer
if layer is None and 'counts' not in adata.layers:
result.add_recommendation(
"Store raw counts in adata.layers['counts'] before any normalization. "
"This preserves the original data for scvi-tools."
)
# Check for raw attribute
if adata.raw is not None:
result.info["has_raw"] = True
result.add_recommendation(
"adata.raw exists. If X is normalized, use adata.raw.to_adata() "
"to recover raw counts."
)
else:
result.info["has_raw"] = False
return result
def suggest_model(adata, result: ValidationResult) -> str:
"""
Suggest appropriate scvi-tools model based on data.
Parameters
----------
adata : AnnData
Data to analyze
result : ValidationResult
Validation result with info
Returns
-------
String with model suggestion
"""
suggestions = []
# Check for multi-modal data
if 'protein_expression' in adata.obsm:
suggestions.append("totalVI: CITE-seq data detected (protein + RNA)")
if 'spliced' in adata.layers and 'unspliced' in adata.layers:
suggestions.append("veloVI: RNA velocity data detected (spliced + unspliced)")
# Check for labels
has_labels = result.info.get('n_labels', 0) > 0
has_batches = result.info.get('n_batches', 0) > 1
if has_batches:
if has_labels:
suggestions.append(
"scANVI: Integration with cell type labels (recommended for label transfer)"
)
else:
suggestions.append(
"scVI: Unsupervised batch integration"
)
else:
suggestions.append(
"scVI: Dimensionality reduction and differential expression"
)
if not suggestions:
suggestions.append("scVI: General-purpose single-cell analysis")
return "\n".join([f" - {s}" for s in suggestions])
def main():
"""Command-line interface."""
parser = argparse.ArgumentParser(
description="Validate AnnData for scvi-tools compatibility"
)
parser.add_argument("file", help="Path to h5ad file")
parser.add_argument("--layer", help="Layer to check (default: X)")
parser.add_argument("--batch-key", help="Batch column to check")
parser.add_argument("--labels-key", help="Labels column to check")
parser.add_argument("--suggest", action="store_true", help="Suggest model type")
args = parser.parse_args()
try:
import scanpy as sc
except ImportError:
print("Error: scanpy is required. Install with: pip install scanpy")
sys.exit(1)
# Load data
print(f"Loading {args.file}...")
try:
adata = sc.read_h5ad(args.file)
except Exception as e:
print(f"Error loading file: {e}")
sys.exit(1)
# Validate
result = validate_for_scvi(
adata,
layer=args.layer,
batch_key=args.batch_key,
labels_key=args.labels_key
)
# Print report
print(result.summary())
# Suggest model
if args.suggest:
print("\nSuggested models:")
print(suggest_model(adata, result))
# Exit code
sys.exit(0 if result.is_valid else 1)
if __name__ == "__main__":
main()
Requirements and compatibility
Written for: Claude Code, Claude apps
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Python
Security
What our scanner noticed· Low risk
- Instructions that use the network
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Anthropic
- Publisher
- Anthropic (Official)
- Source
- anthropics/knowledge-work-plugins · bio-research/skills/scvi-tools · commit e050c2e
- Licence
- Apache License 2.0 (redistribution allowed)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Anthropic.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download scvi-tools.zip