用Python设计PCR引物: Primer3-py 初识

PCR引物设计应该算是生物实验基本技能吧,工具也非常多。Primer-BLAST、Primer Premier 都是比较经典的软件,除此之外还有很多新的在线设计软件,也很方便。不过今天不是要讲怎么用这些现成软件来设计引物,而是要讲讲怎么用Python来做引物设计。

Python拥有众多的第三方包,其中有个叫: Primer3-py
https://pypi.org/project/primer3-py/

Primer3-py 是 Primer3 在 Python 中的一个“包装”,用 Primer3-py 官方的说法就是:提供一个简单可靠的方式让你能更好的自动化设计引物 (The intention is to provide a simple and reliable interface for automated oligo analysis and design)。

注:有人可能没怎么听过 Primer3,这是个引物设计的程序,NCBI 的 Primer-BLAST 引物设计部分用的就是 Primer3。除此之外,Primer3 还有几个网页版和命令行版本,引用次数非常高,高到你难以想象 ... 可以检索一下 Primer3 on the WWW for General Users And For Biologist Programmers


安装

有两种方法,都非常方便:

方法一,使用 pip:
  pip install Cython
  pip install primer3-py
方法二,使用 Bioconda:
  conda install -c bioconda primer3-py

安装好 Primer3-py 之后,不需要另外再单独安装 Primer3。

注:我个人推荐使用 Bioconda 来安装生物及编程相关的各种软件和包,非常出色的一个管理器,虽然有些小瑕疵,但瑕不掩瑜,对做生信分析的人来说算得上是福音,特别是在你被各种软件各种包的安装问题折磨千百遍之后。(这里特指在 Linux 下,其他类型的系统上没有用过,就不评价了)


功能

Primer3-py 的功能其实分两部分:一部分是其本身自带的 引物“热力学计算” 功能,另一部分就是 调用 Primer3 进行引物设计 的功能。

后文用做示例的模板序列来自于部分 BRCA2 的 DNA 序列,FASTA 序列如下:

>NC_000013.11:32315480-32399672 Homo sapiens chromosome 13, GRCh38.p12 Primary Assembly
GTGGCGCGAGCTTCTGAAACTAGGCGGCAGAGGCGGAGCCGCTGTGGCACTGCTGCGCCTCTGCTGCGCC
TCGGGTGTCTTTTGCGGCGGTGGGTCGCCGCCGGGAGAAGCGTGAGGGGACAGATTTGTGACCGGCGCGG
TTTTTGTCAGCTTACTCCGGCCAAAAAAGAACTGCACCTCTGGAGCGGGTTAGTGGTGGTGGTAGTGGGT

来源于NCBI: https://www.ncbi.nlm.nih.gov/nuccore/NC_000013.11report=fasta&from=32315480&to=32399672


Primer3-py 自带功能:引物热力学参数评估

主要有5个可用的命令,分别评估几个引物的热力学参数:

热力学参数 Primer3-py 命令
Tm值 calcTm()
发夹结构 calcHairpin()
同源二聚体 calcHomodimer()
异质二聚体 calcHeterodimer()
3'端稳定性 calcEndStability()

具体例子:

FASTA = """>NC_000013.11:32315480-32399672 Homo sapiens chromosome 13, GRCh38.p12 Primary Assembly
GTGGCGCGAGCTTCTGAAACTAGGCGGCAGAGGCGGAGCCGCTGTGGCACTGCTGCGCCTCTGCTGCGCC
TCGGGTGTCTTTTGCGGCGGTGGGTCGCCGCCGGGAGAAGCGTGAGGGGACAGATTTGTGACCGGCGCGG
TTTTTGTCAGCTTACTCCGGCCAAAAAAGAACTGCACCTCTGGAGCGGGTTAGTGGTGGTGGTAGTGGGT
"""

# 计算引物 Tm 值
primer3.calcTm("GTGGCGCGAGCTTCTGAAAC")
""" 结 果 >>> 56.89119991230376 """

# 检查引物中是否有 发夹结构
primer3.calcHairpin("GTGGCGCGAGCTTCTGAAAC")
""" 结 果 >>> ThermoResult(structure_found=True, tm=57.92, dg=-1484.80, dh=-23500.00, ds=-70.98)"""

