2024-11-30 | 群体遗传变异——SNP及INDEL calling

进行群体遗传学分析的前提是我们得得到变异信息,之前已经介绍了如何进行CNV的识别,那么本文来介绍下如何识别基因组中分布更多、更常见的变异SNP(INDEL顺带)

二代测序 reads 的比对

二代测序 reads 的比对分两步:

用 bwa 将 reads 比对到参考基因组
用 picard 去除 PCR 造成的重复 reads
最终得到比对后的 CRAM 文件,这是一种BAM的压缩格式,在 samtools 给的基准测试中,CRAM 大小约为 BAM 的一半。

bwa 软件实现了三种比对算法 BWA-backtrack, BWA-SWBWA-MEM

  • 第一种算法适用于长度在 100bp 以下的 reads,后两种算法适用于70bp至数M的长 reads。
  • BWA-MEM 是最新的算法,70bp以上的 reads 用 BWA-MEM 就好,70b p以下的用 BWA-backtrack

01. read alignment, sort, and remove PCR duplication

这一步也就是我们常用的数据处理了,包括比对、排序、标记PCR重复

bwa mem -t 4 -M -R '@RG\tID:$sample\tLB:$group\tPL:ILLUMINA\tSM:$sample' $reference.fa $fastq1 $fastq2 | samtools view -b -S -o $sample.bam
java -jar picard.jar SortSam I=$sample.bam O=$sample.sort.bam SORT_ORDER=coordinate VALIDATION_STRINGENCY=LENIENT
java -jar picard.jar MarkDuplicates I=$sample.sort.bam O=$sample.dup.bam ASSUME_SORT_ORDER=coordinate METRICS_FILE=$sample.dup.txt VALIDATION_STRINGENCY=LENIENT REMOVE_DUPLICATES=true
java -jar picard.jar SetNmMdAndUqTags I=$sample.dup.bam O=$sample.dup.sort.fix.bam CREATE_INDEX=true R=$reference.fa VALIDATION_STRINGENCY=LENIENT

# REMOVE_DUPLICATES=true 去除PCR重复
# SetNmMdAndUqTags 设置SAM/BAM文件中的 NM(比对质量)、MD(碱基差异)和 UQ(唯一比对性) 标签,后续过滤可能用得上
# NM(比对质量) > 20 的用于后续 SNP calling
# bwa 中 -R 参数添加头文件信息,
若比对时未加这一参数则可用:
java -jar picard.jar AddOrReplaceReadGroups I=input.bam O=output.bam RGID=$sample RGLB=$sample RGPL=illumina RGPU=$samplePU RGSM=$sample

GATK进行SNP calling

image.png

02.variants calling using GATK4+

GATK4版本之后就不用对INDEL区域进行重比对了,方便

~/gatk-4.1.4.0/gatk HaplotypeCaller -R $reference.fa  -L $chr -ERC GVCF -I $bam -o $chr.gvcf.gz
~/gatk-4.1.4.0/gatk CombineGVCFs -R $reference.fa  --variant $chr.list -o $chr.gvcf.gz
~/gatk-4.1.4.0/gatk GenotypeGVCFs -R $reference.fa  --variant $chr.gvcf.gz --includeNonVariantSites -O $chr.vcf.gz

# -L 分染色体call,占用空间少, CombineGVCFs时指定$chr.list即可
# --includeNonVariantSite 保留非变异位点
  • GATKHaplotypeCaller模块识别每个个体中基因组变异SNPINDEL
  • GATKCombineGVCFs模块对分染色体文件及个体文件进行合并,最后得到群体层面的大gvcf
  • GATKGenotypeGVCFs模块对群体层面的大gvcf进行基因分型,得到基因型

02.variants calling using GATK4+(hard filter)

  • 对SNP和INDEL分别进行硬过滤,因为他们过滤标准不一样
  • GATKSelectVariants模块分别提取出SNP和INDEL
  • 过滤完成后,用MergeVcfs模块对过滤后vcf文件进行合并。
SNP
~/gatk-4.1.4.0/gatk SelectVariants -R $reference.fa -V $Pop.vcf.gz --select-type-to-include SNP -O Pop.SNP.vcf.gz
~/gatk-4.1.4.0/gatk VariantFiltration -R $reference.fa -V Pop.SNP.vcf.gz  --filter-expression "QD < 2.0 || FS > 60.0 || MQ < 40.0 || MQRankSum < -12.5 || ReadPosRankSum < -8.0"  --filter-name "my_snp_filter" -O Pop.HDflt.SNP.vcf.gz
INDEL
~/gatk-4.1.4.0/gatk SelectVariants -R $reference.fa -V $Pop.vcf.gz --select-type-to-include INDEL -O Pop.INDEL.vcf.gz
~/gatk-4.1.4.0/gatk VariantFiltration -R $reference.fa -V Pop.INDEL.vcf.gz --filter-expression "QD < 2.0 || FS > 200.0 || SOR > 10.0 || MQRankSum < -12.5 || ReadPosRankSum < -20" --filter-name "my_indel_filter" -O Pop.HDflt.INDEL.vcf.gz
merge and get PASS site
~/gatk-4.1.4.0/gatk MergeVcfs -I Pop.HDflt.SNP.vcf.gz -I Pop.HDflt.INDEL.vcf.gz -O Pop.HDflt.SNP.INDEL.genotype.vcf
~/gatk-4.1.4.0/gatk SelectVariants -R $reference.fa -V Pop.HDflt.SNP.INDEL.genotype.vcf -O Pop.HDflt.SNP.INDEL.genotype.pass.vcf -select "vc.isNotFiltered()"
call完之后可根据质量值QUAL >= 30去除低质量位点,去除多等位基因等等过滤
vcftools --gzvcf $vcf --minQ 30 --min-alleles 2 --max-alleles 2 --max-missing 0.9 --non-ref-ac 2 --remove-indels --recode --recode-INFO-all --out $filter

