| name | primer-design-primer-basics |
| description | Design PCR primers for a target sequence using primer3-py. Specify target regions, product size, melting temperature, and other constraints. Returns ranked primer pairs with quality metrics. Use when designing standard PCR primers. |
| tool_type | python |
| primary_tool | primer3-py |
Version Compatibility
Reference examples tested with: BioPython 1.83+, pandas 2.2+, primer3-py 2.0+
Before using code patterns, verify installed versions match. If versions differ:
- Python:
pip show <package> then help(module.function) to check signatures
If code throws ImportError, AttributeError, or TypeError, introspect the installed
package and adapt the example to match the actual API rather than retrying.
PCR Primer Design
"Design primers for this sequence" -> Given a template sequence and constraints (product size, Tm, GC%), find ranked primer pairs that amplify the target region.
- Python:
primer3.design_primers() (primer3-py)
- CLI:
primer3_core (Primer3)
Design PCR primers using primer3-py, the Python binding for Primer3.
Required Imports
import primer3
from primer3 import p3helpers
from Bio import SeqIO
from Bio.Seq import Seq
Sequence Preparation (p3helpers)
raw_seq = ' atgc gatc GATC '
clean_seq = p3helpers.sanitize_sequence(raw_seq)
print(f'Cleaned: {clean_seq}')
seq = 'ATGCGATCGATC'
rc_seq = p3helpers.reverse_complement(seq)
print(f'Reverse complement: {rc_seq}')
valid_seq = p3helpers.ensure_acgt_uppercase('atgcNNgatc')
Basic Primer Design
sequence = 'ATGCGTACGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCGATCG'
result = primer3.design_primers(
seq_args={'SEQUENCE_TEMPLATE': sequence},
global_args={
'PRIMER_PRODUCT_SIZE_RANGE': [[100, 300]],
'PRIMER_MIN_TM': 57.0,
'PRIMER_OPT_TM': 60.0,
'PRIMER_MAX_TM': 63.0,
'PRIMER_MIN_GC': 40.0,
'PRIMER_MAX_GC': 60.0,
}
)
Extract Primer Results
num_returned = result['PRIMER_PAIR_NUM_RETURNED']
print(f'Found {num_returned} primer pairs')
for i in range(num_returned):
left = result[f'PRIMER_LEFT_{i}_SEQUENCE']
right = result[f'PRIMER_RIGHT_{i}_SEQUENCE']
left_tm = result[f'PRIMER_LEFT_{i}_TM']
right_tm = result[f'PRIMER_RIGHT_{i}_TM']
product_size = result[f'PRIMER_PAIR_{i}_PRODUCT_SIZE']
print(f'Pair {i}: {left} / {right}')
print(f' Tm: {left_tm:.1f}C / {right_tm:.1f}C, Product: {product_size}bp')
Target a Specific Region
result = primer3.design_primers(
seq_args={
'SEQUENCE_TEMPLATE': sequence,
'SEQUENCE_TARGET': [100, 50],
},
global_args={
'PRIMER_PRODUCT_SIZE_RANGE': [[150, 300]],
'PRIMER_OPT_TM': 60.0,
}
)
Primers Must Span a Region
result = primer3.design_primers(
seq_args={
'SEQUENCE_TEMPLATE': sequence,
'SEQUENCE_INCLUDED_REGION': [50, 200],
},
global_args={'PRIMER_PRODUCT_SIZE_RANGE': [[100, 250]]}
)
Exclude Regions
result = primer3.design_primers(
seq_args={
'SEQUENCE_TEMPLATE': sequence,
'SEQUENCE_EXCLUDED_REGION': [[150, 20], [300, 15]],
},
global_args={'PRIMER_PRODUCT_SIZE_RANGE': [[100, 300]]}
)
Constrain Primer Positions
result = primer3.design_primers(
seq_args={
'SEQUENCE_TEMPLATE': sequence,
'SEQUENCE_FORCE_LEFT_START': 50,
'SEQUENCE_FORCE_RIGHT_START': 250,
},
global_args={'PRIMER_PRODUCT_SIZE_RANGE': [[150, 250]]}
)
Design for Sequencing
result = primer3.design_primers(
seq_args={'SEQUENCE_TEMPLATE': sequence},
global_args={
'PRIMER_PICK_LEFT_PRIMER': 1,
'PRIMER_PICK_RIGHT_PRIMER': 0,
'PRIMER_PICK_INTERNAL_OLIGO': 0,
'PRIMER_OPT_SIZE': 20,
'PRIMER_MIN_SIZE': 18,
'PRIMER_MAX_SIZE': 25,
}
)
Full Parameter Control
result = primer3.design_primers(
seq_args={
'SEQUENCE_TEMPLATE': sequence,
'SEQUENCE_TARGET': [200, 50],
},
global_args={
'PRIMER_PRODUCT_SIZE_RANGE': [[150, 300], [300, 500]],
'PRIMER_NUM_RETURN': 5,
'PRIMER_MIN_SIZE': 18,
'PRIMER_OPT_SIZE': 20,
'PRIMER_MAX_SIZE': 25,
'PRIMER_MIN_TM': 57.0,
'PRIMER_OPT_TM': 60.0,
'PRIMER_MAX_TM': 63.0,
'PRIMER_MIN_GC': 40.0,
'PRIMER_OPT_GC_PERCENT': 50.0,
'PRIMER_MAX_GC': 60.0,
'PRIMER_MAX_POLY_X': 4,
'PRIMER_MAX_NS_ACCEPTED': 0,
'PRIMER_MAX_SELF_ANY': 8,
'PRIMER_MAX_SELF_END': 3,
'PRIMER_PAIR_MAX_COMPL_ANY': 8,
'PRIMER_PAIR_MAX_COMPL_END': 3,
: ,
}
)
Load Sequence from FASTA
from Bio import SeqIO
record = SeqIO.read('gene.fasta', 'fasta')
sequence = str(record.seq)
result = primer3.design_primers(
seq_args={'SEQUENCE_TEMPLATE': sequence, 'SEQUENCE_ID': record.id},
global_args={'PRIMER_PRODUCT_SIZE_RANGE': [[100, 300]], 'PRIMER_OPT_TM': 60.0}
)
Calculate Tm Directly
tm = primer3.calc_tm('ATGCGATCGATCGATCGATC')
print(f'Tm: {tm:.1f}C')
tm = primer3.calc_tm('ATGCGATCGATCGATCGATC', mv_conc=50.0, dv_conc=1.5, dntp_conc=0.2, dna_conc=50.0)
Tm Calculation Defaults
| Parameter | Default | Description |
|---|
| mv_conc | 50.0 mM | Monovalent cations (Na+, K+) |
| dv_conc | 0.0 mM | Divalent cations (Mg2+) |
| dntp_conc | 0.0 mM | dNTP concentration |
| dna_conc | 50.0 nM | DNA oligo concentration |
Calculate Hairpin and Dimer Tm
hairpin = primer3.calc_hairpin('ATGCGATCGATCGATCGATC')
print(f'Hairpin Tm: {hairpin.tm:.1f}C, dG: {hairpin.dg:.1f}')
homodimer = primer3.calc_homodimer('ATGCGATCGATCGATCGATC')
print(f'Homodimer Tm: {homodimer.tm:.1f}C, dG: {homodimer.dg:.1f}')
heterodimer = primer3.calc_heterodimer('ATGCGATCGATCGATCGATC', 'GCTAGCTAGCTAGCTAGCTA')
print(f'Heterodimer Tm: {heterodimer.tm:.1f}C, dG: {heterodimer.dg:.1f}')
Format Results as DataFrame
Goal: Convert primer3 results into a tabular format for comparison, filtering, or export.
Approach: Loop over returned pairs, extract sequence/Tm/GC/size/penalty for each, and build a DataFrame.
Reference (pandas 2.2+):
import pandas as pd
def primers_to_dataframe(result):
rows = []
for i in range(result['PRIMER_PAIR_NUM_RETURNED']):
rows.append({
'pair': i,
'left_seq': result[f'PRIMER_LEFT_{i}_SEQUENCE'],
'right_seq': result[f'PRIMER_RIGHT_{i}_SEQUENCE'],
'left_tm': result[f'PRIMER_LEFT_{i}_TM'],
'right_tm': result[f'PRIMER_RIGHT_{i}_TM'],
'left_gc': result[f'PRIMER_LEFT_{i}_GC_PERCENT'],
'right_gc': result[f'PRIMER_RIGHT_{i}_GC_PERCENT'],
'product_size': result[f'PRIMER_PAIR_{i}_PRODUCT_SIZE'],
'penalty': result[f'PRIMER_PAIR_{i}_PENALTY'],
})
return pd.DataFrame(rows)
df = primers_to_dataframe(result)
print(df)
Common Global Arguments
| Parameter | Description | Default |
|---|
| PRIMER_PRODUCT_SIZE_RANGE | Allowed product sizes | [[100,300]] |
| PRIMER_NUM_RETURN | Number of primer pairs | 5 |
| PRIMER_MIN/OPT/MAX_SIZE | Primer length | 18/20/27 |
| PRIMER_MIN/OPT/MAX_TM | Melting temperature | 57/60/63 |
| PRIMER_MIN/MAX_GC | GC content percent | 20/80 |
| PRIMER_MAX_POLY_X | Max poly-X run | 5 |
| PRIMER_MAX_SELF_ANY | Self complementarity | 8 |
| PRIMER_MAX_SELF_END | 3' self complementarity | 3 |
Related Skills
- qpcr-primers - Design primers with internal probes for qPCR
- primer-validation - Check primers for specificity and secondary structures
- sequence-io/read-sequences - Load template sequences
- database-access/local-blast - BLAST primers for specificity checking