Edit Distance编辑距离(NM tag)- sam/bam格式解读进阶
sam格式很精炼,几乎包含了比对的所有信息,我们平常用到的信息很少,但特殊情况下,我们会用到一些较为生僻的信息,关于这些信息sam官方文档的介绍比较精简,直接看估计很难看懂。
今天要介绍的是如何通过bam文件统计比对的indel和mismatch信息
首先要介绍一个非常重要的概念--编辑距离
定义:从字符串a变到字符串b,所需要的最少的操作步骤(插入,删除,更改)为两个字符串之间的编辑距离。
(2016年11月17日:增加,有点误导,如果一个插入有两个字符,那编辑距离变了几呢?1还是2?我又验证了一遍:确实是2)
这也是sam文档中对NM这个tag的定义。
编辑距离是对两个字符串相似度的度量(参见文章:Edit Distance)
举个栗子:两个字符串“eeba”和“abca”的编辑距离是多少?
根据定义,通过三个步骤:1.将e变为a 2.删除e 3.添加c,我们可以将“eeba”变为“abca”
所以,“eeba”和“abca”之间的编辑距离为3
回到序列比对的问题上
下面是常见的二代比对到ref的结果(bwa):
D00360:96:H2YLYBCXX:1:2110:18364:84053 353 seq1_len154_cov5 1 1 92S59M8I17M1D6M1D67M seq30532_len2134_cov76 1 0 AAAAAAAAAAAAAAAAAAAAAAAACCCTGTCTCTAATAAAATACAAACAATTAGCCGGGCATGGTGGCACGCGCCTTTAGTCCCAGCTACTAGGGAGGCTGAGGCAGGGGAATTGTTTGAACCCGGGAGGTGGAGGTTGCAGTGAGCGGAGTTTTTTTCACTGCACTCCAGCCTGGTGACAAATCAAAAATCCATTTCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAACAACAAA
DDDDDHIIIIIIII<EHHII?EHH0001111111<11<DEH1D1<FH1D<<<C<@GEHD</<11<101<1D<<C<E0D11<<1<D?1F1CC1DE110C0D1011100////0DD<1=@1=FGHCDHH<FG<D0<<<EF?CE<00<<0<D//0;<:D/////;///////;8F.;/.8.8......88.9........-8BBGADHIIHD?>D?HH<,>=HHDD,5CHDCDHD><,,,--8----8-8-- NM:i:25 MD:Z:16A21C16C0A3T15^A6^G1G0T0G3C2T0G1C41A4A2A3 AS:i:49 XS:i:42 SA:Z:seq13646_len513_cov63,125,-,103S125M21S,1,11; RG:Z:chr22
这是ref序列
>seq1_len154_cov5
GGGAGGCTGAGGCAGGAGAATTGTTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCAAGATTGCACTCCAGCCTGGATGACAAGAGTGAAACTCTGTCTCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
cigar字段包含了序列比对的简化信息,M(匹配比对,包含match和mismatch),=(纯match),X(纯mismatch),I(插入),D(删除),还有N、P和S、H。(注:目前只在blasr比对结果中见过=和X)
根据cigar字段可以统计indel信息,但是无法统计mismatch。
这个时候就可以用到NM tag了,mismatch = NM – I - D = 25 – 8 – 1 – 1 = 15
有兴趣的可以对着cigar数一遍,下面是我无聊数着的结果,也是15个
使用python的pysam模块可以很容易的提取出每个比对结果的NM信息
参见之前的帖子:pysam - 多种数据格式读写与处理模块(python)
再次验证一遍:证明NM=len(mismatch) + len(insertion) + len(deletion), 而不是 count(mismatch) + count(insertion) + count(deletion) (count的意思是三个碱基的insertion算一个)
>>> bam_file = pysam.AlignmentFile(infile, "rb")
>>> for line in bam_file:
... if 300 < line.query_alignment_length < 500:
... break
...
>>> line.query_alignment_length
321
>>> line.seq
'CTCTTCATCACGTCACTTGTCCATGTCAATGGCTACAGGTTGGAAGTTTGGCCGCGGAGGGTGGGCAGGCAAGAGAAAGAAATCAGATAGGGCAGATGGTAGGGTAAAAGGAGGGGGTTAAGTGCAAATTGTCTACTGTTTGCAAATGGGAAGCATGTGATTGTTAAAATTTATACGATAAACCTTCTCATCATGTTGAGTCTCATGCTTGCGCCAAGAAGATCGGGTTCGGCGGGTCAAGCTGATAAGCAACTTGGGCAGCAAAGTCGTTCAGTGATACAAAATCATGTGCAAAAATCACAAGCATTCTTATAAACACCA'
>>> line.cigarstring
'5148H3M1I2M1I4M2I3M3I3M1D2M1I4M3I1M1I4M1D10M1D5M4I4M3D1M3I18M1I1M1I1M1I4M4D2M1I2M2I4M2I4M1I4M5I4M1I9M1I14M3I1M1I2M2I7M2I7M3I2M1I5M2I1M1I2M1I1M1I4M5I3M1I2M3I1M1I4M4I3M4I2M2I1M3I19M3I10M2I4M1I11M1D27M2I6M25212H'
>>> line.reference_name
'Backbone_1'
>>> line.reference_start
7164
>>> line.reference_end
7413
>>> line.get_tag('NM')
100
取出了一条长度适中的比对结果,cigar字段比较全面。
取出了比对上的ref:
>>> ref = 'CTCTCTCACCACTCCTATTCAACACAGTGTTGGAAGTTCTGGACAGGGCAATCAGGCAAGAGAAAGAAATAAAGGGTATTCAATTAGGAAAAGAGGAAGTCAAATTGTCCCCGTTTGCAGATGACATGATTGTATATTTAGAAAACCCCACTGTTTCAGCCCCAAATCTCCTTAAGCTGATAAGCAACTTCAGCAAAGTCTCAGGATACAAAATCAATGTGCAAAAATCACAAGCATTCTTATACACCA'
先通过我自己写的cigar校正函数校正:
def formatSeqByCigar(seq, cigar):
'''
Input: query_alignment_sequence and cigar from sam file
Output: formatSeq
Purpose: make sure the pos is one to one correspondence(seq to ref)
'''
formatSeq = ''
pointer = 0; qstart = 0; qend = -1; origin_seq_len = 0
if cigar[0][0] == 4 or cigar[0][0] == 5:
qstart = cigar[0][1]
if cigar[-1][0] == 4 or cigar[-1][0] == 5:
qend = - cigar[-1][1] - 1 # fushu count
for pair in cigar:
operation = pair[0]
cigar_len = pair[1]
if operation == 0: # 0==M
formatSeq += seq[pointer:(pointer+cigar_len)]
pointer += cigar_len
origin_seq_len += cigar_len
elif operation == 1: # 1==I
pointer += cigar_len
origin_seq_len += cigar_len
elif operation == 2: # 2==D
formatSeq += 'D'*cigar_len
elif operation == 4 or operation == 5: # 5==H
origin_seq_len += cigar_len
continue
else:
print (cigar)
raise TypeError("There are cigar besides S/M/D/I/H\n")
return formatSeq, qstart, qend, origin_seq_len
然后分别计算deletion和mismatch:
>>> i = 0
>>> count = 0
>>> while i < len(ref):
if formatSeq[i] != ref[i]:
count += 1
i += 1 >>> count
17
>>> formatSeq.count('D')
11
可以看出deletion有11个,退出mismatch有6个。
随手一推insertion有83个。
而
>>> cigarstring = '5148H3M1I2M1I4M2I3M3I3M1D2M1I4M3I1M1I4M1D10M1D5M4I4M3D1M3I18M1I1M1I1M1I4M4D2M1I2M2I4M2I4M1I4M5I4M1I9M1I14M3I1M1I2M2I7M2I7M3I2M1I5M2I1M1I2M1I1M1I4M5I3M1I2M3I1M1I4M4I3M4I2M2I1M3I19M3I10M2I4M1I11M1D27M2I6M25212H'
>>> cigarstring.count('I')
41
>>> cigarstring.count('D')
6
用count计算显然不对。
验证成功
真切的明白了计算机有多么伟大,如果要是你肉眼去比对去数的话,我估计你会立马崩溃。
Edit Distance编辑距离(NM tag)- sam/bam格式解读进阶的更多相关文章
- mismatch位置(MD tag)- sam/bam格式解读进阶
这算是第二讲了,前面一讲是:Edit Distance编辑距离(NM tag)- sam/bam格式解读进阶 MD是mismatch位置的字符串的表示形式,貌似在call SNP和indel的时候会用 ...
- sam/bam格式
1)Sam (Sequence Alignment/Map) ------------------------------------------------- 1) SAM 文件产生背景 随着Ill ...
- [LeetCode] Edit Distance 编辑距离
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...
- leetCode 72.Edit Distance (编辑距离) 解题思路和方法
Edit Distance Given two words word1 and word2, find the minimum number of steps required to convert ...
- [LeetCode] 72. Edit Distance 编辑距离
Given two words word1 and word2, find the minimum number of operations required to convert word1 to ...
- leetcode72. Edit Distance(编辑距离)
以下为个人翻译方便理解 编辑距离问题是一个经典的动态规划问题.首先定义dp[i][j表示word1[0..i-1]到word2[0..j-1]的最小操作数(即编辑距离). 状态转换方程有两种情况:边界 ...
- 【LeetCode每天一题】Edit Distance(编辑距离)
Given two words word1 and word2, find the minimum number of operations required to convert word1 to ...
- 【LeetCode】72. Edit Distance 编辑距离(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 记忆化搜索 动态规划 日期 题目地址:http ...
- edit distance(编辑距离,两个字符串之间相似性的问题)
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...
随机推荐
- [转]get,post数据长度的限制
一.问题起因 在某项目释放后Bug统计的附件<释放后问题>里有: 问题 原因 分析 备注 CSV处理时,如果处理的主题数过多,发生URL参数上限的错误: 可变长度的参数通过URL方式传递, ...
- [Django_1_2]数据库设置
Django 数据库设置 本篇将介绍Django中的数据库设置,了解模型(models,数据库中的表项设计). 上一篇文章为:<a href="http://www.cnblogs.c ...
- div+css基础
Div+css技术 Div是用于存放文字,图片,元素的容器 Css 是用于指定存放在div中的内容如何显示,包括内容的位置和外观(层叠样式表) Html 文件 <!--必须引入的文件--> ...
- xcode下编译.a文件的路径
http://www.it165.net/pro/html/201503/36842.html 每当我们编译之后, 实际上系统就给我编译好了一个可以运行的.app文件,在某个路径下 如果我们建立的是静 ...
- c++中char*\wchar_t*\string\wstring之间的相互转换
string U2A(const wstring& str)//Unicode字符转Ascii字符 { string strDes; if ( str.empty() ) goto __end ...
- UVA 11552 四 Fewest Flops
Fewest Flops Time Limit:2000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Statu ...
- MyBatis Mapper 接口如何通过JDK动态代理来包装SqlSession 源码分析
我们以往使用ibatis或者mybatis 都是以这种方式调用XML当中定义的CRUD标签来执行SQL 比如这样 <?xml version="1.0" encoding=& ...
- s2-029 Struts2 标签远程代码执行分析(含POC)
1.标签介绍 Struts2标签库提供了主题.模板支持,极大地简化了视图页面的编写,而且,struts2的主题.模板都提供了很好的扩展性.实现了更好的代码复用.Struts2允许在页面中使用自定义组件 ...
- JAVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版下载
JAVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版下载JDK(Java Development Kit,Java开发包,Java开发工具)是一个写Java的applet和 ...
- SQL——存储过程实例 循环
--循环 create or replace procedure p_xunhuan(input in number,output out number) is ); begin ; ..input ...