使用Try / Except和循环的DNA Motif枚举 - Python3

时间:2017-08-21 17:32:32

标签: python loops try-catch bioinformatics hamming-distance

过去几天我一直在努力解决特定的生物信息学问题,我想知道是否有人能够在我的逻辑中找到错误或在我的代码中找到错误(或两者都有)。 该函数应该从所有DNA串中找到所有k-mers,其汉明距离最多为d。 这就是我想要做的事情:

  1. 从所有可能的k-mers的迭代开始,并将它们与每个字符串进行比较

  2. 这意味着我需要另一个遍历DNA串的循环

  3. 我为c+k <= len(DNA[0])-1制作了一个while循环。 c+k是我的大小为k的窗口,我想在每个DNA字符串中找到至少一个窗口,其中我的组合与该字符串的汉明距离等于或小于任意{{1 }}。如果汉明距离符合标准,则while循环中断,允许比较下一个字符串。如果没有,则窗口会发生变化,如果d,汉明距离仍然不符合标准,我会创建一个名称错误c+k==len(DNA[0])-1,异常会导致{{1} }}

  4. 但是,我的函数只返回int(a)以外的任何内容,我不明白。

    inner_loop

    我认为自从我的第二个内循环崩溃后,这将导致我的第一个内循环通过,然后set()中的另一个组合将被测试,但我的import itertools def combination(k): bases=['A','T','G','C'] combo=[''.join(p) for p in itertools.product(bases, repeat=k)] return combo def hammingDistance(Pattern, seq): if Pattern == seq: return 0 else: dist=0 for i in range(len(seq)): if Pattern[i] != seq[i]: dist += 1 return dist def motif_enumeration(k, d, DNA): combos = combination(k) global pattern for combo in combos: try: inner_loop(k, d, DNA, combo) except: continue return set(pattern) def inner_loop(k, d, DNA, combo): global pattern for strings in DNA: inner_loop_two(k, d, DNA, combo, strings) def inner_loop_two(k, d, DNA, combo, strings): global pattern c=0 while c+k < len(DNA[0]): print(combo, strings[c:c+k], hammingDistance(combo, strings[c:c+k])) if d >= hammingDistance(combo, strings[c:c+k]) and strings == DNA[len(DNA)-1]: #if we've reached the last string and the condition is met, #that means that the combo is suitable for each string of DNA pattern += [combo] elif d >= hammingDistance(combo, strings[c:c+k]): #condition is met for one string, now move onto next break elif d < hammingDistance(combo, strings[c:c+k]) and c+k == len(DNA[0])-1: #Name error causes this inner loop two to crash, thus causing the first inner loop #to pass int(a) elif d < hammingDistance(combo, strings[c:c+k]): #change the window to see if the combo is valid later in the string c += 1 pattern = [] DNA=['ATTTGGC', 'TGCCTTA', 'CGGTATC', 'GAAAATT'] print(motif_enumeration(3,1,DNA)) print(pattern) 中的第一个条件永远不会打印任何东西。我还注意到,当内循环崩溃并且motif_enumeration继续时,它继续用于外循环和内循环。这是我的意思的一个例子......

    inner_loop_two

    我的预期输出为motif_enumeration

1 个答案:

答案 0 :(得分:2)

逻辑的核心组件是,如果组合在目标字符串的所有上的任何位置匹配,我们希望将组合收集到模式集中。我们可以使用Python的allany函数来执行此操作。这些功能可以有效地工作,因为它们会在决定结果后立即停止测试。

import itertools

def combination(k):
    return (''.join(p) for p in itertools.product('ATCG', repeat=k))

def hamming_distance(pattern, seq):
    return sum(c1 != c2 for c1, c2 in zip(pattern, seq))

def window(s, k):
    for i in range(1 + len(s) - k):
        yield s[i:i+k]

def motif_enumeration(k, d, DNA):
    pattern = set()
    for combo in combination(k):
        if all(any(hamming_distance(combo, pat) <= d 
                for pat in window(string, k)) for string in DNA):
            pattern.add(combo)
    return pattern

DNA = ['ATTTGGC', 'TGCCTTA', 'CGGTATC', 'GAAAATT']
print(motif_enumeration(3, 1, DNA))

<强>输出

{'GTT', 'ATA', 'TTT', 'ATT'}

我对您的代码进行了一些其他更改。我们可以通过将生成器传递给sum函数来有效地计算汉明距离。我们可以节省时间和时间RAM通过使用生成器将组合元组转换为字符串而不是将它们放入列表中。

motif_enumeration函数可以进一步浓缩为集合理解,但我必须承认它相当密集,甚至比以前的版本更难阅读。但是,它可能稍微有点效率。

def motif_enumeration(k, d, DNA):
    return {combo for combo in combination(k)
        if all(any(hamming_distance(combo, pat) <= d 
            for pat in window(string, k)) for string in DNA)}

这是一个稍微易读的版本,我已经给motif_enumeration辅助函数in_window执行内部测试。

# Return True if combo is within d in any window of string
def in_window(combo, string, k, d):
    return any(hamming_distance(combo, pat) <= d for pat in window(string, k))

def motif_enumeration(k, d, DNA):
    pattern = set()
    for combo in combination(k):
        if all(in_window(combo, string, k, d) for string in DNA):
            pattern.add(combo)
    return pattern