Skip to content

How to Classify Your Own Variants with the ACMG/AMP Criteria

Oak
A feathered dinosaur-like creature on a black plinth, its plumage graded in five color bands, beside single feathers mounted on glass slides.

By the end of this you will have a table with one row per coding variant in your genome. Each row carries its ACMG/AMP evidence codes, an automated five-tier classification, and the annotations that drove each code. The codes include PVS1, PS1, PM2 and PP3. They also include BA1, BS1, BP4, and so on. The tiers are pathogenic, likely pathogenic, uncertain significance, likely benign and benign. The annotations are gnomAD popmax allele frequency, ClinVar assertions with review status, transcript-level consequence, splice predictions, and a missense meta-predictor score. You will also have a shortlist, usually between five and fifty variants out of four to five million, worth manual curation. You need a germline VCF or gVCF aligned to GRCh38, from WGS at 30x or better or from an exome. You also need 60-100 GB of free disk, roughly 32 GB RAM for VEP with a local cache, and a Linux box. Everything below is open-source and runs offline once the databases are downloaded, which matters because you are about to send your genome through it. Nothing here is a diagnosis. An automated classification is a hypothesis about evidence. It is not a clinical result. Anything you would act on needs orthogonal confirmation in an accredited laboratory and interpretation by a clinical geneticist or genetic counselor.

1. Get your VCF into a canonical, normalized form

Classification tools are unforgiving about representation. The same deletion written as a left-aligned two-base event or a right-aligned three-base event will hit or miss a ClinVar record depending on alignment. Normalize first.

# split multiallelics, left-align and trim against the reference
bcftools norm -m -any -f GRCh38.primary_assembly.genome.fa \
  -c w -Oz -o me.norm.vcf.gz me.raw.vcf.gz
bcftools index -t me.norm.vcf.gz

# drop non-PASS and low-depth calls before annotation
bcftools view -f PASS -i 'FORMAT/DP>=10 & FORMAT/GQ>=20' \
  -Oz -o me.pass.vcf.gz me.norm.vcf.gz
bcftools index -t me.pass.vcf.gz

Check your contig naming (chr1 vs 1) against every database you plan to use and fix it once with bcftools annotate --rename-chrs. Mixed conventions are the single most common reason a pipeline silently annotates nothing.

If you only have a gVCF, genotype it first (gatk GenotypeGVCFs) rather than trying to feed reference blocks to an annotator. If your data came from a consumer array rather than sequencing, stop here for the pathogenic side of the work: arrays genotype selected positions and cannot support absence-of-variant reasoning, and imputed calls at rare sites are unreliable in exactly the frequency range where ACMG criteria care most.

2. Annotate with VEP, picking transcripts deliberately

Consequence assignment is where classification is decided in practice. PVS1 (null variant in a gene where loss of function is a known mechanism) depends entirely on which transcript you call canonical and whether the variant lands before the last exon.

vep --offline --cache --dir_cache $VEP_CACHE \
  --assembly GRCh38 --species homo_sapiens \
  --fasta GRCh38.primary_assembly.genome.fa \
  --input_file me.pass.vcf.gz --format vcf \
  --vcf --compress_output bgzip --output_file me.vep.vcf.gz \
  --everything --hgvsg --shift_hgvs 1 \
  --mane_select --canonical --symbol --numbers --domains \
  --af_gnomade --af_gnomadg --max_af \
  --plugin SpliceAI,snv=spliceai_scores.raw.snv.hg38.vcf.gz,indel=spliceai_scores.raw.indel.hg38.vcf.gz \
  --plugin AlphMissense,file=AlphaMissense_hg38.tsv.gz \
  --plugin REVEL,file=new_tabbed_revel_grch38.tsv.gz \
  --plugin LoFtool --plugin NMD \
  --custom clinvar_20250xx.vcf.gz,ClinVar,vcf,exact,0,CLNSIG,CLNREVSTAT,CLNDN,CLNHGVS \
  --fork 8 --buffer_size 20000

Two decisions to make explicitly. First, use --mane_select as your primary transcript rather than VEP’s --pick heuristic. MANE Select transcripts are the ones ClinVar submitters and ClinGen expert panels increasingly report against, so your coordinates will line up with theirs. Keep all consequences in the output and filter later: a variant that is intronic on MANE Select and missense on a tissue-specific transcript is worth seeing. Second, keep --shift_hgvs 1 on so your HGVS strings match ClinVar’s 3’-shifted convention for indels in repeats.

