small-rna-seq/target-prediction/SKILL.md
Predicts and prioritizes miRNA target genes with seed-based tools (miRanda, TargetScan, miRDB) and experimentally validated databases (miRTarBase, multiMiR). Use when deciding that a predicted target is a hypothesis not a finding; ranking by the right score (weighted context++, mirSVR, miRDB); raising confidence by intersecting predictions with inversely-correlated mRNA DE; weighing validated (CLIP/reporter) over predicted evidence; or avoiding the circular enrichment of unfiltered target lists.
npx skillsauth add GPTomics/bioSkills bio-small-rna-seq-target-predictionInstall 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: miRanda 3.3a+, BioPython 1.83+, pandas 2.2+, gseapy 1.1+
Before using code patterns, verify installed versions match. If versions differ:
<tool> --version then <tool> --help to confirm flagspip 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.
"Predict target genes for my miRNAs" -> Generate candidate mRNA targets by seed complementarity and thermodynamics, then raise confidence with conservation, validated databases, and matched expression.
miranda miRNA.fa UTR.fa -sc 140 -en -20 -strict for de novo predictionSeed-based prediction has a false-positive rate near 50% even for conserved sites (Pinzon 2017), because a 6mer seed match occurs by chance roughly once per 4 kb of sequence, so a multi-kb 3' UTR carries many spurious matches. It also has a RECALL problem in the opposite direction: AGO-CLIP and CLASH show that roughly 60% of real interactions are noncanonical, and the bulged, seedless, and 3'-compensatory sites among them are missed entirely by seed-only tools (3'-supplementary sites keep a canonical seed and are still found), so a clean seed list is incomplete, not just imprecise (Helwak 2013). Worse, a single miRNA represses most of its real targets only modestly - typically less than two-fold at the protein level (Baek 2008; Selbach 2008) - so miRNAs are rheostats, not switches, and large single-target claims should be distrusted. The decisive move is therefore not running more predictors (five seed-based tools agreeing is pseudo-replication, not independent evidence) but climbing an evidence ladder and, above all, intersecting predictions with INVERSELY-correlated differentially expressed mRNA or protein from the SAME samples. Prediction proposes; expression disposes.
| Evidence tier (low to high) | What it means | |------------------------------|----------------| | seed match alone | weakest; common by chance | | + conservation (TargetScan PCT) | precision up, recall down (misses species-specific targets) | | + multiple independent tools / ML (miRDB) | modestly higher precision | | + AGO-CLIP footprint | the miRNA's complex bound there (but CLIP is cell-type/state-specific - a peak from another tissue is weak evidence) | | + CLASH/CLEAR-CLIP chimera | direct miRNA-target duplex | | + anti-correlated matched miRNA/mRNA(protein) DE | functional in YOUR system | | + reporter / seed-mutation rescue (miRTarBase "strong") | causal, gold standard |
| Tool | Scoring philosophy | Use for | Caveat | |------|--------------------|---------|--------| | TargetScan (context++) | conservation + 14-feature regression of repression | conserved-site prioritization | v7 = context++; v8 = a different Kd/biochemical model | | miRanda + mirSVR | thermodynamic alignment + expression-trained regression | non-conserved / non-canonical sites | permissive; tune thresholds | | miRDB / MirTarget | ML (SVM) on CLIP + overexpression data | data-driven ranking (score 0-100) | score >= 80 is the conventional high-confidence cut | | RNAhybrid | pure MFE hybridization, no seed constraint | exploratory, no-seed sites | most false positives without filters | | miRTarBase / TarBase (ENCORI) | experimentally validated interactions | the gold tier; anchor claims here | "less strong" CLIP/NGS entries are not individually validated | | multiMiR | unifies predicted + validated sources | one-call aggregation | inherits each source DB's errors |
Goal: Predict miRNA-mRNA target sites by complementarity and duplex energy.
Approach: Align miRNA sequences against 3' UTRs with a minimum score and a maximum (negative) energy, requiring strict seed pairing.
miranda miRNA.fa UTRs.fa -sc 140 -en -20 -strict -out predictions.txt
# -sc 140: minimum alignment score (keep alignments with score >= 140; default 140)
# -en -20: maximum free energy in kcal/mol (keep energies <= -20; value is negative)
# -strict: require canonical seed pairing at positions 2-8 (no gaps/wobble in seed)
# Tunable: many use -sc 150 / -en -7 (looser) up to -sc 155 / -en -20 (stringent)
Goal: Extract interaction records into a DataFrame.
Approach: Read the lines miRanda prefixes with '>' (per-hit summary) and pull miRNA, target, score, and energy.
import pandas as pd
def parse_miranda(output_file):
rows = []
with open(output_file) as f:
for line in f:
if line.startswith('>') and not line.startswith('>>'):
p = line.strip().split('\t')
if len(p) >= 5:
rows.append({'mirna': p[0].lstrip('>'), 'target': p[1],
'score': float(p[2]), 'energy': float(p[3])})
return pd.DataFrame(rows)
Goal: Retrieve conserved-site predictions and rank a miRNA's targets.
Approach: Read the downloadable per-site context-scores file and rank by the weighted context++ score (more negative = stronger predicted repression across the whole UTR).
import pandas as pd
def query_targetscan(mirbase_id, ts_file='Predicted_Targets_Context_Scores.default_predictions.txt'):
# Verified column names: the miRNA column is 'Mirbase ID' (NOT 'miRNA family'),
# the gene column is 'Gene ID', and 'weighted context++ score' aggregates a UTR's sites.
df = pd.read_csv(ts_file, sep='\t')
hits = df[df['Mirbase ID'] == mirbase_id]
return hits.sort_values('weighted context++ score') # ascending: most negative first
Goal: Retrieve ML-based target predictions above the conventional confidence cut.
Approach: Read the miRDB prediction download and keep targets with score >= 80.
def query_mirdb(mirna_id, mirdb_file='miRDB_v6.0_prediction_result.txt'):
df = pd.read_csv(mirdb_file, sep='\t', header=None, names=['mirna', 'refseq', 'score'])
hits = df[df['mirna'] == mirna_id]
return hits[hits['score'] >= 80].sort_values('score', ascending=False)
Goal: Anchor target claims in experimental evidence rather than prediction.
Approach: Query miRTarBase for validated interactions and weight by evidence type; use multiMiR (R) to unify predicted and validated sources in one call.
def get_validated_targets(mirna, mirtarbase_file='miRTarBase_MTI.xlsx'):
df = pd.read_excel(mirtarbase_file)
hits = df[df['miRNA'] == mirna]
# 'Support Type' separates strong (reporter/western/qPCR) from less-strong (CLIP/NGS)
return hits[['Target Gene', 'Experiments', 'Support Type']]
Goal: Keep only targets that behave functionally in the actual experiment.
Approach: Intersect predicted (or CLIP-supported) targets of UP miRNAs with DOWN mRNAs from matched samples; note the blind spot that translation-only targets may not move at the mRNA level.
def functional_targets(predicted_targets, mrna_de, mirna_direction):
# mrna_de: DataFrame with index = gene, column 'log2FC' from matched mRNA-seq.
# Anti-correlation: an UP miRNA should repress -> targets DOWN (and vice versa).
# Blind spot: miRNAs also act translationally, so some real targets stay flat at
# the mRNA level (need ribosome profiling / proteomics to see those).
want_down = mirna_direction == 'up'
moved = mrna_de[(mrna_de['log2FC'] < 0) == want_down].index
return [g for g in predicted_targets if g in set(moved)]
Goal: Locate seed matches in a UTR and classify site strength.
Approach: The seed is miRNA positions 2-7; a site is the reverse complement of the seed in the 3' UTR. Canonical sites by decreasing efficacy: 8mer > 7mer-m8 > 7mer-A1 > 6mer.
from Bio.Seq import Seq
def find_seed_matches(mirna_seq, utr_seq):
# 7mer-m8 site = reverse complement of miRNA positions 2-8 found in the UTR
seed = str(Seq(mirna_seq)[1:8])
site = str(Seq(seed).reverse_complement())
matches, start = [], 0
while True:
pos = utr_seq.find(site, start)
if pos == -1:
break
matches.append(pos)
start = pos + 1
return matches
| Symptom | Cause | Fix |
|---------|-------|-----|
| KeyError: 'miRNA family' on TargetScan file | Wrong column name for the context-scores file | The miRNA column is Mirbase ID; rank by weighted context++ score |
| Hundreds of "targets", almost none real | Treating seed prediction as truth | Intersect with anti-correlated mRNA DE; anchor in miRTarBase strong evidence |
| Every miRNA "regulates cancer pathways" | Enrichment on an unfiltered predicted target list (circular) | Build the list from validated/CLIP or expression-filtered targets before enrichment |
| Five tools "agree" so a target is trusted | All five use the seed (pseudo-replication) | Require an orthogonal evidence tier (CLIP/validated/expression), not more seed tools |
| A strong single-target claim | miRNAs repress most targets < 2-fold | Treat large single-target effects skeptically; demand validation |
| ceRNA/sponge mechanism asserted | Stoichiometry usually too low to matter (Denzler) | Require absolute abundance (miRNA copies vs added sites) before accepting it |
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.