Skip to content

Commit

Permalink
expose the user config file to primerdesign.py
Browse files Browse the repository at this point in the history
  • Loading branch information
Runsheng committed Oct 27, 2022
1 parent ad85e0c commit 69c0def
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 14 deletions.
23 changes: 20 additions & 3 deletions bin/primerdesign.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@
"""

import argparse
import os,sys
import os
import sys
import json

#currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
#parentdir = os.path.dirname(os.path.dirname(currentdir))
#sys.path.insert(0,parentdir)

# self import
from primerdiffer.walk_chr import flow_walk_chr
from primerdiffer.walk_chr import flow_walk_chr, primer3_general_settings

parser=argparse.ArgumentParser()
parser.add_argument("-d", "--wkdir", default=None,
Expand Down Expand Up @@ -53,11 +55,25 @@
parser.add_argument("--prefix", default="primers",
help="prefix of output file, default is primers")

# add user settings
parser.add_argument("--primer3config", default=None,
help="the config file for the primer3 ")

# default handler
args = parser.parse_args(args=None if sys.argv[1:] else ['--help'])
wkdir=os.getcwd() if args.wkdir is None else args.wkdir


# deal with config
primer3_setting = primer3_general_settings
if args.primer3config is None:
pass
else: # update the primer3 setting from the givien parameters
with open(args.primer3config, "r") as f:
primer3_user_setting = eval(f.read()) # read the config as a dict
primer3_setting.update(primer3_user_setting)


flow_walk_chr(wkdir=wkdir,
genome1=args.genome1,
genome2=args.genome2,
Expand All @@ -69,4 +85,5 @@
db2_maxhit=args.hit2,
interval=args.interval,
jump=args.jump,
out_prefix=args.prefix)
out_prefix=args.prefix,
primer3_settings=primer3_setting)
2 changes: 1 addition & 1 deletion primerdiffer/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__= "0.1.2"
__version__= "0.1.4"
13 changes: 9 additions & 4 deletions primerdiffer/walk_chr.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@

from primerdiffer.primer_check import my_design_primer, primer_check
from primerdiffer.utils import dic2dic, fasta2dic, chr_select, tuple_to_pos_str, pos_str_to_tuple, checkblastdb
from primerdiffer.general_settings import primer3_general_settings


def walk_chr_dense(genome, chro, start, end, db1, db2,
cutoff_alignlength=16, cutoff_free3=2, product_cutoff=2000,
db1_maxhit=1, db2_maxhit=0,
interval=500000, jump=4000, out_prefix="primers", debugmod=False):
interval=500000, jump=4000, out_prefix="primers", debugmod=False,
primer3_settings=primer3_general_settings
):
"""
:param genome: genome is a dict in name:seq,
:param chro:
Expand All @@ -41,7 +44,7 @@ def walk_chr_dense(genome, chro, start, end, db1, db2,
if "N" in seq.upper():
offset += 1
else:
myprimer = my_design_primer(name=name, seq=seq)
myprimer = my_design_primer(name=name, seq=seq, primer3_settings=primer3_settings)
primer_used = primer_check(myprimer,db1,db2,
cutoff_alignlength, cutoff_free3, product_cutoff,
db1_maxhit, db2_maxhit,
Expand All @@ -67,7 +70,8 @@ def walk_chr_dense(genome, chro, start, end, db1, db2,
def flow_walk_chr(wkdir, genome1, genome2, pos_str,
cutoff_alignlength=16, cutoff_free3=2, product_cutoff=2000,
db1_maxhit=1, db2_maxhit=0,
interval=4000, jump=400, out_prefix="primers"):
interval=4000, jump=400, out_prefix="primers",
primer3_settings = primer3_general_settings):
"""
genome1: the genome fasta file used to design primers
Expand All @@ -94,5 +98,6 @@ def flow_walk_chr(wkdir, genome1, genome2, pos_str,
product_cutoff=product_cutoff,
db1_maxhit=db1_maxhit,
db2_maxhit=db2_maxhit,
interval=interval, jump=jump, out_prefix=out_prefix)
interval=interval, jump=jump, out_prefix=out_prefix,
primer3_settings=primer3_settings)
print(primer_dict)
50 changes: 44 additions & 6 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pip install primerdiffer # will also install primer3-py and biopython
conda install -c bioconda blast # install ncbi blast, which is not included in pip installation
```

## Case example: primerdesign.py for primerdiffer
## Case example: used primerdesign.py to design primers for two haplotypes
Design genome-wide specific primers for two species/sub-species/divergent sequences:
- Greedy design primers for a region in genome1 and make a specificity check using genome2
- The dis-similarity between genome1 and genome2 >= 5%.
Expand Down Expand Up @@ -63,8 +63,8 @@ from [cb5.fa](https://github.com/Runsheng/cbgenome/releases/download/cb5pre_cn3p

The _C. nigoni_ genome is cn3_new.fa and _C. briggsae_ genome is cb5.fa. To design _C. briggsae_ unique primer,
which would not amplify any region in _C. nigoni_, and amplify only one region in _C. briggsae_.
The targeted region for C. briggsae is ChrX:12881200-15106660 (-pos),
one primer is designed for every 4kb interval (--interval).
The targeted region for C. briggsae is ChrX:12881200-15106660 (-pos or --position),
one primer is designed for every 4kb interval (-i or --interval).
```bash
primerdesign.py -g1 cb5.fa -g2 cn3_new.fa -pos "ChrX:12881200-15106660" --interval 4000
```
Expand Down Expand Up @@ -119,9 +119,47 @@ head ispcr.fa
#ATGATGATGATGATGGTGGGGTGAGAATAGAGT
```

## Case example: Design general purpose primers with given parameters
The default primer design parameter is as described in [general_setting.py](https://github.com/Runsheng/primerdiffer/blob/master/primerdiffer/general_settings.py):
```python
primer3_general_settings = {
'PRIMER_OPT_SIZE': 20,
'PRIMER_PICK_LEFT_PRIMER':1,
'PRIMER_PICK_RIGHT_PRIMER':1,
'PRIMER_PICK_INTERNAL_OLIGO': 0,
'PRIMER_MIN_SIZE': 18,
'PRIMER_MAX_SIZE': 23,
'PRIMER_OPT_TM': 57.0,
'PRIMER_MIN_TM': 46.0,
'PRIMER_MAX_TM': 63.0,
'PRIMER_MIN_GC': 20.0,
'PRIMER_MAX_GC': 80.0,
'PRIMER_PRODUCT_SIZE_RANGE': [[250, 650]],
'PRIMER_NUM_RETURN':10,
'PRIMER_MIN_THREE_PRIME_DISTANCE':10,
'PRIMER_LIB_AMBIGUITY_CODES_CONSENSUS':0
}
```
The new parameter can be supplemnted as a file with the terms which need to be changed, for example, create a file with name of config.txt
```python
# content of config.txt
# only changed the product size, the others are the same the default
{'PRIMER_PRODUCT_SIZE_RANGE': [[100, 200]]}
```
Run primerdesign.py to design a qPCR primer(product size 100-20bp, use the config.txt for primer3config) for _C. briggsae_ mitochondrial DNA sequence
[NC_009885.1](https://www.ncbi.nlm.nih.gov/nuccore/NC_009885.1?report=fasta) in any region (use 0:-1 means from the first
nucleotide to the last); check the _C. briggsae_ genome cb5.fa for false priming, make sure the hit is 0.
```bash
primerdesign.py -g1 NC_009885.fa -g2 cb5.fa -pos "NC_009885.1:0:-1" \
--interval 1000 --hit1 1 --hit2 0 \
--primer3config config.txt
```




## Roadmap for other functions:
1. To use user-provided primer parameters.Primer design parameter now is fine-tuned for general purpose PCR, which can be found in "general_settings.py".This file may need be modified to generate primers for specific purpose PCR like real-time qPCR.
2. To update the RFLP method for primer design to differ sequences with almost identical sequence.
3. To update the primer design using VCF file for closely related haplotypes.
1. To update the RFLP method for primer design to differ sequences with almost identical sequence.
2. To update the primer design using VCF file for closely related haplotypes.


6 changes: 6 additions & 0 deletions test/test_walk_chr.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ def setUp(self):
self.cb4_genome = "/t1/ref_BN/cb5.fa"
#self.name, self.seq = chr_select(self.cb4_genome, "ChrX", 19424476,19655212)

def test_config_dump_load(self):
import json
from primerdiffer.general_settings import primer3_general_settings
with open("./test/primer3config", "w") as fw:
json.dump(primer3_general_settings, )


def test_walk_chr_dense(self):
wkdir=os.getcwd()
Expand Down
19 changes: 19 additions & 0 deletions test/user_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# use the user setting
# a minimal config can keep only the terms which need to be changed, like
# {'PRIMER_PRODUCT_SIZE_RANGE': [[100,200]]}
{ 'PRIMER_OPT_SIZE': 20,
'PRIMER_PICK_LEFT_PRIMER':1,
'PRIMER_PICK_RIGHT_PRIMER':1,
'PRIMER_PICK_INTERNAL_OLIGO': 0,
'PRIMER_MIN_SIZE': 18,
'PRIMER_MAX_SIZE': 23,
'PRIMER_OPT_TM': 57.0,
'PRIMER_MIN_TM': 46.0,
'PRIMER_MAX_TM': 63.0,
'PRIMER_MIN_GC': 20.0,
'PRIMER_MAX_GC': 80.0,
'PRIMER_PRODUCT_SIZE_RANGE': [[100,200]],
'PRIMER_NUM_RETURN':10,
'PRIMER_MIN_THREE_PRIME_DISTANCE':10,
'PRIMER_LIB_AMBIGUITY_CODES_CONSENSUS':0
}

0 comments on commit 69c0def

Please sign in to comment.