All chapters
Variant Calling
intermediateVariant Calling Strategies
Germline vs Somatic Calling
🧬Germline (HaplotypeCaller)Single sample GVCF → joint genotyping → VQSR | Expected VAF 50% (het) or 100% (hom) | Rare disease, hereditary cancer
🎯Somatic (Mutect2)Tumour + Normal paired | Low VAF variants (1-50%) | Panel of normals | Oncology, cancer panels
🤖DeepVariant (ML)CNN on pileup images | >99.9% F1 on SNPs | Works on WES/WGS/FFPE | Alternative to GATK
GATK HaplotypeCaller - Best Practices
HaplotypeCaller uses a local de-novo assembly of the active region to call SNVs and indels simultaneously. Run in GVCF mode per sample, then joint-genotype across cohorts.
code
# Step 1: Per-sample GVCF gatk HaplotypeCaller \ -R hg38.fa \ -I recal.bam \ -O sample.g.vcf.gz \ -ERC GVCF \ -L intervals.interval_list \ --dbsnp dbsnp_138.hg38.vcf.gz # Step 2: Combine GVCFs (for cohort calling) gatk CombineGVCFs \ -R hg38.fa \ -V sample1.g.vcf.gz \ -V sample2.g.vcf.gz \ -O cohort.g.vcf.gz # Step 3: Joint genotyping gatk GenotypeGVCFs \ -R hg38.fa \ -V cohort.g.vcf.gz \ -O raw_variants.vcf.gz
Variant Filtration
VQSR (Variant Quality Score Recalibration) is ideal for large cohorts. For small cohorts/single samples, use hard filters.
code
# Hard filters (single sample / small cohort) # SNP filters gatk VariantFiltration \ -V raw_variants.vcf.gz \ --filter-expression "QD < 2.0" --filter-name "QD2" \ --filter-expression "FS > 60.0" --filter-name "FS60" \ --filter-expression "MQ < 40.0" --filter-name "MQ40" \ --filter-expression "MQRankSum < -12.5" --filter-name "MQRankSum-12.5" \ --filter-expression "ReadPosRankSum < -8.0" --filter-name "ReadPosRankSum-8" \ -O filtered_snps.vcf.gz # Indel filters gatk VariantFiltration \ --filter-expression "QD < 2.0" --filter-name "QD2" \ --filter-expression "FS > 200.0" --filter-name "FS200" \ --filter-expression "ReadPosRankSum < -20.0" --filter-name "ReadPosRankSum-20"
- QD (QualByDepth): variant quality normalised by depth; <2 = low confidence
- FS (FisherStrand): strand bias; >60 (SNP) or >200 (indel) = likely artifact
- MQ (RMSMappingQuality): mapping quality of supporting reads; <40 = poor alignment
- MQRankSum: comparison of MQ between alt and ref reads; large negative = artifact
- ReadPosRankSum: whether alt reads cluster at end of reads (artifact pattern)
DeepVariant (ML-based)
Google's DeepVariant uses a convolutional neural network trained on pileup images. Outperforms GATK on SNPs (F1 >99.9%) and is competitive on indels.
code
# Run with Docker (easiest) docker run \ -v /data:/data \ google/deepvariant:1.6.1 \ /opt/deepvariant/bin/run_deepvariant \ --model_type=WES \ --ref=/data/hg38.fa \ --reads=/data/sample.bam \ --regions=/data/capture.bed \ --output_vcf=/data/output.vcf.gz \ --num_shards=16