利用python为探索进化路径的实验构建‘dna’库

最近在阅读了
Wirkshark网络分析的艺术以及Wireshark网络分析就这么简单以后,提起了继续写技术博客的想法。之前总是觉得很多的小的细节可能不用被记录,所以大概把自己弄的很没有话说的样子,但是后来深受启发。毕竟每一次项目中的每一次疑问加解答都时可以成为一篇技术博客的文章的。于是重新开始整理自己所作的工作。

问题

前阵子一个组由于课题的目的,希望可以设计一连串的类似于primer的dna序列,不过由于出发点的问题,所以是想要基于一段原始的DNA序列进行所有突变可能的枚举的。原始的长度有17bp那么长,那么所有突变的可能大概就有4^17-1这么多种可能,这么大的内容我用python是很难进行枚举的。每一次枚举到了一半的时候就占满了服务器500G的内存。所以我只能想别的方法。

涉及解决方案

  1. 枚举方面。
     作为一个程序员,当然不可能说写17个循环从而来枚举所有的可能。但是不这样又很难实现这样的枚举所有序列问题。后来想到了一个解决方案,就是类似于树的方法。
init_start = ['A','T','C','G']
while len(init_start) <= 17:
    current = init_start.pop(0)
    for _i in ['A','T','C','G']:
        init_start += [current + _i]

用一个很简单的类似于BFS(Breadth-First-Search)的一个树的遍历的方法。因为这个穷举过程归根结底其实就是对一个树的表现的过程。所以应该也会有两种思路,我用的就是类似于BFS的构建过程。这样可以保证遍历所有的节点。

*但是正如我之前说的,这个穷举实在太大,所以没有什么意义,所以我后来也深入了解了一下对方的课题目的。从而修改了自己的目标,这也是一个 生信人 非常重要的一个要求。不要盲目的跑程序和写程序,一定要跟对方沟通,让对方知道你能做什么,你发现的问题。如果对方本身也目的模糊,你一定要从一个逻辑思考的角度给他梳理清楚,否则就是在坑自己了。当然也在 坑别人就是。 *


  1. 回到最开始的目的。他们想做应该是设计这么一个library,从而去寻找进化的路径。当然这个其实是非常困难的,但是如果实验设计的好的话,应该也是可以做的。那么一个生信的能做些什么呢

因为我们现在有一个野生型的序列,我们能做的应该是利用计算机把所有进化的可能性尽可能均匀分布,从而构建这么一个库,剩下的可能是一个碰运气的过程了。

我的思路大概是这样的。

  1. 按照与野生型的差异(我们可以简单的用变了多少个碱基来描述)作为每一列的特征。这样我们最多应该是有17列的,也就是从突变1个碱基一直到每一个碱基都不一样了。
  2. 由于他们需要探索进化的途径,那么我们的每一列,应该都是前一列的一个衍生。(当然这个模型十分简单,因为也许突变会在几次突变后重新往野生型的序列去变异)
  3. 明确下来后,这也就非常的简单了。因为每一次其实也就是只突变了一个。
  4. 接下来就是明确代码所需要实现的模块。

a. 给定序列,突变位置,突变的数量,即随机的在突变位置的候选中选择突变的数量的数字,然后在这些数字的基础上进行突变。

def randome_shuffle(dna_seq, change_area, num_alt):
    '''
    :param dna_seq:
    :param change_area: 0-coordinate. consist of all pos to change.Not continuous.
    :param num_alt:
    :return:
    '''
    if len(change_area) < num_alt:
        raise SyntaxError, 'alt allele num is bigger than the area range.'
    count_alt = 0
    changed_pos_bucket = []
    while count_alt < num_alt:
        pos = random.choice(change_area)
        if pos in changed_pos_bucket:
            continue
        else:
            changed_pos_bucket += [pos]
            count_alt += 1
            _cache = base[::]
            _cache.remove(dna_seq[pos].upper())
            alt = _cache[random.randint(0, 2)]
            if pos != len(dna_seq) - 1:
                dna_seq = dna_seq[:pos] + alt + dna_seq[pos + 1:]
            else:
                dna_seq = dna_seq[:pos] + alt
    return dna_seq, tuple(sorted(changed_pos_bucket))

b. 给定序列,突变位置,结合a函数递归生成结果。重点在于我们的递归每一次只需要基于前一次变化,往后再变化1个新的位置的碱基(自然界中当然可能会发生在已发生过的位置,但是这里的模型简单不考虑),这样就形成了一个递归的链条,其实也就是我刚刚说的思路1中的每一行。。

def recursive_generate_lib(start_seq, area):
    bucket = []
    if not area:
        return bucket
    new_seq, changed_pos = randome_shuffle(start_seq, area, 1)
    bucket.append(new_seq)
    area.remove(changed_pos[0])
    if area:
        bucket += recursive_generate_lib(new_seq, area)
    return bucket

c. 给定需要变化的区域,突变数量的范围进行构建一个符合要求的dna库。由于上一个函数的原因,其实我们仅仅需要给定一个初始点,就可以得出一行。那么有多少个初始点,就可以有多少行。

从实验目的来说,如果突变数量从1开始,初始点的可能性只有17*3 == 51种,其中可能还有一部分需要被硬性筛选条件过滤的。所以只剩下有限的24种初始点。但是如果突变数量从2开始,其实就十分的多了,所以也就不加赘述和计算。

从以上的内容中,我们实现了为一个探索进化路径实验设计DNA库的编程脚本。其中还有一部分我之前没有涉及到的内容我也简单进行一下描述。

设计一段DNA序列,其实类似于设计一段primer,有一些硬性的条件需要我们去满足。例如:序列中不能有5bp以上的寡聚核苷酸链。序列中不能有自身互补的结构。序列的GC含量需要满足40%-60%间。

这些过程都可以很轻易的用Python进行实现,这里我直接贴上代码,具体的使用和为什么这么写由大家自己去思考。

base = ['A', 'C', 'T', 'G']
complementary = {'A': 'T',
                 'T': 'A',
                 'C': 'G',
                 'G': 'C'}
from collections import Counter

def cal_GC_content(dna_seq):
    bucket = []
    for _i in dna_seq:
        bucket.append(_i)
    caled_dict = Counter(bucket)
    for _base in base:
        if _base not in caled_dict.keys():
            caled_dict[_base] = 0
    gc_sum = sum([caled_dict.get('G'), caled_dict.get('C')])
    return float(gc_sum) / sum(caled_dict.values())
def filter_poly(dna_seq, poly_num):
    for _i in base:
        if _i * poly_num in dna_seq:
            return False
    return True


def filter_self_complementary(dna_seq, length):
    for _i in base:
        if _i * length in dna_seq:
            if complementary[_i] * length in dna_seq:
                return False
    return True
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容