Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Find differentially accessible chromatin regions between conditions using DiffBind or DESeq2. Use when comparing chromatin accessibility between treatment groups, cell types, or developmental stages in ATAC-seq experiments.
.claude/skills/bio-atac-seq-differential-accessibility/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-15 | ✗→✓ | ▲ Improved | — | — |
| case-05 | ✗→✓ | ▲ Improved | — | — |
| case-06 | ✗→✓ | ▲ Improved | — | — |
| case-04 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✗→✓ | ▲ Improved | — | — |
Reference examples tested with: DESeq2 1.42+, GenomicRanges 1.54+, Subread 2.0+, numpy 1.26+, pandas 2.2+, scanpy 1.10+, scipy 1.12+
Before using code patterns, verify installed versions match. If versions differ:
pip show <package> then help(module.function) to check signaturespackageVersion('<pkg>') then ?function_name to verify parameters<tool> --version then <tool> --help to confirm flagsIf code throws ImportError, AttributeError, or TypeError, introspect the installed package and adapt the example to match the actual API rather than retrying.
"Find differentially accessible regions between my conditions" → Identify chromatin regions with statistically significant changes in accessibility between treatment groups, cell types, or timepoints.
DiffBind or DESeq2 on a peak-by-sample count matrixGoal: Identify differentially accessible chromatin regions between experimental conditions.
Approach: Load sample metadata and peak files into DiffBind, count reads in consensus peaks, normalize, define contrasts, and run differential analysis with DESeq2 backend.
rlibrary(DiffBind) # 1. Create sample sheet samples <- data.frame( SampleID = c('ctrl_1', 'ctrl_2', 'treat_1', 'treat_2'), Condition = c('control', 'control', 'treated', 'treated'), Replicate = c(1, 2, 1, 2), bamReads = c('ctrl_1.bam', 'ctrl_2.bam', 'treat_1.bam', 'treat_2.bam'), Peaks = c('ctrl_1.narrowPeak', 'ctrl_2.narrowPeak', 'treat_1.narrowPeak', 'treat_2.narrowPeak') ) write.csv(samples, 'samples.csv', row.names=FALSE) # 2. Load data dba <- dba(sampleSheet='samples.csv') # 3. Count reads dba <- dba.count(dba) # 4. Normalize dba <- dba.normalize(dba) # 5. Set up contrasts dba <- dba.contrast(dba, contrast=c('Condition', 'treated', 'control')) # 6. Differential analysis dba <- dba.analyze(dba) # 7. Get results results <- dba.report(dba)
rlibrary(DiffBind) # Load samples dba <- dba(sampleSheet='samples.csv') # Count with specific parameters dba <- dba.count(dba, summits=250, # Re-center peaks on summit minOverlap=2, # Peak in at least 2 samples score=DBA_SCORE_NORMALIZED) # Normalize dba <- dba.normalize(dba, normalize=DBA_NORM_NATIVE) # Analyze dba <- dba.contrast(dba, contrast=c('Condition', 'treated', 'control')) dba <- dba.analyze(dba, method=DBA_DESEQ2) # Extract results results <- dba.report(dba, th=0.05, bCounts=TRUE) # Save write.csv(as.data.frame(results), 'differential_peaks.csv')
r# PCA plot dba.plotPCA(dba, attributes=DBA_CONDITION) # MA plot dba.plotMA(dba) # Volcano plot dba.plotVolcano(dba) # Heatmap of differential peaks dba.plotHeatmap(dba, contrast=1, correlations=FALSE) # Venn diagram of overlapping peaks dba.plotVenn(dba, contrast=1, bDB=TRUE, bGain=TRUE, bLoss=TRUE)
Goal: Run differential accessibility analysis using DESeq2 on a peak count matrix without DiffBind.
Approach: Load peak-by-sample counts into a DESeqDataSet, filter low counts, run the DESeq2 pipeline, and extract significant differential peaks.
rlibrary(DESeq2) library(GenomicRanges) # Load peak counts (from featureCounts or custom counting) counts <- read.delim('peak_counts.txt', row.names=1) # Sample metadata coldata <- data.frame( row.names = colnames(counts), condition = factor(c('control', 'control', 'treated', 'treated')) ) # Create DESeq object dds <- DESeqDataSetFromMatrix(countData=counts, colData=coldata, design=~condition) # Filter low counts dds <- dds[rowSums(counts(dds)) >= 10, ] # Run DESeq2 dds <- DESeq(dds) # Results res <- results(dds, contrast=c('condition', 'treated', 'control')) res <- res[order(res$padj), ] # Significant peaks sig <- subset(res, padj < 0.05 & abs(log2FoldChange) > 1)
Goal: Generate a peak-by-sample count matrix as input for differential analysis.
Approach: Convert consensus peaks to SAF format and run featureCounts to count reads from all BAM files in each peak region.
bash# Using featureCounts # First convert peaks to SAF format awk 'BEGIN{OFS="\t"; print "GeneID\tChr\tStart\tEnd\tStrand"} {print $1"_"$2"_"$3, $1, $2, $3, "."}' consensus_peaks.bed > peaks.saf featureCounts \ -a peaks.saf \ -F SAF \ -o peak_counts.txt \ -p \ --countReadPairs \ -T 8 \ *.bam
pythonimport pandas as pd import numpy as np from scipy import stats def simple_differential(counts_file, groups): '''Simple differential accessibility test.''' counts = pd.read_csv(counts_file, sep='\t', index_col=0, comment='#') # Normalize to CPM cpm = counts.div(counts.sum()) * 1e6 # Log transform log_cpm = np.log2(cpm + 1) # Separate groups group1 = [c for c in counts.columns if groups[c] == 'control'] group2 = [c for c in counts.columns if groups[c] == 'treated'] results = [] for peak in counts.index: g1_vals = log_cpm.loc[peak, group1] g2_vals = log_cpm.loc[peak, group2] log2fc = g2_vals.mean() - g1_vals.mean() t_stat, pval = stats.ttest_ind(g1_vals, g2_vals) results.append({ 'peak': peak, 'log2FoldChange': log2fc, 'pvalue': pval }) df = pd.DataFrame(results) df['padj'] = stats.false_discovery_control(df['pvalue']) return df
Goal: Map differential peaks to nearby genes and genomic features for biological interpretation.
Approach: Use ChIPseeker to annotate peaks with promoter/intron/intergenic classification and distance to nearest TSS.
rlibrary(ChIPseeker) library(TxDb.Hsapiens.UCSC.hg38.knownGene) # Annotate differential peaks diff_peaks <- dba.report(dba) peakAnno <- annotatePeak(diff_peaks, TxDb=TxDb.Hsapiens.UCSC.hg38.knownGene) # Plot annotation plotAnnoPie(peakAnno) plotDistToTSS(peakAnno) # Get genes genes <- as.data.frame(peakAnno)$geneId
r# Get significant results sig_peaks <- dba.report(dba, th=0.05, fold=1) # Opened in treatment opened <- sig_peaks[sig_peaks$Fold > 0] # Closed in treatment closed <- sig_peaks[sig_peaks$Fold < 0] # Export as BED export.bed(opened, 'opened_peaks.bed') export.bed(closed, 'closed_peaks.bed')
r# Complex design with batch correction samples$Batch <- factor(c('A', 'B', 'A', 'B')) dba <- dba(sampleSheet=samples) dba <- dba.count(dba) dba <- dba.normalize(dba) # Design formula approach dba <- dba.contrast(dba, design='~Batch + Condition') dba <- dba.analyze(dba)
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-15 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
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. 22 cases were attempted. The headline lift of +23 percentage points is the difference between those two pass rates over the 22 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.