Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Pooled CRISPR screens

A pooled CRISPR screen gives each cell a guide RNA that knocks out one gene, then sequences the cell, so one experiment measures many perturbations. The analysis decides which guide each cell carries, checks that each perturbation changed its target gene, separates the cells that kept the gene’s function, and asks what each perturbation changed.

This page analyzes the ECCITE-seq screen of Papalexi et al. (2021), which looked for regulators of PD-L1, the immune checkpoint protein encoded by CD274. THP-1 cells, a human acute myeloid leukemia line, were transduced with guides against 26 genes and with non-targeting control guides, then stimulated with interferon gamma (IFN-γ), TGF-β1 and decitabine to induce PD-L1. ECCITE-seq measured four things in each cell: RNA, the guide it carries, a hashtag antibody that marks its replicate, and four surface proteins, PD-L1 among them. The page ends where the paper did: cells that lost an IFN-γ pathway gene lower PD-L1 protein, while cells that carry the same guides but escaped the edit look like controls.

Download the screen

GEO series GSE153056 holds the screen as four count tables, one per measurement, and the authors’ cell metadata; the five files total 66 MB. The tables hold the 20,729 cells that the authors kept after quality control, hashtag demultiplexing and guide assignment, so this page checks those decisions rather than making them from raw droplets.

The example uses a temporary directory. Use a project directory instead if you want to keep the downloaded files and the store after closing the notebook.

Started: 2026-10-30T05:36:54.926892Z | Wall time: 2.734 s

rna 64.14 protein 0.20 hashtag 0.17 guide 0.34 metadata 1.06 Name: Downloaded MB, dtype: float64

Started: 2026-10-30T05:36:57.664077Z | Wall time: 14.411 s

Read the count tables

Each table has features along rows and cells along columns. Cell barcodes start with their 10x lane, l1_ to l8_, and every file lists the same cells in the same order. The guide table counts 111 guides: 9 non-targeting (NT) guides, 3 against PD-L1, 1 against eGFP, and 3 or 4 against each of 25 other genes. The protein table counts four antibodies, against CD86, PD-L1, PD-L2 and CD366.

CellsFeatures
Guides20729111
Hashtags2072912
Proteins207294

Started: 2026-10-30T05:37:12.077050Z | Wall time: 2.280 s

The guide table needs one correction. None of its entries is 0: each of the 111 guides has at least one count in every cell, and 93% of the entries are exactly 1, while a cell should hold no molecule of most guides. The table therefore stores each count plus one. The authors’ rule shows the same offset: they assigned each cell its top guide when it had at least five counts, and the smallest count of a cell’s top guide in the table is 6. Subtract one to restore the counts.

Smallest entry 1 Entries equal to 1 (%) 92.9 Smallest top-guide count of a cell 6 Name: Guide table, dtype: object

Started: 2026-10-30T05:37:14.359821Z | Wall time: 0.026 s

The RNA table has 18,649 genes and about 70 million nonzero counts, which take about 3 GB as a dense table. Read one gene at a time and keep only its nonzero counts.

Genes 18649 Nonzero counts 69529049 Name: RNA table, dtype: int64

Started: 2026-10-30T05:37:14.387399Z | Wall time: 15.967 s

Build one store with four assays

A CyteArc store keeps each measurement as an assay, and all assays share one table of cells. Combine the four tables into one AnnData whose feature_types column names each feature’s assay, and import it with assay_split_key. The assay names RNA, CRISPR, HTO and ADT declare each assay’s type, so CyteArc reads the guide counts as a CRISPR assay. Feature IDs must be unique across the file, and CD86 names both a gene and an antibody, so the antibodies get IDs with the suffix -protein, while their names stay as the authors wrote them. Each cell’s lane, the prefix of its barcode, becomes a cell column.

Started: 2026-10-30T05:37:30.356901Z | Wall time: 1.678 s

The import’s default count layout suits large matrices and needs more memory than the 4 GB that this page allows, so pass the smaller layout that fits; a store of this size reads fast in either layout.

