variant-calling/clinical-interpretation/SKILL.md
Classify variant clinical significance with the ACMG/AMP germline framework and its 2018-2025 ClinGen refinements (graded PVS1 decision tree, PM2 downgraded to Supporting, PP5/BP6 retired, calibrated PP3/BP4, Bayesian points), the AMP/ASCO/CAP somatic tiers and ClinGen oncogenicity system, ClinVar star-rating and gnomAD grpmax filtering-AF interpretation. Use when deciding germline-vs-somatic framework, applying current (not flat-2015) ACMG points, checking for a gene-specific VCEP specification, judging whether a ClinVar assertion or gnomAD frequency is usable evidence, calibrating a pathogenicity predictor, evaluating PVS1 on the MANE Select transcript, or building a VUS reanalysis loop. Not for functional annotation itself (see variant-calling/variant-annotation).
npx skillsauth add GPTomics/bioSkills bio-variant-calling-clinical-interpretationInstall 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: bcftools 1.19+, cyvcf2 0.30+, InterVar 2.2+
Before using code patterns, verify installed versions match. If versions differ:
pip show <package> then help(module.function) to check signatures<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.
Note: interpretation guidance evolves. Flat 2015 ACMG defaults are OUT OF DATE; verify the current ClinGen SVI recommendations and any gene-specific VCEP specification before classifying. Never apply germline ACMG to a somatic variant.
"Classify this variant / write the ACMG rationale" -> Assemble independent, calibrated evidence lines and combine them under the correct framework for a pinned (gene, transcript, disease) context.
A variant's clinical significance is NOT a database lookup. It is a Bayesian sum of INDEPENDENT, CALIBRATED evidence relative to a pinned context (genome build, MANE Select transcript, gene disease-mechanism, disease prevalence, framework version). Three traps sink most naive pipelines:
| Variant origin | Framework | Question answered | Cite | |----------------|-----------|-------------------|------| | Germline (constitutional) | ACMG/AMP + ClinGen SVI | Pathogenic..Benign for a Mendelian disorder | Richards 2015; Abou Tayoun 2018; Tavtigian 2020; Pejaver 2022 | | Somatic (tumor), actionability | AMP/ASCO/CAP tiers I-IV | Diagnostic/prognostic/therapeutic significance in THIS tumor type | Li 2017 | | Somatic, oncogenicity | ClinGen/CGC/VICC points | Oncogenic..Benign (is it a driver) | Horak 2022 |
Before applying generic ACMG, check for a ClinGen Variant Curation Expert Panel (VCEP) specification for the gene (e.g. hearing loss, RASopathy, cardiomyopathy, ENIGMA BRCA1/2). A VCEP spec reweights and constrains criteria and OVERRIDES generic defaults; a 3-star ClinVar assertion often reflects one.
The 2015 consensus (Richards 2015 Genet Med 17:405-424) defines five tiers (Pathogenic, Likely Pathogenic, VUS, Likely Benign, Benign) and 28 coded criteria at default strengths: PVS1 (very strong), PS1-4 (strong), PM1-6 (moderate), PP1-5 (supporting); BA1 (stand-alone), BS1-4 (strong), BP1-7 (supporting). A director does NOT interpret with raw 2015 anymore. Apply these ClinGen SVI corrections:
| Refinement | What changed | Consequence for the classifier | |------------|--------------|-------------------------------| | Graded PVS1 (Abou Tayoun 2018 Hum Mutat 39:1517) | PVS1 is a decision tree, not automatic for any null | Emit PVS1 at Very Strong / Strong / Moderate / Supporting per NMD + mechanism (below) | | PM2 -> Supporting (ClinGen SVI PM2 v1.0, approved Sept 2020) | Absence from gnomAD is WEAK | Apply PM2 at Supporting, never Moderate | | PP5 / BP6 RETIRED (Biesecker & Harrison 2018 Genet Med 20:1687) | An assertion cannot substitute for evidence | Never use PP5/BP6; cite the underlying data instead | | Calibrated PP3 / BP4 (Pejaver 2022 AJHG 109:2163) | Computational evidence is graded, not flat-Supporting | Use ONE calibrated predictor at its calibrated strength (below) | | Bayesian points (Tavtigian 2018/2020) | Verbal combining rules approximate naive Bayes | Sum points; graded/fractional strengths are coherent |
Goal: Combine graded evidence into a tier reproducibly instead of matching verbal rule patterns.
Approach: Assign each met criterion a point value by strength (benign subtracts), sum, and threshold. This underlies the emerging points-based ACMG/AMP/CAP/ClinGen overhaul, so prefer it over the 2015 verbal table.
| Strength | Points (P side) | OddsPath (Tavtigian 2018, prior ~0.10) | |----------|-----------------|-----------------------------------------| | Supporting | +1 | ~2.08 | | Moderate | +2 | ~4.33 | | Strong | +4 | ~18.7 | | Very Strong | +8 | ~350 |
Classification by summed points: Pathogenic >= 10, Likely Pathogenic 6-9, VUS 0-5, Likely Benign -1 to -6, Benign <= -7 (confirm the exact benign cutpoints against Tavtigian 2020 before hard-coding). Benign criteria (BA1/BS/BP) contribute negative points at the same magnitudes.
Goal: Assign PVS1 the CORRECT strength for a null variant instead of firing it on any "HIGH impact" call.
Approach: Route by gene LOF mechanism, then variant type, then NMD prediction and exon location (Abou Tayoun 2018). Evaluate on the MANE Select transcript, not whichever isoform maximizes severity.
"Look up this variant in ClinVar" -> Read WHO submitted, at what review status, on WHAT evidence -- then re-derive, do not adopt the conclusion.
| CLNREVSTAT | Stars | Usable as evidence? | |------------|-------|---------------------| | practice_guideline | 4 | Strongest single-DB signal; still verify vs current evidence | | reviewed_by_expert_panel | 3 | VCEP; strong, often implies a gene specification | | criteria_provided,_multiple_submitters,_no_conflicts | 2 | Consensus; check submitters shared no common error | | criteria_provided,_single_submitter | 1 | A LEAD only -- not usable as evidence | | criteria_provided,_conflicting_classifications | 1 | Conflict is an informative signal, not noise to average | | no_assertion_criteria_provided | 0 | No weight |
Rules: 1-star / no-criteria is not evidence. Conflicting interpretations flag genuinely hard variants (penetrance, ancestry, mechanism) -- investigate, do not average. Concordance is not independence (two submitters can copy one original error). PP5/BP6 are retired precisely because an assertion cannot be an evidence input.
Goal: Attach ClinVar assertions as LEADS and surface review status alongside significance.
Approach: Annotate CLNSIG/CLNDN/CLNREVSTAT from the ClinVar VCF, then always carry CLNREVSTAT so a 1-star call is never mistaken for evidence. Download the build-matched ClinVar VCF first (usage-guide.md).
bcftools annotate -a clinvar.vcf.gz \
-c INFO/CLNSIG,INFO/CLNDN,INFO/CLNREVSTAT input.vcf.gz -Oz -o with_clinvar.vcf.gz
# Surface P/LP leads WITH their review status (never drop CLNREVSTAT)
bcftools view -i 'INFO/CLNSIG~"athogenic"' with_clinvar.vcf.gz \
| bcftools query -f '%CHROM:%POS %REF>%ALT\t%INFO/CLNSIG\t%INFO/CLNREVSTAT\n'
Goal: Decide BA1/BS1 (or PM2_Supporting) correctly for THIS disease, not with a universal 1% line.
Approach: Compare the gnomAD grpmax filtering allele frequency to the maximum credible population AF derived from disease prevalence, heterogeneity, inheritance and penetrance (Whiffin 2017 Genet Med 19:1151). A flat cutoff is wrong in both directions.
fafmax_faf95_max INFO field (fafmax_faf95_max_joint in the joint exome+genome VCF). Using grpmax, not global AF, avoids diluting a variant common in one ancestry across the whole cohort; using the CI lower bound guards against a noisy small-subpopulation estimate.# Illustrative: filter on a grpmax filtering-AF field, keeping absent sites (annotation-dependent)
bcftools view -i 'INFO/fafmax_faf95_max<0.0001 || INFO/fafmax_faf95_max="."' \
input.vcf.gz -Oz -o faf_filtered.vcf.gz
Goal: Convert a computational score into PP3/BP4 at a defensible strength without double-counting.
Approach: Pick ONE predictor that reached >= Strong in the ClinGen calibration and apply it at its calibrated threshold (Pejaver 2022). Stacking correlated tools fakes independence and silently over-calls pathogenic.
Goal: Rank candidate variants for review triage using available annotations.
Approach: Combine ClinVar leads, grpmax frequency and a single calibrated predictor into a tier. This is a triage helper, not an ACMG classification -- computational scores are supporting only, and stacking here is for RANKING, not evidence.
from cyvcf2 import VCF
def triage_tier(variant):
# Triage ranking ONLY; not equivalent to ACMG. ClinVar is a lead (carry review status
# separately), scores are PP3/BP4-supporting, and stacking predictors here just ranks.
clnsig = str(variant.INFO.get('CLNSIG', ''))
faf = variant.INFO.get('fafmax_faf95_max', 0) or 0
revel = variant.INFO.get('REVEL', 0) or 0 # single calibrated predictor
if 'Pathogenic' in clnsig and 'Likely' not in clnsig:
return 'PATHOGENIC_LEAD'
if 'Likely_pathogenic' in clnsig:
return 'LIKELY_PATHOGENIC_LEAD'
if 'Benign' in clnsig or faf > 0.05: # BA1 territory; confirm vs disease-max credible AF
return 'BENIGN_LEAD'
if revel >= 0.644 and faf < 0.0001: # REVEL PP3_Supporting threshold (Pejaver 2022)
return 'VUS_FAVOR_PATH'
if revel <= 0.290: # REVEL BP4_Supporting threshold
return 'VUS_FAVOR_BENIGN'
return 'VUS'
vcf = VCF('annotated.vcf.gz')
report = {'PATHOGENIC_LEAD', 'LIKELY_PATHOGENIC_LEAD', 'VUS_FAVOR_PATH'}
for v in vcf:
tier = triage_tier(v)
if tier in report:
gene = v.INFO.get('SYMBOL', 'NA')
print(f'{gene}\t{v.CHROM}:{v.POS}\t{tier}\t{v.INFO.get("CLNREVSTAT", ".")}')
"Interpret this tumor variant" -> Ask about actionability and oncogenicity in THIS tumor type, never germline pathogenicity. Tier is tumor-type-specific (BRAF V600E is Tier I in melanoma, lower elsewhere) -- a context-dependence with no germline analog.
AMP/ASCO/CAP tiers (Li 2017 J Mol Diagn 19:4) -- clinical actionability:
ClinGen/CGC/VICC oncogenicity (Horak 2022 Genet Med 24:986) -- a SEPARATE points-based axis (Oncogenic..Benign) using cancer-specific codes (hotspot recurrence, functional oncogenic data, tumor frequency). Oncogenicity != actionability: an oncogenic driver may have no drug (Tier III despite oncogenic).
Knowledgebase evidence levels: OncoKB Level 1-4 + R1/R2 (therapeutic), CIViC evidence A-E (read the evidence item, not just the letter), COSMIC recurrence (a hotspot SIGNAL, not clinical actionability). Tumor-only assays cannot cleanly separate somatic from germline -- a ~50%/~100% VAF variant may be germline; filter and disclose explicitly, or use paired tumor-normal.
A classification is a snapshot relative to the evidence available on its date. Build a reanalysis loop: periodically re-annotate stored VCFs against the latest ClinVar and gnomAD releases and flag VUS whose evidence changed (new functional/segregation data, a new VCEP spec, a frequency that now crosses BA1/BS1). A one-time classification without reanalysis is a latent error.
Goal: Re-score stored VUS against a newer ClinVar release and surface those whose assertion has since become definitive.
Approach: Re-annotate the prior results with the current ClinVar under a distinct INFO tag, then select records that were Uncertain but now carry a pathogenic/benign assertion.
# Re-annotate against a newer ClinVar; find VUS that now carry a definitive assertion
bcftools annotate -a clinvar_latest.vcf.gz -c INFO/CLNSIG_NEW:=INFO/CLNSIG \
prior_results.vcf.gz -Oz -o reannotated.vcf.gz
bcftools view -i 'INFO/CLNSIG~"Uncertain" && (INFO/CLNSIG_NEW~"athogenic" || INFO/CLNSIG_NEW~"enign")' \
reannotated.vcf.gz -Oz -o reclassified.vcf.gz
| Symptom / mistake | Cause | Fix | |-------------------|-------|-----| | PVS1 fired on any stop_gained | Used SnpEff HIGH-impact bucket | Route through the Abou Tayoun tree: mechanism + NMD + MANE transcript | | PM2 applied at Moderate | Flat 2015 default | PM2_Supporting (ClinGen SVI 2020) | | Over-called pathogenic | Stacked SIFT+PolyPhen+REVEL | One calibrated predictor at its calibrated strength; the others are inside REVEL | | Adopted a 1-star ClinVar "Pathogenic" | Treated an assertion as evidence | 1-star is a lead; re-derive; carry CLNREVSTAT | | Benign called on global AF > 1% | Ignored grpmax + disease context | grpmax FAF vs disease max-credible AF (Whiffin) | | Common founder allele benignized | Global AF hid an ancestry-specific frequency | Use grpmax; presence in gnomAD != benign | | ACMG applied to a tumor variant | Wrong framework | Li 2017 tiers + Horak 2022 oncogenicity | | "Absent in gnomAD" across versions | v2 is GRCh37, v3/v4 GRCh38 | Liftover the variant; check site callability |
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.