Quick start

crispyx provides a Scanpy-style API for streaming CRISPR screen analysis. Each operation reads data from disk so large .h5ad files can be processed on commodity hardware without loading the full count matrix into memory.

The typical workflow, with the guide page for each step:

  1. Load – open a dataset on disk (Loading and preparing data)

  2. QC – filter cells, perturbations, and genes (Quality control and dimension reduction)

  3. Preprocess – normalise and log-transform, streaming (Working with large data covers the storage formats each step prefers)

  4. HVG selection – pick highly variable genes (Quality control and dimension reduction)

  5. Dimension reduction – PCA and KNN graph construction (Quality control and dimension reduction)

  6. Pseudo-bulk – aggregate per perturbation (Pseudo-bulk and effect sizes)

  7. Differential expression – t-test, Wilcoxon, or NB-GLM (Differential expression)

  8. Plot – visualise results with Scanpy-style helpers (Differential expression)

Screens run in batches, donors or lines: Covariate adjustment compares the ways crispyx adjusts for them. The crispyx tutorial runs the whole workflow on a small dataset.

A first run

import crispyx as cx

adata_ro = cx.read_h5ad_ondisk("data/demo_benchmark.h5ad")
adata_ro = cx.pp.qc_summary(
    adata_ro,
    perturbation_column="perturbation",
    min_genes=100,
    min_cells_per_perturbation=15,
    min_cells_per_gene=10,
)
adata_pb = cx.pb.normalized_effects(
    adata_ro,
    groupby="perturbation",
)
adata_ro = cx.tl.rank_genes_groups(
    adata_ro,
    perturbation_column="perturbation",
    method="wilcoxon",
)
print(adata_ro.uns["rank_genes_groups"])  # preview without loading everything
de_results = adata_ro.uns["rank_genes_groups"].load()
de_full = de_results["full"]
var_table = adata_ro.var.load()