WARNING: `obsm` slot in H5ad file is empty.
DataStore has 20729 (20729) cells with 4 assays: ADT CRISPR HTO RNA Cell metadata: 'I', 'ids', 'names', 'ADT_nCounts', 'ADT_nFeatures', 'CRISPR_nCounts', 'CRISPR_nFeatures', 'HTO_nCounts', 'HTO_nFeatures', 'RNA_nCounts', 'RNA_nFeatures', 'RNA_percentMito', 'RNA_percentRibo', 'lane' ADT assay has 4 features and following metadata: 'I', 'ids', 'names', 'dropOuts', 'feature_types', 'nCells' CRISPR assay has 111 features and following metadata: 'I', 'ids', 'names', 'dropOuts', 'feature_types', 'nCells' HTO assay has 12 features and following metadata: 'I', 'ids', 'names', 'dropOuts', 'feature_types', 'nCells' RNA assay has 18649 features and following metadata: 'I', 'ids', 'names', 'dropOuts', 'feature_types', 'nCells'

Started: 2026-10-30T05:37:32.037120Z | Wall time: 14.112 s

Record the replicates and the guide targets

The cells come from three replicates, each stained with its own hashtag antibody before the replicates were pooled. The deposit holds only the singlets that the authors kept, so most hashtags have no background cells left to fit, and calling the hashtags again would not reproduce the authors’ calls; HTO demultiplexing shows how to call hashtags from the counts of every droplet. Record the hashtag that the authors called as each cell’s replicate, and check it against the hashtag counts.

Heatmap of the mean CLR count of 12 hashtags in three replicates; each replicate is high for its own hashtag and near zero for most others.

Started: 2026-10-30T05:37:46.151856Z | Wall time: 0.598 s

Each replicate carries its own hashtag. Lanes 1 to 4 hold replicate rep1-tx and lanes 5 to 8 the other two, so a replicate also shows a little of the other hashtags pooled in its lanes, and none of the rest. The -ctrl hashtags marked unstimulated cells, which the authors left out of these tables.

Each guide ID names its target gene, followed by g and the guide’s number, such as IRF1g4, and NT names the non-targeting guides. Write each guide’s target as the guide assay’s target_gene_name column, which perturbation.labels reads, and as target_gene_id, which the efficiency, association and profile steps use to find the target in the RNA assay. This store identifies genes by their symbols, so a target’s symbol is also its RNA feature ID. The PD-L1 guides target CD274, PD-L1’s gene.

NTATF2BRD4CAV1CD86ETV7IFNGR1IFNGR2IRF1IRF7...STAT1STAT2STAT3STAT5ATNFRSF14UBE2L6CUL3CMTM6CD274eGFP
Guides9444444444...4444443331

1 rows × 28 columns

Started: 2026-10-30T05:37:46.753112Z | Wall time: 0.052 s

Map the expression of every cell

Run the RNA recipe over all cells. The authors already removed low-quality cells, so skip filtering, and keep 2,000 highly variable genes and 40 principal components, as the authors did. The screen needs no clusters, doublet scores or markers. Snapshot the replicate and the lane, so that the run keeps them with its cells.

WARNING: 2 of 43 s_genes were not found in the assay feature names
Two UMAP panels of 20,729 THP-1 cells, colored by replicate and by cell-cycle phase.

Started: 2026-10-30T05:37:46.807190Z | Wall time: 92.555 s

Replicate and cell-cycle phase shape the map. The paper found the same, and it is why Mixscape, below, compares each cell with control cells of similar state.

Call guides

Every cell holds a few molecules of guides it does not carry, ambient molecules from other cells, so a nonzero count is not a call. perturbation.call_guides fits each guide’s counts with a Poisson background plus a Gaussian for the cells that carry the guide, as Replogle et al. (2022) did, and calls a guide in the cells whose counts reach the fitted threshold. Call guides over the RNA run’s cells, so that the labels below share the run’s cells and can color its map. Print the warnings: they name the guides whose fit calls no cell.

4 of 111 guide fits call no cell: 1 have no cell with a UMI of the guide, 2 have too few cells or counts to fit, 1 have no admissible fit. For example 'eGFPg1', 'PDL1g2', 'PDL1g3', 'MYCg4'. perturbation.load_guide_thresholds lists every status.
call One guide 18330 Multiple 1806 Negative 593 Name: count, dtype: int64

Started: 2026-10-30T05:39:19.364940Z | Wall time: 6.207 s

