ribo-seq/translation-efficiency/SKILL.md
Quantify translation efficiency (TE) as ribosome occupancy relative to mRNA abundance and test for differential TE between conditions. Use when separating translational from transcriptional regulation, distinguishing genuine translational control from buffering, or choosing between riborex, Xtail, anota2seq, and DESeq2 interaction models.
npx skillsauth add GPTomics/bioSkills bio-ribo-seq-translation-efficiencyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Reference examples tested with: riborex 2.4+, xtail 1.1+, anota2seq 1.24+, DESeq2 1.42+, pandas 2.2+
Before using code patterns, verify installed versions match. If versions differ:
packageVersion('<pkg>') then ?function_name to verify parameterspip show <package> then help(module.function) to check signaturesIf code throws ImportError, AttributeError, or TypeError, introspect the installed package and adapt the example to match the actual API rather than retrying.
"Calculate translation efficiency from my Ribo-seq and RNA-seq" -> Compute footprint density relative to mRNA density per gene and test which genes change translation independently of transcription, distinguishing real translational control from buffering.
riborex (DESeq2/edgeR backend), Xtail, or anota2seq for differential TETE = RPF density / mRNA density over the SAME region. Both assays must come from matched samples and be counted over the CDS. TE isolates translational regulation and is a relative translation-rate proxy at steady state; occupancy is not protein output.
The naive per-gene ratio (TPM_ribo/TPM_rna) is fine for ranking and plots but WRONG for differential testing: it ignores count heteroskedasticity, treating a gene with 5 reads like one with 5000. Differential TE is NOT "compute TE per condition then test the difference" -- it is a CONDITION x ASSAY INTERACTION on raw counts with proper negative-binomial dispersion modeling, where log2FC(TE) = log2FC(RPF) - log2FC(mRNA). The whole differential-TE field exists to do this interaction correctly.
When both assays move, there are distinct biological modes that a single TE fold-change cannot separate:
| Mode | RPF | mRNA | TE | Meaning | |------|-----|------|-----|---------| | mRNA abundance | up | up | ~flat | transcriptional, not translational | | translation (forwarded) | up | flat | up | genuine translational control -> protein changes | | buffering | flat | up | down | translation absorbs the mRNA change, protein held constant |
Buffering (a homeostatic mechanism) and genuine translational activation can produce the SAME |log2FC(TE)|. Calling a buffered gene "translationally activated" is a wrong conclusion. Only anota2seq formally names the mode, by regressing translated mRNA on total mRNA (analysis of partial variance).
| Tool | Statistic | Names buffering | Best when | |------|-----------|-----------------|-----------| | riborex | wraps DESeq2/edgeR/Voom on a merged interaction design | no | fast drop-in for DESeq2 users | | Xtail | two pipelines (FC-vs-FC, ratio-vs-ratio), reports the more conservative | partial (won't call a buffered gene a hit) | conservative differential-TE calls + clean plots | | anota2seq | per-mRNA APV + random variance model | YES | mode-of-regulation biology; the postdoc-grade choice | | RiboDiff | NB GLM, shared dispersion by default | no | few replicates; CLI pipeline | | DESeq2 interaction | ~assay+condition+assay:condition, Wald or LRT | no (post-hoc) | full control, custom contrasts, batch terms |
Goal: Rank genes by TE for a quick look, not for inference.
Approach: Normalize both assays, take the log2 ratio over the CDS with a pseudocount.
import numpy as np
def log2_te(ribo_cds_tpm, rna_cds_tpm, pseudocount=0.1):
'''Per-gene log2 TE for ranking/plots. Both inputs counted over the CDS.
Pseudocount 0.1 TPM avoids log(0) and dampens low-count noise. Not for testing.
'''
return np.log2((ribo_cds_tpm + pseudocount) / (rna_cds_tpm + pseudocount))
Count BOTH assays over the CDS. Using full-transcript RNA against CDS-only RPF introduces a UTR-length confound (long-UTR genes look low-TE). Exclude the first ~15 and last ~5 codons of the CDS so initiation and termination peaks do not dominate the RPF count.
Goal: Test differential TE reusing a familiar DE engine.
Approach: Pass CDS count matrices and condition vectors; riborex builds the interaction design internally and returns DESeq2-format results.
library(riborex)
# rna_counts / ribo_counts: genes x samples integer CDS counts
res <- riborex(rnaCntTable = rna_counts, riboCntTable = ribo_counts,
rnaCond = c("ctrl", "ctrl", "treat", "treat"),
riboCond = c("ctrl", "ctrl", "treat", "treat"),
engine = "DESeq2")
sig <- res[which(res$padj < 0.05), ] # log2FoldChange is the TE change
Engines are "DESeq2" (default), "edgeR", "edgeRD", "Voom" (Voom is single-factor only).
Goal: Separate translation, buffering, and mRNA-abundance regulation.
Approach: Provide translated (RPF) and total (RNA) matrices, run the pipeline, then classify each gene's mode.
library(anota2seq)
ads <- anota2seqDataSetFromMatrix(dataP = ribo_counts, dataT = rna_counts,
phenoVec = c("ctrl", "ctrl", "treat", "treat"),
dataType = "RNAseq", normalize = TRUE)
ads <- anota2seqRun(ads, useRVM = TRUE)
ads <- anota2seqRegModes(ads) # one mode per gene: translation > abundance > buffering
translation_hits <- anota2seqGetOutput(ads, analysis = "translation",
output = "selected", selContrast = 1)
Goal: Full control over the interaction model.
Approach: Merge RPF and RNA counts, fit the interaction, and select the interaction coefficient by name from resultsNames (never hardcode it).
library(DESeq2)
counts <- cbind(ribo_counts, rna_counts)
coldata <- data.frame(
condition = factor(rep(c("ctrl", "ctrl", "treat", "treat"), 2)),
assay = factor(rep(c("ribo", "rna"), each = 4)))
dds <- DESeqDataSetFromMatrix(counts, coldata, ~ assay + condition + assay:condition)
dds <- DESeq(dds)
# The interaction name is auto-generated from factor levels; pick it programmatically.
# DESeq2 renders interaction coefficients with a DOT (e.g. assayrna.conditiontreat),
# while main effects use underscores -- so match the dot, not the formula's colon.
nm <- grep("\\.", resultsNames(dds), value = TRUE)
res_te <- results(dds, name = nm)
Size factors are estimated PER ASSAY (ribo among ribo, RNA among RNA); the implicit assumption is that the median gene's TE is unchanged. If a global translational shift is expected (e.g. mTOR inhibition), median normalization is violated and spike-ins are needed to anchor absolute scale.
mRNA isoform switching changes the CDS/UTR counting region between conditions; UTR changes that alter uORF usage can make a main-ORF TE change SECONDARY to uORF regulation rather than direct translational control. Cross-check called ORFs and uORFs (see orf-detection) before attributing a TE shift to the main ORF.
| Symptom | Cause | Fix |
|---------|-------|-----|
| Low-count genes dominate the hit list | t-test/ratio on log-TE | Use count-based GLM (riborex/Xtail/anota2seq/DESeq2) |
| Long-UTR genes systematically low TE | RNA counted over full transcript, RPF over CDS | Count both over the CDS |
| results(dds, name='conditiontreat.assayribo') errors | Hardcoded interaction name | Select from resultsNames(dds) by the "." term (interaction coefficients render with a dot, not the formula's colon) |
| Unstable dispersion or anota2seq RVM warnings | Too few replicates (n=2 as in the examples) | Use >=3 replicates per condition per assay; n=2 is illustrative only |
| Buffered gene reported as translationally activated | Single TE fold-change cannot separate modes | Use anota2seq mode-of-regulation |
| TE shifts vanish or invert globally | Global translational change breaks median normalization | Add spike-ins; do not assume median TE unchanged |
| Initiation peak inflates RPF counts | Whole-CDS counting including start/stop peaks | Trim first ~15 / last ~5 codons |
tools
End-to-end CLIP-seq pipeline from FASTQ to ENCODE-compliant binding sites, single-nucleotide crosslink maps, annotation, motifs, and (optionally) differential binding. Use when running the full Yeo lab eCLIP / iCLIP / iCLIP2 / iCLIP3 / irCLIP / PAR-CLIP analysis with SMInput control, protocol-specific UMI extraction, ENCODE STAR parameters, CLIPper or Skipper peak calling with stringent log2 FC and -log10 p thresholds, IDR rescue and self-consistency QC, and downstream motif registration with mCross or PEKA.
development
Detect, date, and contextualize whole-genome duplication (WGD / paleopolyploidy) events using wgd v2 (Chen et al 2024), KsRates (Sensalari 2022 substitution-rate-corrected Ks dating), DupGen_finder (Qiao 2019), MAPS (Li 2018 phylogenomic), POInT (Conant 2008 ordered-block), SLEDGe (2024 ML-based), Whale.jl (Bayesian DL+WGD), and synteny-anchored paranome construction. Use when identifying ancient polyploidy from Ks distributions and synteny block analysis, positioning WGD events relative to speciation, distinguishing tandem from segmental from WGD duplications, dating the 2R/3R vertebrate / fish / salmonid WGDs, building paranome and Ks-age mixture models, applying KsRates substitution-rate correction across lineages, or testing alternative biased-fractionation / dosage-balance models post-WGD.
tools
Build whole-genome alignments using Progressive Cactus (Armstrong 2020 reference-free clade-level WGA), Minigraph-Cactus (Hickey 2024 pangenome-aware), LASTZ chain/net (UCSC pipeline), MUMmer4 (Marçais 2018 pairwise), minimap2 -x asm5/10/20 (Li 2018 fast pairwise), AnchorWave (Song 2022 WGD-aware), and Mauve / progressiveMauve (bacterial). Operates the HAL toolkit (Hickey 2013) for downstream extraction including halSynteny, halLiftover, halBranchMutations, and hal2maf. Use when constructing multi-species alignments for comparative-annotation projection (TOGA), synteny detection, conservation analyses (phyloP / PhastCons), or pangenome graph construction; selecting between reference-free (Cactus) and reference-anchored (LASTZ chains/nets) approaches; tuning sensitivity for closely vs distantly related genomes; or producing HAL files for genome-wide downstream tools.
development
Detect syntenic blocks and structural rearrangements between genomes using MCScanX (Wang 2012), JCVI/MCScan (Tang 2008 Python), GENESPACE (Lovell 2022) for orthology-anchored riparian visualization, SyRI for structural variation, AnchorWave for sequence-level synteny, i-ADHoRe 3.0 for highly diverged species, SynNet for synteny networks, and ntSynt for multi-genome macrosynteny. Use when identifying collinear gene blocks across species, distinguishing macrosynteny from microsynteny, detecting inversions/translocations/duplications, anchoring orthology in WGD lineages, producing publication riparian plots, computing synteny block age via Ks (cross-references whole-genome-duplication), or running synteny-aware ortholog inference in polyploids.