The in silico predictors here feed PP3 and BP4, and they are not interchangeable. Meta-predictors trained on ClinVar labels inherit circularity: a variant used in training will look confidently predicted no matter what the model learned. Reviews of in silico predictor performance are clear that these tools stratify risk usefully at the population level but that single-variant confidence is limited, which is why PP3 is a supporting-strength code rather than strong.1 Use SpliceAI delta scores for splice-region reasoning and AlphaMissense or REVEL for missense. Record the raw score in your table. The pass/fail flag alone is not enough.

3. Run automated ACMG/AMP classification

InterVar is the reference implementation of automated ACMG/AMP coding, and it remains the tool most papers benchmark against. It runs 18 of the 28 criteria automatically and leaves the rest for you.

python InterVar.py \
  -b hg38 -i me.pass.vcf.gz --input_type=VCF \
  -o me.intervar \
  -t intervardb \
  --table_annovar=/opt/annovar/table_annovar.pl \
  --convert2annovar=/opt/annovar/convert2annovar.pl \
  --annotate_variation=/opt/annovar/annotate_variation.pl \
  --database_locat=/data/annovar/humandb \
  --skip_annovar=F

The output is a TSV with one row per variant and a column per criterion. Read the InterVar column as a starting point. It is not an answer. The evidence columns are the useful part.

A second opinion is worth the hour. Run one of the newer classifiers alongside InterVar and diff the calls. MAGI-ACMG implements ACMG plus the ACGS refinements with explicit frequency thresholds per inheritance model, which makes its BA1/BS1 behavior easier to audit than InterVar’s.2 AAVC reports higher agreement with expert panels by automating more criteria and pulling in structured functional evidence.3 A systematic comparison of these tools found meaningful disagreement between them on the same variant sets, concentrated in the criteria that require gene-specific or clinical context.4 Where two tools disagree, you have found a variant that needs manual curation. That disagreement is the signal. It is not noise.

# join InterVar output onto your VEP table on chrom/pos/ref/alt
bcftools +split-vep -f '%CHROM\t%POS\t%REF\t%ALT\t%SYMBOL\t%Consequence\t%HGVSc\t%HGVSp\t%MAX_AF\t%gnomADg_AF\t%ClinVar_CLNSIG\t%ClinVar_CLNREVSTAT\t%SpliceAI_pred_DS_AG\t%SpliceAI_pred_DS_AL\t%SpliceAI_pred_DS_DG\t%SpliceAI_pred_DS_DL\t%am_pathogenicity\t%REVEL\n' \
  -d -s worst me.vep.vcf.gz > me.vep.tsv

4. Apply the frequency filters that do most of the work

Most of your four million variants are removed by allele frequency, and this is legitimate ACMG reasoning. It is not a shortcut. BA1 is a standalone benign criterion: allele frequency above 5% in a large population database classifies the variant benign on its own. The ClinGen Sequence Variant Interpretation working group has published gene-specific BA1/BS1 thresholds for many genes, and where those exist they override the generic 5%.

import pandas as pd
df = pd.read_csv("me.vep.tsv", sep="\t", na_values=[".", ""])

# BA1: standalone benign
ba1 = df["MAX_AF"].fillna(0) >= 0.05

# PM2_supporting: absent or ultra-rare in gnomAD. Note the downgrade:
# PM2 was moved from moderate to supporting strength by ClinGen SVI.
pm2 = df["gnomADg_AF"].fillna(0) < 1e-5

candidates = df[~ba1 & (
    df["Consequence"].str.contains(
        "frameshift|stop_gained|start_lost|splice_acceptor|splice_donor|missense|inframe",
        na=False)
)]

Recognize the arithmetic you are working with. Any two human genomes differ at roughly one site in a thousand across the genome, so a 30x WGS yields four to five million variant calls, and effectively all of them are common polymorphism or private neutral variation.5 The interpretive problem is that rare variants are individually uninformative. Finding variants is not the hard part. A healthy person carries on the order of a hundred loss-of-function variants, and statistical association from a single genome is impossible. Interpretation therefore leans on prior knowledge rather than your own data.6 Population-scale sequencing studies repeatedly show that the number of rare, never-before-seen variants per genome is large enough that “rare and predicted damaging” is a weak filter on its own.6

