Skip to content

Commit e52f558

Browse files
committed
moved get_permutations and changed threshold to required
1 parent 77cb3a5 commit e52f558

File tree

4 files changed

+30
-30
lines changed

4 files changed

+30
-30
lines changed

varvamp/command.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def get_args(sysargs):
4646
QPCR_parser = mode_parser.add_parser(
4747
"qpcr",
4848
help="design qPCR primers",
49-
usage="varvamp qpcr [optional arguments] <alignment> <output dir>"
49+
usage="varvamp qpcr -t [optional arguments] <alignment> <output dir>"
5050
)
5151
parser.add_argument(
5252
"input",
@@ -145,9 +145,8 @@ def get_args(sysargs):
145145
QPCR_parser.add_argument(
146146
"-t",
147147
"--threshold",
148-
metavar="0.9",
148+
required=True,
149149
type=float,
150-
default=0.9,
151150
help="consensus threshold (0-1) - higher values result in higher specificity at the expense of found primers"
152151
)
153152
QPCR_parser.add_argument(

varvamp/scripts/primers.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"""
44

55
# BUILTIN
6-
from itertools import chain
6+
import itertools
77
import re
88
import multiprocessing
99

@@ -13,7 +13,7 @@
1313
import primer3 as p3
1414

1515
# varVAMP
16-
from varvamp.scripts import config, reporting
16+
from varvamp.scripts import config
1717

1818

1919
def calc_gc(seq):
@@ -476,6 +476,21 @@ def find_best_primers(left_primer_candidates, right_primer_candidates, high_cons
476476
return all_primers
477477

478478

479+
def get_permutations(seq):
480+
"""
481+
get all permutations of an ambiguous sequence.
482+
"""
483+
groups = itertools.groupby(seq, lambda char: char not in config.AMBIG_NUCS)
484+
splits = []
485+
for b, group in groups:
486+
if b:
487+
splits.extend([[g] for g in group])
488+
else:
489+
for nuc in group:
490+
splits.append(config.AMBIG_NUCS[nuc])
491+
return[''.join(p) for p in itertools.product(*splits)]
492+
493+
479494
def parse_primer_fasta(fasta_path):
480495
"""
481496
Parse a primer FASTA file and return a list of sequences using BioPython.
@@ -487,9 +502,9 @@ def parse_primer_fasta(fasta_path):
487502
seq = str(record.seq).lower()
488503
# Only include primers up to 40 nucleotides
489504
if len(seq) <= 40:
490-
sequences.append(reporting.get_permutations(seq))
505+
sequences.append(get_permutations(seq))
491506

492-
return list(chain.from_iterable(sequences))
507+
return list(itertools.chain.from_iterable(sequences))
493508

494509

495510
def check_primer_against_externals(args):
@@ -538,4 +553,4 @@ def filter_non_dimer_candidates(primer_candidates, external_sequences, n_threads
538553
filtered_results = [result for result in results if result is not None]
539554
return {name: data for name, data in filtered_results}
540555
else:
541-
return [primer for primer in results if primer is not None]
556+
return [primer for primer in results if primer is not None]

varvamp/scripts/qpcr.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ def _process_kmer_batch_probes(args):
6161
probe_idx = 0
6262

6363
for kmer in kmers:
64-
if not primers.filter_kmer_direction_independent(kmer[0], config.QPROBE_TMP, config.QPROBE_GC_RANGE,
65-
config.QPROBE_SIZES):
64+
if not primers.filter_kmer_direction_independent(kmer[0], config.QPROBE_TMP, config.QPROBE_GC_RANGE, config.QPROBE_SIZES):
6665
continue
6766
if ambiguous_ends(ambiguous_consensus[kmer[1]:kmer[2]]):
6867
continue
@@ -112,6 +111,8 @@ def get_qpcr_probes(kmers, ambiguous_consensus, alignment_cleaned, num_processes
112111
probe_candidates = {}
113112
probe_idx = 0
114113
for batch_probes in results:
114+
if batch_probes is None:
115+
continue
115116
for probe_name, probe_data in batch_probes.items():
116117
# Extract direction from original probe name
117118
direction = "LEFT" if "LEFT" in probe_name else "RIGHT"
@@ -175,9 +176,9 @@ def dimer_in_combinations(right_primer, left_primer, probe, ambiguous_consensus)
175176
# for the probe check all permutations and possible overhangs to ensure
176177
# that none of the primers could cause unspecific probe binding.
177178
# first get all permutations
178-
probe_per = reporting.get_permutations(ambiguous_consensus[probe[1]:probe[2]])
179-
left_per = reporting.get_permutations(ambiguous_consensus[left_primer[1]:left_primer[2]])
180-
right_per = reporting.get_permutations(ambiguous_consensus[right_primer[1]:right_primer[2]])
179+
probe_per = primers.get_permutations(ambiguous_consensus[probe[1]:probe[2]])
180+
left_per = primers.get_permutations(ambiguous_consensus[left_primer[1]:left_primer[2]])
181+
right_per = primers.get_permutations(ambiguous_consensus[right_primer[1]:right_primer[2]])
181182
# then check all permutations
182183
for combination in [(probe_per, left_per), (probe_per, right_per)]:
183184
for oligo1 in combination[0]:

varvamp/scripts/reporting.py

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
# BUILT-INS
55
import os
66
import math
7-
import itertools
87

98
# LIBS
109
import pandas as pd
@@ -94,20 +93,6 @@ def write_all_primers(path, scheme_name, all_primers):
9493
write_primers_to_bed(outfile, scheme_name, primer, all_primers[direction][primer], round(all_primers[direction][primer][3], 2), direction)
9594

9695

97-
def get_permutations(seq):
98-
"""
99-
get all permutations of an ambiguous sequence. needed to
100-
correctly report the gc and the temperature.
101-
"""
102-
groups = itertools.groupby(seq, lambda char: char not in config.AMBIG_NUCS)
103-
splits = []
104-
for b, group in groups:
105-
if b:
106-
splits.extend([[g] for g in group])
107-
else:
108-
for nuc in group:
109-
splits.append(config.AMBIG_NUCS[nuc])
110-
return[''.join(p) for p in itertools.product(*splits)]
11196

11297

11398
def calc_mean_stats(permutations):
@@ -190,7 +175,7 @@ def write_qpcr_to_files(path, final_schemes, ambiguous_consensus, scheme_name, l
190175
else:
191176
direction = "+"
192177

193-
permutations = get_permutations(seq)
178+
permutations = primers.get_permutations(seq)
194179
gc, temp = calc_mean_stats(permutations)
195180
primer_name = f"{amp_name}_{oligo_type}"
196181

@@ -295,7 +280,7 @@ def write_scheme_to_files(path, amplicon_scheme, ambiguous_consensus, scheme_nam
295280
# write primers to fasta pool file
296281
print(f">{primer_name}\n{seq.upper()}", file=primer_fasta)
297282
# calc primer parameters for all permutations
298-
permutations = get_permutations(seq)
283+
permutations = primers.get_permutations(seq)
299284
gc, temp = calc_mean_stats(permutations)
300285
# write tsv file
301286
print(

0 commit comments

Comments
 (0)