No cell holds a UMI of the eGFP guide, two PD-L1 guides have too few cells or counts to fit, and MYCg4’s counts admit no fit. Of the 20,729 cells, 18,330 carry one called guide, 1,806 several, and 593 none. The plot shows how many guides each cell carries, how many cells carry each guide, and the share of a cell’s guide UMIs that its top guide holds.

Three panels: cells by number of called guides, cells per guide ranked from most to fewest, and the top guide's share of each cell's guide UMIs for cells with no, one or several called guides.

Started: 2026-10-30T05:39:25.574090Z | Wall time: 0.800 s

Inspect a fit to see where its threshold falls. The histogram counts the cells by their UMIs of the guide; the cells above the threshold are called, and the curve is the fitted probability that a cell carries the guide.

Two histograms of cells by UMI count of guides IRF1g4 and NTg4, with called cells in blue, the fitted posterior of carrying the guide, and the threshold.

Started: 2026-10-30T05:39:26.376157Z | Wall time: 1.766 s

Lanes 1 to 4 have more guide UMIs per cell than lanes 5 to 8, and sample_column="lane" fits each lane separately. Each lane, though, holds about 25 cells of a typical guide. Compare the two choices on the calls they make.

One fit per guideOne fit per guide and lane
Fits111888
Fits that call no cell458
Cells with one guide1833017093
Cells with several guides18063300
Cells with no guide593336

Started: 2026-10-30T05:39:28.144545Z | Wall time: 0.922 s

Fitting each lane leaves 58 of 888 fits without a call and puts other thresholds among the ambient counts, which nearly doubles the cells with several guides. Keep one fit per guide.

The authors assigned each cell its top guide. Compare the cells with one called guide with their assignment.

Cells with one called guide 18330 Same guide as the authors (%) 99.69 Name: Guide calls, dtype: object

Started: 2026-10-30T05:39:29.068378Z | Wall time: 0.026 s

Label cells by target

perturbation.labels labels each cell by the gene that its called guides target. Name the control targets explicitly; CyteArc never guesses them. Cells with control guides only are labelled control, cells with guides of one gene take the gene’s name, also when they carry control guides too, cells with guides of two or more genes are Multiple, and cells without a called guide are Negative.

labelcontrolMultipleIFNGR2IFNGR1ATF2CD86IRF1JAK2TNFRSF14MARCH8...PDCD1LG2UBE2L6IRF7STAT3STAT1BRD4CUL3MYCSPI1CD274
Cells216413971122107810621057997908907877...57248947945739933323996452

1 rows × 29 columns

Started: 2026-10-30T05:39:29.096719Z | Wall time: 0.268 s

A cell with several called guides keeps one label when its guides target one gene, or one gene and the controls. Count those cells, and compare the labels with the authors’ target of each cell.

Cells with several guides and one label 409 Cells labelled by both 18739 Same label as the authors (%) 98.8 Different labels 218 Of these, a gene here and a control for the authors 171 Name: Labels, dtype: object

Started: 2026-10-30T05:39:29.367676Z | Wall time: 0.029 s

Most disagreements are cells that carry a control guide beside a gene’s guide: CyteArc labels them by the gene, while the authors assigned the top guide, a control.

On the map, cells that lost IFNGR2 or JAK2 gather in one region, while cells of most other targets mix with the controls.

UMAP of the cells labelled control, IFNGR2, JAK2, IRF1 and SMAD4; IFNGR2 and JAK2 cells gather in one region.

Started: 2026-10-30T05:39:29.398194Z | Wall time: 0.310 s

Check each perturbation’s target gene

perturbation.efficiency compares the expression of each target gene in the cells of its perturbation with the control cells. remaining_fraction is the share of the control expression left after scaling each cell to a common library size.

targetn_cellscontrol_mean_umiremaining_fractionadjusted_p_value
20STAT139912.7800.2050.000
12JAK29082.7840.2140.000
21STAT26191.5910.5130.000
1BRD43331.5830.5590.000
6CUL32390.4240.6360.002
15NFKBIA7083.1420.6410.000
19SPI1459.7200.6630.001
22STAT34572.3140.6640.000
9IFNGR211225.4640.6670.000
2CAV17880.0150.6810.609
18SMAD45860.2240.6820.000
5CMTM67792.6370.6860.000
25UBE2L64898.1240.7340.000
23STAT5A6110.1520.7550.029
24TNFRSF149071.7960.7560.000
4CD8610570.2650.8310.059
3CD27420.6000.8340.854
10IRF199712.4430.8460.000
7ETV77713.3110.8760.000
16PDCD1LG25720.2840.8960.415
11IRF74795.8800.9340.002
0ATF210620.3460.9730.929
17POU2F25940.4250.9850.929
8IFNGR110780.9941.0410.275
14MYC960.6411.1870.141
13MARCH88770.0301.5120.124

