【问题标题】:How to find inverted repeated pattern in a FASTA sequence?如何在 FASTA 序列中找到反向重复模式?
【发布时间】:2018-01-14 07:04:57
【问题描述】:

假设我的长序列看起来像:

5’-AGGGTTTCCC**TGACCT**TCACTGC**AGGTCA**TGCA-3

这个长序列中的两个斜体子序列(这里是两个星号)一起称为反向重复模式。这两个子序列中四个字母(如 A、T、G、C)的长度和组合会有所不同。但这两个子序列之间存在关系。请注意,当您考虑第一个子序列时,它的互补子序列是 ACTGGA(根据 A 与 T 结合,G 与 C 结合),当您反转此互补子序列(即最后一个字母在前)时,它与第二个子序列匹配。

FASTA 序列中存在大量此类模式(包含 1000 万个 ATGC 字母),我想找到此类模式及其开始和结束位置。

【问题讨论】:

  • 有长度限制吗?这看起来像是一项计算量非常大的任务。
  • 1) 反向重复多长时间(至少)? 2) 他们可以相距多远(最大)?
  • 总是两个子序列可以形成一个反向重复单元。假设它们相隔 100 个碱基。

标签: python fasta


【解决方案1】:

我是 Python 和生物信息学的新手,但我正在通过 rosalind.info 网站学习两者。您可以使用后缀树来执行此操作。后缀树(参见http://en.wikipedia.org/wiki/Suffix_tree)是一种神奇的数据结构,它使生物信息学中的一切成为可能。您可以快速定位多个长序列中的公共子字符串。后缀树只需要线性时间,因此长度为 10,000,000 是可行的。

所以首先找到序列的逆补。然后将两者都放入后缀树中,并找到它们之间的公共子字符串(一些最小长度)。

下面的代码使用这个后缀树实现:http://www.daimi.au.dk/~mailund/suffix_tree.html。它是用 C 语言编写的,带有 Python 绑定。它不会处理大量的序列,但两个没问题。但是我不能说这是否能处理 10,000,000 的长度。

from suffix_tree import GeneralisedSuffixTree

baseComplement = { 'A' : 'T', 'C' : 'G', 'G' : 'C', 'T' : 'A' }

def revc(seq):
    return "".join([baseComplement[base] for base in seq[::-1]])

data = "AGGGTTTCCCTGACCTTCACTGCAGGTCATGCA"
# revc  TGCATGACCTGCAGTGAAGGTCAGGGAAACCCT
#       012345678901234567890123456789012
#                 1         2         3
minlength = 6

n = len(data)
tree = GeneralisedSuffixTree([data, revc(data)])
for shared in tree.sharedSubstrings(minlength):
    #print shared
    _, start, stop = shared[0]
    seq = data[start:stop]
    _, rstart, rstop = shared[1]
    rseq = data[n-rstop:n-rstart]
    print "Match: {0} at [{1}:{2}] and {3} at [{4}:{5}]".format(seq, start, stop, rseq, n-rstop, n-rstart)

这会产生输出

Match: AGGTCA at [23:29] and TGACCT at [10:16]
Match: TGACCT at [10:16] and AGGTCA at [23:29]
Match: CTGCAG at [19:25] and CTGCAG at [19:25]

它找到每个匹配两次,每端一次。里面也有一个反向回文!

【讨论】:

  • 非常感谢。我在下面发表了评论(算法的一个小版本)。你能实现吗?
  • @user1964587:如果这回答了问题,请点击复选标记接受答案。至于实现你的想法,我会留给你。 :-) 但是,您提出的解决方案听起来至少需要 O(n^2) 运行时间,而后缀树是 O(n),因此会更快。但对于 10,000,000 长的序列,您将需要大量 RAM。
  • 是的,我同意你的后缀树方法是个好主意。但是,如果您针对整个基因组的一小部分 DNA 修改您的程序,那么它会更有效。假设首先考虑 20 个字母并生成其反向补码,并使用后缀树方法找到它的共享序列。如果找到两个共享序列,则转到下一部分并重复整个过程(并且不考虑上一部分进行下一次计算)否则增加前一个序列的长度。我正在尝试但无法弄清楚如何做吧。你能实现它吗?
  • 这是一个很大的要求!你为什么不开始一点一点地研究它,当你有一个特定的问题时,在上面发布一个新问题。
  • 我无法打印变量“树”。我想看看树变量的结构。简单的“打印树”在这里不起作用。
【解决方案2】:

这是一个蛮力实现,尽管它在超长序列上可能不是很有用。

def substrings(s, lmin, lmax):
    for i in range(len(s)):
        for l in range(lmin, lmax+1):
            subst = s[i:i+l]
            if len(subst) == l:
                yield i, l, subst

