π§ Variant Calling Fundamentals
π― What is Variant Calling?
Variant calling is the process of identifying differences between a sample genome and a reference genome. It detects SNPs, indels, and structural variants from aligned sequencing reads, producing a VCF file for downstream analysis. It's a cornerstone of clinical genomics, population genetics, and cancer research.
Why Variant Calling Matters
Clinical: Disease diagnosis. Cancer: Somatic mutations. Population: Diversity. Pharmacogenomics: Drug response. Agriculture: Crop traits. Evolution: Adaptation.
# Variant Calling β the big picture
# Identifying differences from a reference genome.
# CONCEPTUAL OVERVIEW
print("""
=== Variant Calling ===
What it is:
- Compare sample to reference
- Identify SNPs, indels, SVs
- Produce VCF file
- Annotate variants
Why it's hard:
- Sequencing errors
- Mapping errors
- Low coverage
- Repeats
- Heterozygosity
- Somatic mosaicism
Types of calling:
- Germline: Inherited variants
- Somatic: Acquired (cancer)
- De novo: New mutations
- Population: Many samples
Steps:
1. Quality control (QC)
2. Alignment (BWA, Bowtie2)
3. Preprocessing (mark duplicates, BQSR)
4. Variant calling (GATK, FreeBayes)
5. Filtering (VQSR, hard filters)
6. Annotation (VEP, SnpEff)
7. Interpretation
Applications:
- Clinical diagnosis
- Cancer genomics
- Population genetics
- Pharmacogenomics
- Agriculture
- Evolutionary biology
""")
# WHY IT MATTERS
print("=== Why It Matters ===")
print("""
Biological questions:
- What variants does this sample have?
- Are they pathogenic?
- What is the population frequency?
- Are they somatic or germline?
- What is the functional impact?
Variant calling answers:
- List of variants
- Genotypes
- Quality scores
- Functional annotations
- Clinical significance
""")
# HISTORICAL CONTEXT
print("=== Historical Context ===")
print("""
2000s: Sanger sequencing, capillary
2005: NGS (454, Illumina)
2009: GATK (Broad Institute)
2010: FreeBayes, SAMtools
2011: VCF format (1000 Genomes)
2013: GATK HaplotypeCaller
2015: Mutect2
2016: DeepVariant (Google)
2020s: Long-read calling, pangenomes
""")
# CHALLENGES
print("=== Challenges ===")
print("""
1. SEQUENCING ERRORS
- False positives
- Need high coverage
2. MAPPING ERRORS
- Repeats
- Structural variants
- Need better aligners
3. LOW COVERAGE
- Missing variants
- Allele dropout
4. HETEROZYGOSITY
- Diploid genomes
- Phasing
5. SOMATIC MOSAICISM
- Low allele fraction
- Need deep coverage
6. STRUCTURAL VARIANTS
- Hard to detect
- Need long reads
""")π― Why Variant Calling Matters
π― The Value of Variant Calling
Variant calling is the bridge between sequencing data and biological insight. It's used in virtually every area of genomics.
Biological Insights
Clinical: Diagnosis. Cancer: Somatic. Population: Diversity. Pharma: Drug. Agri: Traits. Evolution: Adaptation.
# Why Variant Calling Matters
print("=== 1. Clinical Genomics ===")
print("""
Clinical:
- Rare disease diagnosis
- Hereditary cancer
- Pharmacogenomics
- Prenatal testing
Examples:
- BRCA1/2 (breast cancer)
- CFTR (cystic fibrosis)
- CYP2D6 (drug metabolism)
- HLA typing
Workflow:
1. Patient DNA
2. Sequencing
3. Variant calling
4. Annotation
5. Clinical report
Tools:
- GATK
- VEP
- ClinVar
- ACMG guidelines
""")
print("\n=== 2. Cancer Genomics ===")
print("""
Cancer:
- Somatic mutations
- Driver mutations
- Tumor heterogeneity
- Treatment selection
Examples:
- EGFR (lung cancer)
- BRAF (melanoma)
- KRAS (colorectal)
- PIK3CA (breast)
Workflow:
1. Tumor + normal
2. Sequencing
3. Somatic calling (Mutect2)
4. Filtering
5. Annotation
6. Report
Tools:
- Mutect2
- Strelka2
- VarScan2
- FACETS
""")
print("\n=== 3. Population Genetics ===")
print("""
Population:
- Diversity
- GWAS
- Selection
- Migration
Examples:
- 1000 Genomes
- gnomAD
- UK Biobank
- HGDP
Workflow:
1. Many samples
2. Joint calling
3. Filtering
4. Analysis
Tools:
- GATK
- bcftools
- PLINK
- VCFtools
""")
print("\n=== 4. Pharmacogenomics ===")
print("""
Pharmacogenomics:
- Drug response
- Adverse reactions
- Dosing
Examples:
- CYP2D6
- CYP2C19
- TPMT
- DPYD
Workflow:
1. Genotype
2. Star alleles
3. Diplotype
4. Phenotype
5. Recommendation
Tools:
- PharmGKB
- CPIC
- Stargazer
- Aldy
""")
print("\n=== 5. Agriculture ===")
print("""
Agriculture:
- Crop traits
- Breeding
- Selection
- Yield
Examples:
- Rice
- Maize
- Wheat
- Tomato
Workflow:
1. Genotype
2. GWAS
3. Marker-assisted selection
4. Breeding
Tools:
- GATK
- TASSEL
- PLINK
""")
print("\n=== 6. Evolutionary Biology ===")
print("""
Evolution:
- Adaptation
- Speciation
- Phylogenetics
- Ancient DNA
Examples:
- Darwin's finches
- Human evolution
- Neanderthal
- Ancient DNA
Workflow:
1. Sequence
2. Variant calling
3. Comparative
4. Analysis
Tools:
- GATK
- bcftools
- PAML
""")
print("\n=== 7. Metagenomics ===")
print("""
Metagenomics:
- Strain variation
- Community
- Antibiotic resistance
Examples:
- Gut microbiome
- Environmental
- Clinical infections
Workflow:
1. Metagenome assembly
2. Binning
3. Variant calling
4. Analysis
Tools:
- metaSNV
- inStrain
- StrainPhlAn
""")
print("\n=== 8. Forensic Genetics ===")
print("""
Forensic:
- Identification
- Paternity
- Ancestry
Examples:
- CODIS
- SNP panels
- mtDNA
Workflow:
1. Sample
2. Sequencing
3. Variant calling
4. Comparison
Tools:
- GATK
- ForenSeq
""")𧬠Variant Types
π― What Variants Exist?
Variants come in many sizes and types: SNPs, indels, structural variants, copy number variants, and more.
Variant Types
SNP: Single base. Indel: Insertion/deletion. MNP: Multiple bases. SV: Large. CNV: Copy number. STR: Repeat.
# Variant Types
print("=== 1. SNP (Single Nucleotide Polymorphism) ===")
print("""
SNP:
- Single base change
- Most common
- ~1 per 1000 bp
Example:
Reference: A C G T
Sample: A C A T
^
SNP: G>A
Types:
- Transition: PurineβPurine (AβG), PyrimidineβPyrimidine (CβT)
- Transversion: PurineβPyrimidine
Tools:
- GATK
- FreeBayes
- bcftools
""")
print("\n=== 2. Indel (Insertion/Deletion) ===")
print("""
Indel:
- Insertion or deletion
- 1-50 bp (short)
- > 50 bp = SV
Example (insertion):
Reference: A C G T
Sample: A C T G T
^
Insertion: T
Example (deletion):
Reference: A C G T
Sample: A C T
^
Deletion: G
Tools:
- GATK
- FreeBayes
- bcftools
""")
print("\n=== 3. MNP (Multi-Nucleotide Polymorphism) ===")
print("""
MNP:
- Multiple adjacent SNPs
- Often treated as separate
Example:
Reference: A C G T
Sample: A T A T
^ ^
MNP: CG>TA
""")
print("\n=== 4. Structural Variants (SV) ===")
print("""
SV:
- Large variants (> 50 bp)
- Deletions, duplications
- Inversions, translocations
Types:
- DEL: Deletion
- DUP: Duplication
- INV: Inversion
- TRA: Translocation
- INS: Insertion
Tools:
- Delly
- Manta
- Lumpy
- Sniffles (long reads)
""")
print("\n=== 5. Copy Number Variants (CNV) ===")
print("""
CNV:
- Copy number change
- Deletions, duplications
- Large segments
Example:
Reference: 2 copies
Sample: 1 copy (deletion)
3 copies (duplication)
Tools:
- CNVnator
- CNVkit
- Control-FREEC
- GATK gCNV
""")
print("\n=== 6. Short Tandem Repeats (STR) ===")
print("""
STR:
- Repeated 2-6 bp
- Length variation
- Forensics, disease
Example:
Reference: (CAG)10
Sample: (CAG)15
Diseases:
- Huntington's
- Fragile X
- Myotonic dystrophy
Tools:
- ExpansionHunter
- GangSTR
- lobSTR
""")
print("\n=== 7. Mitochondrial Variants ===")
print("""
mtDNA:
- Circular genome
- High copy number
- Heteroplasmy
Types:
- SNPs
- Indels
- Large deletions
Tools:
- mtDNA-Server
- Mutserve
- GATK (mtDNA mode)
""")
print("\n=== 8. Somatic Variants ===")
print("""
Somatic:
- Acquired mutations
- Cancer
- Mosaicism
Types:
- SNVs
- Indels
- SVs
- CNVs
Tools:
- Mutect2
- Strelka2
- VarScan2
- FACETS
""")
print("\n=== Comparison ===")
print(f"{'Variant':<20} {'Size':<20} {'Frequency':<15} {'Tools':<25}")
print("-" * 80)
print(f"{'SNP':<20} {'1 bp':<20} {'~1/1000':<15} {'GATK':<25}")
print(f"{'Indel':<20} {'1-50 bp':<20} {'~1/10k':<15} {'GATK':<25}")
print(f"{'MNP':<20} {'2-10 bp':<20} {'Rare':<15} {'GATK':<25}")
print(f"{'SV':<20} {'> 50 bp':<20} {'~1/100':<15} {'Delly':<25}")
print(f"{'CNV':<20} {'> 1 kb':<20} {'~1/100':<15} {'CNVkit':<25}")
print(f"{'STR':<20} {'2-6 bp units':<20} {'Variable':<15} {'ExpansionHunter':<25}")πͺ Germline Calling
π― Inherited Variants
Germline variant calling identifies variants present in all cells, inherited from parents. It's the most common type of variant calling.
Germline
Inherited: All cells. Diploid: Two alleles. Genotype: 0/0, 0/1, 1/1. GATK: Gold standard. VQSR: Filtering. Joint: Many samples.
# Germline Variant Calling
print("=== Workflow ===")
print("""
1. QUALITY CONTROL
- FastQC
- Trimmomatic / fastp
- Remove adapters
2. ALIGNMENT
- BWA-MEM
- Bowtie2
- Minimap2 (long reads)
3. PREPROCESSING
- Mark duplicates (Picard)
- Sort (samtools)
- BQSR (GATK)
4. VARIANT CALLING
- GATK HaplotypeCaller
- FreeBayes
- bcftools
5. FILTERING
- VQSR (GATK)
- Hard filters
- bcftools filter
6. ANNOTATION
- VEP
- SnpEff
- ANNOVAR
""")
print("\n=== GATK HaplotypeCaller ===")
print("""
HaplotypeCaller:
- Local de novo assembly
- Haplotype-based
- Most accurate
- Gold standard
Steps:
1. Active regions
2. Local assembly
3. Haplotype calling
4. Genotyping
Command:
gatk HaplotypeCaller \
-R reference.fasta \
-I sample.bam \
-O sample.g.vcf.gz \
-ERC GVCF
Joint calling:
gatk GenomicsDBImport \
-V sample1.g.vcf.gz \
-V sample2.g.vcf.gz \
--genomicsdb-workspace-path db
gatk GenotypeGVCFs \
-R reference.fasta \
-V gendb://db \
-O cohort.vcf.gz
""")
print("\n=== FreeBayes ===")
print("""
FreeBayes:
- Bayesian
- Haplotype-based
- Flexible
- Good for non-diploid
Command:
freebayes -f reference.fasta sample.bam > variants.vcf
Options:
-p 2 (ploidy)
-C 2 (min alt count)
-q 20 (min base quality)
-m 30 (min mapping quality)
""")
print("\n=== bcftools ===")
print("""
bcftools:
- Fast
- Simple
- Part of samtools
Command:
bcftools mpileup -f reference.fasta sample.bam | \
bcftools call -mv -Oz -o variants.vcf.gz
Options:
-m (multiallelic)
-v (variants only)
-Oz (compressed VCF)
""")
print("\n=== Filtering ===")
print("""
VQSR (Variant Quality Score Recalibration):
- Machine learning
- Needs many variants
- GATK
Hard filters:
- QD < 2
- FS > 60
- MQ < 40
- ReadPosRankSum < -8
bcftools filter:
bcftools filter -s LowQual -e '%QUAL<20' variants.vcf
""")
print("\n=== Best Practices ===")
print("""
1. High coverage (30x+)
2. Good reference
3. BQSR
4. VQSR or hard filters
5. Validate with truth set
6. Check Ti/Tv ratio
7. Check het/hom ratio
""")π¦ Somatic Calling
π― Acquired Mutations
Somatic variant calling identifies mutations acquired during life, such as in cancer. It requires tumor-normal paired samples and special filters.
Somatic
Acquired: Some cells. Tumor: Cancer. VAF: Allele fraction. Tumor-normal: Paired. Mutect2: Gold standard. Filter: Artifacts.
# Somatic Variant Calling
print("=== Workflow ===")
print("""
1. TUMOR + NORMAL
- Paired samples
- Same individual
2. ALIGNMENT
- BWA-MEM
- Mark duplicates
3. SOMATIC CALLING
- Mutect2
- Strelka2
- VarScan2
4. FILTERING
- FilterMutectCalls
- Panel of normals
- Germline resource
5. ANNOTATION
- VEP
- Oncotator
- CIViC
""")
print("\n=== Mutect2 ===")
print("""
Mutect2:
- GATK somatic caller
- Tumor-normal
- Tumor-only mode
- Gold standard
Command (tumor-normal):
gatk Mutect2 \
-R reference.fasta \
-I tumor.bam \
-I normal.bam \
-normal normal_sample \
-O somatic.vcf.gz
Filtering:
gatk FilterMutectCalls \
-R reference.fasta \
-V somatic.vcf.gz \
-O somatic.filtered.vcf.gz
""")
print("\n=== Strelka2 ===")
print("""
Strelka2:
- Fast
- Accurate
- Somatic + germline
Command:
configureStrelkaSomaticWorkflow.py \
--tumor tumor.bam \
--normal normal.bam \
--reference reference.fasta \
--runDir strelka_run
./strelka_run/runWorkflow.py -m local -j 8
""")
print("\n=== VAF (Variant Allele Fraction) ===")
print("""
VAF:
- Fraction of reads with variant
- Tumor purity affects
- Clonal vs subclonal
Example:
Tumor: 100 reads, 30 alt β VAF = 0.30
Normal: 100 reads, 0 alt β VAF = 0.00
β Somatic variant
Interpretation:
- VAF ~ 0.5: Heterozygous (germline)
- VAF ~ 0.25: Subclonal
- VAF ~ 0.1: Low fraction
""")
print("\n=== Tumor Purity & Ploidy ===")
print("""
Purity:
- Fraction of tumor cells
- Affects VAF
Ploidy:
- Copy number
- Affects VAF
Tools:
- FACETS
- PurBayes
- ABSOLUTE
- PureCN
""")
print("\n=== Filtering ===")
print("""
Artifacts:
- Oxidative damage (8-oxoG)
- FFPE artifacts
- Mapping errors
- Strand bias
Filters:
- Panel of normals (PoN)
- Germline resource (gnomAD)
- Orientation bias
- Read position
- Fragment length
Tools:
- FilterMutectCalls
- GATK
""")
print("\n=== Best Practices ===")
print("""
1. High coverage (100x+ tumor)
2. Matched normal
3. Panel of normals
4. Germline resource
5. Multiple callers
6. Validate with orthogonal
7. Check VAF distribution
""")ποΈ Structural Variants
π― Large-Scale Variation
Structural variants (SVs) are large changes (> 50 bp): deletions, duplications, inversions, and translocations. They're harder to detect but often impactful.
SVs
Large: > 50 bp. Types: DEL, DUP, INV, TRA. Short reads: Hard. Long reads: Better. Delly: Popular. Manta: Accurate.
# Structural Variants
print("=== SV Types ===")
print("""
1. DELETION (DEL)
- Loss of segment
- Most common SV
2. DUPLICATION (DUP)
- Gain of segment
- Tandem or dispersed
3. INVERSION (INV)
- Reversed segment
- Balanced
4. TRANSLOCATION (TRA)
- Inter-chromosomal
- Balanced or unbalanced
5. INSERTION (INS)
- Novel sequence
- Transposons
6. COMPLEX
- Multiple events
""")
print("\n=== Detection Methods ===")
print("""
1. Read pair (RP)
- Discordant pairs
- Distance/orientation
2. Split read (SR)
- Split alignment
- Precise breakpoints
3. Read depth (RD)
- Coverage changes
- CNV detection
4. Assembly
- Local assembly
- De novo
5. Long reads
- Direct detection
- Best for SVs
""")
print("\n=== Tools ===")
print("""
1. Delly
- Read pair + split read
- Germline + somatic
- Fast
2. Manta
- Read pair + split read
- Accurate
- Somatic
3. Lumpy
- Read pair + split read
- Flexible
4. Sniffles
- Long reads
- Nanopore + PacBio
5. cuteSV
- Long reads
- Fast
6. SVIM
- Long reads
- Accurate
""")
print("\n=== Delly ===")
print("""
Delly:
- Discovery + genotyping
- Germline + somatic
Command:
delly call -g reference.fasta sample.bam > sv.bcf
delly merge -o merged.bcf sample1.bcf sample2.bcf
Options:
-q 20 (min map quality)
-s 15 (min cluster size)
""")
print("\n=== Manta ===")
print("""
Manta:
- Somatic + germline
- Fast
- Accurate
Command:
configManta.py \
--tumorBam tumor.bam \
--normalBam normal.bam \
--referenceFasta reference.fasta \
--runDir manta_run
./manta_run/runWorkflow.py -j 8
""")
print("\n=== Sniffles ===")
print("""
Sniffles:
- Long reads
- Nanopore + PacBio
Command:
sniffles -i sorted.bam -v variants.vcf
Options:
--minsupport 3
--minsvlen 50
""")
print("\n=== Best Practices ===")
print("""
1. Use multiple callers
2. Combine short + long
3. High coverage
4. Validate with orthogonal
5. Check breakpoints
6. Annotate with genes
7. Use for clinical
""")π VCF Format
π― The Standard Variant Format
VCF (Variant Call Format) is the standard text format for storing variants. It's used by all major variant tools.
VCF
Header: Metadata. Columns: CHROM, POS, ID, REF, ALT. QUAL: Quality. FILTER: Pass/fail. INFO: Annotations. FORMAT: Genotypes.
# VCF Format
print("=== VCF Structure ===")
print("""
##fileformat=VCFv4.2
##fileDate=20250125
##reference=GRCh38.fasta
##contig=
##INFO=
##INFO=
##FORMAT=
##FORMAT=
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT SAMPLE1
chr1 1000 . A G 50.0 PASS DP=30;AF=0.5 GT:DP 0/1:30
chr1 2000 . C T 60.0 PASS DP=40;AF=0.25 GT:DP 0/1:40
""")
print("\n=== Columns ===")
print("""
CHROM: Chromosome
POS: Position (1-based)
ID: Variant ID (dbSNP)
REF: Reference allele
ALT: Alternate allele(s)
QUAL: Quality score (Phred)
FILTER: PASS or filter name
INFO: Additional info
FORMAT: Genotype format
SAMPLE: Sample columns
""")
print("\n=== Genotype (GT) ===")
print("""
GT values:
0/0: Homozygous reference
0/1: Heterozygous
1/1: Homozygous alternate
./.: Missing
1|0: Phased
Examples:
0/0: No variant
0/1: One copy variant
1/1: Two copies variant
1/2: Two different variants
""")
print("\n=== INFO Fields ===")
print("""
Common INFO:
DP: Total depth
AF: Allele frequency
AC: Allele count
AN: Allele number
MQ: Mapping quality
QD: Quality by depth
FS: Fisher strand
SOR: Strand odds ratio
ReadPosRankSum
MQRankSum
""")
print("\n=== FORMAT Fields ===")
print("""
Common FORMAT:
GT: Genotype
DP: Read depth
AD: Allelic depths
AF: Allele frequency
PL: Phred likelihoods
GQ: Genotype quality
GL: Genotype likelihoods
MIN_DP: Min depth
RGQ: Reference genotype quality
""")
print("\n=== Example VCF ===")
print("""
##fileformat=VCFv4.2
##FILTER=
##FILTER=
##INFO=
##INFO=
##FORMAT=
##FORMAT=
##FORMAT=
#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT SAMPLE1
chr1 1000 rs123 A G 50.0 PASS DP=30;AF=0.5 GT:DP:AD 0/1:30:15,15
chr1 2000 . C T 60.0 PASS DP=40;AF=0.25 GT:DP:AD 0/1:40:30,10
chr1 3000 . G A 20.0 LowQual DP=10;AF=0.1 GT:DP:AD 0/1:10:9,1
""")
print("\n=== Tools ===")
print("""
1. bcftools
- View, filter, merge
- Stats, annotate
2. VCFtools
- Filter, statistics
- Format conversion
3. GATK
- Variant manipulation
- Filtering
4. SnpSift
- Filter, annotate
- Expression language
5. CyVCF2
- Python
- Fast parsing
""")
print("\n=== bcftools Examples ===")
print("""
# View VCF
bcftools view variants.vcf.gz
# Filter by quality
bcftools filter -e 'QUAL<20' variants.vcf.gz -o filtered.vcf.gz
# Statistics
bcftools stats variants.vcf.gz
# Merge VCFs
bcftools merge sample1.vcf.gz sample2.vcf.gz -o merged.vcf.gz
# Annotate
bcftools annotate -a annotations.vcf.gz -c ID variants.vcf.gz
# Convert to BCF
bcftools view -O b variants.vcf.gz -o variants.bcf
""") π οΈ Tools (GATK, FreeBayes, bcftools)
π― Ready-to-Use Variant Callers
Many high-quality variant callers exist. Each has strengths and is suited to different use cases.
Tools
GATK: Gold standard. FreeBayes: Flexible. bcftools: Fast. Mutect2: Somatic. Strelka2: Somatic. DeepVariant: AI.
# Tools
print("=== GATK ===")
print("""
GATK (Genome Analysis Toolkit):
- Broad Institute
- Gold standard
- Germline + somatic
- Many tools
Key tools:
- HaplotypeCaller (germline)
- Mutect2 (somatic)
- GenotypeGVCFs (joint)
- VariantRecalibrator (VQSR)
- ApplyVQSR
- SelectVariants
- VariantFiltration
Command (germline):
gatk HaplotypeCaller \
-R reference.fasta \
-I sample.bam \
-O sample.g.vcf.gz \
-ERC GVCF
Joint calling:
gatk GenomicsDBImport \
-V sample1.g.vcf.gz \
-V sample2.g.vcf.gz \
--genomicsdb-workspace-path db
gatk GenotypeGVCFs \
-R reference.fasta \
-V gendb://db \
-O cohort.vcf.gz
""")
print("\n=== FreeBayes ===")
print("""
FreeBayes:
- Bayesian
- Haplotype-based
- Flexible
- Non-diploid
Command:
freebayes -f reference.fasta sample.bam > variants.vcf
Options:
-p 2 (ploidy)
-C 2 (min alt count)
-q 20 (min base quality)
-m 30 (min mapping quality)
-r chr1:1000-2000 (region)
""")
print("\n=== bcftools ===")
print("""
bcftools:
- Fast
- Simple
- Part of samtools
- VCF manipulation
Calling:
bcftools mpileup -f reference.fasta sample.bam | \
bcftools call -mv -Oz -o variants.vcf.gz
Filtering:
bcftools filter -s LowQual -e '%QUAL<20' variants.vcf.gz
Stats:
bcftools stats variants.vcf.gz
Merge:
bcftools merge sample1.vcf.gz sample2.vcf.gz -o merged.vcf.gz
""")
print("\n=== DeepVariant ===")
print("""
DeepVariant:
- Google
- Deep learning
- Accurate
- Germline
Command:
deepvariant \
--ref reference.fasta \
--reads sample.bam \
--output_vcf variants.vcf.gz \
--output_gvcf sample.g.vcf.gz
Models:
--model_type=WGS
--model_type=WES
--model_type=PACBIO
--model_type=ONT
""")
print("\n=== Mutect2 ===")
print("""
Mutect2:
- Somatic
- Tumor-normal
- GATK
Command:
gatk Mutect2 \
-R reference.fasta \
-I tumor.bam \
-I normal.bam \
-normal normal_sample \
-O somatic.vcf.gz
Filtering:
gatk FilterMutectCalls \
-R reference.fasta \
-V somatic.vcf.gz \
-O somatic.filtered.vcf.gz
""")
print("\n=== Strelka2 ===")
print("""
Strelka2:
- Somatic + germline
- Fast
- Accurate
Somatic:
configureStrelkaSomaticWorkflow.py \
--tumor tumor.bam \
--normal normal.bam \
--reference reference.fasta \
--runDir strelka_run
./strelka_run/runWorkflow.py -j 8
Germline:
configureStrelkaGermlineWorkflow.py \
--bam sample.bam \
--reference reference.fasta \
--runDir strelka_run
""")
print("\n=== Other Tools ===")
print("""
1. VarScan2
- Somatic
- Java
2. LoFreq
- Low frequency
- Viral
3. SNVer
- Pooled
4. Platypus
- Haplotype
5. Octopus
- Deep learning
6. Delly
- SV
7. Manta
- SV
8. CNVkit
- CNV
""")
print("\n=== Installation ===")
print("""
# Conda
conda install -c bioconda gatk4 freebayes bcftools samtools deepvariant
# Docker
docker pull broadinstitute/gatk:latest
# From source
git clone https://github.com/broadinstitute/gatk.git
cd gatk && ./gradlew installDist
""")π Annotation (VEP, SnpEff)
π― Adding Function to Variants
Variant annotation adds functional information to variants: gene, consequence, population frequency, and clinical significance.
Annotation
Gene: Which gene. Consequence: Missense, nonsense. Frequency: gnomAD. Clinical: ClinVar. Impact: CADD, SIFT. VEP: Ensembl. SnpEff: Fast.
# Variant Annotation
print("=== VEP (Variant Effect Predictor) ===")
print("""
VEP:
- Ensembl
- Comprehensive
- Most popular
Command:
vep -i variants.vcf \
--cache \
--assembly GRCh38 \
--offline \
--vcf \
--force_overwrite \
-o annotated.vcf
Options:
--cache (use cache)
--offline (no internet)
--vcf (VCF output)
--json (JSON output)
--everything (all annotations)
--pick (one per variant)
Plugins:
--plugin CADD
--plugin ClinVar
--plugin gnomAD
--plugin SIFT
--plugin PolyPhen
--plugin LoF
""")
print("\n=== SnpEff ===")
print("""
SnpEff:
- Fast
- Java
- Comprehensive
Command:
snpEff ann GRCh38.105 variants.vcf > annotated.vcf
Build database:
snpEff build -gtf22 -v GRCh38.105
Options:
-canon (canonical transcripts)
-no-downstream
-no-upstream
-stats (HTML report)
""")
print("\n=== ANNOVAR ===")
print("""
ANNOVAR:
- Comprehensive
- Many databases
- Popular
Command:
annotate_variation.pl \
-geneanno \
-buildver hg38 \
variants.vcf \
humandb/
Databases:
- refGene
- ensGene
- knownGene
- gnomAD
- ClinVar
- dbSNP
- CADD
- SIFT
- PolyPhen
""")
print("\n=== Consequence Types ===")
print("""
Impact:
HIGH:
- Stop gained
- Frameshift
- Splice acceptor/donor
- Start lost
MODERATE:
- Missense
- In-frame indel
- Splice region
LOW:
- Synonymous
- Stop retained
MODIFIER:
- Intronic
- Intergenic
- UTR
""")
print("\n=== Population Frequency ===")
print("""
Databases:
- gnomAD
- 1000 Genomes
- ExAC
- ESP
- UK Biobank
Filter:
- AF < 0.01 (rare)
- AF < 0.001 (very rare)
- AF < 0.0001 (ultra-rare)
Example:
gnomAD_AF = 0.0001
β Rare variant
""")
print("\n=== Clinical Significance ===")
print("""
Databases:
- ClinVar
- OMIM
- HGMD
- LOVD
Classifications:
- Pathogenic
- Likely pathogenic
- VUS (uncertain)
- Likely benign
- Benign
ACMG guidelines:
- PVS1, PS1-4
- PM1-6
- PP1-5
- BA1, BS1-4
- BP1-7
""")
print("\n=== Impact Prediction ===")
print("""
Tools:
- CADD (Combined Annotation Dependent Depletion)
- SIFT
- PolyPhen-2
- REVEL
- MutPred
- PrimateAI
Scores:
- CADD > 20: Deleterious
- SIFT < 0.05: Deleterious
- PolyPhen > 0.85: Probably damaging
- REVEL > 0.5: Pathogenic
""")
print("\n=== Best Practices ===")
print("""
1. Use multiple annotators
2. Check gene models
3. Filter by frequency
4. Check clinical databases
5. Predict impact
6. Manual curation
7. Report with guidelines
""")π Python Integration
π― Variant Calling from Python
You can run variant callers from Python using subprocess and parse VCFs with pysam and CyVCF2.
Python
subprocess: Run CLI. pysam: BAM/VCF. CyVCF2: Fast VCF. scikit-allel: Analysis. Plot: Visualize. Pipeline: Automate.
# Python Integration
print("=== Run GATK ===")
print("""
import subprocess
import os
def run_gatk_haplotypecaller(reference, bam, output_vcf,
threads=4):
\"\"\"Run GATK HaplotypeCaller.\"\"\"
cmd = [
'gatk', 'HaplotypeCaller',
'-R', reference,
'-I', bam,
'-O', output_vcf,
'-ERC', 'GVCF',
'--native-pair-hmm-threads', str(threads)
]
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError(f"GATK failed: {result.stderr}")
return output_vcf
# Use
# vcf = run_gatk_haplotypecaller("ref.fasta", "sample.bam", "output.g.vcf.gz")
""")
print("\n=== Run FreeBayes ===")
print("""
def run_freebayes(reference, bam, output_vcf,
ploidy=2, min_qual=20):
\"\"\"Run FreeBayes.\"\"\"
cmd = [
'freebayes',
'-f', reference,
'-p', str(ploidy),
'-q', str(min_qual),
bam
]
with open(output_vcf, 'w') as f:
result = subprocess.run(cmd, stdout=f, stderr=subprocess.PIPE,
text=True)
if result.returncode != 0:
raise RuntimeError(f"FreeBayes failed: {result.stderr}")
return output_vcf
# Use
# vcf = run_freebayes("ref.fasta", "sample.bam", "variants.vcf")
""")
print("\n=== Run bcftools ===")
print("""
def run_bcftools(reference, bam, output_vcf):
\"\"\"Run bcftools mpileup + call.\"\"\"
cmd = (
f"bcftools mpileup -f {reference} {bam} | "
f"bcftools call -mv -Oz -o {output_vcf}"
)
result = subprocess.run(cmd, shell=True, capture_output=True,
text=True)
if result.returncode != 0:
raise RuntimeError(f"bcftools failed: {result.stderr}")
return output_vcf
# Use
# vcf = run_bcftools("ref.fasta", "sample.bam", "variants.vcf.gz")
""")
print("\n=== Parse VCF with pysam ===")
print("""
import pysam
def parse_vcf(vcf_file):
\"\"\"Parse VCF with pysam.\"\"\"
vcf = pysam.VariantFile(vcf_file)
print(f"Samples: {list(vcf.header.samples)}")
for record in vcf:
print(f"{record.chrom}:{record.pos} "
f"{record.ref}>{','.join(record.alts)} "
f"QUAL={record.qual}")
for sample in record.samples:
gt = record.samples[sample]['GT']
dp = record.samples[sample].get('DP', 'N/A')
print(f" {sample}: GT={gt} DP={dp}")
# Use
# parse_vcf("variants.vcf.gz")
""")
print("\n=== Parse VCF with CyVCF2 ===")
print("""
from cyvcf2 import VCF
def parse_vcf_cyvcf2(vcf_file):
\"\"\"Parse VCF with CyVCF2 (fast).\"\"\"
vcf = VCF(vcf_file)
for variant in vcf:
print(f"{variant.CHROM}:{variant.POS} "
f"{variant.REF}>{variant.ALT[0]} "
f"QUAL={variant.QUAL} "
f"AF={variant.INFO.get('AF', 'N/A')}")
for sample in variant.genotypes:
print(f" GT: {sample}")
# Use
# parse_vcf_cyvcf2("variants.vcf.gz")
""")
print("\n=== Filter VCF ===")
print("""
import pysam
def filter_vcf(input_vcf, output_vcf,
min_qual=20, min_dp=10):
\"\"\"Filter VCF by quality and depth.\"\"\"
vcf_in = pysam.VariantFile(input_vcf)
vcf_out = pysam.VariantFile(output_vcf, 'w', header=vcf_in.header)
count = 0
for record in vcf_in:
# Quality filter
if record.qual is None or record.qual < min_qual:
continue
# Depth filter
dp = record.info.get('DP', 0)
if dp < min_dp:
continue
vcf_out.write(record)
count += 1
vcf_out.close()
print(f"Written {count} variants")
# Use
# filter_vcf("raw.vcf.gz", "filtered.vcf.gz")
""")
print("\n=== VCF Statistics ===")
print("""
from cyvcf2 import VCF
from collections import Counter
def vcf_stats(vcf_file):
\"\"\"Compute VCF statistics.\"\"\"
vcf = VCF(vcf_file)
stats = {
'total': 0,
'snps': 0,
'indels': 0,
'chromosomes': Counter(),
'qualities': []
}
for variant in vcf:
stats['total'] += 1
stats['chromosomes'][variant.CHROM] += 1
stats['qualities'].append(variant.QUAL)
if variant.is_snp:
stats['snps'] += 1
elif variant.is_indel:
stats['indels'] += 1
print(f"Total variants: {stats['total']}")
print(f"SNPs: {stats['snps']}")
print(f"Indels: {stats['indels']}")
print(f"Mean QUAL: {sum(stats['qualities'])/len(stats['qualities']):.1f}")
return stats
# Use
# stats = vcf_stats("variants.vcf.gz")
""")
print("\n=== Ti/Tv Ratio ===")
print("""
from cyvcf2 import VCF
def ti_tv_ratio(vcf_file):
\"\"\"Compute transition/transversion ratio.\"\"\"
vcf = VCF(vcf_file)
transitions = 0
transversions = 0
ti_pairs = {('A','G'), ('G','A'), ('C','T'), ('T','C')}
for variant in vcf:
if not variant.is_snp:
continue
ref = variant.REF
alt = variant.ALT[0]
if (ref, alt) in ti_pairs:
transitions += 1
else:
transversions += 1
ratio = transitions / transversions if transversions > 0 else 0
print(f"Transitions: {transitions}")
print(f"Transversions: {transversions}")
print(f"Ti/Tv ratio: {ratio:.2f}")
return ratio
# Use
# ratio = ti_tv_ratio("variants.vcf.gz")
""")
print("\n=== Complete Pipeline ===")
print("""
import subprocess
from cyvcf2 import VCF
def variant_calling_pipeline(reference, bam, output_vcf,
caller="gatk", threads=4):
\"\"\"Complete variant calling pipeline.\"\"\"
# Choose caller
if caller == "gatk":
cmd = ['gatk', 'HaplotypeCaller',
'-R', reference, '-I', bam, '-O', output_vcf,
'--native-pair-hmm-threads', str(threads)]
elif caller == "freebayes":
cmd = ['freebayes', '-f', reference, bam]
elif caller == "bcftools":
cmd = f"bcftools mpileup -f {reference} {bam} | bcftools call -mv -Oz -o {output_vcf}"
else:
raise ValueError(f"Unknown caller: {caller}")
# Run
print(f"Running {caller}...")
if caller == "bcftools":
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
else:
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode != 0:
raise RuntimeError(f"{caller} failed: {result.stderr}")
# Stats
vcf = VCF(output_vcf)
count = sum(1 for _ in vcf)
print(f"Variants called: {count}")
return output_vcf
# Use
# vcf = variant_calling_pipeline("ref.fasta", "sample.bam", "variants.vcf.gz")
""")π Quality & Filtering
π― Is My Variant Real?
Variant quality assessment and filtering are critical. Metrics include QUAL, depth, strand bias, and Ti/Tv ratio.
Quality Metrics
QUAL: Quality score. DP: Depth. GQ: Genotype quality. FS: Strand bias. MQ: Mapping quality. Ti/Tv: Transition ratio.
# Quality & Filtering
print("=== QUAL (Quality Score) ===")
print("""
QUAL:
- Phred-scaled
- Probability variant is real
- QUAL 20 = 99% confidence
- QUAL 30 = 99.9%
- QUAL 50 = 99.999%
Filter:
- QUAL < 20: Low quality
- QUAL > 30: Good
""")
print("\n=== DP (Depth) ===")
print("""
DP:
- Read depth
- Coverage
- Confidence
Filter:
- DP < 10: Low coverage
- DP > 100: Possible repeat
- Ideal: 20-60 for WGS
- Ideal: 50-100 for WES
Excess depth:
- Paralogs
- Repeats
- CNVs
""")
print("\n=== GQ (Genotype Quality) ===")
print("""
GQ:
- Confidence in genotype
- Phred-scaled
- GQ 20 = 99%
- GQ 30 = 99.9%
Filter:
- GQ < 20: Low confidence
- GQ > 30: High confidence
""")
print("\n=== Strand Bias ===")
print("""
Strand bias:
- Variant on one strand
- Artifact
FS (Fisher Strand):
- FS > 60: Strand bias (SNP)
- FS > 200: Strand bias (indel)
SOR (Strand Odds Ratio):
- SOR > 3: Strand bias
""")
print("\n=== Mapping Quality ===")
print("""
MQ:
- Mapping quality
- MQ < 40: Poor mapping
- MQ > 50: Good
MQRankSum:
- MQ difference ref/alt
- MQRankSum < -12.5: Bad
ReadPosRankSum:
- Read position bias
- ReadPosRankSum < -8: Bad
""")
print("\n=== Ti/Tv Ratio ===")
print("""
Ti/Tv:
- Transitions / Transversions
- Expected ~2.0-2.1 for WGS
- Expected ~3.0 for WES
- Lower: False positives
Transitions:
- AβG, CβT
Transversions:
- AβC, AβT, GβC, GβT
Filter:
- Ti/Tv < 1.5: Suspicious
- Ti/Tv ~2.0: Good
""")
print("\n=== Filtering Strategies ===")
print("""
1. Hard filters:
- QUAL < 20
- DP < 10
- FS > 60
- MQ < 40
- ReadPosRankSum < -8
- MQRankSum < -12.5
2. VQSR:
- Machine learning
- Needs many variants
- GATK
3. bcftools filter:
- Expression-based
- Flexible
4. Manual:
- Inspect IGV
- Check coverage
""")
print("\n=== Best Practices ===")
print("""
1. Check Ti/Tv ratio
2. Check het/hom ratio
3. Check depth distribution
4. Check strand bias
5. Validate with truth set
6. Use orthogonal methods
7. Report all metrics
""")βοΈ Tool Comparison
π― Which Variant Caller?
Choosing the right variant caller depends on data type, variant type, and analysis goals.
Comparison
GATK: Gold standard. FreeBayes: Flexible. bcftools: Fast. DeepVariant: AI. Mutect2: Somatic. Strelka2: Somatic.
| Tool | Type | Speed | Accuracy | Best For |
|---|---|---|---|---|
| GATK HaplotypeCaller | Germline | Medium | Excellent | Clinical, gold standard |
| FreeBayes | Germline | Medium | Very good | Flexible, non-diploid |
| bcftools | Germline | Fast | Good | Quick, simple |
| DeepVariant | Germline | Medium | Excellent | AI, accurate |
| Mutect2 | Somatic | Medium | Excellent | Cancer, tumor-normal |
| Strelka2 | Somatic | Fast | Very good | Cancer, fast |
| VarScan2 | Somatic | Fast | Good | Legacy |
| Delly | SV | Fast | Good | Structural variants |
| Manta | SV | Medium | Very good | Somatic SVs |
| Sniffles | SV | Fast | Good | Long-read SVs |
# Decision Guide
print("=== Choose Tool by Variant Type ===")
print("""
Germline SNPs/indels:
β GATK HaplotypeCaller (best)
β DeepVariant (AI)
β FreeBayes (flexible)
Somatic SNPs/indels:
β Mutect2 (best)
β Strelka2
β VarScan2
Structural variants:
β Delly (short reads)
β Manta (somatic)
β Sniffles (long reads)
CNVs:
β CNVkit
β GATK gCNV
β Control-FREEC
STRs:
β ExpansionHunter
β GangSTR
β lobSTR
""")
print("\n=== Choose Tool by Data Type ===")
print("""
WGS (whole genome):
β GATK HaplotypeCaller
β DeepVariant
WES (exome):
β GATK HaplotypeCaller
β FreeBayes
Targeted panel:
β GATK
β bcftools
Long reads:
β Sniffles (SV)
β Clair3 (SNP)
β PEPPER (SNP)
Single-cell:
β Monovar
β SCcaller
β cellsnp-lite
""")
print("\n=== Speed Comparison ===")
print(f"{'Tool':<25} {'WGS 30x':<15} {'WES 50x':<15} {'Targeted':<15}")
print("-" * 70)
print(f"{'GATK HaplotypeCaller':<25} {'2-4 hours':<15} {'30 min':<15} {'5 min':<15}")
print(f"{'DeepVariant':<25} {'1-2 hours':<15} {'20 min':<15} {'3 min':<15}")
print(f"{'FreeBayes':<25} {'1-2 hours':<15} {'20 min':<15} {'3 min':<15}")
print(f"{'bcftools':<25} {'30 min':<15} {'10 min':<15} {'1 min':<15}")
print(f"{'Mutect2':<25} {'3-5 hours':<15} {'45 min':<15} {'10 min':<15}")
print("\n=== Accuracy Benchmark ===")
print(f"{'Tool':<25} {'SNP F1':<15} {'Indel F1':<15}")
print("-" * 55)
print(f"{'GATK HaplotypeCaller':<25} {'0.99':<15} {'0.98':<15}")
print(f"{'DeepVariant':<25} {'0.99':<15} {'0.99':<15}")
print(f"{'FreeBayes':<25} {'0.98':<15} {'0.95':<15}")
print(f"{'bcftools':<25} {'0.97':<15} {'0.93':<15}")
print(f"{'Strelka2':<25} {'0.99':<15} {'0.98':<15}")
print("\n=== When to Use Which ===")
print("""
USE GATK:
β Clinical
β Gold standard
β Joint calling
β Best practices
USE DeepVariant:
β AI
β Accurate
β Easy
β Cloud
USE FreeBayes:
β Flexible
β Non-diploid
β Small genomes
USE bcftools:
β Quick
β Simple
β Small data
USE Mutect2:
β Cancer
β Tumor-normal
β Somatic
USE Strelka2:
β Cancer
β Fast
β Somatic + germline
""")πΌ Use Cases
π― Where Variant Calling Is Used
Variant calling is used in virtually every area of genomics: clinical, cancer, population, agriculture, and more.
Use Cases
Clinical: Diagnosis. Cancer: Somatic. Population: Diversity. Pharma: Drug. Agri: Traits. Evolution: Adaptation.
# Use Cases
print("=== 1. Clinical Genomics ===")
print("""
Use case:
- Rare disease
- Hereditary cancer
- Pharmacogenomics
Workflow:
1. Patient DNA
2. Sequencing
3. Variant calling (GATK)
4. Annotation (VEP)
5. Filtering (frequency, impact)
6. ACMG classification
7. Clinical report
Examples:
- BRCA1/2
- CFTR
- CYP2D6
- HLA
Tools:
- GATK
- VEP
- ClinVar
- InterVar
""")
print("\n=== 2. Cancer Genomics ===")
print("""
Use case:
- Somatic mutations
- Driver mutations
- Treatment selection
Workflow:
1. Tumor + normal
2. Sequencing
3. Somatic calling (Mutect2)
4. Filtering (PoN, gnomAD)
5. Annotation
6. Report
Examples:
- EGFR
- BRAF
- KRAS
- PIK3CA
Tools:
- Mutect2
- Strelka2
- VEP
- CIViC
""")
print("\n=== 3. Population Genetics ===")
print("""
Use case:
- Diversity
- GWAS
- Selection
Workflow:
1. Many samples
2. Joint calling
3. Filtering
4. Analysis
Examples:
- 1000 Genomes
- gnomAD
- UK Biobank
Tools:
- GATK
- bcftools
- PLINK
- VCFtools
""")
print("\n=== 4. Pharmacogenomics ===")
print("""
Use case:
- Drug response
- Dosing
- Adverse reactions
Workflow:
1. Genotype
2. Star alleles
3. Diplotype
4. Phenotype
5. Recommendation
Examples:
- CYP2D6
- CYP2C19
- TPMT
- DPYD
Tools:
- Stargazer
- Aldy
- PharmGKB
- CPIC
""")
print("\n=== 5. Agriculture ===")
print("""
Use case:
- Crop traits
- Breeding
- Selection
Workflow:
1. Genotype
2. GWAS
3. Marker-assisted selection
4. Breeding
Examples:
- Rice
- Maize
- Wheat
- Tomato
Tools:
- GATK
- TASSEL
- PLINK
""")
print("\n=== 6. Evolutionary Biology ===")
print("""
Use case:
- Adaptation
- Speciation
- Ancient DNA
Workflow:
1. Sequence
2. Variant calling
3. Comparative
4. Analysis
Examples:
- Darwin's finches
- Human evolution
- Neanderthal
Tools:
- GATK
- bcftools
- PAML
""")
print("\n=== 7. Metagenomics ===")
print("""
Use case:
- Strain variation
- Community
- Antibiotic resistance
Workflow:
1. Metagenome assembly
2. Binning
3. Variant calling
4. Analysis
Tools:
- metaSNV
- inStrain
- StrainPhlAn
""")
print("\n=== 8. Forensic Genetics ===")
print("""
Use case:
- Identification
- Paternity
- Ancestry
Workflow:
1. Sample
2. Sequencing
3. Variant calling
4. Comparison
Tools:
- GATK
- ForenSeq
""")
print("\n=== Comparison ===")
print(f"{'Use Case':<25} {'Tool':<20} {'Output':<20}")
print("-" * 65)
print(f"{'Clinical':<25} {'GATK + VEP':<20} {'Report':<20}")
print(f"{'Cancer':<25} {'Mutect2':<20} {'Somatic VCF':<20}")
print(f"{'Population':<25} {'GATK joint':<20} {'Cohort VCF':<20}")
print(f"{'Pharma':<25} {'Stargazer':<20} {'Diplotype':<20}")
print(f"{'Agriculture':<25} {'GATK':<20} {'GWAS':<20}")
print(f"{'Evolution':<25} {'bcftools':<20} {'Variants':<20}")
print(f"{'Metagenome':<25} {'metaSNV':<20} {'Strains':<20}")
print(f"{'Forensic':<25} {'GATK':<20} {'Profile':<20}")β FAQ
π― Frequently Asked Questions
Answers to common questions about variant calling.
What is variant calling?
Variant calling is the process of identifying differences between a sample genome and a reference genome. It detects SNPs, indels, and structural variants from aligned sequencing reads, producing a VCF file for downstream analysis.
What is the difference between germline and somatic variant calling?
Germline variant calling identifies inherited variants present in all cells (e.g., GATK HaplotypeCaller). Somatic variant calling identifies acquired mutations present in only some cells, such as in tumors (e.g., Mutect2, Strelka2). Somatic calling requires tumor-normal paired samples and special filters.
Which variant caller should I use?
Use GATK HaplotypeCaller for germline (gold standard), FreeBayes for flexible germline, bcftools for fast and simple calling, Mutect2 for somatic, Strelka2 for somatic and germline, and Delly/Manta for structural variants. For clinical, GATK is the most validated.
What is a VCF file?
VCF (Variant Call Format) is the standard text format for storing variants. It contains a header with metadata and columns: CHROM, POS, ID, REF, ALT, QUAL, FILTER, INFO, FORMAT, and sample genotypes. It's used by all major variant tools.
What is variant annotation?
Variant annotation adds functional information to variants: gene, transcript, consequence (missense, nonsense, synonymous), population frequency (gnomAD), clinical significance (ClinVar), and predicted impact (CADD, SIFT, PolyPhen). Tools include VEP, SnpEff, and ANNOVAR.
What coverage do I need for variant calling?
For germline WGS: 30x. For germline WES: 50-100x. For somatic: 100x+ tumor, 30x normal. For clinical: 100x+. Higher coverage improves sensitivity, especially for low allele fraction variants.
What is VQSR?
VQSR (Variant Quality Score Recalibration) is a GATK machine learning method for filtering variants. It uses known truth sets (e.g., HapMap, Omni) to train a model that separates true variants from false positives. It requires many variants and is more accurate than hard filters.
What is Ti/Tv ratio?
Ti/Tv is the ratio of transitions (AβG, CβT) to transversions (AβC, AβT, GβC, GβT). For WGS, expected ~2.0-2.1. For WES, ~3.0. A lower ratio suggests false positives. It's a quality metric for variant calls.
How do I detect structural variants?
Use Delly, Manta, or Lumpy for short reads, and Sniffles or cuteSV for long reads. SVs are detected using read pairs, split reads, and read depth. Long reads are best for accurate SV detection.
What is joint calling?
Joint calling calls variants across many samples simultaneously. It improves accuracy by sharing information across samples, especially for low-coverage data. GATK's GenomicsDBImport + GenotypeGVCFs is the standard workflow.
# Quick Reference
print("=== Quick Answers ===")
print("""
Q: What is variant calling?
A: Identify differences from reference.
Q: Germline vs somatic?
A: Germline inherited; somatic acquired.
Q: Best tool germline?
A: GATK HaplotypeCaller.
Q: Best tool somatic?
A: Mutect2.
Q: What is VCF?
A: Standard variant format.
Q: Coverage needed?
A: 30x WGS, 100x somatic.
Q: What is VQSR?
A: Machine learning filtering.
Q: What is Ti/Tv?
A: Quality metric (~2.0 WGS).
Q: What is joint calling?
A: Many samples together.
Q: What is annotation?
A: Add function to variants.
Q: Free tools?
A: Yes β all major tools are free.
""")π Future
π― Where Variant Calling Is Going
The future is AI-augmented, long-read, pangenomic, and clinical-grade.
Future Directions
AI: Deep learning. Long reads: Better SVs. Pangenome: Graph. Clinical: Routine. Cloud: Serverless. Integration: Unified.
# Future of Variant Calling
print("=== 1. AI-Augmented Calling ===")
print("""
Trend: Deep learning
Ideas:
- DeepVariant (Google)
- Clair3 (long reads)
- PEPPER (Nanopore)
- Neural networks
Examples:
- DeepVariant: CNN on pileup
- Clair3: RNN for long reads
- PEPPER: Deep learning for ONT
Future:
- Learned filters
- Better sensitivity
- Lower coverage
- Clinical-grade
""")
print("\n=== 2. Long-Read Variant Calling ===")
print("""
Trend: Long reads
Current:
- Short reads standard
- SVs hard
Long reads:
- Better SVs
- Phasing
- Methylation
- Full-length genes
Tools:
- Clair3
- PEPPER
- Sniffles
- cuteSV
Future:
- Long-read first
- Complete genomes
- T2T
""")
print("\n=== 3. Pangenome Variant Calling ===")
print("""
Trend: Graph genomes
Current:
- Linear reference
- Reference bias
Pangenome:
- Graph reference
- Multiple genomes
- Less bias
Tools:
- vg
- GraphTyper
- PanGenie
- minigraph
Future:
- Graph-based calling
- Better diversity
- Clinical
""")
print("\n=== 4. Clinical-Grade Calling ===")
print("""
Trend: Routine clinical
Current:
- Research
- Specialized
Future:
- Clinical routine
- Rare disease
- Cancer
- Pharmacogenomics
Examples:
- CYP2D6
- HLA
- BRCA1/2
- Cancer SVs
Requirements:
- Accuracy
- Speed
- Cost
- Regulation
""")
print("\n=== 5. Cloud-Native ===")
print("""
Trend: Cloud calling
Current:
- Self-managed
- Manual scaling
Future:
- Serverless
- Auto-scaling
- Pay per use
- Global
Examples:
- AWS HealthOmics
- Google Cloud Life Sciences
- Azure Genomics
- Terra
""")
print("\n=== 6. Integration ===")
print("""
Trend: Unified pipelines
Current:
- Separate tools
- Manual pipelines
Future:
- Integrated platforms
- Workflow managers
- Reproducible science
- ML-ready
Examples:
- Galaxy
- Nextflow
- Snakemake
- Terra
- nf-core
""")
# TIMELINE
print("\n=== Timeline ===")
print("""
Past:
2009: GATK
2010: FreeBayes
2011: VCF format
2013: HaplotypeCaller
2015: Mutect2
2016: DeepVariant
2020: Long-read calling
Present:
2025: AI-augmented
2026: Pangenome
Future:
2030: Clinical-grade?
2035: Graph calling?
2040: Quantum calling?
""")
print("\n=== Final Thoughts ===")
print("""
Variant calling is:
- Fundamental to genomics
- Needed for clinical
- Needed for cancer
- Needed for population
- Rapidly improving
The future is:
- AI-augmented
- Long-read
- Pangenome
- Clinical-grade
- Cloud-native
"Variants are the differences
that make us who we are."
Keep exploring. Keep building.
""")