Started: 2026-10-30T05:39:29.710536Z | Wall time: 1.241 s

Dot plot of each target's log2 fold change of its own gene against the control cells, strongest knockdown first, colored by significance and sized by cells.

Started: 2026-10-30T05:39:30.954172Z | Wall time: 0.504 s

STAT1 and JAK2 keep about a fifth of their control expression. IFNGR1 keeps all of it, although its cells change more than most in the steps below. A Cas9 knockout lowers its target’s transcripts mainly when nonsense-mediated decay degrades the edited transcripts, so in a knockout screen a fraction near 1 does not show that the edit failed. The PD-L1 guides are called in two cells only, too few for any comparison.

Rank perturbations by E-distance

The E-distance measures how far a perturbation moves the center of its cells from the control cells, here in the RNA run’s 40 principal components, with a permutation test for each target Peidli et al., 2024.

Dot plot of each target's E-distance from the control cells, largest first, colored by significance and sized by cells.

Started: 2026-10-30T05:39:31.459700Z | Wall time: 1.635 s

Thirteen targets move their cells significantly, led by STAT1, JAK2, IFNGR1 and IFNGR2. Their adjusted p-values sit at the floor that 1,000 permutations allow, so raise n_permutations to rank them by p-value.

Separate knocked-out cells from escapers

Some cells that carry a targeting guide keep their target’s function, for example after an in-frame edit, and look like controls. Mixscape finds them Papalexi et al., 2021. perturbation.signature subtracts from each cell the mean expression of its 20 nearest control cells in the same replicate, which removes what the cell shares with controls of similar state, such as its cell-cycle phase. perturbation.mixscape then finds the genes that each target changes, and fits each target’s cells as a mixture of a knocked-out (KO) group and a non-perturbed (NP) group that looks like the controls.

statusn_cellsn_kon_de_genesko_share
target
SMAD4fitted58649310830.84
IFNGR1fitted107887315150.81
JAK2fitted90872315160.80
STAT2fitted619490780.79
STAT1fitted39930914010.77
IFNGR2fitted112285515600.76
IRF1fitted9976885320.69
SPI1fitted452160.47
BRD4fitted3331411070.42
CUL3fitted23987520.36
MYCfitted9625340.26
CD274few_de_genes2000.00
ETV7few_de_genes771000.00
CMTM6few_de_genes779010.00
CAV1few_de_genes788000.00
ATF2few_de_genes1062000.00
CD86few_de_genes1057000.00
IRF7few_de_genes479000.00
POU2F2few_de_genes594010.00
PDCD1LG2few_de_genes572000.00
NFKBIAfew_de_genes708010.00
MARCH8few_de_genes877000.00
STAT3few_de_genes457010.00
STAT5Afew_de_genes611000.00
TNFRSF14few_de_genes907010.00
UBE2L6few_de_genes489010.00

Started: 2026-10-30T05:39:33.096857Z | Wall time: 23.156 s

Horizontal bars of the share of each target's cells that Mixscape calls knocked out or not perturbed.

Started: 2026-10-30T05:39:56.255717Z | Wall time: 0.728 s

Mixscape finds KO cells for 11 targets, from 26% of MYC’s cells to 84% of SMAD4’s; the other 15 change too few genes to separate, so all their cells are NP. The paper reports the same split: 11 genes with 23% to 83% KO cells, 15 with none, and 75% for IFNGR2, against 76% here. The paper also found that IRF1’s four guides knock out different shares of their cells, from 39% to 92%.

global_classKONPKO share
call
IRF1g11491190.56
IRF1g21021340.43
IRF1g3146400.78
IRF1g4283110.96

Started: 2026-10-30T05:39:56.986508Z | Wall time: 0.033 s

Here the four guides knock out 43% to 96% of their cells, so a target’s KO share pools guides of different efficacy.

Compare PD-L1 protein between knocked-out cells and escapers

