(20)一个WES实战-生信菜鸟团博客2周年精选文章集
WES就是通常我们说的全外显子测序,已经逐步应用到医疗领域了!本次例子的测试数据就是一个自闭症家系的全外显子测序数据结果,我本来雄心勃勃的想帮助他解决病因的问题,后来发现我还是太嫩了,只是会一点数据分析而已!
目录如下:
WES(一)测序质量控制
WES(二)snp-calling
WES(三)snp-filter
WES(四)不同个体的比较
WES(五)不同软件比较
WES(六)用annovar注释
WES(七)看de novo变异情况
其实还远远不够,剩余的分析,我会在直播我的基因组系列补全,欢迎大家继续围观!
WES(一)测序质量控制
Posted on 2015年11月1日
这一步主要看看这些外显子测序数据的测序质量如何:
首先用fastqc处理,会出一些图表,肯定是没问题的啦,如果数据有问题,公司就不会给你,那样不砸了他们自己的招牌嘛。
然后我们粗略统计下平均测序深度及目标区域覆盖度,这个是重点,不过一般没问题的,因为现在芯片捕获技术非常成熟了,而且实验水平大幅提升,没有以前那么多的问题了。
这个外显子项目的测序文件里面,mpileup文件是1371416525行,意味着总的测序长度是1.3G,以前我接触的一般是600M左右的
因为外显子目标区域并不大,就34729283bp,也就是约35M。
即使加上侧翼长度
54692160 外显子加上前后50bp
73066288 外显子加上前后100bp
90362533 外显子加上前后150bp
然后我要根据外显子记录文件对mpileup文件进行计数,统计外显子coverage,还有测序深度,这个脚本其实蛮有难度的!
我前面提到过外显子组的序列仅占全基因组序列的1%左右,而我在NCBI里面拿到 consensus coding sequence (CCDS)记录CCDS.20150512.txt文件,是基于hg38版本的,需要首先转换成hg19才可以来计算这次测序项目的覆盖度和平均测序深度。
参考:http://www.bio-info-trainee.com/?p=990 ( liftover基因组版本之间的coordinate转换)
awk '{print "chr"$3,$4,$5,$1,0,$2,$4,$5,"255,0,0"}' CCDS.20150512.exon.txt >CCDS.20150512.exon.hg38.bed
~/bio-soft/liftover/liftOver CCDS.20150512.exon.hg38.bed ~/bio-soft/liftover/hg38ToHg19.over.chain CCDS.20150512.exon.hg19.bed unmap
下面这个程序就是读取转换好的外显子记录的数据,对一家三口一起统计,然后再读取每个样本的20G左右的mpileup文件,进行统计,所以很耗费时间。
外显子目标区域平均测序深度接近100X,所以很明显是非常好的捕获效率啦!而全基因组背景深度才3.3,这 符合实验原理, 即与探针杂交碱基多的片段比少的片段更易被捕获. 对非特异杂交的,基因组覆盖度非特异的背景 DNA 也进行了测序。
接下来对测序深度进行简单统计,脚本如下,但是这个图没多大意思。因为我们的外显子的35M区域平均都接近100X的测序量
WES(二)snp-calling
Posted on 2015年11月1日
准备文件:下载必备的软件和参考基因组数据
1、软件
ps:还有samtools,freebayes和varscan软件,我以前下载过,这次就没有再弄了,但是下面会用到
2、参考基因组
3、参考 突变数据
第一步,下载数据
第二步,bwa比对
第三步,sam转为bam,并sort好
第四步,标记PCR重复,并去除
第五步,产生需要重排的坐标记录
第六步,根据重排记录文件把比对结果重新比对
第七步,把最终的bam文件转为mpileup文件
第八步,用bcftools 来call snp
第九步,用freebayes来call snp
第十步,用gatk 来call snp
第十一步,用varscan来call snp
下面的图片是按照顺序来的,我就不整理了
WES(三)snp-filter
Posted on 2015年11月1日
其中freebayes,bcftools,gatk都是把所有的snp细节都call出来了,可以看到下面这些软件的结果有的高达一百多万个snp,而一般文献都说外显子组测序可鉴定约8万个变异!
这样得到突变太多了,所以需要过滤。这里过滤的统一标准都是qual大于20,测序深度大于10。过滤之后的snp数量如下
perl -alne '{next if $F[5]<20;/DP=(\d+)/;next if $1<10;next if /INDEL/;/(DP4=.*?);/;print "$F[0]\t$F[1]\t$F[3]\t$F[4]:$1"}' Sample3.bcftools.vcf >Sample3.bcftools.vcf.filter
perl -alne '{next if $F[5]<20;/DP=(\d+)/;next if $1<10;next if /INDEL/;/(DP4=.*?);/;print "$F[0]\t$F[1]\t$F[3]\t$F[4]:$1"}' Sample4.bcftools.vcf >Sample4.bcftools.vcf.filter
perl -alne '{next if $F[5]<20;/DP=(\d+)/;next if $1<10;next if /INDEL/;/(DP4=.*?);/;print "$F[0]\t$F[1]\t$F[3]\t$F[4]:$1"}' Sample5.bcftools.vcf >Sample5.bcftools.vcf.filter
perl -alne '{next if $F[5]<20;/DP=(\d+)/;next if $1<10;next unless /TYPE=snp/;@tmp=split/:/,$F[9];print "$F[0]\t$F[1]\t$F[3]\t$F[4]:$tmp[0]:$tmp[1]"}' Sample3.freebayes.vcf > Sample3.freebayes.vcf.filter
perl -alne '{next if $F[5]<20;/DP=(\d+)/;next if $1<10;next unless /TYPE=snp/;@tmp=split/:/,$F[9];print "$F[0]\t$F[1]\t$F[3]\t$F[4]:$tmp[0]:$tmp[1]"}' Sample4.freebayes.vcf > Sample4.freebayes.vcf.filter
perl -alne '{next if $F[5]<20;/DP=(\d+)/;next if $1<10;next unless /TYPE=snp/;@tmp=split/:/,$F[9];print "$F[0]\t$F[1]\t$F[3]\t$F[4]:$tmp[0]:$tmp[1]"}' Sample5.freebayes.vcf > Sample5.freebayes.vcf.filter
perl -alne '{next if $F[5]<20;/DP=(\d+)/;next if $1<10;next if length($F[3]) >1;next if length($F[4]) >1;@tmp=split/:/,$F[9];print "$F[0]\t$F[1]\t$F[3]\t$F[4]:$tmp[0]:$tmp[1]:$tmp[2]"}' Sample3.gatk.UG.vcf >Sample3.gatk.UG.vcf.filter
perl -alne '{next if $F[5]<20;/DP=(\d+)/;next if $1<10;next if length($F[3]) >1;next if length($F[4]) >1;@tmp=split/:/,$F[9];print "$F[0]\t$F[1]\t$F[3]\t$F[4]:$tmp[0]:$tmp[1]:$tmp[2]"}' Sample4.gatk.UG.vcf >Sample4.gatk.UG.vcf.filter
perl -alne '{next if $F[5]<20;/DP=(\d+)/;next if $1<10;next if length($F[3]) >1;next if length($F[4]) >1;@tmp=split/:/,$F[9];print "$F[0]\t$F[1]\t$F[3]\t$F[4]:$tmp[0]:$tmp[1]:$tmp[2]"}' Sample5.gatk.UG.vcf >Sample5.gatk.UG.vcf.filter
perl -alne '{@tmp=split/:/,$F[9];next if $tmp[3]<10;print "$F[0]\t$F[1]\t$F[3]\t$F[4]:$tmp[0]:$tmp[3]"}' Sample3.varscan.snp.vcf >Sample3.varscan.snp.vcf.filter
perl -alne '{@tmp=split/:/,$F[9];next if $tmp[3]<10;print "$F[0]\t$F[1]\t$F[3]\t$F[4]:$tmp[0]:$tmp[3]"}' Sample4.varscan.snp.vcf >Sample4.varscan.snp.vcf.filter
perl -alne '{@tmp=split/:/,$F[9];next if $tmp[3]<10;print "$F[0]\t$F[1]\t$F[3]\t$F[4]:$tmp[0]:$tmp[3]"}' Sample5.varscan.snp.vcf >Sample5.varscan.snp.vcf.filter
这样不同工具产生的snp记录数就比较整齐了,我们先比较四种不同工具的call snp的情况,然后再比较三个人的区别。
然后写了一个程序把所有的snp合并起来比较
得到了一个很有趣的表格,我放在excel里面看了看 ,主要是要看生物学意义,但是我的生物学知识好多都忘了,得重新学习了
WES(四)不同个体的比较
Posted on 2015年11月1日
3-4-5分别就是孩子、父亲、母亲
我对每个个体取他们的四种软件的公共snp来进行分析,并且只分析基因型,看看是否符合孟德尔遗传定律
结果如下:
粗略看起来好像很少不符合孟德尔遗传定律耶
然后我写了程序计算
总共127138个可以计算的位点,共有18063个位点不符合孟德尔遗传定律,而且它们在染色体的分布情况如下
我检查了一下,不符合的原因,发现我把
chr1 100617887 C T:DP4=0,0,36,3 T:1/1:40 T:1/1:0,40:40 miss T:DP4=0,0,49,9 T:1/1:59 T:1/1:0,58:59 miss T:DP4=0,0,43,8 T:1/1:53 T:1/1:0,53:53 T:1/1:50
计算成了chr1 100617887 C 0/0 0/0 1/1 所以认为不符合,因为我认为只有四个软件都认为是snp的我才当作是snp的基因型,否则都是0/0
那么我就改写了程序,全部用gatk结果来计算。这次可以计算的snp有个176036,不符合的有20309,而且我看了不符合的snp的染色体分布,Y染色体有点异常
但是很失败,没什么发现!
WES(五)不同软件比较
Posted on 2015年11月1日
主要是画韦恩图看看,参考:http://www.bio-info-trainee.com/?p=893
对合并而且过滤的高质量snp信息来看看四种不同的snp calling软件的差异
我们用R语言来画韦恩图
可以看出不同软件的差异还是蛮大的,所以我只选四个软件的公共snp来进行分析
首先是sample3
然后是sample4
然后是sample5
可以看出,不同的软件差异还是蛮大的,所以我重新比较了一下,这次只比较,它们不同的软件在exon位点上面的snp的差异,毕竟,我们这次是外显子测序,重点应该是外显子snp
然后我们用同样的程序,画韦恩图,这次能明显看出来了,大部分的snp位点都至少有两到三个软件支持
所以,只有测序深度达到一定级别,用什么软件来做snp-calling其实影响并不大。
WES(六)用annovar注释
Posted on 2015年11月1日
使用annovar软件参考自:http://www.bio-info-trainee.com/?p=641
/home/jmzeng/bio-soft/annovar/convert2annovar.pl -format vcf4 Sample3.varscan.snp.vcf > Sample3.annovar
/home/jmzeng/bio-soft/annovar/convert2annovar.pl -format vcf4 Sample4.varscan.snp.vcf > Sample4.annovar
/home/jmzeng/bio-soft/annovar/convert2annovar.pl -format vcf4 Sample5.varscan.snp.vcf > Sample5.annovar
然后用下面这个脚本批量注释
Reading gene annotation from /home/jmzeng/bio-soft/annovar/humandb/hg19_refGene.txt ... Done with 50914 transcripts (including 11516 without coding sequence annotation) for 26271 unique genes
最后查看结果可知,真正在外显子上面的突变并不多
23515 Sample3.anno.exonic_variant_function
23913 Sample4.anno.exonic_variant_function
24009 Sample5.anno.exonic_variant_function
annovar软件就是把我们得到的十万多个snp分类了,看看这些snp分别是基因的哪些位置,是否引起蛋白突变
downstream
exonic
exonic;splicing
intergenic
intronic
ncRNA_exonic
ncRNA_intronic
ncRNA_splicing
ncRNA_UTR3
ncRNA_UTR5
splicing
upstream
upstream;downstream
UTR3
UTR5
UTR5;UTR3
WES(七)看de novo变异情况
Posted on 2015年11月1日
de novo变异寻找这个也属于snp-calling的一部分,但是有点不同的就是该软件考虑了一家三口的测序文件,找de novo突变
软件有介绍这个功能:http://varscan.sourceforge.net/trio-calling-de-novo-mutations.html
而且还专门有一篇文章讲ASD和autism与de novo变异的关系,但是文章不清不楚的,没什么意思
Trio Calling for de novo Mutations
Min coverage: 10
Min reads2: 4
Min var freq: 0.2
Min avg qual: 15
P-value thresh: 0.05
Adj. min reads2: 2
Adj. var freq: 0.05
Adj. p-value: 0.15
Reading input from trio.filter.mpileup
1371416525 bases in pileup file (137M的序列)
83123183 met the coverage requirement of 10 (其中有83M的测序深度大于10X)
145104 variant positions (132268 SNP, 12836 indel) (共发现15.5万的变异位点)
4403 were failed by the strand-filter
139153 variant positions reported (126762 SNP, 12391 indel)
502 de novo mutations reported (376 SNP, 126 indel) (真正属于 de novo mutations只有502个)
1734 initially DeNovo were re-called Germline
12 initially DeNovo were re-called MIE
3 initially DeNovo were re-called MultAlleles
522 initially MIE were re-called Germline
1 initially MIE were re-called MultAlleles
3851 initially Untransmitted were re-called Germline
然后我看了看输出的文件trio.mpileup.output.snp.vcf
软件是这样解释的:The output of the trio subcommand is a single VCF in which all variants are classified as germline (transmitted or untransmitted), de novo, or MIE.
FILTER - mendelError if MIE, otherwise PASS
STATUS - 1=untransmitted, 2=transmitted, 3=denovo, 4=MIE
DENOVO - if present, indicates a high-confidence de novo mutation call
里面的信息量好还是不清楚
我首先对我们拿到的trio.de_novo.mutaion.snp.vcf文件进行简化,只看基因型!
head status.txt (顺序是dad,mom,child)
STATUS=2 0/0 0/1 0/1
STATUS=2 1/1 1/1 1/1
STATUS=2 0/1 0/0 0/1
STATUS=2 1/1 1/1 1/1
STATUS=1 0/1 0/0 0/0
STATUS=1 0/1 0/0 0/0
STATUS=2 1/1 1/1 1/1
STATUS=2 1/1 1/1 1/1
STATUS=2 1/1 1/1 1/1
STATUS=2 0/1 0/1 0/1
那么总结如下:
26564 STATUS=1 无所以无 (0/0 0/1 0/0或者 0/1 0/0 0/0等等)
97764 STATUS=2 有所以有 (1/1 1/1 1/1 或者0/1 0/1 1/1等等)
385 STATUS=3 无中生有 (0/0 0/0 0/1 或者0/0 0/0 1/1)
1485 STATUS=4 有中生无 (1/1 0/1 0/0 等等)
我用annovar注释了一下
/home/jmzeng/bio-soft/annovar/convert2annovar.pl -format vcf4 trio.mpileup.output.snp.vcf > trio.snp.annovar
/home/jmzeng/bio-soft/annovar/annotate_variation.pl -buildver hg19 --geneanno --outfile trio.snp.anno trio.snp.annovar /home/jmzeng/bio-soft/annovar/humandb
结果是:
A total of 132268 locus in VCF file passed QC threshold, representing 132809 SNPs (86633 transitions and 46176 transversions) and 3 indels/substitutions
可以看到最后被注释到外显子上面的突变有两万多个
23794 284345 3123333 trio.snp.anno.exonic_variant_function
这个应该是非常有意义的,但是我还没学会后面的分析。只能先做到这里了