Generated banner for Scvi Tools
Generated logo for Scvi Tools

Scvi Tools

AnthropicOfficialPublished by Anthropic

  • Skill
  • Tool integration
  • Data and AI
  • Apache-2.0
  • Low risk
  • Has scripts

From the author

Deep learning for single-cell analysis using scvi-tools. This skill should be used when users need (1) data integration and batch correction with scVI/scANVI, (2) ATAC-seq analysis with PeakVI, (3) CITE-seq multi-modal analysis with totalVI, (4) multiome RNA+ATAC analysis with MultiVI, (5) spatial transcriptomics deconvolution with DestVI, (6) label transfer and reference mapping with scANVI/scArches, (7) RNA velocity with veloVI, or (8) any deep learning-based single-cell method. Triggers include mentions of scVI, scANVI, totalVI, PeakVI, MultiVI, DestVI, veloVI, sysVI, scArches, variational autoencoder, VAE, batch correction, data integration, multi-modal, CITE-seq, multiome, reference mapping, latent space.
— the description by Anthropic

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

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/anthropics/scvi-tools/download
  2. Unzip 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

  1. Identify the appropriate workflow from the model/workflow tables below

  2. Read the corresponding reference file for detailed steps and code

  3. Use scripts in scripts/ to avoid rewriting common code

  4. For installation or GPU issues, consult references/environment_setup.md

  5. For 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 TypeModelPrimary Use Case
scRNA-seqscVIUnsupervised integration, DE, imputation
scRNA-seq + labelsscANVILabel transfer, semi-supervised integration
CITE-seq (RNA+protein)totalVIMulti-modal integration, protein denoising
scATAC-seqPeakVIChromatin accessibility analysis
Multiome (RNA+ATAC)MultiVIJoint modality analysis
Spatial + scRNA referenceDestVICell type deconvolution
RNA velocityveloVITranscriptional dynamics
Cross-technologysysVISystem-level batch correction

Workflow Reference Files

WorkflowReference FileDescription
Environment Setupreferences/environment_setup.mdInstallation, GPU, version info
Data Preparationreferences/data_preparation.mdFormatting data for any model
scRNA Integrationreferences/scrna_integration.mdscVI/scANVI batch correction
ATAC-seq Analysisreferences/atac_peakvi.mdPeakVI for accessibility
CITE-seq Analysisreferences/citeseq_totalvi.mdtotalVI for protein+RNA
Multiome Analysisreferences/multiome_multivi.mdMultiVI for RNA+ATAC
Spatial Deconvolutionreferences/spatial_deconvolution.mdDestVI spatial analysis
Label Transferreferences/label_transfer.mdscANVI reference mapping
scArches Mappingreferences/scarches_mapping.mdQuery-to-reference mapping
Batch Correctionreferences/batch_correction_sysvi.mdAdvanced batch methods
RNA Velocityreferences/rna_velocity_velovi.mdveloVI dynamics
Troubleshootingreferences/troubleshooting.mdCommon issues and solutions

CLI Scripts

Modular scripts for common workflows. Chain together or modify as needed.

Pipeline Scripts
ScriptPurposeUsage
prepare_data.pyQC, filter, HVG selectionpython scripts/prepare_data.py raw.h5ad prepared.h5ad --batch-key batch
train_model.pyTrain any scvi-tools modelpython scripts/train_model.py prepared.h5ad results/ --model scvi
cluster_embed.pyNeighbors, UMAP, Leidenpython scripts/cluster_embed.py adata.h5ad results/
differential_expression.pyDE analysispython scripts/differential_expression.py model/ adata.h5ad de.csv --groupby leiden
transfer_labels.pyLabel transfer with scANVIpython scripts/transfer_labels.py ref_model/ query.h5ad results/
integrate_datasets.pyMulti-dataset integrationpython scripts/integrate_datasets.py results/ data1.h5ad data2.h5ad
validate_adata.pyCheck data compatibilitypython 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 leiden
Python Utilities

The scripts/model_utils.py provides importable functions for custom workflows:

FunctionPurpose
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

  1. 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")
  2. 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()
  3. 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

scripts/model_utils.py

#!/usr/bin/env python3
"""
Utility functions for scvi-tools model training and evaluation.

Usage:
    from model_utils import prepare_adata, train_scvi, evaluate_integration
"""