The protein assay tests the classes on a measurement that Mixscape did not use. Compare PD-L1 protein, normalized by centered log ratio (CLR) across cells, between each target’s KO and NP cells and the control cells, for the five targets whose loss lowered PD-L1 in the paper and the three whose loss raised it.

Violin plots of CLR-normalized PD-L1 protein for control cells and for the KO and NP cells of IFNGR1, IFNGR2, JAK2, STAT1, IRF1, CUL3, BRD4 and MYC.

Started: 2026-10-30T05:39:57.022413Z | Wall time: 0.704 s

mixscape_classIFNGR1 KOIFNGR1 NPIFNGR2 KOIFNGR2 NPJAK2 KOJAK2 NPSTAT1 KOSTAT1 NPIRF1 KOIRF1 NPCUL3 KOCUL3 NPBRD4 KOBRD4 NPMYC KOMYC NP
PD-L1 median minus control-0.49-0.07-0.49-0.06-0.5-0.1-0.430.08-0.210.00.480.060.20.120.6-0.08

Started: 2026-10-30T05:39:57.729014Z | Wall time: 0.074 s

KO cells of IFNGR1, IFNGR2, JAK2, STAT1 and IRF1 hold less PD-L1 than the control cells, while their NP cells hold about as much as the controls: escapers keep the IFN-γ response. KO cells of CUL3, BRD4 and MYC hold more, as the paper found. CMTM6 is the exception that Mixscape cannot catch: its cells change no genes, so Mixscape calls them all NP, yet their PD-L1 median sits 0.23 below the controls, a change of the protein without an RNA counterpart.

mixscape_classJAK2 KOIFNGR2 KOIFNGR1 KOSTAT1 KOCMTM6 NPIRF1 KOJAK2 NPMYC NP
PD-L1 median minus control-0.5-0.49-0.49-0.43-0.23-0.21-0.1-0.08

Started: 2026-10-30T05:39:57.805198Z | Wall time: 0.015 s

Test which genes each perturbation changes

perturbation.associations runs SCEPTRE’s test Barry et al., 2024 on each pair of a target and a gene: the target’s cells against the control cells, with a regression that accounts for each cell’s sequencing depth and replicate, and p-values from resampled cells. Test every target against the 2,000 variable genes of the RNA run. The method also checks itself: groups of control guides are tested against the other control cells, where every discovery is false, and each target against its own gene, where a knockout should lower the gene. In a screen whose cells carry several guides by design, pass moi="high", which compares each target’s cells with every other labelled cell.

Calibration grade excellent False discoveries in the calibration pairs 0 Calibration pairs 39150 Discovery pairs tested 39150 Discoveries at FDR 0.1 6188 Name: Association tests, dtype: object

Started: 2026-10-30T05:39:57.822021Z | Wall time: 95.363 s

Read the calibration before any discovery. None of the 39,150 calibration pairs is significant, so the grade is excellent. The plot shows the calibration pairs’ p-values against their expected values, their fold changes, and both sets of controls.

Three panels: observed against expected p-values of the negative-control and discovery pairs, the fold changes of the negative-control pairs, and the p-values of the positive and negative controls.

Started: 2026-10-30T05:41:33.187473Z | Wall time: 0.961 s

The positive controls measure power. Most knockouts lower their own gene; IFNGR1 does not, as its efficiency showed.

targetn_cellszlog2_fold_changep_valuesignificant
12JAK2908-24.198-1.8250.000True
20STAT1399-22.930-2.1190.000True
9IFNGR21122-12.156-0.4280.000True
5CMTM6779-11.144-0.4570.000True
21STAT2619-11.098-0.7270.000True
25UBE2L6489-10.741-0.4160.000True
22STAT3457-8.580-0.4870.000True
15NFKBIA708-7.307-0.5380.000True
24TNFRSF14907-7.009-0.3150.000True
10IRF1997-6.660-0.1660.000True
1BRD4333-6.161-0.4900.000True
18SMAD4586-4.888-0.7280.000True
7ETV7771-3.989-0.1560.000True
19SPI145-3.500-0.4530.000True
6CUL3239-3.193-0.5700.001True
23STAT5A611-1.930-0.3340.064True
11IRF7479-1.914-0.0910.068True
4CD861057-1.129-0.0970.304False
16PDCD1LG2572-1.124-0.1330.228False
17POU2F2594-0.897-0.1090.356False
0ATF21062-0.569-0.0420.576False
2CAV1788-0.400-0.1460.740False
8IFNGR11078-0.0620.0010.924False
14MYC961.3700.3150.244False
13MARCH88772.2140.4470.044True