5. Reconcile against ClinVar, weighting by review status

ClinVar is the highest-yield single annotation, and the review status field is as important as the significance field. Treat the tiers differently:

  • Practice guideline or reviewed by expert panel (three or four stars): the classification came from a ClinGen variant curation expert panel applying gene-specific criteria. Accept it over your automated call.
  • Criteria provided, multiple submitters, no conflicts (two stars): strong. Reasonable to accept.
  • Single submitter (one star): read the submitted evidence summary as well as the label. The label alone is not enough. Many single-submitter pathogenic calls predate current frequency data.
  • No assertion criteria provided (zero stars): treat it as annotation. It is not evidence.
tiers = {
 "practice guideline": 4, "reviewed by expert panel": 3,
 "criteria provided, multiple submitters, no conflicts": 2,
 "criteria provided, single submitter": 1,
 "criteria provided, conflicting classifications": 1,
}
candidates = candidates.assign(
    stars=candidates["ClinVar_CLNREVSTAT"]
      .str.replace("_", " ").map(tiers).fillna(0)
)
shortlist = candidates[
    candidates["ClinVar_CLNSIG"].str.contains("athogenic", na=False)
    | ((candidates["stars"] < 2) & (candidates["gnomADg_AF"].fillna(0) < 1e-4))
]

Two criteria people ask about and get wrong. PS1 applies when a different nucleotide change produces the same amino acid change as a variant already established as pathogenic, and it requires that you confirm the splicing consequence is not different. PM5 is the neighbor case: a novel missense change at a residue where a different missense change has been established as pathogenic. PM5 is moderate strength, weaker than PS1, and it is the criterion most often over-applied. The known pathogenic variant at that residue has to be genuinely established, meaning a two-star-or-better ClinVar assertion or an expert panel call, and you have to check that the mechanism plausibly transfers. A different substitution at the same position can be tolerated where the pathogenic one was not.

6. Curate the shortlist manually in the ClinGen Variant Curation Interface

At this point you have tens of variants, and automation stops paying. Move them into the ClinGen Variant Curation Interface, which implements the ACMG/AMP criteria as a structured evidence-entry workflow, pulls in population, computational, and literature evidence per variant, and records your rationale for each code you apply or reject.7 This is the same platform expert panels use, so your curation is comparable to theirs and revisable when evidence changes.

Work in this order per variant, and write down why for each code:

  1. Is the gene relevant to any phenotype at all, and is the mechanism loss of function, gain of function, or dominant negative? PVS1 requires a gene where LOF is established. A truncating variant in a gain-of-function gene gets no PVS1. Check the ClinGen gene-disease validity classification first.
  2. If truncating: which exon, and what fraction of the protein is removed? Does NMD apply, and is the last exon involved? The ClinGen SVI PVS1 decision tree walks this and will often downgrade PVS1 to strong, moderate, or supporting. Gene-specific implementations exist and matter: automated classification for hearing loss genes required encoding gene-specific PVS1 and PM2 rules rather than generic ones to match expert calls.8
  3. Population: BA1, BS1, PM2 at the gene-specific threshold if one is published.
  4. Computational: PP3/BP4 at one supporting point, using a calibrated score cutoff for the specific predictor you used.
  5. Literature and functional: PS3/BS3 need functional assays with established validity, which is the evidence type least amenable to automation and the reason automated and expert classifications diverge.4
  6. Segregation and de novo (PP1, PS2, PM6) need family data. Without relatives sequenced, these are unavailable to you, and that missing evidence is often the difference between likely pathogenic and uncertain significance.

Note that the criteria have a history and they will move again. The 2007 ACMG recommendations used a six-tier scheme with different vocabulary before the 2015 guideline established the five-tier structure and the coded evidence framework everyone now uses.9 Record which criteria version you applied. A classification without a date and a guideline version is not reproducible.

Common problems