# 计算引物 同源二聚体
primer3.calcHomodimer("GTGGCGCGAGCTTCTGAAAC")
""" 结 果 >>> ThermoResult(structure_found=True, tm=9.76, dg=-6863.20, dh=-45200.00, ds=-123.61) """

# 计算引物 异质二聚体
primer3.calcHeterodimer("GTGGCGCGAGCTTCTGAAAC", FASTA)
""" 结 果 >>> ThermoResult(structure_found=True, tm=21.59, dg=-6561.64, dh=-89000.00, ds=-265.80) """

# 计算引物 3'端稳定性
primer3.bindings.calcEndStability("GTGGCGCGAGCTTCTGAAAC", FASTA)
""" 结 果 >>> ThermoResult(structure_found=True, tm=15.21, dg=-3968.79, dh=-95900.00, ds=-296.41) """

这部分就先简单介绍一下最基本用法,详细参数和结果下一篇再进一步讲解。也可以自行查看官方文档:https://libnano.github.io/primer3-py/quickstart.html


通过 Primer3-py 调用 Primer3:设计引物

用 Primer3-py 来调用 Primer3 可以说是非常方便了,一行代码的事:

primer3.bindings.designPrimers()

不过这行命令的主要参数有两个:seq_args(Primer3 序列和设计参数)和 global_args(Primer3 全局参数)

而这两个参数包含了 Primer3 里的参数,那么麻烦就来了。因为 Primer3 需要读取一个配置文件(Setting File),包含用于引物设计所有参数,而包括序列本身在内,Primer3 配置文件中可选的参数大概有100~200个,版本不同参数还会有些出入( Primer3-py 内置的是 v2.3.7 )。因为参数实在是太多,具体的使用和解释要参考 Primer3 的官方文档:http://primer3.sourceforge.net/primer3_manual.htm

在这里就先不一一细说了,修改了 Primer3-py 文档示例参数用来演示, 在下一篇文章里会挑重点和结果一起分析。

# Primer3 序列和设计参数,必须要有
seq_args = {
        'SEQUENCE_ID': 'BRCA2_SEGMENT',
        'SEQUENCE_TEMPLATE': "GTGGCGCGAGCTTCTGAAACTAGGCGGCAGAGGCGGAGCCGCTGTGGCACTGCTGCGCCTCTGCTGCGCCTCGGGTGTCTTTTGCGGCGGTGGGTCGCCGCCGGGAGAAGCGTGAGGGGACAGATTTGTGACCGGCGCGGTTTTTGTCAGCTTACTCCGGCCAAAAAAGAACTGCACCTCTGGAGCGGGTTAGTGGTGGTGGTAGTGGGT",
        'SEQUENCE_INCLUDED_REGION': [0,210],
}

# Primer3 全局参数,这个可选
global_args = {
        'PRIMER_OPT_SIZE': 20,
        'PRIMER_PICK_INTERNAL_OLIGO': 1,
        'PRIMER_INTERNAL_MAX_SELF_END': 8,
        'PRIMER_MIN_SIZE': 18,
        'PRIMER_MAX_SIZE': 25,
        'PRIMER_OPT_TM': 60.0,
        'PRIMER_MIN_TM': 57.0,
        'PRIMER_MAX_TM': 63.0,
        'PRIMER_MIN_GC': 20.0,
        'PRIMER_MAX_GC': 80.0,
        'PRIMER_MAX_POLY_X': 100,
        'PRIMER_INTERNAL_MAX_POLY_X': 100,
        'PRIMER_SALT_MONOVALENT': 50.0,
        'PRIMER_DNA_CONC': 50.0,
        'PRIMER_MAX_NS_ACCEPTED': 0,
        'PRIMER_MAX_SELF_ANY': 12,
        'PRIMER_MAX_SELF_END': 8,
        'PRIMER_PAIR_MAX_COMPL_ANY': 12,
        'PRIMER_PAIR_MAX_COMPL_END': 8,
        'PRIMER_PRODUCT_SIZE_RANGE': [[75,100],[100,125],[125,150],[150,175],[175,200]],
}

# 执行命令并返回结果
primer3_result = primer3.bindings.designPrimers(seq_args, global_args)

# 或者不使用 Primer3
primer3_primary_result = primer3.bindings.designPrimers(seq_args)

