Step 5: Filtering (bcftools filter) - aduckwo4-boop/EPP622-2026-SNPCalling GitHub Wiki

Step 5: Filtering (bcftools filter)

Commands

I am going to try a gentle filtering and more stingent filtering. (WARNING: These are different filters than what we have seen in class.)

Gentle: exclude variants with a QUAL less than 20 or less than 5 total read depth across all samples.

Stringent: exclude variants with a QUAL less than 30 or less than 10 total read depth across all samples or a site level mapping quality (root mean square) of less than 40

Two filtering approaches were applied to the raw variant calls to evaluate how different quality thresholds affect SNP retention. Gentle filtering removed variants with low quality scores or insufficient total read depth, while stringent filtering applied higher quality and depth thresholds along with an additional mapping quality requirement.

First, corrected the mapping quality field type in the VCF header:

bcftools view -h all_samples.raw.vcf.gz > header.txt
sed -i '/^##INFO=<ID=MQ,/s/Type=Integer/Type=Float/' header.txt
bcftools reheader \
  -h header.txt \
  -o all_samples.raw.fixed.vcf.gz \
  all_samples.raw.vcf.gz

# bcftools view -h: extracts the VCF header without variant records.
# > header.txt: saves the header to a text file.
# sed -i: edits the header file in place.
# /^##INFO=<ID=MQ,/: identifies the mapping quality annotation.
# s/Type=Integer/Type=Float/: changes the MQ field type from integer to float.
# bcftools reheader: replaces the original VCF header with the corrected header.
# -h: specifies the replacement header file.
# -o: specifies the output VCF filename.

Gentle Filtering

#filtering gentle
bcftools filter \
  -e 'QUAL<20 || INFO/DP<5' \
  -Oz \
  -o all_samples.gentle.vcf.gz \
  all_samples.raw.fixed.vcf.gz


# bcftools filter: filters variants based on specified criteria.
# -e: excludes variants meeting any of the specified conditions.
# QUAL<20: excludes variants with a quality score below 20.
# ||: logical OR, meaning either condition results in exclusion.
# INFO/DP<5: excludes variants with total site depth below 5.
# -Oz: outputs a compressed VCF file.
# -o: specifies the filtered output filename.
# all_samples.raw.fixed.vcf.gz: input VCF with the corrected header.

Stringent Filtering

#filtering stringent
bcftools filter \
  -e 'QUAL<30 || INFO/DP<10 || INFO/MQ<40' \
  -Oz \
  -o all_samples.stringent.vcf.gz \
  all_samples.raw.fixed.vcf.gz


# bcftools filter: filters variants based on specified criteria.
# -e: excludes variants meeting any of the filtering conditions.
# QUAL<30: excludes variants with a quality score below 30.
# ||: logical OR, meaning any condition can result in exclusion.
# INFO/DP<10: excludes variants with total site depth below 10.
# INFO/MQ<40: excludes variants with site-level mapping quality below 40.
# -Oz: outputs a compressed VCF file.
# -o: specifies the filtered output filename.
# all_samples.raw.fixed.vcf.gz: input VCF with the corrected header.

Generated filtering stats

# bcftools stats on gentle
bcftools stats all_samples.gentle.vcf.gz > all_samples.gentle.stats.txt
# bcftools stats on stringent
bcftools stats all_samples.stringent.vcf.gz > all_samples.stringent.stats.txt

# bcftools stats: generates summary statistics for each filtered VCF.
# >: redirects the statistics into a text file.
# all_samples.gentle.stats.txt: statistics for gently filtered variants.
# all_samples.stringent.stats.txt: statistics for stringently filtered variants.

Results

bcftools stats report path and name for gentle filtering: /lustre/isaac24/proj/UTK0505/aduckwo4/622_test2/04_bcftools/all_samples.gentle.stats.txt

bcftools stats report path and name: for stringent filtering: /lustre/isaac24/proj/UTK0505/aduckwo4/622_test2/04_bcftools/all_samples.stringent.stats.txt

VCF number of SNPs
raw 4920
gentle 4869
stringent 4774