Started: 2026-10-30T05:41:34.150807Z | Wall time: 0.016 s

Volcano plot of the log2 fold change and p-value of every tested pair of a target and a gene, with the strongest pairs named.

Started: 2026-10-30T05:41:34.168338Z | Wall time: 0.893 s

The strongest effects belong to the IFN-γ pathway: cells without IFNGR1, IFNGR2 or JAK2 lose interferon-induced genes such as TAP1, WARS and GBP5.

targetIFNGR2IFNGR1JAK2SMAD4STAT1IRF1BRD4CUL3STAT2MYC...MARCH8STAT3PDCD1LG2IRF7CAV1ATF2STAT5AUBE2L6CD86CMTM6
Discoveries92789989287273860325524716393...31312727262525232220

1 rows × 25 columns

Started: 2026-10-30T05:41:35.063525Z | Wall time: 0.015 s

Group perturbations by their effects

perturbation.profiles averages, for each target, the expression of its cells over the variable genes, as z-scores against the control cells of each replicate Replogle et al., 2022. perturbation.cluster then groups targets whose profiles correlate. Cluster only targets with a clear effect, since flat profiles correlate by chance: here the 13 targets whose E-distance is significant. The default smallest cluster, 4, suits screens of hundreds of genes; with 13 targets, allow groups of 3.

2 of 27 targets have fewer than 25 cells and get no profile: 'CD274' (2), 'eGFP' (0). perturbation.load_profiles lists them all in left_out.
clusterprobabilityn_cells
perturbation
SPI1-10.0045
BRD401.00333
CUL301.00239
MYC01.0096
IFNGR111.001078
IFNGR211.001122
JAK211.00908
STAT110.51399
STAT210.09619
IRF110.08997
SMAD410.08586
NFKBIA10.07708
POU2F210.07594

Started: 2026-10-30T05:41:35.080600Z | Wall time: 6.507 s

Heatmap of the correlations between the profiles of 13 targets in leaf order, with a bar marking each target's cluster.

Started: 2026-10-30T05:41:41.589101Z | Wall time: 0.833 s

IFNGR1, IFNGR2 and JAK2 form one cluster, with STAT1 at its edge: the IFN-γ receptor and the signalling genes downstream of it. BRD4, CUL3 and MYC, whose knockouts raised PD-L1, form another. IRF1, SMAD4, STAT2, NFKBIA and POU2F2 join the first cluster with low probability, and SPI1 stays unassigned (-1). The paper’s analysis of perturbation signatures also grouped IFNGR1, IFNGR2, JAK2 and STAT1, and set IRF1 apart. Read a cluster as a hypothesis of shared function, and check it against the pathway it implies.

Collect one row per target

Join the numbers of each step into one table: cells, remaining expression of the target gene, E-distance, KO share, PD-L1 shift of the KO cells, discoveries and cluster.

n_cellsremaining_fractionedistanceko_sharepdl1_ko_shiftdiscoveriescluster
target
STAT13990.21358.530.77-0.437381
JAK29080.21264.950.80-0.508921
IFNGR110781.04252.630.81-0.498991
IFNGR211220.67237.710.76-0.499271
SMAD45860.68162.450.84-0.038721
IRF19970.8576.410.69-0.216031
SPI1450.6663.650.47-0.1176-1
CUL32390.6455.000.360.482470
MYC961.1931.140.260.60930
STAT26190.5129.690.79-0.021631
BRD43330.5628.500.420.202550
POU2F25940.993.930.00NaN411
NFKBIA7080.642.450.00NaN481
IRF74790.930.920.00NaN27<NA>
ETV77710.880.830.00NaN36<NA>
PDCD1LG25720.900.700.00NaN27<NA>
TNFRSF149070.760.490.00NaN41<NA>
CD8610570.830.470.00NaN22<NA>
MARCH88771.510.390.00NaN31<NA>
UBE2L64890.730.330.00NaN23<NA>
CAV17880.680.290.00NaN26<NA>
ATF210620.970.260.00NaN25<NA>
CMTM67790.690.140.00NaN20<NA>
STAT34570.66-0.120.00NaN31<NA>
STAT5A6110.76-0.430.00NaN25<NA>