返回的结果是一个Python字典,内容非常多,乍一看毫无头绪,不过处理一下就会清晰很多。

{'PRIMER_LEFT_EXPLAIN': 'considered 1088, GC content failed 57, low tm 31, high tm 833, ok 167',
 'PRIMER_RIGHT_EXPLAIN': 'considered 1088, GC content failed 47, low tm 93, high tm 644, ok 304',
 'PRIMER_INTERNAL_EXPLAIN': 'considered 1885, GC content failed 67, low tm 453, high tm 661, ok 704',
 'PRIMER_PAIR_EXPLAIN': 'considered 186, unacceptable product size 181, ok 5',
 'PRIMER_LEFT_NUM_RETURNED': 5,
 'PRIMER_RIGHT_NUM_RETURNED': 5,
 'PRIMER_INTERNAL_NUM_RETURNED': 5,
 'PRIMER_PAIR_NUM_RETURNED': 5,
 'PRIMER_PAIR_0_PENALTY': 0.07203216442314897,
 'PRIMER_LEFT_0_PENALTY': 0.0360099993838503,
 'PRIMER_RIGHT_0_PENALTY': 0.03602216503929867,
 'PRIMER_INTERNAL_0_PENALTY': 0.04672637428285498,
 'PRIMER_LEFT_0_SEQUENCE': 'AGCGTGAGGGGACAGATTTG',
 'PRIMER_RIGHT_0_SEQUENCE': 'GCTCCAGAGGTGCAGTTCTT',
 'PRIMER_INTERNAL_0_SEQUENCE': 'CCGGCGCGGTTTTTGTCAGC',
 'PRIMER_LEFT_0': (108, 20),
 'PRIMER_RIGHT_0': (185, 20),
 'PRIMER_INTERNAL_0': (131, 20),
 'PRIMER_LEFT_0_TM': 60.03600999938385,
 'PRIMER_RIGHT_0_TM': 59.9639778349607,
 'PRIMER_INTERNAL_0_TM': 60.046726374282855,
 'PRIMER_LEFT_0_GC_PERCENT': 55.0,
 'PRIMER_RIGHT_0_GC_PERCENT': 55.0,
 'PRIMER_INTERNAL_0_GC_PERCENT': 65.0,
 'PRIMER_LEFT_0_SELF_ANY_TH': 0.0,
 'PRIMER_RIGHT_0_SELF_ANY_TH': 5.308994554799938,
 'PRIMER_INTERNAL_0_SELF_ANY_TH': 6.715563508517448,
 'PRIMER_LEFT_0_SELF_END_TH': 0.0,
 'PRIMER_RIGHT_0_SELF_END_TH': 0.0,
 'PRIMER_INTERNAL_0_SELF_END_TH': 0.0,
 'PRIMER_LEFT_0_HAIRPIN_TH': 0.0,
 'PRIMER_RIGHT_0_HAIRPIN_TH': 41.267496973905224,
 'PRIMER_INTERNAL_0_HAIRPIN_TH': 38.99011028469272,
 'PRIMER_LEFT_0_END_STABILITY': 2.32,
 'PRIMER_RIGHT_0_END_STABILITY': 2.52,
 'PRIMER_PAIR_0_COMPL_ANY_TH': 0.0,
 'PRIMER_PAIR_0_COMPL_END_TH': 0.0,
 'PRIMER_PAIR_0_PRODUCT_SIZE': 78,
 'PRIMER_PAIR_1_PENALTY': 0.2323444485285222,
 'PRIMER_LEFT_1_PENALTY': 0.04078105057766379,
 'PRIMER_RIGHT_1_PENALTY': 0.19156339795085842,
 'PRIMER_INTERNAL_1_PENALTY': 0.1759585850769554,
 'PRIMER_LEFT_1_SEQUENCE': 'GCGCGGTTTTTGTCAGCTTA',
 'PRIMER_RIGHT_1_SEQUENCE': 'ACCCACTACCACCACCACTA',
 'PRIMER_INTERNAL_1_SEQUENCE': 'ACTGCACCTCTGGAGCGGGT',
 'PRIMER_LEFT_1': (134, 20),
 'PRIMER_RIGHT_1': (209, 20),
 'PRIMER_INTERNAL_1': (170, 20),
 'PRIMER_LEFT_1_TM': 60.040781050577664,
 'PRIMER_RIGHT_1_TM': 59.80843660204914,
 'PRIMER_INTERNAL_1_TM': 59.824041414923045,
 'PRIMER_LEFT_1_GC_PERCENT': 50.0,
 'PRIMER_RIGHT_1_GC_PERCENT': 55.0,
 'PRIMER_INTERNAL_1_GC_PERCENT': 65.0,
 'PRIMER_LEFT_1_SELF_ANY_TH': 8.834562170276627,
 'PRIMER_RIGHT_1_SELF_ANY_TH': 0.0,
 'PRIMER_INTERNAL_1_SELF_ANY_TH': 13.054545961563008,
 'PRIMER_LEFT_1_SELF_END_TH': 0.0,
 'PRIMER_RIGHT_1_SELF_END_TH': 0.0,
 'PRIMER_INTERNAL_1_SELF_END_TH': 4.711373579171379,
 'PRIMER_LEFT_1_HAIRPIN_TH': 0.0,
 'PRIMER_RIGHT_1_HAIRPIN_TH': 0.0,
 'PRIMER_INTERNAL_1_HAIRPIN_TH': 41.81896803359854,
 'PRIMER_LEFT_1_END_STABILITY': 3.09,
 'PRIMER_RIGHT_1_END_STABILITY': 2.74,
 'PRIMER_PAIR_1_COMPL_ANY_TH': 0.0,
 'PRIMER_PAIR_1_COMPL_END_TH': 0.0,
 'PRIMER_PAIR_1_PRODUCT_SIZE': 76,
 'PRIMER_PAIR_2_PENALTY': 0.2842985295354765,
 'PRIMER_LEFT_2_PENALTY': 0.0360099993838503,
 'PRIMER_RIGHT_2_PENALTY': 0.24828853015162622,
 'PRIMER_INTERNAL_2_PENALTY': 0.04672637428285498,
 'PRIMER_LEFT_2_SEQUENCE': 'AGCGTGAGGGGACAGATTTG',
 'PRIMER_RIGHT_2_SEQUENCE': 'CTACCACCACCACTAACCCG',
 'PRIMER_INTERNAL_2_SEQUENCE': 'CCGGCGCGGTTTTTGTCAGC',
 'PRIMER_LEFT_2': (108, 20),
 'PRIMER_RIGHT_2': (204, 20),
 'PRIMER_INTERNAL_2': (131, 20),
 'PRIMER_LEFT_2_TM': 60.03600999938385,
 'PRIMER_RIGHT_2_TM': 59.751711469848374,
 'PRIMER_INTERNAL_2_TM': 60.046726374282855,
 'PRIMER_LEFT_2_GC_PERCENT': 55.0,
 'PRIMER_RIGHT_2_GC_PERCENT': 60.0,
 'PRIMER_INTERNAL_2_GC_PERCENT': 65.0,
 'PRIMER_LEFT_2_SELF_ANY_TH': 0.0,
 'PRIMER_RIGHT_2_SELF_ANY_TH': 0.0,
 'PRIMER_INTERNAL_2_SELF_ANY_TH': 6.715563508517448,
 'PRIMER_LEFT_2_SELF_END_TH': 0.0,
 'PRIMER_RIGHT_2_SELF_END_TH': 0.0,
 'PRIMER_INTERNAL_2_SELF_END_TH': 0.0,
 'PRIMER_LEFT_2_HAIRPIN_TH': 0.0,
 'PRIMER_RIGHT_2_HAIRPIN_TH': 0.0,
 'PRIMER_INTERNAL_2_HAIRPIN_TH': 38.99011028469272,
 'PRIMER_LEFT_2_END_STABILITY': 2.32,
 'PRIMER_RIGHT_2_END_STABILITY': 5.28,
 'PRIMER_PAIR_2_COMPL_ANY_TH': 0.0,
 'PRIMER_PAIR_2_COMPL_END_TH': 0.0,
 'PRIMER_PAIR_2_PRODUCT_SIZE': 97,
 'PRIMER_PAIR_3_PENALTY': 0.28653552146357697,
 'PRIMER_LEFT_3_PENALTY': 0.2505133564242783,
 'PRIMER_RIGHT_3_PENALTY': 0.03602216503929867,
 'PRIMER_INTERNAL_3_PENALTY': 0.04672637428285498,
 'PRIMER_LEFT_3_SEQUENCE': 'GAAGCGTGAGGGGACAGATT',
 'PRIMER_RIGHT_3_SEQUENCE': 'GCTCCAGAGGTGCAGTTCTT',
 'PRIMER_INTERNAL_3_SEQUENCE': 'CCGGCGCGGTTTTTGTCAGC',
 'PRIMER_LEFT_3': (106, 20),
 'PRIMER_RIGHT_3': (185, 20),
 'PRIMER_INTERNAL_3': (131, 20),
 'PRIMER_LEFT_3_TM': 59.74948664357572,
 'PRIMER_RIGHT_3_TM': 59.9639778349607,
 'PRIMER_INTERNAL_3_TM': 60.046726374282855,
 'PRIMER_LEFT_3_GC_PERCENT': 55.0,
 'PRIMER_RIGHT_3_GC_PERCENT': 55.0,
 'PRIMER_INTERNAL_3_GC_PERCENT': 65.0,
 'PRIMER_LEFT_3_SELF_ANY_TH': 0.0,
 'PRIMER_RIGHT_3_SELF_ANY_TH': 5.308994554799938,
 'PRIMER_INTERNAL_3_SELF_ANY_TH': 6.715563508517448,
 'PRIMER_LEFT_3_SELF_END_TH': 0.0,
 'PRIMER_RIGHT_3_SELF_END_TH': 0.0,
 'PRIMER_INTERNAL_3_SELF_END_TH': 0.0,
 'PRIMER_LEFT_3_HAIRPIN_TH': 0.0,
 'PRIMER_RIGHT_3_HAIRPIN_TH': 41.267496973905224,
 'PRIMER_INTERNAL_3_HAIRPIN_TH': 38.99011028469272,
 'PRIMER_LEFT_3_END_STABILITY': 2.4,
 'PRIMER_RIGHT_3_END_STABILITY': 2.52,
 'PRIMER_PAIR_3_COMPL_ANY_TH': 0.0,
 'PRIMER_PAIR_3_COMPL_END_TH': 0.0,
 'PRIMER_PAIR_3_PRODUCT_SIZE': 80,
 'PRIMER_PAIR_4_PENALTY': 0.3576746687102741,
 'PRIMER_LEFT_4_PENALTY': 0.3216525036709754,
 'PRIMER_RIGHT_4_PENALTY': 0.03602216503929867,
 'PRIMER_INTERNAL_4_PENALTY': 0.04672637428285498,
 'PRIMER_LEFT_4_SEQUENCE': 'GCGTGAGGGGACAGATTTGT',
 'PRIMER_RIGHT_4_SEQUENCE': 'GCTCCAGAGGTGCAGTTCTT',
 'PRIMER_INTERNAL_4_SEQUENCE': 'CCGGCGCGGTTTTTGTCAGC',
 'PRIMER_LEFT_4': (109, 20),
 'PRIMER_RIGHT_4': (185, 20),
 'PRIMER_INTERNAL_4': (131, 20),
 'PRIMER_LEFT_4_TM': 60.321652503670975,
 'PRIMER_RIGHT_4_TM': 59.9639778349607,
 'PRIMER_INTERNAL_4_TM': 60.046726374282855,
 'PRIMER_LEFT_4_GC_PERCENT': 55.0,
 'PRIMER_RIGHT_4_GC_PERCENT': 55.0,
 'PRIMER_INTERNAL_4_GC_PERCENT': 65.0,
 'PRIMER_LEFT_4_SELF_ANY_TH': 0.0,
 'PRIMER_RIGHT_4_SELF_ANY_TH': 5.308994554799938,
 'PRIMER_INTERNAL_4_SELF_ANY_TH': 6.715563508517448,
 'PRIMER_LEFT_4_SELF_END_TH': 0.0,
 'PRIMER_RIGHT_4_SELF_END_TH': 0.0,
 'PRIMER_INTERNAL_4_SELF_END_TH': 0.0,
 'PRIMER_LEFT_4_HAIRPIN_TH': 41.18192535348908,
 'PRIMER_RIGHT_4_HAIRPIN_TH': 41.267496973905224,
 'PRIMER_INTERNAL_4_HAIRPIN_TH': 38.99011028469272,
 'PRIMER_LEFT_4_END_STABILITY': 2.83,
 'PRIMER_RIGHT_4_END_STABILITY': 2.52,
 'PRIMER_PAIR_4_COMPL_ANY_TH': 0.0,
 'PRIMER_PAIR_4_COMPL_END_TH': 0.0,
 'PRIMER_PAIR_4_PRODUCT_SIZE': 77}

