是否有函数可以根据对齐参数计算对齐序列的分数?

8 投票
2 回答
14051 浏览
提问于 2025-04-16 15:52

我想给已经对齐的序列打分。假设有这样的情况:

seq1 = 'PAVKDLGAEG-ASDKGT--SHVVY----------TI-QLASTFE'
seq2 = 'PAVEDLGATG-ANDKGT--LYNIYARNTEGHPRSTV-QLGSTFE'

还有一些给定的参数:

substitution matrix : blosum62
gap open penalty : -5
gap extension penalty : -1

我查阅了biopython的食谱,但我只找到了一种叫做blogsum62的替换矩阵。我觉得应该有其他人已经实现了这种库。

所以,有人能推荐一些库或者最简短的代码来解决我的问题吗?

提前谢谢大家!

2 个回答

10

blosum62 是一个包含276个项目的字典。

我更倾向于补充缺少的项目,因为它只代表276个元素的一个迭代,而我们要分析的序列可能会有超过276个元素。因此,如果你使用函数 score_match() 来计算每对的分数,这个函数就得对序列中的每个元素进行测试 if pair not in matrix,这意味着肯定会比276次多得多。

还有一个耗时的地方是:每次 score += something 都会创建一个新的整数,并把名字 score 绑定到这个新对象上。每次绑定都需要一些时间,而如果用生成器直接生成整数并立即加到当前值上,就不会有这个时间消耗。

from Bio.SubsMat.MatrixInfo import blosum62 as blosum
from itertools import izip

blosum.update(((b,a),val) for (a,b),val in blosum.items())

def score_pairwise(seq1, seq2, matrix, gap_s, gap_e, gap = True):
    for A,B in izip(seq1, seq2):
        diag = ('-'==A) or ('-'==B)
        yield (gap_e if gap else gap_s) if diag else matrix[(A,B)]
        gap = diag

seq1 = 'PAVKDLGAEG-ASDKGT--SHVVY----------TI-QLASTFE'
seq2 = 'PAVEDLGATG-ANDKGT--LYNIYARNTEGHPRSTV-QLGSTFE'

print sum(score_pairwise(seq1, seq2, blosum, -5, -1))

这个 score_pairwise() 是一个生成器函数,因为它使用了 yield 而不是 return

编辑:
更新了适用于Python 3的代码:

from Bio.SubsMat.MatrixInfo import blosum62 as blosum

blosum.update(((b,a),val) for (a,b),val in list(blosum.items()))

def score_pairwise(seq1, seq2, matrix, gap_s, gap_e, gap = True):
    for A,B in zip(seq1, seq2):
        diag = ('-'==A) or ('-'==B)
        yield (gap_e if gap else gap_s) if diag else matrix[(A,B)]
        gap = diag

seq1 = 'PAVKDLGAEG-ASDKGT--SHVVY----------TI-QLASTFE'
seq2 = 'PAVEDLGATG-ANDKGT--LYNIYARNTEGHPRSTV-QLGSTFE'

print(sum(score_pairwise(seq1, seq2, blosum, -5, -1)))
12

Jessada,

Blosum62矩阵(注意拼写哦;)在Bio.SubsMat.MatrixInfo里,它是一个字典,里面的内容是一些元组对应的分数(比如说('A', 'A')的分数是4分)。这个矩阵没有考虑空缺,而且只包含矩阵的一部分(也就是说,它可能有('T', 'A'),但没有('A', 'T'))。在Biopython里有一些辅助函数,包括在Bio.Pairwise里的函数,但这是我想到的一个解决方案:

from Bio.SubsMat import MatrixInfo

def score_match(pair, matrix):
    if pair not in matrix:
        return matrix[(tuple(reversed(pair)))]
    else:
        return matrix[pair]

def score_pairwise(seq1, seq2, matrix, gap_s, gap_e):
    score = 0
    gap = False
    for i in range(len(seq1)):
        pair = (seq1[i], seq2[i])
        if not gap:
            if '-' in pair:
                gap = True
                score += gap_s
            else:
                score += score_match(pair, matrix)
        else:
            if '-' not in pair:
                gap = False
                score += score_match(pair, matrix)
            else:
                score += gap_e
    return score

seq1 = 'PAVKDLGAEG-ASDKGT--SHVVY----------TI-QLASTFE'
seq2 = 'PAVEDLGATG-ANDKGT--LYNIYARNTEGHPRSTV-QLGSTFE'

blosum = MatrixInfo.blosum62

score_pairwise(seq1, seq2, blosum, -5, -1)

这个方案会为你的比对返回82分。虽然可能还有更好看的方法来实现这些,但这个应该是个不错的起点。

撰写回答