def ivp(s, lmin, lmax):
    mapping = {'A': 'T', 'G': 'C', 'T': 'A', 'C': 'G'}
    for i, l, sub in substrings(s, lmin, lmax):
        try:
            from string import maketrans
        except ImportError: # we're on Python 3
            condition = sub.translate(
                       {ord(k): v for k, v in mapping.items()})[::-1] in s
        else: # Python 2
            condition = sub.translate(maketrans('ATGC', 'TACG'))[::-1] in s
        if condition:
            yield i, l, sub

让我们找到长度为 6 的“反向重复模式”(以及它们的起始位置和长度):

>>> list(ivp('AGGGTTTCCCTGACCTTCACTGCAGGTCATGCA', 6, 6))
[(10, 6, 'TGACCT'), (19, 6, 'CTGCAG'), (23, 6, 'AGGTCA')]

不过,这不会检查两个模式是否重叠。例如,'CTGCAG' 匹配自身。

【讨论】:

  • 我有一个想法,可以找到长序列的倒置回文序列。考虑整个序列的一段 DNA 序列并生成其互补序列。然后反转这个补码序列的部分。然后在这两个部分之间进行动态对齐并计算它的成本(一个来自
  • 实际序列和其他来自反向互补序列)。成本将给出最佳对齐方式的想法。现在,如果最佳对齐的成本 >= 阈值成本,则选择该部分并找到公共区域。该特定部分的两个共同区域将是一个反向重复单元。一旦找到该单元,然后在下一部分重复它,否则连续增加部分的长度。任何人都可以实现这个算法。也许这将是一个有用的解决方案。
  • 我在运行这个 scriot 时收到此错误消息。我哪里错了? Traceback(最近一次调用最后):文件“irc.py”,第 13 行,在 打印列表(ivp('AGGGTTTCCCTGACCTTCACTGCAGGTCATGCA',6, 6))文件“irc.py”,第 11 行,在 ivp if sub .translate(mapping)[::-1] in s: TypeError: expected a character buffer object
  • @user1964587 你没有做错任何事,我编辑了代码以在 Python 2 和 3 上都可以工作。
  • 但是为什么会出现这个错误呢?任何线索。我正在使用 3.2 但尝试使用 2. 仍然存在错误
【解决方案3】:

我有一个找到长序列的倒置回文序列的想法。考虑整个序列的一段 DNA 序列并生成其互补序列。然后反转这个补码序列的部分。然后执行这两个部分之间的动态对齐并计算它的成本(一个来自实际序列,另一个来自反向互补序列)。成本将给出最佳对齐方式的想法。现在,如果最佳对齐的成本 >= 阈值成本,则选择该部分并找到公共区域。该特定部分的两个共同区域将是一个反向重复单元。一旦找到该单元,然后在下一部分重复它,否则连续增加部分的长度。任何人都可以实现这个算法。也许这将是一个有用的解决方案。

【讨论】:

    【解决方案4】:

    我使用列表推导对其进行了尝试。我还是 python 新手,但在过去 5 年左右的时间里一直是 C# 开发人员。这会产生您想要的输出,尽管它绝对没有优化到能够有效地处理 1000 万个字符串。

    注意:因为我们将列表转换为frequent_words中的集合,为了去除重复条目,结果没有排序。

    def pattern_matching(text, pattern):
        """ Returns the start and end positions of each instance of the pattern  """
        return [[x, str(len(pattern) + x)] for x in range(len(text) - len(pattern) + 1) if
                pattern in text[x:len(pattern) + x]]
    
    
    def frequent_words(text, k):
        """ Finds the most common k-mers of k """
        counts = [len(pattern_matching(text, text[x:x + k])) for x in range(len(text) - k)]
        return set([text[x:x + k] for x in range(len(text) - k) if counts[x] == max(counts)])
    
    
    def reverse_complement(pattern):
        """ Formed by taking the complement of each nucleotide in Pattern """
        complements = {'A': 'T', 'C': 'G', 'T': 'A', 'G': 'C'}
        return ''.join([complements.get(c, c) for c in pattern][::-1])
    
    
    def find_invert_repeats(text, pattern_size):
        """ Returns the overlap for frequent words and its reverse """
        freqs = frequent_words(text, pattern_size)
        rev_freqs = frequent_words(reverse_complement(text), pattern_size)
        return [[x, pattern_matching(text, x)] for x in set(freqs).intersection(rev_freqs)]
    

    print(find_invert_repeats("AGGGTTTCCCTGACCTTCACTGCAGGTCATGCA", 6))
    
    [['TGACCT', [[10, '16']]], ['AGGTCA', [[23, '29']]], ['CTGCAG', [[19, '25']]]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多