Site icon Ampersand Tutorials

Variant Calling Explained: How a BAM Becomes an Annotated VCF

Quick answer: Variant calling is the step that decides where a sample’s DNA differs from a reference and how much evidence supports each difference. The input is a coordinate-sorted, duplicate-marked BAM plus the same reference genome used for alignment; the output is a VCF, where each line is a claim about one position. Two tools cover most beginner work: GATK HaplotypeCaller for germline variants and bcftools mpileup for a lighter, scriptable alternative. The real craft is not running the caller but deciding which calls to believe, because an unfiltered VCF is a list of hypotheses, not results.

A companion to the bioinformatics file formats guide and the genome assembly guide: assembly builds the reference, alignment places the reads against it, and variant calling reads the differences.

The pipeline, in order

Variant calling is a short pipeline with three hard prerequisites, and skipping any of them produces calls you cannot trust:

From there the standard stages are:

# Minimal germline path (GATK 4.x style)
gatk MarkDuplicates -I aln.bam -O dedup.bam -M metrics.txt
samtools index dedup.bam

gatk HaplotypeCaller -R ref.fa -I dedup.bam -O sample.g.vcf.gz -ERC GVCF
gatk GenomicsDBImport --sample-name-map cohort.map --intervals chr1:1-250000000 \
    --genomicsdb-workspace-path db
gatk GenotypeGVCFs -R ref.fa -V gendb://db -O cohort.vcf.gz

# Hard filtering for a single sample
gatk VariantFiltration -R ref.fa -V cohort.vcf.gz -O filtered.vcf.gz \
    --filter-expression "QD < 2.0 || FS > 60.0 || MQ < 40.0" --filter-name "LowQual"

What the VCF actually says

Every VCF line is one variant with three kinds of information, and knowing which is which is most of the format:

The FILTER column is where honesty lives. PASS means the call survived your filters; anything else means it did not, and downstream tools ignore non-PASS records only if you tell them to. A pipeline that reports “12,000 variants” without stating the filter used has reported nothing.

Why unfiltered calls are mostly error

A raw caller emits a long tail of low-confidence records that come from sequencing error, mismapping in repetitive regions, paralogous reads collapsed together, and strand artefacts. Filters target exactly those signatures:

VQSR replaces thresholds with a trained classifier, but it needs a large, well-curated training cohort, and it is exactly the kind of step you should not use on three samples.

Germline, somatic, and structural variants are different problems

Beginners often assume one tool answers all variant questions. It does not:

QuestionTypical approachKey difference
Inherited (germline) SNVs and indelsHaplotypeCaller, DeepVariant, bcftoolsVariant is present in most cells; genotype is the output
Tumour (somatic) variantsMutect2 with a matched normalNeeds to subtract the patient’s own germline variants
Structural variants (large events)Manta, Delly, SnifflesCallers work on read pairs and split reads, not base-level pileups
Copy number changesCNVkit, GATK CNVOutput is segments with ratios, not alleles

The consequence is practical: a somatic study that runs a germline caller will report the patient’s normal variants as tumour variants, which is a catastrophic but very common mistake.

Validation is the part people skip

No variant call is proven by the caller that produced it. Confidence comes from comparison against a truth set and an orthogonal method:

If you cannot validate, the honest phrasing is “calls were filtered with X and are reported as candidate variants” — not “we identified 12,000 mutations”.

Annotation is the next pipeline

A VCF with coordinates answers where; annotation answers what. Functional annotation (with tools such as VEP, snpEff, or ANNOVAR) adds gene, transcript, consequence, and population frequency information, and it is what turns a coordinate list into a sentence a biologist can read.

# Merge, filter and annotate
bcftools mpileup -f ref.fa dedup.bam | \
  bcftools call -mv -Oz -o calls.vcf.gz
bcftools filter -s LowQual -e 'QUAL<20 || DP<10' calls.vcf.gz | \
  bcftools view -f PASS -Oz -o filtered.vcf.gz
tabix -p vcf filtered.vcf.gz

Two annotation cautions matter more than the tool choice. First, the reference transcript set determines the consequence, so the same variant can be missense under one annotation release and synonymous under another. Second, population frequency filters are only as good as the population in the database: a variant that looks common in a reference panel may be genuinely rare elsewhere.

Common failure modes

Key takeaways

Challenge

Download a small publicly available BAM with a matched reference, run both bcftools and GATK on one chromosome, and compare the call sets. Then pick three variants found by only one caller, open them in IGV, and work out what the reads actually show. That comparison teaches more about variant calling than any pipeline diagram, because it puts the disagreement where it belongs: in the evidence.

Working on a variant analysis for a project or dissertation? Ampersand Academy offers one-to-one mentoring in bioinformatics and NGS analysis — part of Mahadhi, a development and digital marketing company.

FAQ

What is variant calling in simple terms?

Variant calling compares aligned sequencing reads against a reference genome and reports the positions where the sample differs, together with the evidence supporting each difference. The result is written as a VCF file.

What do I need before running a variant caller?

A coordinate-sorted BAM with duplicates marked, read groups present, and a reference genome that is exactly the same version and contig naming as the one used for alignment.

Which is better, GATK or bcftools?

GATK HaplotypeCaller is the standard for germline human work and handles local haplotype assembly well, while bcftools mpileup is lighter, easier to script, and excellent for bacteria and small panels. Many labs use both and compare.

Why are my VCF calls different from a published study on the same sample?

Differences come from the reference build, alignment settings, caller choice, filter thresholds, and transcript set used for annotation. The method details, not the caller alone, explain most disagreements.

Should I use VQSR or hard filters?

VQSR needs a large, well-curated training cohort to work properly, so it suits large human cohorts. For single samples or non-model organisms, hard filters with organism-appropriate thresholds are the safer choice.

How do I know if a variant call is real?

Check that the alternate allele appears in the reads at that position in a genome browser, that the site passes your filters, and ideally that an independent tool or assay agrees. Benchmarking against a truth set such as GIAB gives you precision and recall rather than a hunch.

What does the FILTER column in a VCF mean?

It records the outcome of your filtering rules. PASS means the record survived; any other value names the filter it failed, and the record should be excluded unless you have a specific reason to keep it.

Exit mobile version