--minQ 30 保留QUAL >= 30
--min-alleles 2 保留双等位基因
--max-alleles 2 保留双等位基因
--non-ref-ac 2  保留非参考等位基因多余2个个体的位点
--remove-indels 去除INDEL
--remove-snps   去除SNP
--max-missing 0.9 缺失率 < 10% 的位点留下

整个硬过滤及质量控制流程HardFilterSnpIndel.sh

#! /bin/bash
## 精准而优雅
#################### Hard filter for SNP ######################
# 如果想要位点多点,则最后--minQ可不设置
# vcftools --non-ref-ac 2  保留非参考等位基因多余2个个体的位点
# 看自己情况设还是不设
###############################################################
# Set up the file name, software
GATK="/home/software/gatk-4.1.4.0/gatk"                # change as you want
vcftools="/home/sll/miniconda3/bin/bcftools"           # change as you want
reference="/home/sll/genome"                           # reference genome fasta file

if [[ $# -ne 2 ]]; then 
    echo "Usage: bash $0  <vcf.gz file>  <outprefix>"
    echo "输出文件前缀推荐和输入文件一样吧"
    echo "对SNP和INDEL进行硬过滤及SNP去除多等位基因,输出过滤后的SNP及INDEL文件"
    exit 1
fi

vcf=$1
out=$2

## get SNP and INDEL
$GATK SelectVariants -R $reference --select-type  SNP  -V $vcf  -O ${out}.snps.vcf.gz
$GATK SelectVariants -R $reference --select-type  INDEL  -V $vcf  -O ${out}.indel.vcf.gz
## filter SNP and INDEL
$GATK VariantFiltration -R $reference -V ${out}.snps.vcf.gz --filter-expression "QD < 2.0 || FS > 60.0 || MQ < 40.0 || SOR > 3.0 || MQRankSum < -12.5 || ReadPosRankSum < -8.0" --filter-name "SNP_FILTER" -O ${out}.snps.HDflt.vcf.gz
$GATK VariantFiltration -R $reference -V ${out}.snps.vcf.gz --filter-expression "QD < 2.0 || FS > 200.0 || SOR > 10.0 || MQRankSum < -12.5 || ReadPosRankSum < -20" --filter-name "INDEL_FILTER" -O ${out}.indel.HDflt.vcf.gz
## get pass for SNP and INDEL
$GATK MergeVcfs -I ${out}.snps.HDflt.vcf.gz -I ${out}.indel.HDflt.vcf.gz -O ${out}.SNP.INDEL.HDflt.vcf.gz
$GATK SelectVariants -R $reference -V ${out}.SNP.INDEL.HDflt.vcf.gz -O ${out}.SNP.INDEL.HDflt.pass.vcf.gz -select "vc.isNotFiltered()"

## get SNP and indel
$vcftools --gzvcf ${out}.SNP.INDEL.HDflt.pass.vcf.gz --minQ 30 --min-alleles 2 --max-alleles 2 --remove-indels --recode --recode-INFO-all --out ${out}.SNP.HDflt.pass
$vcftools --gzvcf ${out}.SNP.INDEL.HDflt.pass.vcf.gz --minQ 30 --min-alleles 2 --max-alleles 2 --remove-snps --recode --recode-INFO-all --out ${out}.INDEL.HDflt.pass

GATK最常用的是硬过滤,因为简单直接,但还有机器学习的方法VQSR那个更加适用于自己的数据

ANGSD进行SNP calling

这个就用来 call 出 SNP 之后与GATK结果取共同鉴定出的SNP,让SNP calling结果更准确,然后他输出的是基因型的似然值(GL),而不是确定的基因型,但下游的大多分析都是基于genotype的,因此,还是将交集部分利用GATK进行genotype calling

angsd -bam $bam.list -only_proper_pairs 1 -uniqueOnly 1 -remove_bads 1 \
                     -minQ 20 -minMapQ 30 -C 50 -ref $reference.fa -r $chr \
                     -out $chr -doQsDist 1 -doDepth 1 -doCounts 1 -maxDepth $max

angsd -bam $bam.list -only_proper_pairs 1 -uniqueOnly 1 -skipTriallelic 1 -remove_bads 1 \
                     -minQ 20 -minMapQ 30 -C 50 -ref $reference.fa -r $chr -out $chr \
                     -doMaf 1 -doMajorMinor 1 -GL 1 -setMinDepth $mindepth -setMaxDepth $maxdepth \
                     -doCounts 1 -dosnpstat 1 -SNP_pval 1

# 第一步是call SNP,及计算多个参数
# 第二步是多个过滤参数及估计genotype likelihood(GL),保证SNP的准确性
# -SNP_pval 1     SNP的p_value,可用于过滤
# -doMajorMinor 1 最终文件无 ref alt 而是 major minor 形式
# -doMaf 1        1: Frequency (fixed major and minor)
# -GL 1           1: SAMtools
                  2: GATK
                  3: SOAPsnp
                  4: SYK
# -doGeno         进行genotype calling,
                  1:print out major minor
                  2: print the called genotype as -1,0,1,2 (count of minor)
                  4: print the called genotype as AA, AC, AG, ...
                  8: print all 3 posts (major,major),(major,minor),(minor,minor)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352

推荐阅读更多精彩内容