1、Primer3的下载与安装
在primer3官网上下载相应版本的程序,解压后安装,然后检测是否有安装错误。例如安装2.6.1版本:
wget https://github.com/primer3-org/primer3/archive/refs/tags/v2.6.1.tar.gz tar xzvf primer3-2.6.1.tar.gz cd primer3-2.6.1/src make make test
安装好之后只需要调用src文件夹中的primer3_core程序就可以了,可以拷贝到其它的地方使用。
primer3的各参数说明可以参考官方文档,中文的可以参考这篇博客。
2、模板的准备
将模板序列单独放在一个文件,如果是fasta格式的可以命名为fasta格式的代码读取文件,如果是tsv格式的(第一列为序列id,第二列为模板序列),使用tsv格式对应的代码读取文件。然后用下面代码进行批量设计。如果对引物条件不敏感,可以在参数中加入这个参数PRIMER_PICK_ANYWAY=1“,如果想获得多对引物可以修改这个参数”PRIMER_NUM_RETURN=1“。其它参数也可以根据需要修改或者添加。
如果只是检测设计的引物是否满足条件,可以引入以下函数修改对应的参数。
#!/usr/bin/perl
use strict;
use warnings;
my $primer3_core = "./primer3_core";
my $Seq_file = "./input_file";
my $primer3out_file = "./primer3out.txt";
############Change the parameter if need #######
my $primer3input = <<SET;
PRIMER_TASK=generic
PRIMER_PICK_LEFT_PRIMER=1
PRIMER_PICK_INTERNAL_OLIGO=0
PRIMER_PICK_RIGHT_PRIMER=1
PRIMER_PRODUCT_SIZE_RANGE=75-100
PRIMER_EXPLAIN_FLAG=1
PRIMER_FIRST_BASE_INDEX=1
PRIMER_LIBERAL_BASE=1
SEQUENCE_FORCE_LEFT_END=41
PRIMER_NUM_RETURN=1
PRIMER_OPT_SIZE=20
PRIMER_MIN_SIZE=18
PRIMER_MAX_SIZE=25
PRIMER_MIN_GC=30.0
PRIMER_MAX_GC=70.0
PRIMER_MIN_TM=58.0
PRIMER_OPT_TM=60.0
PRIMER_MAX_TM=62.0
=
SET
open(F, $Seq_file) or die "Can not open the flankingSeq file $!\n";
open(POUT, ">$primer3out_file");
my $print_out_head = join("\t", ("primer_id", "Foward", "Reverse"));
print POUT $print_out_head."\n";
my %id2seq;
my $id="";
my $seq="";
############if the input file is the fasta format##################
while(<F>){
if(/^>(\S+)/){
if($id){
$id2seq{$id}=$seq;
$seq="";
}
$id=$1;
}else{
s/\s+$//;
$seq.=$_;
}
if(eof){
$id2seq{$id}=$seq;
}
}
############if the input file is the tsv format, use this code################
#while(<F>){
# s/\s+$//;
# ($id, $seq)=split/\t/;
# $id2seq{$id}=$seq;
#}
foreach my $primer_id(keys %id2seq){
my (@primer_left, @primer_right)=&primerPick($primer_id, $id2seq{$primer_id});
my $i=0;
while($i<=$#primer_left){
print POUT $primer_id."\t".$primer_left[$i]."\t". $primer_right[$i]."\n" if($primer_left[$i] and $primer_right[$i]);
}
}
close(POUT);
system("rm ./primer3input.txt");
sub primerPick{
my ($snp_id, $template)=@_;
my $attachmentSet = <<ASET;
SEQUENCE_ID=$snp_id
SEQUENCE_TEMPLATE=$template
ASET
my $primer3set=$attachmentSet.$primer3input;
open(OUT, ">./primer3input.txt");
print OUT $primer3set;
close(OUT);
my $primer3output = `$primer3_core --default_version=2 --io_version=4 --strict_tags <./primer3input.txt `;
my @primer_left="";
if($primer3output=~/PRIMER_LEFT_(\d+)_SEQUENCE=(\w+)/g){
$primer_left[$1]=$2;
}
my @primer_right="";
if($primer3output=~/PRIMER_RIGHT_(\d+)_SEQUENCE=(\w+)/g){
$primer_right[$1]=$2;
}
return @primer_left,@primer_right;
}
sub checkPrimer{
my ($primer_id, $primer_left, $primer_right, $template)=@_;
my $primer3set=$primer3input;
$primer3set=~s/PRIMER_TASK=generic/PRIMER_TASK=check_primers/;
$primer3set=~s/PRIMER_PICK_LEFT_PRIMER=1/PRIMER_PICK_LEFT_PRIMER=0/;
$primer3set=~s/PRIMER_PICK_RIGHT_PRIMER=1/PRIMER_PICK_RIGHT_PRIMER=0/;
my $attachmentSet = <<ASET;
SEQUENCE_ID=$primer_id
SEQUENCE_TEMPLATE=$template
SEQUENCE_PRIMER=$primer_left
SEQUENCE_PRIMER_REVCOMP=$primer_right
ASET
$primer3set = $attachmentSet.$primer3set;
open(OUT, ">./primer3input.txt");
print OUT $primer3set;
close(OUT);
my $primer3out = `$primer3_core --default_version=2 --io_version=4 --strict_tags <./primer3input.txt `;
if($primer3out=~/PRIMER_PAIR_EXPLAIN=considered 1, ok 1/){
return 1;
}else{
return 0;
}
}