注:引物设计参数和结果的具体释义还是要回到 Primer3 文档中去找,下一篇会进一步介绍


Primer3 返回结果的处理

先看看处理完的效果:

PRIMER_PAIR_0 PRIMER_PAIR_1 PRIMER_PAIR_2 PRIMER_PAIR_3 PRIMER_PAIR_4
PRIMER_PAIR_PENALTY 0.0720322 0.232344 0.284299 0.286536 0.357675
PRIMER_LEFT_PENALTY 0.03601 0.0407811 0.03601 0.250513 0.321653
PRIMER_RIGHT_PENALTY 0.0360222 0.191563 0.248289 0.0360222 0.0360222
PRIMER_INTERNAL_PENALTY 0.0467264 0.175959 0.0467264 0.0467264 0.0467264
PRIMER_LEFT_SEQUENCE AGCGTGAGGGGACAGATTTG GCGCGGTTTTTGTCAGCTTA AGCGTGAGGGGACAGATTTG GAAGCGTGAGGGGACAGATT GCGTGAGGGGACAGATTTGT
PRIMER_RIGHT_SEQUENCE GCTCCAGAGGTGCAGTTCTT ACCCACTACCACCACCACTA CTACCACCACCACTAACCCG GCTCCAGAGGTGCAGTTCTT GCTCCAGAGGTGCAGTTCTT
PRIMER_INTERNAL_SEQUENCE CCGGCGCGGTTTTTGTCAGC ACTGCACCTCTGGAGCGGGT CCGGCGCGGTTTTTGTCAGC CCGGCGCGGTTTTTGTCAGC CCGGCGCGGTTTTTGTCAGC
PRIMER_LEFT (108, 20) (134, 20) (108, 20) (106, 20) (109, 20)
PRIMER_RIGHT (185, 20) (209, 20) (204, 20) (185, 20) (185, 20)
PRIMER_INTERNAL (131, 20) (170, 20) (131, 20) (131, 20) (131, 20)
PRIMER_LEFT_TM 60.036 60.0408 60.036 59.7495 60.3217
PRIMER_RIGHT_TM 59.964 59.8084 59.7517 59.964 59.964
PRIMER_INTERNAL_TM 60.0467 59.824 60.0467 60.0467 60.0467
PRIMER_LEFT_GC_PERCENT 55 50 55 55 55
PRIMER_RIGHT_GC_PERCENT 55 55 60 55 55
PRIMER_INTERNAL_GC_PERCENT 65 65 65 65 65
PRIMER_LEFT_SELF_ANY_TH 0 8.83456 0 0 0
PRIMER_RIGHT_SELF_ANY_TH 5.30899 0 0 5.30899 5.30899
PRIMER_INTERNAL_SELF_ANY_TH 6.71556 13.0545 6.71556 6.71556 6.71556
PRIMER_LEFT_SELF_END_TH 0 0 0 0 0
PRIMER_RIGHT_SELF_END_TH 0 0 0 0 0
PRIMER_INTERNAL_SELF_END_TH 0 4.71137 0 0 0
PRIMER_LEFT_HAIRPIN_TH 0 0 0 0 41.1819
PRIMER_RIGHT_HAIRPIN_TH 41.2675 0 0 41.2675 41.2675
PRIMER_INTERNAL_HAIRPIN_TH 38.9901 41.819 38.9901 38.9901 38.9901
PRIMER_LEFT_END_STABILITY 2.32 3.09 2.32 2.4 2.83
PRIMER_RIGHT_END_STABILITY 2.52 2.74 5.28 2.52 2.52
PRIMER_PAIR_COMPL_ANY_TH 0 0 0 0 0
PRIMER_PAIR_COMPL_END_TH 0 0 0 0 0
PRIMER_PAIR_PRODUCT_SIZE 78 76 97 80 77