import numpy as np
import scanpy as sc
from typing import Optional, List, Dict, Tuple
import warnings


def get_mito_genes(adata) -> np.ndarray:
    """
    Identify mitochondrial genes for both human and mouse data.

    Handles common prefixes:
    - Human: MT- (e.g., MT-CO1, MT-ND1)
    - Mouse: mt- or Mt- (e.g., mt-Co1, Mt-Nd1)

    Returns
    -------
    Boolean array indicating mitochondrial genes
    """
    return (
        adata.var_names.str.startswith('MT-') |
        adata.var_names.str.startswith('mt-') |
        adata.var_names.str.startswith('Mt-')
    )


def prepare_adata(
    adata,
    batch_key: Optional[str] = None,
    n_top_genes: int = 2000,
    min_genes: int = 200,
    max_genes: int = 5000,
    max_mito_pct: float = 20.0,
    min_cells: int = 3,
    copy: bool = True
):
    """
    Prepare AnnData for scvi-tools models.
    
    Parameters
    ----------
    adata : AnnData
        Raw count data
    batch_key : str, optional
        Column for batch information
    n_top_genes : int
        Number of highly variable genes
    min_genes : int
        Minimum genes per cell
    max_genes : int
        Maximum genes per cell
    max_mito_pct : float
        Maximum mitochondrial percentage
    min_cells : int
        Minimum cells per gene
    copy : bool
        Return copy of data
        
    Returns
    -------
    AnnData prepared for scvi-tools
    """
    if copy:
        adata = adata.copy()
    
    # Calculate QC metrics
    adata.var['mt'] = get_mito_genes(adata)
    sc.pp.calculate_qc_metrics(adata, qc_vars=['mt'], inplace=True)
    
    # Filter cells
    adata = adata[adata.obs['n_genes_by_counts'] >= min_genes].copy()
    adata = adata[adata.obs['n_genes_by_counts'] <= max_genes].copy()
    adata = adata[adata.obs['pct_counts_mt'] < max_mito_pct].copy()
    
    # Filter genes
    sc.pp.filter_genes(adata, min_cells=min_cells)
    
    # Store raw counts
    adata.layers["counts"] = adata.X.copy()
    
    # HVG selection
    if batch_key and batch_key in adata.obs.columns:
        sc.pp.highly_variable_genes(
            adata,
            n_top_genes=n_top_genes,
            flavor="seurat_v3",
            batch_key=batch_key,
            layer="counts"
        )
    else:
        # Need to normalize for non-seurat_v3 flavor
        sc.pp.normalize_total(adata, target_sum=1e4)
        sc.pp.log1p(adata)
        sc.pp.highly_variable_genes(adata, n_top_genes=n_top_genes)
        # Restore counts to X
        adata.X = adata.layers["counts"].copy()
    
    # Subset to HVGs
    adata = adata[:, adata.var['highly_variable']].copy()
    
    print(f"Prepared AnnData: {adata.shape}")
    if batch_key:
        print(f"Batches: {adata.obs[batch_key].nunique()}")
    
    return adata


