引物是PCR成功的关键因素之一,虽然PCR的稳健性很强,有时让人觉得似乎随便用什么引物都能扩增出来,但是精心设计的引物能够明显提升PCR的成功率,如果你经常做PCR,这能为你省去很多重复实验的麻烦。
本文基于《Methods In Molecular Biology》的“PCR Primer Design”系列文献,冷泉港“PCR Primer Design”操作规程和引物设计生信工具综述,来聊聊引物设计的一般原则。
《Methods In Molecular Biology》是Springer出版的分子生物学方法学系列著作,涵盖了生物学的方方面面,是经典中的经典,它是一本论文集,目前已经更新到2126卷,我收集了1-1252卷,时间跨度从1984-2015,每卷包括10-20篇该领域的高水平论文。其中402卷为“PCR Primer Design”系列,涉及不同类型PCR引物设计的原则、算法、工具等。
冷泉港Protocols在分子生物学领域具有重要的地位,被很多科研人员所推崇,PCR Primer Design来自于2009年第3卷(doi:doi:10.1101/pdb.ip65),简述了PCR引物设计的影响因素和不同类型PCR引物设计的基本策略。
Bioinformatic tools and guideline for PCR primer design(10.5897/AJB2003.000-1019)
-
《Methods In Molecular Biology》的建议
文章主要介绍了PCR引物设计的物理原理和他们设计的Visual-OMP软件的特点,并且介绍了七种关于PCR的谜题及改进方法,要点如下:
①PCR Nearly Always Works and Design Is Not that Important
②Different Methods for Predicting Hybridization Tm Are Essentially Equivalent in Accuracy
Tm对引物十分重要,有很多预测寡核苷酸Tm的方法,他们的准确性基本相同。
③Designing Forward and Reverse Primers to Have Matching Tm’s Is the Best Strategy to Optimize for PCR
很多人认为上下游引物具有接近的Tm对PCR的成功有很大帮助,但要注意在比Tm低的温度(Tm - 5~10℃)退火时,Tm相同的引物与模板的杂合状态也是不同的。
④“Primer Dimer” Artifacts Are Due to Dimerization of Primers
容易形成引物二聚体的因素有:高循环数(>35)有利于形成二聚体,掺入外源基因组DNA,引物结合靶DNA的效率较低,使用具有校正活性的DNA聚合酶(Pfu等)因3'外切活性可能使原本不匹配的3'端互补。
⑤A BLAST Search Is the Best Method for Determining the Specificity of a Primer
⑥At the End of PCR, Amplification Efficiency Is Not Exponential Because the Primers or NTPs Are Exhausted or the Polymerase Looses Activity
PCR扩增具有特征性的“ S”形,有人认为平台期的成因可能引物或dNTP消耗殆尽,事实上平台期的引物和dNTP余量都很富裕,真正导致平台期的原因是积累的dsDNA产物的抑制,这已经得到了实验证明。(使用一些DNA双链结合蛋白是否能减轻这种抑制?比如Sso7d)
⑦Multiplex PCR Can Succeed by Optimization of Individual PCRs
作者从VirOligo(VirOligo是病毒特异性寡核苷酸的数据库,包含用于检测病毒核酸的PCR引物和杂交探针及对应的实验条件)选取大量的引物序列,统计了他们的序列长度、Tm范围、GC含量等指标,重点研究了他们3'端三联体碱基与PCR成功率的相关性,得出一些特定的三联体有助于获得好的PCR结果,要点如下:
①如果允许,应该优先选择WSS(W=A/T,S=C/G)、SWS、TTS作为3'端序列,但要避免这些三联体中包含CG;
②如果选不到合适的,应优先选择NNS;
③尽量避免WWW、CGW、GGG。 冷泉港的建议
文章介绍了进行引物设计要考虑的一般因素,如长度、Tm、GC%、二级结构、重复序列,重点讨论了多重PCR、巢式PCR、TaqMan探针、分子信标引物设计的注意事项与策略,没有建设性建议:
①长度:18-33nt
②引物Tm:55-60℃
③扩增子Tm:>92℃
④末端2bp最好为GC
⑤避免poly序列,避免三个及以上的GPCR引物设计工具与指南
文章介绍了大量PCR引物设计在线工具和软件,并综述了引物设计的一般准则:
①引物长度:18 - 30nt
②熔解温度:52 - 58℃
③GC含量:45% - 60%
④3'-末端序列:G/C
⑤二聚体:尽量避免互补性或回文序列
⑥特异性:尽量避免错配
综上所述,我把普通PCR引物设计的一般原则总结如下:
①长度:18-26bp,可放宽至18-30bp(有研究表明超过30bp再增加引物长度意义不大);
②Tm:54-58℃,可放宽至52~62℃,GC%>60%可进一步放宽,重点是上下游Tm要保持平衡(∆Tm = -3~3℃);
③3'端:优选三联体WSS、SWS、TTS,二连体GC,单体S,尽量规避WWW、CGW、GGG、CG;
④GC%:40% - 60%,可放宽至30%-70%;
⑤其他:避免3'端8bp及以上序列与模板多位点互补,尽量避免上下游3'端4bp及以上反向互补,尽量避免内部回文。
基于上述原则,怎么在实践中应用呢?我认为得分为两种情况:
①基因克隆PCR引物设计
这种情况我们往往并没有太多选择,只能从ATG开始,从TAA等结束,什么GC%、二聚体和错配,可能根本由不得我们。既然起点定了,那只能通过改变长度来匹配最优设计要求了。
②鉴定PCR引物设计
我们只需要确认一段DNA序列上的一部分,起点是相对的,我们可以在整个序列范围内搜索,引物设计的灵活性大大提高,当然搜索时间也要增加。
无论哪种情况,如果我们手动搜索都要花费大量时间,因此最好的办法是通过计算机程序来实现(第一种情况)。
首先:在所有指标中,只有长度可以作为自由的自变量,Tm、GC%、3'端都与之相关,可以作为我们的统计指标,构建一个评分函数:f(x)= k1×φ1(Tm)+k2×φ2(GC%)+k3×φ3(3'NNN)
然后:来建立这三个指标的评分标准
Tm评分标准
Tm | 得分 |
---|---|
<48℃ | 10 |
48℃-52℃ | 30 |
52℃-55℃ | 70 |
55℃-58℃ | 100 |
58℃-62℃ | 80 |
62℃-68℃ | 40 |
>68℃ | 20 |
GC%评分标准
GC% | 得分 |
---|---|
<20 | 0 |
20-30 | 20 |
30-40 | 50 |
40-50 | 100 |
50-60 | 100 |
60-70 | 60 |
70-80 | 20 |
>80 | 0 |
3'端三联体评分标准(根据Onodera的统计结果,拿每个三联体与最小值的差/极差×100)
三联体 | 得分 | 三联体 | 得分 | 三联体 | 得分 | 三联体 | 得分 |
---|---|---|---|---|---|---|---|
AGG | 100 | CAT | 48 | ACA | 36 | CGC | 24 |
TGG | 88 | GAG | 47 | CCA | 34 | CTT | 24 |
CTG | 84 | TGT | 47 | CCG | 34 | GCG | 23 |
ACC | 81 | ATG | 44 | TAC | 34 | TCG | 23 |
TCC | 81 | AGT | 42 | GTA | 32 | CCT | 21 |
CAG | 80 | GGC | 42 | ACG | 31 | CTA | 21 |
AGC | 75 | GAC | 40 | TCA | 31 | GTT | 21 |
GTG | 72 | GAT | 40 | TGA | 31 | TTT | 19 |
TTC | 72 | AAG | 39 | CAA | 29 | ATA | 18 |
CAC | 68 | CCC | 39 | CGG | 29 | TAT | 18 |
TGC | 67 | GGA | 39 | AAT | 27 | GGG | 14 |
CTC | 59 | ACT | 37 | GAA | 27 | ATT | 11 |
GTC | 57 | GCA | 37 | GCT | 27 | CGT | 11 |
TTG | 52 | GCC | 37 | GGT | 27 | CGA | 8 |
AAC | 50 | TAG | 37 | TCT | 26 | TAA | 6 |
ATC | 50 | AAA | 36 | AGA | 24 | TTA | 0 |
系数的权重
系数 | k1 | k2 | k3 |
---|---|---|---|
数值 | 5 | 2 | 3 |
Tm计算公式
关于引物Tm的计算,我在之前的文章PCR退火温度预测做过详细介绍,我们采用von等(von Ahsen N, 2001)的公式:
Tm = 77.1 + 11.7×lg([Na+] + 120 * ([Mg2+] - [dNTPs])1/2) + 41×GC%- 528/n - 0.75×5(DMSO)
式中GC%代表引物的GC比例,n代表引物长度,5(DMSO)代表5%的DMSO添加剂。
一般,聚合酶Mix中Na+浓度为50-100mM,Mg2+为1.5-2.5mM,dNTPs为0.8-1mM,我做了一个估算,这个范围内的离子强度变化仅导致2℃上下的浮动,基本可以忽略。大多Mix添加了防冻剂,防冻剂基本上都是多羟基化合物,这些多羟基化合物容易降低水活度从而降低退火温度,不过因种类和浓度的不同对Tm的影响不同,这里用4℃作一般校正,因此该公式可以简化为:
Tm = 64 + 0.41×GC - 528/n
算法的核心流程
①选取18-30bp的长度范围,以最低长度18bp为生长点,逐渐延长至30bp。
②对于每次生长循环,使用该引物3'端8bp进行全局搜索,如果出现一个以上的配对,直接pass。
③计算并记录每条引物的得分、序列和Tm,采用数组。
④将上游引物数组和下游引物数组分别按得分从高到低进行排序。
⑤引物对匹配,原则上选取引物对总得分最高的,但是必须考虑Tm平衡的问题。我的策略是:从上游最高得分引物开始,依次匹配下游引物,要求优先匹配|∆Tm|<=3℃的引物对,一旦匹配终止本次循环,从上游第二条继续,如果直到筛选结束都没有满足要求的引物对,直接选择上下游最高得分引物作为引物对;
⑥经过步骤⑤,得到的可能是一对引物也可能是多个引物对,而且大多时候是多个。如果只有一对引物,那只能直接输出了。
⑦如果是多个引物对,先按总得分从高到低排序,检查引物对的互补性,如果互补率(互补碱基数/最长碱基数)>50%,继续下一对检测,直到互补率<=50%即可输出,如果全部不满足要求,直接输出总得分最高的引物对。
效果评价
我把完整的代码放在了:http://www.liuzhen106.com/tools/101.html
我用绿色荧光蛋白(GFP)做了测试,结果上游输出一条20bp、Tm=59℃的引物,下游为28bp、Tm=57.5℃。长度差异比较大,好像看起来不大聪明的亚子,我用Snapgene分析了下GFP的序列,它正向30bp的GC%比反向高得多,这是导致长度不平衡的根本原因。我修改了程序,让它把上下游18-30bp全部输出(上游引物自动越过了18bp、19bp,他们末端8-9bp有内部结合位点),经过人工匹配,这确实是最优的引物对。
看来它还是能解决些问题的,针对复杂的序列,我没有指定特殊处理规则,因此程序健壮性不高,不过这样的序列,还是按自己的经验比较好。
核心代码示例
//匹配最佳引物对
function pairing(oliog_Fs,oliog_Rs) {
var pairs = new Array();
for (i=0; i<oliog_Fs.length; i++) {
var score_f = parseInt(oliog_Fs[i].split(",")[0]);
var oligo_f = oliog_Fs[i].split(",")[1];
var tm_f = parseFloat(oliog_Fs[i].split(",")[2]);
for (j=0; j<oliog_Rs.length; j++) {
var score_r = parseInt(oliog_Rs[j].split(",")[0]);
var oligo_r = oliog_Rs[j].split(",")[1];
var tm_r = parseFloat(oliog_Rs[j].split(",")[2]);
if (Math.abs(tm_f - tm_r) <= 3) {
var score = score_f + score_r;
var text = "0000".slice(String(score).length) + String(score) + ',' + oligo_f + ',' + oligo_r + ',' + tm_f.toFixed(1) + ',' + tm_r.toFixed(1);
//继续判断互补性
var length_temp = Math.min(oligo_f.length, oligo_r.length);
if (comp(oligo_f, oligo_r) / length_temp <= 0.5) {
pairs.push(text);
break;
}
}
}
}
if (pairs.length < 1) {
score_f = parseInt(oliog_Fs[0].split(",")[0]);
var oligo_f = oliog_Fs[0].split(",")[1];
tm_f = parseInt(oliog_Fs[0].split(",")[2]);
score_r = parseInt(oliog_Rs[0].split(",")[0]);
var oligo_r = oliog_Rs[0].split(",")[1];
tm_r = parseInt(oliog_Rs[0].split(",")[2]);
var score = score_f + score_r;
var best = "0000".slice(String(score).length) + String(score) + ',' + oligo_f + ',' + oligo_r + ',' + tm_f.toFixed(1) + ',' + tm_r.toFixed(1);
}else {
pairs.sort().reverse();
var best = pairs[0];
}
return best;
}
//引物(集合)搜索
function primer(sequence, length) {
var oligos = new Array();
for (i=18; i<length; i++) {
var oligo = sequence.slice(0, i);
var Tm = tm(oligo);
var GC = gc(oligo);
var triplet = oligo.slice(-3);
var str = oligo.slice(-8);
var pattern = new RegExp(str, "g");
var tempSeq = sequence + 'N' + rev_com(sequence);
if (tempSeq.match(pattern).length > 1) {
continue;
}else {
if (Tm < 48) {var score1 = 10;}
else if(Tm < 52) {var score1 = 30;}
else if(Tm < 55) {var score1 = 70;}
else if(Tm <= 58) {var score1 = 100;}
else if(Tm <= 62) {var score1 = 80;}
else if(Tm <= 68) {var score1 = 40;}
else {var score1 = 20;}
if (GC < 20) {var score2 = 0;}
else if(GC <= 30) {var score2 = 20;}
else if(GC <= 40) {var score2 = 50;}
else if(GC <= 50) {var score2 = 100;}
else if(GC <= 60) {var score2 = 90;}
else if(GC <= 70) {var score2 = 60;}
else if(GC <= 80) {var score2 = 20;}
else {var score2 = 0;}
switch(triplet)
{
case "AGG": {var score3 = 100;break;}
case "TGG": {var score3 = 88;break;}
case "CTG": {var score3 = 84;break;}
case "ACC": {var score3 = 81;break;}
case "TCC": {var score3 = 81;break;}
case "CAG": {var score3 = 80;break;}
case "AGC": {var score3 = 75;break;}
case "GTG": {var score3 = 72;break;}
case "TTC": {var score3 = 72;break;}
case "CAC": {var score3 = 68;break;}
case "TGC": {var score3 = 67;break;}
case "CTC": {var score3 = 59;break;}
case "GTC": {var score3 = 57;break;}
case "TTG": {var score3 = 52;break;}
case "AAC": {var score3 = 50;break;}
case "ATC": {var score3 = 50;break;}
case "CAT": {var score3 = 48;break;}
case "GAG": {var score3 = 47;break;}
case "TGT": {var score3 = 47;break;}
case "ATG": {var score3 = 44;break;}
case "AGT": {var score3 = 42;break;}
case "GGC": {var score3 = 42;break;}
case "GAC": {var score3 = 40;break;}
case "GAT": {var score3 = 40;break;}
case "AAG": {var score3 = 39;break;}
case "CCC": {var score3 = 39;break;}
case "GGA": {var score3 = 39;break;}
case "ACT": {var score3 = 37;break;}
case "GCA": {var score3 = 37;break;}
case "GCC": {var score3 = 37;break;}
case "TAG": {var score3 = 37;break;}
case "AAA": {var score3 = 36;break;}
case "ACA": {var score3 = 36;break;}
case "CCA": {var score3 = 34;break;}
case "CCG": {var score3 = 34;break;}
case "TAC": {var score3 = 34;break;}
case "GTA": {var score3 = 32;break;}
case "ACG": {var score3 = 31;break;}
case "TCA": {var score3 = 31;break;}
case "TGA": {var score3 = 31;break;}
case "CAA": {var score3 = 29;break;}
case "CGG": {var score3 = 29;break;}
case "AAT": {var score3 = 27;break;}
case "GAA": {var score3 = 27;break;}
case "GCT": {var score3 = 27;break;}
case "GGT": {var score3 = 27;break;}
case "TCT": {var score3 = 26;break;}
case "AGA": {var score3 = 24;break;}
case "CGC": {var score3 = 24;break;}
case "CTT": {var score3 = 24;break;}
case "GCG": {var score3 = 23;break;}
case "TCG": {var score3 = 23;break;}
case "CCT": {var score3 = 21;break;}
case "CTA": {var score3 = 21;break;}
case "GTT": {var score3 = 21;break;}
case "TTT": {var score3 = 19;break;}
case "ATA": {var score3 = 18;break;}
case "TAT": {var score3 = 18;break;}
case "GGG": {var score3 = 14;break;}
case "ATT": {var score3 = 11;break;}
case "CGT": {var score3 = 11;break;}
case "CGA": {var score3 = 8;break;}
case "TAA": {var score3 = 6;break;}
case "TTA": {var score3 = 0;break;}
default: break;
}
var score = 5 * score1 + 2 * score2 + 3 * score3;
var text = "0000".slice(String(score).length) + String(score) + ',' + oligo + ',' + String(Tm); //方便排序
oligos.push(text);
}
}
if (oligos.length == 0) {
alert("你的引物太难设计了,还是你自己来吧!");
return;
}else {
oligos.sort().reverse();
return oligos;
}
}