通过处理之后,将看起来没有头绪的“字典”处理成了比较易读的“数据框” ( Dataframe ),这是一种在 R 语言里非常基础的数据格式,最大的优点就是直观,Excel 的表格也长类似的样子。在处理结果的过程当中使用了另外一个强大的 Python 包:Pandas

注:最初开发 Pandas 的目的就是为了将 R 语言的数据处理方式移植到 Python 里,后来随着 Python 被广泛应用于数据分析和人工智能,Pandas 成为了 Python 处理数据时不可或缺的工具包。

要处理 Primer3 返回的结果,第一反应肯定是回头再仔细观察一下 Primer3 返回的结果,看是不是有规律可循。果不其然,除了前几行是一些统计信息外,剩下都是引物对本身的信息,每对引物都有共同的信息,不同引物对间通过数字编号加以区分。另外从 'PRIMER_PAIR_NUM_RETURNED': 5 这一行知道总共有5对引物。有规律可循,那接下来事情就好办了。

第一步:将结果转换成以“引物信息”为键值的新形式的“字典”:
primer3_result_table_dict = {}
for i in range(primer3_result["PRIMER_PAIR_NUM_RETURNED"]):
    primer_id = str(i)
    for key in primer3_result:
        if primer_id in key:

            # 要将每个信息中的数字和下划线去掉
            info_tag = key.replace("_" + primer_id, "")

            # 就是把不同的引物对结果归到一起
            try:
                primer3_result_table_dict[info_tag] 
            except:
                primer3_result_table_dict[info_tag] = []
            finally:
                primer3_result_table_dict[info_tag].append(primer3_result[key])

