生信-序列比对

盲人摸象与BLAST 算法

2018-08-13  本文已影响0人  云间的鲸鱼

“看到BLAST算法,我一下子想起了盲人摸象这个小故事,只不过这一次,要讲一个新故事了,权且叫它‘新盲人摸象’吧。”

国王有一天突然想和当初玩摸象的盲人再玩个新游戏,就把一个自己最喜爱的盲人叫了过来。

国王对他说:“嘿,你还记得上次我告诉你们的象的全貌吗?”

盲人:“当然记得啦,它的牙齿像一个大萝卜,鼻子像一段长长的水管,耳朵像大蒲扇,四条腿像柱子,尾巴像条草绳,···”

国王:“好啦好啦,看来你都记住了。我下面带你到动物园里面去,你要靠摸准确地找出大象哦。”

盲人:“谨遵王命,喵喵喵。”

国王:“汪汪汪。”

于是国王带了盲人到动物园去,刚进去,一只鸡咯咯叫着从他们身边跑过,盲人一欠身就把它捞了起来上下其手:“喔,嘴又尖又短像个小图钉,摸不到鼻子和耳朵,浑身都是鸡毛掸子的毛毛,只有两条小细腿,尾巴似乎也摸不到,看来完全不是哦。”

鸡奋力挣脱了他的咸猪手,委屈地咯咯着。

接着他们又路遇鸭、羊、狗、鸡,盲人通过抚摸牙齿、鼻子、耳朵、腿、尾巴的方式都排除了。

于是二人头顶着鸡毛、鸭毛、狗毛继续往前走。

在驴马馆,盲人有了惊喜的发现:“嗨呀,尾巴像草绳!嗨呀,四条腿!”

国王站在一旁,憋着笑,要看盲人出丑。

盲人沿着尾巴开始往别的地方摸,“背上这些毛怎么肥四?啊,说不定是长了草。这耳朵好小哦,根本不能扇风嘛。也摸不到长鼻子和大牙,看来根本不是嘛。”

盲人又依次因为野猪的獠牙、长颈鹿的腿、大食蚁兽的长鼻子而空欢喜一场。终于到了大象馆,盲人此时已谨慎了许多,“鼻子对上了”,他接着往上摸,“牙也能对上”,“耳朵是蒲扇,腿是柱子,尾巴是草绳,身上没毛”。

“是大象!”他转身兴奋地告诉国王。“妙啊!”国王也为自己看到了盲人笨拙而有趣的比对而兴奋。“走走走,我要给你升官,就······去管光垫鬃菊吧,干这个,眼睛好不好使都是次要的。”

盲人也很兴奋:“国王万岁,王啊,我的腿有些疼,不知道是不是被什么咬了。”

国王:“啊,好像是被你摸的那条狗咬了,我刚刚似乎也中招了。不要紧,太医刚刚从极寒之地带来几针异喵,一会就顺便给我们打上。”

后来,再也没人见过国王和盲人,这个王国,从此就没有新的故事了。新盲人摸象,是流传下来的最后一个故事。

故事讲完了。大象,就对应着我们提交的DNA或是氨基酸序列,动物园,就是包含着许许多多其他序列的数据库。而我们的目标,就是应用BLAST算法,给出提交序列与数据库序列的最佳局部联配结果。

具体过程

序列:TGCGGAGCGG
获取单词表:TGC、GCG、CGG、GGA、GAG、AGC(GCG、CGG)<最后两个前面已经出现过了,这里舍去>

列举所有的k_字母表:如AAA、AAT、AAC、AAG等等。
依次将这些字母依据打分矩阵和上一步获得的k_字母匹配打分,获得一个标志着匹配度的分数。
设置一个匹配值T,将所有分数超过T的k_字母加入查询树当中去。T越大,越严格,当T设为最大时,种子中的k_字母就是上一步所获得的所有K字母。

部分实现

这次比较新的东西主要是构建查询树这一部分,其他在前面写过,此处略去不表。

计分规则,匹配计3分,AT或CG配对计1分,其他不匹配情况计-3分。

def mark(word1, word2):
    # 给两个单词打分
    ld = ["AT", "TA", "CG", "GC"]
    score = 0
    for a, b in zip(word1, word2):
        if a == b:
            score += 3
        elif a + b in ld:
            score += 1
        else:
            score += -3
    return score

def find_all(L,K,A,word):
    # 参数分别为字符列表、单词长度、包含结果的列表、当前单词
    if len(word) == K:
        A.append(word)
        return
    for i in L:
        find_all(L,K,A,word+i)

def get_tree(seq, K, T):
    # 参数分别为DNA序列,单词长度K,分数阈值T
    F = []
    for i in range(0, len(seq)-K+1):
        F.append(seq[i:i+K])
    # 先把列表转换为集合实现去重,再转换为列表
    F = list(set(F))
    A = []
    find_all(['A','T','C','G'], K, A, "")
    TREE = []
    for i in F:
        for j in A:
            if mark(i,j) >= T:
                TREE.append(j)
    print("查询树中共包含", len(TREE), "个节点")
    for t in TREE:
        print(t)

调用函数

get_tree("ATCGTCCA",3,9)
get_tree("ATCGTCCA",3,6)
get_tree("ATCGTCCA",3,3)

结果如下

查询树中共包含 6 个节点
CGT
CCA
TCG
TCC
GTC
ATC
查询树中共包含 24 个节点
CCT
CGA
CGT
GGT
CCA
CCT
CGA
GCA
ACG
TCC
TCG
TGG
ACC
TCC
TCG
TGC
CTC
GAC
GTC
GTG
AAC
ATC
ATG
TTC
查询树中共包含 84 个节点
AGT
TGT
CAT
CTT
CCA
CCT
CGA
CGT
CGC
CGG
GCA
GCT
GGA
GGT
ACA
TCA
CAA
CTA
CCA
CCT
CCC
CCG
CGA
CGT
GCA
GCT
GGA
GGT
ACC
ACG
AGC
AGG
TAG
TTG
TCA
TCT
TCC
TCG
TGC
TGG
CCG
GCG
ACC
ACG
AGC
AGG
TAC
TTC
TCA
TCT
TCC
TCG
TGC
TGG
CCC
GCC
ATC
TTC
CAC
CAG
CTC
CTG
GAC
GAG
GTA
GTT
GTC
GTG
GCC
GGC
AAC
AAG
ATA
ATT
ATC
ATG
ACC
AGC
TAC
TAG
TTC
TTG
CTC
GTC

可以看到,当K降低时,查询树会更加庞大。

上一篇 下一篇

猜你喜欢

热点阅读