Every classification comes back uncertain. This is the normal result. It is not a pipeline bug. VUS is the modal outcome for rare missense variants, and the response is to leave them unclassified rather than push them either way. Reclassification happens as population databases and ClinVar grow, so re-run your shortlist annually rather than treating the answer as final.

Your automated caller says pathogenic and ClinVar’s expert panel says benign. The expert panel wins. Gene-specific criteria specifications adjust thresholds and strengths in ways generic tools cannot know, and benchmark comparisons show generic tools over-call pathogenicity relative to expert panels in exactly these genes.4

PVS1 fires on a variant in the last exon. Generic implementations often miss the NMD-escape logic. Check the exon number and the distance to the stop codon, and downgrade the strength.

Nothing matched ClinVar. Usually contig naming or an unnormalized indel. Re-check with bcftools norm --check-ref e and confirm your ClinVar VCF uses the same chromosome prefix.

Short-read WGS missed the variant class that matters. Repeat expansions, segmental duplications (including parts of PMS2, SMN1, and the HLA region), and structural variants larger than about 50 bp are poorly covered by 30x short reads. A clean negative from this pipeline is not a clean negative for those regions, and the practical limits of short-read genome interpretation are well documented.10

You want to act on something. Research-grade sequencing is not clinical sequencing. Confirmatory testing in an accredited laboratory and interpretation with a clinical geneticist or genetic counselor is the required next step, and pharmacogenomic or risk-related findings in particular should not change anything you take without a clinician.

Footnotes

  1. Panagiotis Katsonis, Kevin Wilhelm, Amanda Williams, et al. Genome interpretation using in silico predictors of variant impact. Human Genetics, 2022. https://doi.org/10.1007/s00439-022-02457-6 ↩

  2. Francesca Cristofoli, Muharrem Daja, Paolo Enrico Maltese, et al. MAGI-ACMG: Algorithm for the Classification of Variants According to ACMG and ACGS Recommendations. Genes, 2023. https://doi.org/10.3390/genes14081600 ↩

  3. R. Arda İnan, Barış Kayaalp, Fatimah Safieh, et al. AAVC: An automated framework for high-accuracy ACMG-based variant classification. Genetics in Medicine, 2026. https://doi.org/10.1016/j.gim.2026.102624 ↩

  4. Tohid Ghasemnejad, Yuheng Liang, Khadijeh Hoda Jahanian, et al. Comprehensive evaluation of ACMG/AMP-based variant classification tools. Bioinformatics, 2026. https://doi.org/10.1093/bioinformatics/btaf623 ↩ ↩2 ↩3

  5. Tuuli Lappalainen, Alexandra J. Scott, Margot Brandt, et al. Genomic Analysis in the Age of Human Genome Sequencing. Cell, 2019. https://doi.org/10.1016/j.cell.2019.02.032 ↩

  6. David B. Goldstein, Andrew Allen, Jonathan Keebler, et al. Sequencing studies in human genetics: design and interpretation. Nature Reviews Genetics, 2013. https://doi.org/10.1038/nrg3455 ↩ ↩2

  7. Christine G. Preston, Matt W. Wright, Rao Madhavrao, et al. ClinGen Variant Curation Interface: A Variant Classification Platform for the Application of Evidence Criteria from ACMG/AMP Guidelines. 2021. https://doi.org/10.1101/2021.02.12.21251663 ↩

  8. Damianos P. Melidis, Christian Landgraf, Gunnar Schmidt, et al. GenOtoScope: Towards automating ACMG classification of variants associated with congenital hearing loss. PLOS Computational Biology, 2022. https://doi.org/10.1371/journal.pcbi.1009785 ↩

  9. C. Sue Richards, Sherri Bale, Daniel B. Bellissimo, et al. ACMG recommendations for standards for interpretation and reporting of sequence variations: Revisions 2007. Genetics in Medicine, 2008. https://doi.org/10.1097/gim.0b013e31816b5cae ↩

  10. Hubert E Blum, Konrad Oexle. Clinical Interpretation and Implications of Whole Genome Sequencing. Journal of Next Generation Sequencing & Applications, 2014. https://doi.org/10.4172/2469-9853.1000105 ↩

Oak builds longitudinal molecular profiles of individuals: whole-genome sequencing, blood RNA sequencing, and plasma proteomics, delivered as a detailed report plus every data file. Build your profile.