Started: 2026-10-30T05:41:42.423551Z | Wall time: 0.023 s

Run the analysis as one recipe

ds.pipeline.perturbation runs the same steps as one durable run: guide calling, labels, efficiency, E-distances, the signature and Mixscape, the association tests, and the profiles and their clusters. Give it the RNA run as cells with that run’s settings, so that it uses the run’s cells, variable genes and PCA, and the settings used above. When Mixscape runs, the recipe profiles each target’s knocked-out cells unless profiles sets "cells": "labelled", which profiles every labelled cell as above. Every step matches a call above, so the run reuses the saved results and computes nothing.

StatusOutputsReused
Stage
input_snapshotcompleted33
filteringskipped00
guide_callingcompleted22
perturbation_labelscompleted11
efficiencycompleted11
highly_variable_featurescompleted11
normalizationcompleted11
pcacompleted11
harmonyskipped00
edistancecompleted11
signaturecompleted11
mixscapecompleted11
associationscompleted11
profilescompleted11
perturbation_clusterscompleted11

Started: 2026-10-30T05:41:42.448236Z | Wall time: 1.783 s

The run’s cell view holds each cell’s guide call, perturbation label and Mixscape class, frozen with the run.

idsguide_callperturbation_labelis_controlmixscape_class
0l1_AAACCTGAGCCAGAACSTAT2g2STAT2FalseSTAT2 KO
1l1_AAACCTGAGTGGACGTCAV1g4CAV1FalseCAV1 NP
2l1_AAACCTGCATGAGCGASTAT1g2STAT1FalseSTAT1 KO
3l1_AAACCTGTCTTGTCATCD86g1CD86FalseCD86 NP
4l1_AAACGGGAGAACAACTIRF7g2IRF7FalseIRF7 NP

Started: 2026-10-30T05:41:44.233664Z | Wall time: 0.141 s

Each stage records a summary with the numbers to check before reading results, in the same order as the steps above.

guide_calling {'guide_thresholds': {'samples': 1, 'guides': 111, 'statuses': {'fitted': 107, 'no_cells': 1, 'too_sparse': 2, 'no_fit': 1, 'no_positive': 0}}, 'guide_calls': {'cells': 20729, 'negative': 593, 'single': 18330, 'multiple': 1806, 'calledGuides': 107}}
perturbation_labels {'cells': 20729, 'controls': 2164, 'negative': 593, 'multipleTargets': 1397, 'targets': 27, 'targetCells': {'min': 0, 'median': 611.0, 'max': 1122}, 'fewCellTargets': {'eGFP': 0, 'CD274': 2}, 'fewCellTargetCount': 2}
efficiency {'by': 'target', 'rows': 27, 'statuses': {'tested': 26, 'no_feature': 0, 'no_cells': 1, 'no_control_expression': 0}, 'knockedDown': 17, 'medianRemainingFraction': 0.7446, 'noFeature': []}
edistance {'by': 'target', 'rows': 27, 'statuses': {'tested': 26, 'too_few_cells': 1}, 'significant': 13, 'atFloor': 13, 'nPermutations': 1000}
mixscape {'rows': 26, 'statuses': {'fitted': 11, 'few_de_genes': 15, 'few_cells': 0, 'no_fit': 0}, 'cells': 16575, 'knockedOut': 4705, 'fewDeGenes': ['ATF2', 'CAV1', 'CD274', 'CD86', 'CMTM6', 'ETV7', 'IRF7', 'MARCH8', 'NFKBIA', 'PDCD1LG2', 'POU2F2', 'STAT3', 'STAT5A', 'TNFRSF14', 'UBE2L6'], 'perturbationType': 'KO'}
associations {'discoveryPairs': 54000, 'testedDiscoveryPairs': 39150, 'discoveries': 6188, 'calibrationPairs': 39150, 'falseDiscoveries': 0, 'calibrationGrade': 'excellent', 'calibrationStatus': 'checked', 'falseDiscoveriesByControlGuides': {}, 'positivePairs': 27, 'positiveDetected': 18, 'alpha': 0.1}
profiles {'perturbations': 25, 'features': 2000, 'leftOut': 2, 'zeroSdFeatures': 195, 'samples': 3}
perturbation_clusters {'perturbations': 13, 'clusters': 2, 'unassigned': 1, 'largestCluster': 9}
guide_calling 4 of 111 guide fits call no cell: 1 have no cell with a UMI of the guide, 2 have too few cells or counts to fit, 1 have no admissible fit. For example 'eGFPg1', 'PDL1g2', 'PDL1g3', 'MYCg4'. perturbation.load_guide_thresholds lists every status.
profiles 2 of 27 targets have fewer than 25 cells and get no profile: 'CD274' (2), 'eGFP' (0). perturbation.load_profiles lists them all in left_out.

