varvamp 1.2.0__py3-none-any.whl → 1.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- varvamp/__init__.py +1 -1
- varvamp/command.py +23 -14
- varvamp/scripts/logging.py +12 -3
- varvamp/scripts/reporting.py +58 -58
- {varvamp-1.2.0.dist-info → varvamp-1.2.1.dist-info}/METADATA +4 -6
- {varvamp-1.2.0.dist-info → varvamp-1.2.1.dist-info}/RECORD +9 -9
- {varvamp-1.2.0.dist-info → varvamp-1.2.1.dist-info}/WHEEL +1 -1
- {varvamp-1.2.0.dist-info → varvamp-1.2.1.dist-info}/entry_points.txt +0 -0
- {varvamp-1.2.0.dist-info → varvamp-1.2.1.dist-info}/top_level.txt +0 -0
varvamp/__init__.py
CHANGED
varvamp/command.py
CHANGED
|
@@ -89,6 +89,13 @@ def get_args(sysargs):
|
|
|
89
89
|
type=int,
|
|
90
90
|
default=1
|
|
91
91
|
)
|
|
92
|
+
par.add_argument(
|
|
93
|
+
"--name",
|
|
94
|
+
help="name of the scheme",
|
|
95
|
+
metavar="varVAMP",
|
|
96
|
+
type=str,
|
|
97
|
+
default="varVAMP"
|
|
98
|
+
)
|
|
92
99
|
for par in (SINGLE_parser, TILED_parser):
|
|
93
100
|
par.add_argument(
|
|
94
101
|
"-ol",
|
|
@@ -261,10 +268,10 @@ def shared_workflow(args, log_file):
|
|
|
261
268
|
ambiguous_consensus,
|
|
262
269
|
alignment_cleaned
|
|
263
270
|
)
|
|
264
|
-
for
|
|
271
|
+
for primer_type, primer_candidates in [("+", left_primer_candidates), ("-", right_primer_candidates)]:
|
|
265
272
|
if not primer_candidates:
|
|
266
273
|
logging.raise_error(
|
|
267
|
-
f"no {
|
|
274
|
+
f"no {primer_type} primers found.\n",
|
|
268
275
|
log_file,
|
|
269
276
|
exit=True
|
|
270
277
|
)
|
|
@@ -330,7 +337,7 @@ def single_and_tiled_shared_workflow(args, left_primer_candidates, right_primer_
|
|
|
330
337
|
return all_primers, amplicons
|
|
331
338
|
|
|
332
339
|
|
|
333
|
-
def single_workflow(args, amplicons,
|
|
340
|
+
def single_workflow(args, amplicons, log_file):
|
|
334
341
|
"""
|
|
335
342
|
workflow part specific for single mode
|
|
336
343
|
"""
|
|
@@ -477,13 +484,13 @@ def qpcr_workflow(args, data_dir, alignment_cleaned, ambiguous_consensus, majori
|
|
|
477
484
|
return probe_regions, final_schemes
|
|
478
485
|
|
|
479
486
|
|
|
480
|
-
def main(
|
|
487
|
+
def main():
|
|
481
488
|
"""
|
|
482
489
|
main varvamp workflow
|
|
483
490
|
"""
|
|
484
491
|
|
|
485
492
|
# start varVAMP
|
|
486
|
-
args = get_args(
|
|
493
|
+
args = get_args(sys.argv[1:])
|
|
487
494
|
if not args.verbose:
|
|
488
495
|
sys.stdout = open(os.devnull, 'w')
|
|
489
496
|
start_time = datetime.datetime.now()
|
|
@@ -496,10 +503,10 @@ def main(sysargs=sys.argv[1:]):
|
|
|
496
503
|
alignment_cleaned, majority_consensus, ambiguous_consensus, primer_regions, left_primer_candidates, right_primer_candidates = shared_workflow(args, log_file)
|
|
497
504
|
|
|
498
505
|
# write files that are shared in all modes
|
|
499
|
-
reporting.write_regions_to_bed(primer_regions, data_dir)
|
|
506
|
+
reporting.write_regions_to_bed(primer_regions, args.name, data_dir)
|
|
500
507
|
reporting.write_alignment(data_dir, alignment_cleaned)
|
|
501
|
-
reporting.write_fasta(data_dir, "majority_consensus", majority_consensus)
|
|
502
|
-
reporting.write_fasta(results_dir, "ambiguous_consensus", ambiguous_consensus)
|
|
508
|
+
reporting.write_fasta(data_dir, f"majority_consensus", f"{args.name}_consensus",majority_consensus)
|
|
509
|
+
reporting.write_fasta(results_dir, f"ambiguous_consensus", f"{args.name}_consensus", ambiguous_consensus)
|
|
503
510
|
|
|
504
511
|
# Functions called from here on return lists of amplicons that are refined step-wise into final schemes.
|
|
505
512
|
# These lists that are passed between functions and later used for reporting consist of dictionary elemnts,
|
|
@@ -526,7 +533,6 @@ def main(sysargs=sys.argv[1:]):
|
|
|
526
533
|
amplicon_scheme = single_workflow(
|
|
527
534
|
args,
|
|
528
535
|
amplicons,
|
|
529
|
-
all_primers,
|
|
530
536
|
log_file
|
|
531
537
|
)
|
|
532
538
|
elif args.mode == "tiled":
|
|
@@ -549,11 +555,12 @@ def main(sysargs=sys.argv[1:]):
|
|
|
549
555
|
else:
|
|
550
556
|
# make sure amplicons with no off-target products and with low penalties get the lowest numbers
|
|
551
557
|
amplicon_scheme.sort(key=lambda x: (x.get("off_targets", False), x["penalty"]))
|
|
552
|
-
reporting.write_all_primers(data_dir, all_primers)
|
|
558
|
+
reporting.write_all_primers(data_dir, args.name, all_primers)
|
|
553
559
|
reporting.write_scheme_to_files(
|
|
554
560
|
results_dir,
|
|
555
561
|
amplicon_scheme,
|
|
556
562
|
ambiguous_consensus,
|
|
563
|
+
args.name,
|
|
557
564
|
args.mode,
|
|
558
565
|
log_file
|
|
559
566
|
)
|
|
@@ -561,10 +568,11 @@ def main(sysargs=sys.argv[1:]):
|
|
|
561
568
|
results_dir,
|
|
562
569
|
alignment_cleaned,
|
|
563
570
|
primer_regions,
|
|
571
|
+
args.name,
|
|
564
572
|
all_primers=all_primers,
|
|
565
573
|
amplicon_scheme=amplicon_scheme,
|
|
566
574
|
)
|
|
567
|
-
reporting.per_base_mismatch_plot(results_dir, amplicon_scheme, args.threshold)
|
|
575
|
+
reporting.per_base_mismatch_plot(results_dir, amplicon_scheme, args.threshold, args.name)
|
|
568
576
|
|
|
569
577
|
# QPCR mode
|
|
570
578
|
if args.mode == "qpcr":
|
|
@@ -583,16 +591,17 @@ def main(sysargs=sys.argv[1:]):
|
|
|
583
591
|
|
|
584
592
|
# make sure amplicons with no off-target products and with low penalties get the lowest numbers
|
|
585
593
|
final_schemes.sort(key=lambda x: (x.get("off_targets", False), x["penalty"]))
|
|
586
|
-
reporting.write_regions_to_bed(probe_regions, data_dir, "probe")
|
|
587
|
-
reporting.write_qpcr_to_files(results_dir, final_schemes, ambiguous_consensus, log_file)
|
|
594
|
+
reporting.write_regions_to_bed(probe_regions, args.name, data_dir, "probe")
|
|
595
|
+
reporting.write_qpcr_to_files(results_dir, final_schemes, ambiguous_consensus, args.name, log_file)
|
|
588
596
|
reporting.varvamp_plot(
|
|
589
597
|
results_dir,
|
|
590
598
|
alignment_cleaned,
|
|
591
599
|
primer_regions,
|
|
600
|
+
args.name,
|
|
592
601
|
probe_regions=probe_regions,
|
|
593
602
|
amplicon_scheme=final_schemes
|
|
594
603
|
)
|
|
595
|
-
reporting.per_base_mismatch_plot(results_dir, final_schemes, args.threshold, mode="QPCR")
|
|
604
|
+
reporting.per_base_mismatch_plot(results_dir, final_schemes, args.threshold, args.name, mode="QPCR")
|
|
596
605
|
|
|
597
606
|
# varVAMP finished
|
|
598
607
|
logging.varvamp_progress(log_file, progress=1, start_time=start_time)
|
varvamp/scripts/logging.py
CHANGED
|
@@ -15,12 +15,12 @@ from varvamp.scripts import config
|
|
|
15
15
|
from varvamp import __version__
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
def create_dir_structure(
|
|
18
|
+
def create_dir_structure(dir_path):
|
|
19
19
|
"""
|
|
20
20
|
create output folders and log file
|
|
21
21
|
"""
|
|
22
22
|
cwd = os.getcwd()
|
|
23
|
-
results_dir = os.path.join(cwd,
|
|
23
|
+
results_dir = os.path.join(cwd, dir_path)
|
|
24
24
|
data_dir = os.path.join(results_dir, "data/")
|
|
25
25
|
# create folders
|
|
26
26
|
if not os.path.exists(results_dir):
|
|
@@ -567,7 +567,7 @@ def goodbye_message():
|
|
|
567
567
|
"Thank you. Come again.",
|
|
568
568
|
">Placeholder for your advertisement<",
|
|
569
569
|
"Make primers great again!",
|
|
570
|
-
"Ciao cacao!"
|
|
570
|
+
"Ciao cacao!",
|
|
571
571
|
"And now lets pray to the PCR gods.",
|
|
572
572
|
"**bibobibobop** task finished",
|
|
573
573
|
"Thank you for traveling with varVAMP.",
|
|
@@ -581,5 +581,14 @@ def goodbye_message():
|
|
|
581
581
|
"Barba non facit philosophum.",
|
|
582
582
|
"Task failed successfully.",
|
|
583
583
|
"Never gonna give you up, never gonna let you down.",
|
|
584
|
+
"Have you tried turning it off and on again?",
|
|
585
|
+
"Look, I am your primer scheme.",
|
|
586
|
+
"Quod erat demonstrandum.",
|
|
587
|
+
"Miau?",
|
|
588
|
+
"This is an automated message informing you that you are awsome.",
|
|
589
|
+
"Why was the negative-sense virus angry at the positive-sense virus?\nBecause he was left stranded!",
|
|
590
|
+
"If you see this message twice, you are an experienced user.",
|
|
591
|
+
"No one expects the spanish inquisition!",
|
|
592
|
+
"Primer design you must."
|
|
584
593
|
]
|
|
585
594
|
print(f"\n{random.choice(messages)}")
|
varvamp/scripts/reporting.py
CHANGED
|
@@ -19,11 +19,11 @@ from varvamp.scripts import config
|
|
|
19
19
|
from varvamp.scripts import logging
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def write_fasta(path, seq_id, seq):
|
|
22
|
+
def write_fasta(path, file_name, seq_id, seq):
|
|
23
23
|
"""
|
|
24
24
|
write fasta files
|
|
25
25
|
"""
|
|
26
|
-
name = f"{
|
|
26
|
+
name = f"{file_name}.fasta"
|
|
27
27
|
out = os.path.join(path, name)
|
|
28
28
|
with open(out, 'w') as o:
|
|
29
29
|
print(f">{seq_id}\n{seq}", file=o)
|
|
@@ -40,7 +40,7 @@ def write_alignment(path, alignment):
|
|
|
40
40
|
print(f">{seq[0]}\n{seq[1]}", file=o)
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
def write_regions_to_bed(primer_regions, path, mode=None):
|
|
43
|
+
def write_regions_to_bed(primer_regions, scheme_name, path, mode=None):
|
|
44
44
|
"""
|
|
45
45
|
write primer regions as bed file
|
|
46
46
|
"""
|
|
@@ -53,7 +53,7 @@ def write_regions_to_bed(primer_regions, path, mode=None):
|
|
|
53
53
|
with open(outfile, 'w') as o:
|
|
54
54
|
for counter, region in enumerate(primer_regions):
|
|
55
55
|
print(
|
|
56
|
-
"
|
|
56
|
+
f"{scheme_name}_consensus",
|
|
57
57
|
region[0],
|
|
58
58
|
region[1],
|
|
59
59
|
"REGION_"+str(counter),
|
|
@@ -62,24 +62,30 @@ def write_regions_to_bed(primer_regions, path, mode=None):
|
|
|
62
62
|
)
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
def write_primers_to_bed(outfile, primer_name, primer_properties, direction):
|
|
65
|
+
def write_primers_to_bed(outfile, scheme_name, primer_name, primer_properties, numeric_value, direction, sequence=None):
|
|
66
66
|
"""
|
|
67
67
|
write primers as bed file
|
|
68
68
|
"""
|
|
69
69
|
with open(outfile, 'a') as o:
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
# write header for primer bed
|
|
71
|
+
if os.path.getsize(outfile) == 0 and sequence is not None:
|
|
72
|
+
print("#chrom\tchromStart\tchromEnd\tprimer-name\tpool\tstrand\tprimer-sequence", file=o)
|
|
73
|
+
data = [f"{scheme_name}_consensus",
|
|
72
74
|
primer_properties[1], # start
|
|
73
75
|
primer_properties[2], # stop
|
|
74
76
|
primer_name,
|
|
75
|
-
|
|
76
|
-
direction
|
|
77
|
+
numeric_value, # can be pool or score
|
|
78
|
+
direction]
|
|
79
|
+
if sequence is not None:
|
|
80
|
+
data.append(sequence)
|
|
81
|
+
print(
|
|
82
|
+
*data,
|
|
77
83
|
sep="\t",
|
|
78
84
|
file=o
|
|
79
85
|
)
|
|
80
86
|
|
|
81
87
|
|
|
82
|
-
def write_all_primers(path, all_primers):
|
|
88
|
+
def write_all_primers(path, scheme_name, all_primers):
|
|
83
89
|
"""
|
|
84
90
|
write all primers that varVAMP designed as bed file
|
|
85
91
|
"""
|
|
@@ -87,7 +93,7 @@ def write_all_primers(path, all_primers):
|
|
|
87
93
|
|
|
88
94
|
for direction in all_primers:
|
|
89
95
|
for primer in all_primers[direction]:
|
|
90
|
-
write_primers_to_bed(outfile, primer, all_primers[direction][primer], direction)
|
|
96
|
+
write_primers_to_bed(outfile, scheme_name, primer, all_primers[direction][primer], round(all_primers[direction][primer][3], 2), direction)
|
|
91
97
|
|
|
92
98
|
|
|
93
99
|
def get_permutations(seq):
|
|
@@ -120,7 +126,7 @@ def calc_mean_stats(permutations):
|
|
|
120
126
|
return round(gc/len(permutations), 1), round(temp/len(permutations), 1)
|
|
121
127
|
|
|
122
128
|
|
|
123
|
-
def write_qpcr_to_files(path, final_schemes, ambiguous_consensus, log_file):
|
|
129
|
+
def write_qpcr_to_files(path, final_schemes, ambiguous_consensus, scheme_name, log_file):
|
|
124
130
|
"""
|
|
125
131
|
write all relevant bed files and tsv file for the qPCR design
|
|
126
132
|
"""
|
|
@@ -141,10 +147,10 @@ def write_qpcr_to_files(path, final_schemes, ambiguous_consensus, log_file):
|
|
|
141
147
|
file=tsv
|
|
142
148
|
)
|
|
143
149
|
for n, amp in enumerate(final_schemes):
|
|
144
|
-
amp_name = f"
|
|
150
|
+
amp_name = f"{scheme_name}_{n}"
|
|
145
151
|
# write bed amplicon file
|
|
146
152
|
print(
|
|
147
|
-
"
|
|
153
|
+
f"{scheme_name}_consensus",
|
|
148
154
|
amp["LEFT"][1],
|
|
149
155
|
amp["RIGHT"][2],
|
|
150
156
|
amp_name,
|
|
@@ -188,6 +194,7 @@ def write_qpcr_to_files(path, final_schemes, ambiguous_consensus, log_file):
|
|
|
188
194
|
|
|
189
195
|
permutations = get_permutations(seq)
|
|
190
196
|
gc, temp = calc_mean_stats(permutations)
|
|
197
|
+
primer_name = f"{amp_name}_{oligo_type}"
|
|
191
198
|
|
|
192
199
|
print(
|
|
193
200
|
amp_name,
|
|
@@ -208,15 +215,18 @@ def write_qpcr_to_files(path, final_schemes, ambiguous_consensus, log_file):
|
|
|
208
215
|
# write primer bed file
|
|
209
216
|
write_primers_to_bed(
|
|
210
217
|
primer_bed_file,
|
|
211
|
-
|
|
218
|
+
scheme_name,
|
|
219
|
+
primer_name,
|
|
212
220
|
amp[oligo_type],
|
|
213
|
-
|
|
221
|
+
round(amp[oligo_type][3], 2),
|
|
222
|
+
direction,
|
|
223
|
+
seq.upper()
|
|
214
224
|
)
|
|
215
225
|
# write fasta
|
|
216
|
-
print(f">{
|
|
226
|
+
print(f">{primer_name}\n{seq.upper()}", file=fasta)
|
|
217
227
|
|
|
218
228
|
|
|
219
|
-
def write_scheme_to_files(path, amplicon_scheme, ambiguous_consensus, mode, log_file):
|
|
229
|
+
def write_scheme_to_files(path, amplicon_scheme, ambiguous_consensus, scheme_name, mode, log_file):
|
|
220
230
|
"""
|
|
221
231
|
write all relevant bed files and a tsv file with all primer stats
|
|
222
232
|
"""
|
|
@@ -229,7 +239,7 @@ def write_scheme_to_files(path, amplicon_scheme, ambiguous_consensus, mode, log_
|
|
|
229
239
|
with open(tsv_file, "w") as tsv, open(amplicon_bed_file, "w") as bed, open(tabular_file, "w") as tabular:
|
|
230
240
|
# write header for primer tsv
|
|
231
241
|
print(
|
|
232
|
-
"amlicon_name\tamplicon_length\tprimer_name\
|
|
242
|
+
"amlicon_name\tamplicon_length\tprimer_name\tprimer_name_all_primers\tpool\tstart\tstop\tseq\tsize\tgc_best\ttemp_best\tmean_gc\tmean_temp\tpenalty\toff_target_amplicons",
|
|
233
243
|
file=tsv
|
|
234
244
|
)
|
|
235
245
|
amplicon_bed_records = []
|
|
@@ -240,12 +250,12 @@ def write_scheme_to_files(path, amplicon_scheme, ambiguous_consensus, mode, log_
|
|
|
240
250
|
if mode == "single":
|
|
241
251
|
primer_fasta_file = os.path.join(path, "primers.fasta")
|
|
242
252
|
else:
|
|
243
|
-
primer_fasta_file = os.path.join(path, f"primers_pool_{pool}.fasta")
|
|
253
|
+
primer_fasta_file = os.path.join(path, f"primers_pool_{pool+1}.fasta")
|
|
244
254
|
with open(primer_fasta_file, "w") as primer_fasta:
|
|
245
255
|
for counter, amp in enumerate(amplicon_scheme[pool::len(pools)]):
|
|
246
256
|
# give a new amplicon name
|
|
247
257
|
amplicon_index = counter*len(pools) + pool
|
|
248
|
-
|
|
258
|
+
amp_name = f"{scheme_name}_{amplicon_index}"
|
|
249
259
|
# get left and right primers and their names
|
|
250
260
|
amp_length = amp["RIGHT"][2] - amp["LEFT"][1]
|
|
251
261
|
if "off_targets" in amp:
|
|
@@ -258,14 +268,14 @@ def write_scheme_to_files(path, amplicon_scheme, ambiguous_consensus, mode, log_
|
|
|
258
268
|
amplicon_has_off_target = "n.d."
|
|
259
269
|
# write amplicon bed
|
|
260
270
|
if mode == "tiled":
|
|
261
|
-
bed_score = pool
|
|
271
|
+
bed_score = pool+1
|
|
262
272
|
elif mode == "single":
|
|
263
273
|
bed_score = round(amp["LEFT"][3] + amp["RIGHT"][3], 1)
|
|
264
274
|
amplicon_bed_records.append(
|
|
265
275
|
(
|
|
266
276
|
amp["LEFT"][1],
|
|
267
277
|
amp["RIGHT"][2],
|
|
268
|
-
|
|
278
|
+
amp_name,
|
|
269
279
|
bed_score
|
|
270
280
|
)
|
|
271
281
|
)
|
|
@@ -273,7 +283,7 @@ def write_scheme_to_files(path, amplicon_scheme, ambiguous_consensus, mode, log_
|
|
|
273
283
|
(
|
|
274
284
|
# will need amplicon_index for sorting
|
|
275
285
|
amplicon_index,
|
|
276
|
-
(f"{
|
|
286
|
+
(f"{amp_name}_LEFT", f"{amp_name}_RIGHT")
|
|
277
287
|
)
|
|
278
288
|
)
|
|
279
289
|
# write primer tsv and primer bed
|
|
@@ -281,9 +291,9 @@ def write_scheme_to_files(path, amplicon_scheme, ambiguous_consensus, mode, log_
|
|
|
281
291
|
seq = ambiguous_consensus[primer[1]:primer[2]]
|
|
282
292
|
if direction == "-":
|
|
283
293
|
seq = primers.rev_complement(seq)
|
|
284
|
-
primer_name = f"{
|
|
294
|
+
primer_name = f"{amp_name}_RIGHT"
|
|
285
295
|
else:
|
|
286
|
-
primer_name = f"{
|
|
296
|
+
primer_name = f"{amp_name}_LEFT"
|
|
287
297
|
# write primers to fasta pool file
|
|
288
298
|
print(f">{primer_name}\n{seq.upper()}", file=primer_fasta)
|
|
289
299
|
# calc primer parameters for all permutations
|
|
@@ -291,11 +301,11 @@ def write_scheme_to_files(path, amplicon_scheme, ambiguous_consensus, mode, log_
|
|
|
291
301
|
gc, temp = calc_mean_stats(permutations)
|
|
292
302
|
# write tsv file
|
|
293
303
|
print(
|
|
294
|
-
|
|
304
|
+
amp_name,
|
|
295
305
|
amp_length,
|
|
296
306
|
primer_name,
|
|
297
307
|
primer[-1],
|
|
298
|
-
pool,
|
|
308
|
+
pool+1,
|
|
299
309
|
primer[1] + 1,
|
|
300
310
|
primer[2],
|
|
301
311
|
seq.upper(),
|
|
@@ -313,13 +323,13 @@ def write_scheme_to_files(path, amplicon_scheme, ambiguous_consensus, mode, log_
|
|
|
313
323
|
(
|
|
314
324
|
# will need amplicon_index for sorting
|
|
315
325
|
amplicon_index,
|
|
316
|
-
(primer_name, primer, direction)
|
|
326
|
+
(primer_name, primer, pool+1, direction, seq.upper())
|
|
317
327
|
)
|
|
318
328
|
)
|
|
319
329
|
# write amplicon bed with amplicons sorted by start position
|
|
320
330
|
for record in sorted(amplicon_bed_records, key=lambda x: x[0]):
|
|
321
331
|
print(
|
|
322
|
-
"
|
|
332
|
+
f"{scheme_name}_consensus",
|
|
323
333
|
*record,
|
|
324
334
|
".",
|
|
325
335
|
sep="\t",
|
|
@@ -336,6 +346,7 @@ def write_scheme_to_files(path, amplicon_scheme, ambiguous_consensus, mode, log_
|
|
|
336
346
|
for record in sorted(primer_bed_records):
|
|
337
347
|
write_primers_to_bed(
|
|
338
348
|
primer_bed_file,
|
|
349
|
+
scheme_name,
|
|
339
350
|
*record[1]
|
|
340
351
|
)
|
|
341
352
|
|
|
@@ -352,7 +363,7 @@ def write_dimers(path, primer_dimers):
|
|
|
352
363
|
)
|
|
353
364
|
for pool, primer1, primer2 in primer_dimers:
|
|
354
365
|
print(
|
|
355
|
-
pool,
|
|
366
|
+
pool+1,
|
|
356
367
|
primer1[1],
|
|
357
368
|
primer2[1],
|
|
358
369
|
round(primers.calc_dimer(primer1[2][0], primer2[2][0]).tm, 1),
|
|
@@ -405,7 +416,7 @@ def alignment_entropy(alignment_cleaned):
|
|
|
405
416
|
return entropy_df
|
|
406
417
|
|
|
407
418
|
|
|
408
|
-
def entropy_subplot(ax, alignment_cleaned):
|
|
419
|
+
def entropy_subplot(ax, alignment_cleaned, scheme_name):
|
|
409
420
|
"""
|
|
410
421
|
creates the entropy subplot
|
|
411
422
|
"""
|
|
@@ -417,7 +428,7 @@ def entropy_subplot(ax, alignment_cleaned):
|
|
|
417
428
|
ax[0].set_ylim((0, 1))
|
|
418
429
|
ax[0].set_xlim(0, max(entropy_df["position"]))
|
|
419
430
|
ax[0].set_ylabel("normalized Shannon's entropy")
|
|
420
|
-
ax[0].set_title("
|
|
431
|
+
ax[0].set_title(f"{scheme_name} amplicon design")
|
|
421
432
|
ax[0].spines['top'].set_visible(False)
|
|
422
433
|
ax[0].spines['right'].set_visible(False)
|
|
423
434
|
|
|
@@ -501,7 +512,7 @@ def qpcr_subplot(ax, amplicon_scheme):
|
|
|
501
512
|
ax[1].hlines(0.75, probe[1], probe[2], linewidth=5, color="darkgrey", label="probe")
|
|
502
513
|
|
|
503
514
|
|
|
504
|
-
def varvamp_plot(path, alignment_cleaned, primer_regions, all_primers=None, amplicon_scheme=None, probe_regions=None):
|
|
515
|
+
def varvamp_plot(path, alignment_cleaned, primer_regions, scheme_name, all_primers=None, amplicon_scheme=None, probe_regions=None):
|
|
505
516
|
"""
|
|
506
517
|
creates overview plot for the amplicon design
|
|
507
518
|
and per base coverage plots
|
|
@@ -514,7 +525,7 @@ def varvamp_plot(path, alignment_cleaned, primer_regions, all_primers=None, ampl
|
|
|
514
525
|
fig, ax = plt.subplots(2, 1, figsize=[22, 6], squeeze=True, sharex=True, gridspec_kw={'height_ratios': [4, 1]})
|
|
515
526
|
fig.subplots_adjust(hspace=0)
|
|
516
527
|
# entropy plot
|
|
517
|
-
entropy_subplot(ax, alignment_cleaned)
|
|
528
|
+
entropy_subplot(ax, alignment_cleaned, scheme_name)
|
|
518
529
|
# primer regions plot
|
|
519
530
|
region_subplot(ax, primer_regions)
|
|
520
531
|
# probe region plot for probes
|
|
@@ -540,43 +551,32 @@ def varvamp_plot(path, alignment_cleaned, primer_regions, all_primers=None, ampl
|
|
|
540
551
|
plt.close()
|
|
541
552
|
|
|
542
553
|
|
|
543
|
-
def
|
|
554
|
+
def get_primers_for_plot(amplicon_scheme, scheme_name, mode):
|
|
544
555
|
"""
|
|
545
556
|
get the primers for per base pair plot (single, tiled)
|
|
546
557
|
"""
|
|
547
558
|
amplicon_primers = []
|
|
548
559
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
return amplicon_primers
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
def get_QPCR_primers_for_plot(amplicon_schemes):
|
|
558
|
-
"""
|
|
559
|
-
get the primers for per base pair plot (qpcr)
|
|
560
|
-
"""
|
|
561
|
-
amplicon_primers = []
|
|
560
|
+
if mode == "SINGLE/TILED":
|
|
561
|
+
oligo_types = ["LEFT", "RIGHT"]
|
|
562
|
+
else:
|
|
563
|
+
oligo_types = ["PROBE", "LEFT", "RIGHT"]
|
|
562
564
|
|
|
563
|
-
for counter, amp in enumerate(
|
|
564
|
-
for
|
|
565
|
-
primer_name = f"
|
|
566
|
-
amplicon_primers.append((primer_name, amp[
|
|
565
|
+
for counter, amp in enumerate(amplicon_scheme):
|
|
566
|
+
for oligo_type in oligo_types:
|
|
567
|
+
primer_name = f"{scheme_name}_{counter}_{oligo_type}"
|
|
568
|
+
amplicon_primers.append((primer_name, amp[oligo_type]))
|
|
567
569
|
|
|
568
570
|
return amplicon_primers
|
|
569
571
|
|
|
570
572
|
|
|
571
|
-
def per_base_mismatch_plot(path, amplicon_scheme, threshold, mode="SINGLE/TILED"):
|
|
573
|
+
def per_base_mismatch_plot(path, amplicon_scheme, threshold, scheme_name, mode="SINGLE/TILED"):
|
|
572
574
|
"""
|
|
573
575
|
per base pair mismatch multiplot
|
|
574
576
|
"""
|
|
575
577
|
out = os.path.join(path, "per_base_mismatches.pdf")
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
elif mode == "QPCR":
|
|
579
|
-
amplicon_primers = get_QPCR_primers_for_plot(amplicon_scheme)
|
|
578
|
+
|
|
579
|
+
amplicon_primers = get_primers_for_plot(amplicon_scheme, scheme_name, mode)
|
|
580
580
|
# ini multi pdf
|
|
581
581
|
with PdfPages(out) as pdf:
|
|
582
582
|
# always print 4 primers to one page
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: varvamp
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Variable VirusAMPlicons (varVAMP) is a tool to design primers for highly diverse viruses
|
|
5
5
|
Home-page: https://github.com/jonas-fuchs/varVAMP
|
|
6
6
|
Author: Dr. Jonas Fuchs
|
|
@@ -61,15 +61,13 @@ For a lot of virus genera it is difficult to design pan-specific primers. varVAM
|
|
|
61
61
|
|
|
62
62
|
We, in collaboration with specialists for the respective viruses, have already designed and wet-lab evaluated primer schemes for various viral pathogens. All the input data and varVAMP outputs are freely available [here](https://github.com/jonas-fuchs/ViralPrimerSchemes).
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
Moreover, varVAMP primers are now available at [primerschemes](https://labs.primalscheme.com/). varVAMP now reports primer bed files in ARTICv3 format. Feel free to contribute newly designed schemes via this [Github repository of the QuickLab](https://github.com/quick-lab/primerschemes). Use [primal-page](https://github.com/ChrisgKent/primal-page) developed by [Chris Kent](https://github.com/ChrisgKent) to generate data for compatible pull-requests.
|
|
65
65
|
|
|
66
|
-
# Citing varVAMP
|
|
67
|
-
|
|
68
|
-
Please cite with the respective DOI of the version you used:
|
|
66
|
+
# Citing varVAMP
|
|
69
67
|
|
|
70
68
|
**varVAMP: automated pan-specific primer design for tiled full genome sequencing and qPCR of highly diverse viral pathogens.**
|
|
71
69
|
|
|
72
|
-
(
|
|
70
|
+
[biorxiv preprint](https://doi.org/10.1101/2024.05.08.593102)
|
|
73
71
|
|
|
74
72
|
---
|
|
75
73
|
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
varvamp/__init__.py,sha256=
|
|
1
|
+
varvamp/__init__.py,sha256=dcU1t4AmPwg3LoG01RN2Q4VvzPKoZ00gRfg-qoofv28,107
|
|
2
2
|
varvamp/__main__.py,sha256=9R3mbX2_Q5LByPx8WLoTbvZ-G2dbRSMpDlgze0Wm5Fc,98
|
|
3
|
-
varvamp/command.py,sha256=
|
|
3
|
+
varvamp/command.py,sha256=Oh6WdYgbPKRChrxCoOOEFJHjINF3BIXahmSlYILDfPU,19723
|
|
4
4
|
varvamp/scripts/__init__.py,sha256=DtRsgfnA60BvccKMuD-Ueo1UpxaeANUfIWxGi1xPcV0,46
|
|
5
5
|
varvamp/scripts/alignment.py,sha256=w2I7BnaUt_rh1EaDQaU9Q_dmL_q019NtnaC8YMccOgM,7317
|
|
6
6
|
varvamp/scripts/blast.py,sha256=yF1-FjL7-P8sxSO6x4Q15gzj_I3LbE8ZfP37w6K3Akk,8434
|
|
7
7
|
varvamp/scripts/consensus.py,sha256=eU5eKU9iXyWeln2BW_LMPI8JiEq0_NXBI0jy4kMOvQg,3375
|
|
8
8
|
varvamp/scripts/default_config.py,sha256=8yjZ1ugZ5pus1daWRXeQMo-lVIikJXV4_q7FPEkTS64,3766
|
|
9
9
|
varvamp/scripts/get_config.py,sha256=Kvg3YhttUbDeRxjKhfxLjI5JSKpPoiLSEYqcE6rT4Xk,2940
|
|
10
|
-
varvamp/scripts/logging.py,sha256=
|
|
10
|
+
varvamp/scripts/logging.py,sha256=bk7SA7DtNtKtAJXRGLAQyA0stpLqBmRUydBG0dpoZQ0,20820
|
|
11
11
|
varvamp/scripts/param_estimation.py,sha256=jpfmbjCFp23V07af3y1uO2dQZJiWLlyOBa11aMphkko,3694
|
|
12
12
|
varvamp/scripts/primers.py,sha256=zLNs3lWiHS0dBmRIMpi8v0XxWi26JrS43YJW7xhEneM,13422
|
|
13
13
|
varvamp/scripts/qpcr.py,sha256=qO6JTl36WMUZGoz6NHIjRrtMOF87yQedmj-sE85Yay8,14453
|
|
14
14
|
varvamp/scripts/regions.py,sha256=VgYAlZmkC3rT946yhAdxATi-YT4oGcEwAPa0BkkfWIg,3239
|
|
15
|
-
varvamp/scripts/reporting.py,sha256=
|
|
15
|
+
varvamp/scripts/reporting.py,sha256=_o-A-X1OPEB6ym0w-q3Tb0nehVJwuCbsoyspZjzmvs4,22921
|
|
16
16
|
varvamp/scripts/scheme.py,sha256=lB-HT-rFSjN0o1KemzojyMT3jBw-LSrDGakshBXCAR4,16198
|
|
17
|
-
varvamp-1.2.
|
|
18
|
-
varvamp-1.2.
|
|
19
|
-
varvamp-1.2.
|
|
20
|
-
varvamp-1.2.
|
|
21
|
-
varvamp-1.2.
|
|
17
|
+
varvamp-1.2.1.dist-info/METADATA,sha256=tqQlI16IR0-DMDNYV1e6Ka9SzbzKbtqF1zV4gwBiVRM,5382
|
|
18
|
+
varvamp-1.2.1.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
|
19
|
+
varvamp-1.2.1.dist-info/entry_points.txt,sha256=puzW-basyBexZT4JVRUfUEqobvFmEyfqRQaqFjp7rB0,49
|
|
20
|
+
varvamp-1.2.1.dist-info/top_level.txt,sha256=11oVwE3SBUB9aTmvpvEDru95Tc5GZqQikzzFjw2eVGc,8
|
|
21
|
+
varvamp-1.2.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|