libnano / primer3-py

Simple oligo analysis and primer design
https://libnano.github.io/primer3-py
GNU General Public License v2.0
157 stars 43 forks source link

Fix `_ThermoAnalysis._set_globals_and_seq_args` for improper checks on `misprime_lib` and `mishyb_lib` #135

Closed grinner closed 7 months ago

grinner commented 7 months ago

Fix _ThermoAnalysis._set_globals_and_seq_args for improper checks on misprime_lib and mishyb_lib leading to incorrect initialization of mp_lib and mh_lib and extensive run delays. See #133

Test code:

import time

from primer3 import __version__
from primer3.bindings import design_primers

# FASTA file from https://www.ncbi.nlm.nih.gov/nuccore/NC_004547.2
ref_fasta = 'NC_004547.2.fa'

seq = '''\
GATTGATTGAAGTCCAGGCACCGATTCTCAGCCGTATCGGCGATGGCACACAGGATAACTTGTCTGGTAC
AGAAAAAGCGGTGCAGGTTAAGGTAAAAGCCTTACCGGATGCCACATTTGAAGTGGTGCACTCACTGGCA
AAATGGAAACGCAAAACGCTGGGCGCGTATGATTTTAGCTTCGGTGAAGGCATTTATACTCACATGAAGG
CGCTGCGTCCGGACGAAGATCGCCTGAGCCCGATCCACTCGGTTTATGTCGATCAGTGGGATTGGGAGCG
CGTGATGGAGGATGGCGAGCGCAATGCTGAATATCTGAAATCGACGGTCACGCGTATTTATCAAGGCATT
AAAGCGACTGAGGCTGCGGTACATCAGGCGTTTGGCATTCAGCCTTTCCTGCCAGAGCAGATTCATTTTG
TGCATACCGAAACCTTGCTGAAGCGTTATCCCGATCTGGACGCCAAAGGGCGTGAGCGAGCTATAGCTAA
AGAGCTGGGTGCGGTCTTCCTGATTGGGATTGGCGGTAAGCTGTCCAGCGGACACTCTCACGATGTGCGT
GCACCGGATTATGATGACTGGACGACACCAGGCGAGCAGGAATTGGCGGGTTTGAACGGCGATATCGTCG
TCTGGAACCCAGTCCTGAACGATGCGTTTGAGATTTCATCCATGGGTATCCGCGTGGACGCAGAGGCGCT
AACACGCCAACTGGCACTGACGCAGGATGAGGAACGTCTGAAGCTTGAATGGCATCAGGCGCTGCTGCGC
'''.replace('\n', '')

GLOBALS = {
    'PRIMER_OPT_SIZE': 20,
    'PRIMER_MIN_SIZE': 18,
    'PRIMER_MAX_SIZE': 25,
    'PRIMER_PRODUCT_SIZE_RANGE': [
        [200, 250], [250, 300],
        [150, 200], [100, 150],
        [70, 100],
    ],
    'PRIMER_NUM_RETURN': 50,
    'PRIMER_MISPRIMING_LIBRARY': ref_fasta,
    'PRIMER_LIB_AMBIGUITY_CODES_CONSENSUS': 0,
}

seq_args = {
    'SEQUENCE_ID': 'XXX',
    'SEQUENCE_TEMPLATE': seq,
}

print('Using empty dicts for misprime_lib and mishyb_lib')
start = time.time()
candidates = design_primers(
    seq_args,
    GLOBALS,
    misprime_lib={},
    mishyb_lib={},
)
taken = time.time() - start
print(
    f'primer3 {__version__} with empty dicts gave {len(candidates)} in '
    f'{round(taken, 2)} seconds'
)

print("\nUsing None for misprime_lib and mishyb_lib")
start = time.time()
candidates = design_primers(
    seq_args,
    GLOBALS,
    misprime_lib=None,
    mishyb_lib=None,
)

taken = time.time() - start
print(
    f'primer3 {__version__} with None gave {len(candidates)} in '
    f'{round(taken, 2)} seconds\n',
)

Before:

Using empty dicts for misprime_lib and mishyb_lib
primer3 2.0.2 with empty dicts gave 1161 in 0.67 seconds

Using None for misprime_lib and mishyb_lib
primer3 2.0.2 with None gave 12 in 56.61 seconds

After

Using empty dicts for misprime_lib and mishyb_lib
primer3 2.0.3 with empty dicts gave 1161 in 0.66 seconds

Using None for misprime_lib and mishyb_lib
primer3 2.0.3 with None gave 1161 in 0.66 seconds