Started: 2026-10-30T05:41:44.376381Z | Wall time: 0.006 s

Test effects across replicates

Cells from one experiment are not independent replicates, so a claim that a perturbation changes a gene in general needs a test across replicates. Sum each gene’s counts per target and replicate with compare.compute_bulk, leaving out the Negative and Multiple cells. CytePool tests such pseudobulk profiles of each target against the control cells with limma, edgeR or DESeq2.

ATF2_rep1-txATF2_rep3-txATF2_rep4-txBRD4_rep1-txBRD4_rep3-txBRD4_rep4-tx
AL627309.1355211
AP006222.22718171102
RP4-669L17.10223000
RP11-206L10.3215201
RP11-206L10.21267234

Started: 2026-10-30T05:41:44.384579Z | Wall time: 2.095 s

Common mistakes and limitations

  • Counting ambient guide molecules as calls: every cell holds a few molecules of guides it does not carry. Call guides with a fitted threshold, inspect the fits with plots.guide_thresholds, and read the share of cells with several guides, which a low-MOI screen keeps small.

  • Fitting thresholds per lane or GEM group without enough cells: a fit needs cells that carry the guide in each sample. Compare the calls before choosing sample_column.

  • Treating Negative cells as controls: controls are the cells that carry control guides only, which perturbation.labels names from the targets in controls.

  • Reading a remaining fraction near 1 as a failed knockout: Cas9 edits lower transcripts mainly through nonsense-mediated decay. Read the E-distance, Mixscape’s classes and the association tests too.

  • Reporting a target with no Mixscape KO cells as having no effect: Mixscape sees changes of the transcriptome only, as CMTM6’s lower PD-L1 protein shows.

  • Reading discoveries before the calibration check: a moderate or severe grade means the test is miscalibrated for the screen, and its discoveries are not trustworthy until the cause is fixed.

  • Treating cells as replicates: test effects across replicates with pseudobulk profiles before claiming them in general.

The DataStore API reference documents every ds.perturbation method and its checks.

References
  1. Papalexi, E., Mimitou, E. P., Butler, A. W., Foster, S., Bracken, B., Mauck, W. M., Wessels, H.-H., Hao, Y., Yeung, B. Z., Smibert, P., & Satija, R. (2021). Characterizing the molecular regulation of inhibitory immune checkpoints with multimodal single-cell screens. Nature Genetics, 53(3), 322–331. 10.1038/s41588-021-00778-2
  2. Replogle, J. M., Saunders, R. A., Pogson, A. N., Hussmann, J. A., Lenail, A., Guna, A., Mascibroda, L., Wagner, E. J., Adelman, K., Lithwick-Yanai, G., Iremadze, N., Oberstrass, F., Lipson, D., Bonnar, J. L., Jost, M., Norman, T. M., & Weissman, J. S. (2022). Mapping information-rich genotype-phenotype landscapes with genome-scale Perturb-seq. Cell, 185(14), 2559-2575.e28. 10.1016/j.cell.2022.05.013
  3. Peidli, S., Green, T. D., Shen, C., Gross, T., Min, J., Garda, S., Yuan, B., Schumacher, L. J., Taylor-King, J. P., Marks, D. S., Luna, A., Blüthgen, N., & Sander, C. (2024). scPerturb: harmonized single-cell perturbation data. Nature Methods, 21(3), 531–540. 10.1038/s41592-023-02144-y
  4. Barry, T., Mason, K., Roeder, K., & Katsevich, E. (2024). Robust differential expression testing for single-cell CRISPR screens at low multiplicity of infection. Genome Biology, 25(1), 124. 10.1186/s13059-024-03254-2