第二步:用 Pandas 将新“字典”转换成“数据框”:
import pandas as pd

index = []
for i in range(primer3_result["PRIMER_PAIR_NUM_RETURNED"]):

    # 为每一对引物加个索引
    index.append("PRIMER_PAIR_" + str(i))

# 一步完成 “字典” => “数据框”
primer3_result_df = pd.DataFrame(primer3_result_table_dict, index=index)

# 转置一下,更方便查看一些
primer3_result_df = primer3_result_df.T

# 导出成文件,可以用Excel或者其他编辑器打开查看
primer3_result_df.to_csv("primer3_result.csv", sep="\t")

print(primer3_result_df)

如果觉得看表格还是不够直观,那么通过可视化来变得更直观一些。用引物 TM 值的数据来做个例子:

TM 的折线图

这是用 Plotly 包做的可视化,因为与主题相关性不大就不放了代码了,除了 Plotly 之外优秀的 Python 可视化包还有很多。不过与其他包相比,Plotly 最大的优点是它的交互性非常好,如果有兴趣了解,之后会有可视化相关的文章进行详细介绍。


总结:

实话说,现在的引物设计软件已经非常方便了,很多人会觉得实在想不出来为什么还要多此一举,趟这个浑水自己写代码。如果你只是偶尔设计一两对引物,那么确实是完全没有必要。不过当需要设计高通量测序 Panel(什么是 Panel ?往期易微升文章有介绍)的时候,你可能要同时设计几十甚至上百对引物,完了之后还要通过参数进行微调,以减小每对引物之间的相互影响。这对于一般的设计软件是不是就成了几乎不可能完成的任务。而 Primer3-py 的优势在这里就体现出来了,不仅可以通过调用 Primer3 来进行细致和精准的引物设计和调整,还能便捷的衔接 Python 将引物设计的前后处理流程化,使批量引物设计变得更高效和可控。这些内容的细节,也是之后要介绍的“多重PCR引物设计”中的一部分,对于喜欢鼓捣的人来说,完成这个任务是个不错的挑战。随着“多重PCR捕获-高通量测序”不断被应用于各个场景,“多重PCR引物设计”的实用性也在随之增加。


文章中测试使用的环境:
  • Ubuntu: 18.04.1 LTS
  • Python: v3.6.7
  • Jupyterlab: v0.35.4
  • Primer3-py: v0.5.7
  • Pandas: v0.23.4






用Python设计PCR引物: Primer3-py 初识_第1张图片
易微升公众号

你可能感兴趣的:(用Python设计PCR引物: Primer3-py 初识)