def train_scvi(
    adata,
    batch_key: Optional[str] = None,
    labels_key: Optional[str] = None,
    n_latent: int = 30,
    n_layers: int = 2,
    max_epochs: int = 200,
    early_stopping: bool = True,
    use_gpu: bool = True
):
    """
    Train scVI or scANVI model.
    
    Parameters
    ----------
    adata : AnnData
        Prepared data with counts layer
    batch_key : str, optional
        Batch column
    labels_key : str, optional
        Cell type labels (uses scANVI if provided)
    n_latent : int
        Latent dimensions
    n_layers : int
        Encoder/decoder layers
    max_epochs : int
        Maximum training epochs
    early_stopping : bool
        Use early stopping
    use_gpu : bool
        Use GPU if available
        
    Returns
    -------
    Trained model
    """
    import scvi
    
    # Setup AnnData
    scvi.model.SCVI.setup_anndata(
        adata,
        layer="counts",
        batch_key=batch_key
    )
    
    if labels_key and labels_key in adata.obs.columns:
        # Train scVI first
        scvi_model = scvi.model.SCVI(
            adata,
            n_latent=n_latent,
            n_layers=n_layers
        )
        scvi_model.train(
            max_epochs=max_epochs,
            early_stopping=early_stopping
        )
        
        # Initialize scANVI
        model = scvi.model.SCANVI.from_scvi_model(
            scvi_model,
            labels_key=labels_key,
            unlabeled_category="Unknown"
        )
        model.train(max_epochs=max_epochs // 4)
        
        # Store representation
        adata.obsm["X_scANVI"] = model.get_latent_representation()
    else:
        # Train scVI only
        model = scvi.model.SCVI(
            adata,
            n_latent=n_latent,
            n_layers=n_layers
        )
        model.train(
            max_epochs=max_epochs,
            early_stopping=early_stopping
        )
        
        # Store representation
        adata.obsm["X_scVI"] = model.get_latent_representation()
    
    return model


def evaluate_integration(
    adata,
    batch_key: str,
    label_key: str,
    embedding_key: str = "X_scVI"
) -> Dict[str, float]:
    """
    Evaluate integration quality using basic metrics.
    
    Parameters
    ----------
    adata : AnnData
        Integrated data
    batch_key : str
        Batch column
    label_key : str
        Cell type column
    embedding_key : str
        Key in obsm for embedding
        
    Returns
    -------
    Dictionary of metrics
    """
    from sklearn.metrics import silhouette_score
    from sklearn.neighbors import NearestNeighbors
    
    X = adata.obsm[embedding_key]
    batch = adata.obs[batch_key].values
    labels = adata.obs[label_key].values
    
    metrics = {}
    
    # Silhouette scores
    try:
        # Cell type silhouette (higher = better separation)
        metrics["silhouette_label"] = silhouette_score(X, labels)
        
        # Batch silhouette (lower = better mixing)
        metrics["silhouette_batch"] = silhouette_score(X, batch)
    except Exception as e:
        warnings.warn(f"Silhouette calculation failed: {e}")
    
    # Batch mixing in neighbors
    try:
        nn = NearestNeighbors(n_neighbors=50)
        nn.fit(X)
        distances, indices = nn.kneighbors(X)
        
        batch_mixing = []
        for i in range(len(X)):
            neighbor_batches = batch[indices[i]]
            unique_batches = len(np.unique(neighbor_batches))
            batch_mixing.append(unique_batches / len(np.unique(batch)))
        
        metrics["batch_mixing"] = np.mean(batch_mixing)
    except Exception as e:
        warnings.warn(f"Batch mixing calculation failed: {e}")
    
    return metrics


def get_marker_genes(
    model,
    adata,
    groupby: str,
    n_genes: int = 10
) -> Dict[str, List[str]]:
    """
    Get marker genes using scVI differential expression.
    
    Parameters
    ----------
    model : scvi model
        Trained scVI/scANVI model
    adata : AnnData
        Data used for training
    groupby : str
        Column to group cells by
    n_genes : int
        Number of top markers per group
        
    Returns
    -------
    Dictionary of {group: [marker_genes]}
    """
    markers = {}
    groups = adata.obs[groupby].unique()
    
    for group in groups:
        # Get DE results for this group vs rest
        de_results = model.differential_expression(
            groupby=groupby,
            group1=group
        )
        
        # Filter and sort
        de_sig = de_results[
            (de_results["is_de_fdr_0.05"] == True) &
            (de_results["lfc_mean"] > 0.5)
        ].sort_values("lfc_mean", ascending=False)
        
        markers[group] = de_sig.index[:n_genes].tolist()
    
    return markers


def plot_training_history(model, save_path: Optional[str] = None):
    """
    Plot model training history.
    
    Parameters
    ----------
    model : scvi model
        Trained model
    save_path : str, optional
        Path to save figure
    """
    import matplotlib.pyplot as plt
    
    fig, axes = plt.subplots(1, 2, figsize=(12, 4))
    
    # ELBO
    if "elbo_train" in model.history:
        axes[0].plot(model.history["elbo_train"], label="Train")
    if "elbo_validation" in model.history:
        axes[0].plot(model.history["elbo_validation"], label="Validation")
    axes[0].set_xlabel("Epoch")
    axes[0].set_ylabel("ELBO")
    axes[0].legend()
    axes[0].set_title("Training Loss")
    
    # Reconstruction
    if "reconstruction_loss_train" in model.history:
        axes[1].plot(model.history["reconstruction_loss_train"], label="Train")
    if "reconstruction_loss_validation" in model.history:
        axes[1].plot(model.history["reconstruction_loss_validation"], label="Validation")
    axes[1].set_xlabel("Epoch")
    axes[1].set_ylabel("Reconstruction Loss")
    axes[1].legend()
    axes[1].set_title("Reconstruction Loss")
    
    plt.tight_layout()
    
    if save_path:
        plt.savefig(save_path, dpi=150, bbox_inches="tight")
    
    return fig


def save_results(
    model,
    adata,
    output_dir: str,
    save_model: bool = True,
    save_adata: bool = True,
    plot_umap: bool = True
):
    """
    Save model, processed data, and visualization.

    Parameters
    ----------
    model : scvi model
        Trained model
    adata : AnnData
        Processed data with latent representation
    output_dir : str
        Output directory path
    save_model : bool
        Save the trained model
    save_adata : bool
        Save the processed AnnData
    plot_umap : bool
        Generate and save UMAP plot
    """
    import os
    import scanpy as sc
    import matplotlib.pyplot as plt

    os.makedirs(output_dir, exist_ok=True)

    # Save model
    if save_model:
        model_path = os.path.join(output_dir, "model")
        model.save(model_path)
        print(f"Model saved to {model_path}")

    # Save AnnData
    if save_adata:
        adata_path = os.path.join(output_dir, "adata_processed.h5ad")
        adata.write(adata_path)
        print(f"AnnData saved to {adata_path}")

    # Generate UMAP if needed
    if plot_umap:
        # Determine which embedding to use
        if "X_scANVI" in adata.obsm:
            rep_key = "X_scANVI"
        elif "X_scVI" in adata.obsm:
            rep_key = "X_scVI"
        else:
            rep_key = None

        if rep_key is not None:
            # Compute neighbors and UMAP if not present
            if "X_umap" not in adata.obsm:
                sc.pp.neighbors(adata, use_rep=rep_key)
                sc.tl.umap(adata)

            # Plot
            fig, axes = plt.subplots(1, 2, figsize=(12, 5))

            # Plot by batch if available
            batch_cols = [c for c in adata.obs.columns if 'batch' in c.lower()]
            if batch_cols:
                sc.pl.umap(adata, color=batch_cols[0], ax=axes[0], show=False, title="By Batch")

            # Plot by cluster
            if "leiden" not in adata.obs:
                sc.tl.leiden(adata)
            sc.pl.umap(adata, color="leiden", ax=axes[1], show=False, title="Clusters")

            plt.tight_layout()
            plot_path = os.path.join(output_dir, "umap.png")
            plt.savefig(plot_path, dpi=150, bbox_inches="tight")
            plt.close()
            print(f"UMAP plot saved to {plot_path}")


def auto_select_model(adata) -> str:
    """
    Suggest the best scvi-tools model based on available data.

    Parameters
    ----------
    adata : AnnData
        Data to analyze

    Returns
    -------
    String with model recommendation and reasoning
    """
    suggestions = []

    # Check for multi-modal data
    if 'protein_expression' in adata.obsm:
        suggestions.append({
            'model': 'totalVI',
            'reason': 'CITE-seq data detected (protein + RNA)',
            'priority': 1
        })

    if 'spliced' in adata.layers and 'unspliced' in adata.layers:
        suggestions.append({
            'model': 'veloVI',
            'reason': 'RNA velocity data detected (spliced + unspliced)',
            'priority': 1
        })

    # Check for ATAC data indicators
    if adata.n_vars > 100000:  # Many peaks suggest ATAC
        suggestions.append({
            'model': 'PeakVI',
            'reason': f'Large number of features ({adata.n_vars}) suggests ATAC-seq peaks',
            'priority': 2
        })

    # Check for labels
    label_cols = [c for c in adata.obs.columns if 'cell' in c.lower() or 'type' in c.lower() or 'label' in c.lower()]
    has_labels = len(label_cols) > 0

    # Check for batch info
    batch_cols = [c for c in adata.obs.columns if 'batch' in c.lower() or 'sample' in c.lower()]
    has_batch = len(batch_cols) > 0

    if has_batch:
        if has_labels:
            suggestions.append({
                'model': 'scANVI',
                'reason': f'Batch info ({batch_cols[0]}) + labels ({label_cols[0]}) available',
                'priority': 1
            })
        else:
            suggestions.append({
                'model': 'scVI',
                'reason': f'Batch info ({batch_cols[0]}) available, no labels',
                'priority': 1
            })
    else:
        suggestions.append({
            'model': 'scVI',
            'reason': 'Standard scRNA-seq analysis',
            'priority': 2
        })

    # Sort by priority
    suggestions.sort(key=lambda x: x['priority'])

    # Format output
    lines = ["Recommended models (in order of priority):"]
    for i, s in enumerate(suggestions, 1):
        lines.append(f"  {i}. {s['model']}: {s['reason']}")

    return "\n".join(lines)


def compare_integrations(
    adata,
    batch_key: str,
    label_key: str,
    embedding_keys: List[str] = None
) -> Dict[str, Dict[str, float]]:
    """
    Compare multiple integration methods using standard metrics.

    Parameters
    ----------
    adata : AnnData
        Data with integration embeddings in obsm
    batch_key : str
        Batch column in obs
    label_key : str
        Cell type column in obs
    embedding_keys : list, optional
        Keys in obsm to compare (default: auto-detect)

    Returns
    -------
    Dictionary of {embedding: {metric: value}}
    """
    from sklearn.metrics import silhouette_score

    # Auto-detect embeddings
    if embedding_keys is None:
        embedding_keys = [k for k in adata.obsm.keys()
                         if k.startswith('X_') and 'umap' not in k.lower()]

    results = {}

    for key in embedding_keys:
        if key not in adata.obsm:
            continue

        X = adata.obsm[key]
        batch = adata.obs[batch_key].values
        labels = adata.obs[label_key].values

        metrics = {}

        try:
            # Silhouette scores
            metrics["silhouette_label"] = silhouette_score(X, labels)
            metrics["silhouette_batch"] = silhouette_score(X, batch)

            # Combined score (higher label preservation, lower batch separation = better)
            metrics["integration_score"] = metrics["silhouette_label"] - metrics["silhouette_batch"]

        except Exception as e:
            metrics["error"] = str(e)

        results[key] = metrics

    return results


def quick_clustering(
    adata,
    use_rep: str = None,
    resolution: float = 1.0,
    n_neighbors: int = 15
):
    """
    Quick clustering pipeline on latent representation.

    Parameters
    ----------
    adata : AnnData
        Data with latent representation
    use_rep : str, optional
        Key in obsm (auto-detects scVI/scANVI if not specified)
    resolution : float
        Leiden clustering resolution
    n_neighbors : int
        Number of neighbors for graph

    Returns
    -------
    AnnData with neighbors, UMAP, and leiden clustering
    """
    import scanpy as sc

    # Auto-detect representation
    if use_rep is None:
        if "X_scANVI" in adata.obsm:
            use_rep = "X_scANVI"
        elif "X_scVI" in adata.obsm:
            use_rep = "X_scVI"
        elif "X_totalVI" in adata.obsm:
            use_rep = "X_totalVI"
        elif "X_PeakVI" in adata.obsm:
            use_rep = "X_PeakVI"
        elif "X_MultiVI" in adata.obsm:
            use_rep = "X_MultiVI"
        else:
            raise ValueError("No scvi-tools embedding found in obsm")

    print(f"Using representation: {use_rep}")

    # Compute neighbors
    sc.pp.neighbors(adata, use_rep=use_rep, n_neighbors=n_neighbors)

    # UMAP
    sc.tl.umap(adata)

    # Leiden clustering
    sc.tl.leiden(adata, resolution=resolution)

    print(f"Found {adata.obs['leiden'].nunique()} clusters")

    return adata


if __name__ == "__main__":
    print("scvi-tools model utilities")
    print("\nAvailable functions:")
    print("  - prepare_adata: Standard data preparation (QC, HVG, layer setup)")
    print("  - train_scvi: Train scVI or scANVI with sensible defaults")
    print("  - evaluate_integration: Compute batch mixing and silhouette metrics")
    print("  - get_marker_genes: Extract markers using scVI differential expression")
    print("  - plot_training_history: Visualize training convergence")
    print("  - save_results: Save model, data, and visualizations")
    print("  - auto_select_model: Suggest best model for your data")
    print("  - compare_integrations: Compare multiple integration embeddings")
    print("  - quick_clustering: Quick clustering on latent representation")

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 or Anthropic.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download scvi-tools.zip