Install any skill in seconds. Free to start, no credit card required.
Get Started Free →End-to-end CRISPR screen analysis from FASTQ to hit genes. Orchestrates guide counting, QC, statistical analysis with MAGeCK, and hit calling with multiple methods. Use when analyzing pooled CRISPR screens from count data to hit calling.
.claude/skills/bio-workflows-crispr-screen-pipeline/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 85% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 64% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 83% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 130% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 11% | 0% |
<!--
#
#
-->
FASTQ Files ──> Guide Counting ──> Count Matrix
│
▼
┌─────────────────────────────────────────────┐
│ crispr-screen-pipeline │
├─────────────────────────────────────────────┤
│ 1. Guide Counting (MAGeCK count) │
│ 2. QC: Library coverage, gini index │
│ 3. Gene-level Analysis (MAGeCK RRA/MLE) │
│ 4. Hit Calling (FDR, effect size) │
│ 5. Visualization & Reporting │
└─────────────────────────────────────────────┘
│
▼
Hit Genes + Volcano/Rank Plotsbash# From FASTQ files mageck count \ -l library.csv \ -n experiment \ --sample-label Day0,Day14_Rep1,Day14_Rep2,Day14_Rep3 \ --fastq Day0.fastq.gz Day14_Rep1.fastq.gz Day14_Rep2.fastq.gz Day14_Rep3.fastq.gz \ --trim-5 0 \ --pdf-report
pythonimport pandas as pd import numpy as np import matplotlib.pyplot as plt counts = pd.read_csv('experiment.count.txt', sep='\t', index_col=0) counts_numeric = counts.iloc[:, 1:] qc_stats = {} for col in counts_numeric.columns: total = counts_numeric[col].sum() zeros = (counts_numeric[col] == 0).sum() gini = calculate_gini(counts_numeric[col].values) qc_stats[col] = {'total_reads': total, 'zero_count_guides': zeros, 'gini': gini} qc_df = pd.DataFrame(qc_stats).T print('QC Summary:') print(qc_df) # Gini index function def calculate_gini(x): x = np.sort(x[x > 0]) n = len(x) cumsum = np.cumsum(x) return (2 * np.sum((np.arange(1, n+1) * x)) - (n + 1) * cumsum[-1]) / (n * cumsum[-1]) # QC thresholds assert qc_df['zero_count_guides'].max() < len(counts) * 0.2, 'Too many zero-count guides' assert qc_df['gini'].max() < 0.4, 'Gini index too high (uneven distribution)' print('QC passed!')
bash# For dropout/negative selection screens mageck test \ -k experiment.count.txt \ -t Day14_Rep1,Day14_Rep2,Day14_Rep3 \ -c Day0 \ -n negative_screen \ --pdf-report \ --gene-lfc-method alphamedian
bash# For screens with multiple conditions # Design matrix: design.txt # samplename,baseline,treatment # Day0,1,0 # Day14_Ctrl,1,0 # Day14_Drug,1,1 mageck mle \ -k experiment.count.txt \ -d design.txt \ -n mle_analysis \ --threads 8
pythonimport pandas as pd # Load MAGeCK results gene_summary = pd.read_csv('negative_screen.gene_summary.txt', sep='\t') # Define hits gene_summary['neg_hit'] = (gene_summary['neg|fdr'] < 0.05) & (gene_summary['neg|lfc'] < -0.5) gene_summary['pos_hit'] = (gene_summary['pos|fdr'] < 0.05) & (gene_summary['pos|lfc'] > 0.5) neg_hits = gene_summary[gene_summary['neg_hit']].sort_values('neg|rank') pos_hits = gene_summary[gene_summary['pos_hit']].sort_values('pos|rank') print(f'Negative selection hits (dropout): {len(neg_hits)}') print(f'Positive selection hits (enriched): {len(pos_hits)}') # Save hit lists neg_hits.to_csv('negative_hits.csv', index=False) pos_hits.to_csv('positive_hits.csv', index=False)
pythonimport matplotlib.pyplot as plt import numpy as np # Volcano plot fig, ax = plt.subplots(figsize=(10, 8)) x = gene_summary['neg|lfc'] y = -np.log10(gene_summary['neg|fdr'] + 1e-10) colors = ['red' if h else 'blue' if p else 'gray' for h, p in zip(gene_summary['neg_hit'], gene_summary['pos_hit'])] ax.scatter(x, y, c=colors, alpha=0.5, s=20) ax.axhline(-np.log10(0.05), linestyle='--', color='black', alpha=0.5) ax.axvline(-0.5, linestyle='--', color='black', alpha=0.5) ax.axvline(0.5, linestyle='--', color='black', alpha=0.5) ax.set_xlabel('Log2 Fold Change') ax.set_ylabel('-Log10(FDR)') ax.set_title('CRISPR Screen Volcano Plot') plt.tight_layout() plt.savefig('volcano_plot.png', dpi=150)
rlibrary(MAGeCKFlute) library(ggplot2) # Load MAGeCK results gene_summary <- read.delim('negative_screen.gene_summary.txt') sgrna_summary <- read.delim('negative_screen.sgrna_summary.txt') # QC with MAGeCKFlute FluteMLE(mle_output = 'mle_analysis.gene_summary.txt', treatname = 'treatment', proj = 'crispr_screen', pathview.top = 10) # Or for RRA results FluteRRA(gene_summary = gene_summary, sgrna_summary = sgrna_summary, proj = 'rra_analysis') # Custom rank plot gene_summary$rank <- rank(gene_summary$`neg.score`) gene_summary$is_hit <- gene_summary$`neg.fdr` < 0.05 ggplot(gene_summary, aes(x = rank, y = -log10(`neg.fdr` + 1e-10), color = is_hit)) + geom_point(alpha = 0.5) + geom_hline(yintercept = -log10(0.05), linetype = 'dashed') + scale_color_manual(values = c('gray', 'red')) + theme_bw() + labs(title = 'Gene Rank Plot', x = 'Rank', y = '-Log10(FDR)') ggsave('rank_plot.png', width = 10, height = 6)
bash# Calculate Bayes Factor for essentiality BAGEL.py bf \ -i experiment.count.txt \ -o bagel_output \ -e CEGv2.txt \ -n NEGv1.txt \ -c Day0 \ -s Day14_Rep1,Day14_Rep2,Day14_Rep3 # Precision-recall analysis BAGEL.py pr \ -i bagel_output.bf \ -o bagel_pr \ -e CEGv2.txt \ -n NEGv1.txt
| Stage | Check | Action if Failed | |-------|-------|------------------| | Counting | >70% mapping rate | Check library/trimming | | Zero guides | <20% | Check sequencing depth | | Gini index | <0.4 | Check for amplification bias | | Replicates | r > 0.8 | Check experimental consistency | | Controls | Separate in PCA | Check screen worked |
bash# For enrichment screens (e.g., drug resistance) mageck test \ -k counts.txt \ -t Resistant_Rep1,Resistant_Rep2 \ -c Sensitive \ -n positive_screen \ --gene-lfc-method alphamedian
bash# Same workflow, different interpretation # CRISPRi: negative LFC = gene promotes phenotype # CRISPRa: positive LFC = gene promotes phenotype mageck test -k counts.txt -t Treated -c Control -n crispri_screen
<!-- AUTHOR_SIGNATURE: 9a7f3c2e-MD-BABU-MIA-2026-MSSM-SECURE -->
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 12,684 | 11,727 | -8% | 1 | 1 | 0% | 2,675 | 4,750 | +78% | 0 | 0 | — |
case-02 | pass→pass | 15,778 | 10,963 | -31% | 1 | 1 | 0% | 3,129 | 4,584 | +47% | 0 | 0 | — |
case-03 | pass→pass | 4,106 | 4,477 | +9% | 1 | 1 | 0% | 702 | 3,296 | +370% | 0 | 0 | — |
case-04 | fail→pass | 13,356 | 11,441 | -14% | 1 | 1 | 0% | 2,591 | 4,800 | +85% | 0 | 0 | — |
case-10 | pass→pass | 12,704 | 3,632 | -71% | 1 | 1 | 0% | 2,112 | 3,033 | +44% | 0 | 0 | — |
case-05 | fail→pass | 10,928 | 10,736 | -2% | 1 | 1 | 0% | 2,181 | 3,575 | +64% | 0 | 0 | — |
case-06 | pass→pass | 8,742 | 6,962 | -20% | 1 | 1 | 0% | 1,783 | 3,731 | +109% | 0 | 0 | — |
case-07 | fail→pass | 13,162 | 8,088 | -39% | 1 | 1 | 0% | 2,163 | 3,952 | +83% | 0 | 0 | — |
case-08 | pass→pass | 6,643 | 2,742 | -59% | 1 | 1 | 0% | 1,284 | 2,906 | +126% | 0 | 0 | — |
case-09 | pass→pass | 11,016 | 7,766 | -30% | 1 | 1 | 0% | 1,731 | 3,750 | +117% | 0 | 0 | — |
case-11 | fail→pass | 10,250 | 9,526 | -7% | 1 | 1 | 0% | 1,710 | 3,926 | +130% | 0 | 0 | — |
case-12 | pass→pass | 8,757 | 4,963 | -43% | 1 | 1 | 0% | 1,889 | 3,593 | +90% | 0 | 0 | — |
case-13 | fail→pass | 36,529 | 8,916 | -76% | 1 | 1 | 0% | 3,922 | 4,345 | +11% | 0 | 0 | — |
case-14 | fail→fail | 7,460 | 3,854 | -48% | 1 | 1 | 0% | 1,478 | 3,139 | +112% | 0 | 0 | — |
case-15 | pass→pass | 8,049 | 5,523 | -31% | 1 | 1 | 0% | 1,477 | 3,465 | +135% | 0 | 0 | — |
case-16 | pass→pass | 8,805 | 6,202 | -30% | 1 | 1 | 0% | 1,595 | 3,507 | +120% | 0 | 0 | — |
case-17 | pass→pass | 7,087 | 6,660 | -6% | 1 | 1 | 0% | 1,461 | 3,775 | +158% | 0 | 0 | — |
case-18 | fail→pass | 12,222 | 7,924 | -35% | 1 | 1 | 0% | 2,633 | 4,088 | +55% | 0 | 0 | — |
case-19 | pass→pass | 12,734 | 8,831 | -31% | 1 | 1 | 0% | 2,228 | 3,888 | +75% | 0 | 0 | — |
case-20 | pass→pass | 11,792 | 12,136 | +3% | 1 | 1 | 0% | 2,258 | 4,945 | +119% | 0 | 0 | — |
case-21 | pass→pass | 13,270 | 20,459 | +54% | 1 | 1 | 0% | 2,175 | 6,166 | +183% | 0 | 0 | — |
case-22 | pass→pass | 12,405 | 13,701 | +10% | 1 | 1 | 0% | 2,684 | 5,267 | +96% | 0 | 0 | — |
case-23 | pass→pass | 10,943 | 9,011 | -18% | 1 | 1 | 0% | 2,133 | 4,064 | +91% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +26 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 7/24/2026 | +45% |
Other measured skills in the registry, with their headline benchmark lift.