strkit 0.8.0a5__tar.gz → 0.8.0a7__tar.gz
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.
- {strkit-0.8.0a5/strkit.egg-info → strkit-0.8.0a7}/PKG-INFO +1 -1
- strkit-0.8.0a7/strkit/VERSION +1 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/call_locus.py +71 -52
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/call_sample.py +2 -2
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/snvs.py +13 -28
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/types.py +8 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7/strkit.egg-info}/PKG-INFO +1 -1
- strkit-0.8.0a5/strkit/VERSION +0 -1
- {strkit-0.8.0a5 → strkit-0.8.0a7}/LICENSE +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/MANIFEST.in +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/README.md +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/pyproject.toml +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/setup.cfg +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/setup.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/__init__.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/__init__.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/allele.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/__init__.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/align_matrix.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/cigar.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/realign.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/repeats.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/utils.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/re_caller.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/repeathmm.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/straglr.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/tandem_genotypes.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/catalog/__init__.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/catalog/combine.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/constants.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/__init__.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/_bed_4.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/converter.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/expansionhunter.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/gangstr.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/hipstr.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/straglr.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/tandem_genotypes.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/entry.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/exceptions.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/json.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/logger.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/__init__.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/base.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/expansionhunter.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/gangstr.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/repeathmm.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/result.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/straglr.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/strkit.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/tandem_genotypes.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/vcf_utils.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/utils.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/viz/__init__.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/viz/server.py +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/viz/static/logo.png +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/viz/templates/browser.html +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit.egg-info/SOURCES.txt +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit.egg-info/dependency_links.txt +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit.egg-info/entry_points.txt +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit.egg-info/requires.txt +0 -0
- {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.8.0a7
|
|
@@ -310,8 +310,10 @@ def call_alleles_with_incorporated_snvs(
|
|
|
310
310
|
ws = ws / np.sum(ws)
|
|
311
311
|
c_ws.append(ws)
|
|
312
312
|
|
|
313
|
-
cdd: list[
|
|
314
|
-
|
|
313
|
+
cdd: list[CallDict] = []
|
|
314
|
+
|
|
315
|
+
for ci in cluster_indices:
|
|
316
|
+
cc: Optional[CallDict] = call_alleles(
|
|
315
317
|
cns[ci], (), # Don't bother separating by strand for now...
|
|
316
318
|
c_ws[ci], (),
|
|
317
319
|
bootstrap_iterations=num_bootstrap // n_alleles, # Apportion the bootstrap iters across alleles
|
|
@@ -327,16 +329,14 @@ def call_alleles_with_incorporated_snvs(
|
|
|
327
329
|
logger_=logger_,
|
|
328
330
|
debug_str=f"{locus_log_str} a{ci}"
|
|
329
331
|
)
|
|
330
|
-
for ci in cluster_indices
|
|
331
|
-
]
|
|
332
332
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
333
|
+
if cc is None: # Early escape
|
|
334
|
+
# One of the calls could not be made... what to do?
|
|
335
|
+
# TODO: !!!!
|
|
336
|
+
# For now, revert to dist
|
|
337
|
+
return "dist", None
|
|
338
338
|
|
|
339
|
-
|
|
339
|
+
cdd.append(cc)
|
|
340
340
|
|
|
341
341
|
# TODO: Multi-allele phasing across STRs
|
|
342
342
|
|
|
@@ -409,10 +409,11 @@ def call_locus(
|
|
|
409
409
|
left_flank_coord = left_coord - flank_size
|
|
410
410
|
right_flank_coord = right_coord + flank_size
|
|
411
411
|
|
|
412
|
-
ref_left_flank_seq = ""
|
|
413
|
-
ref_right_flank_seq = ""
|
|
414
|
-
|
|
415
|
-
|
|
412
|
+
ref_left_flank_seq: str = ""
|
|
413
|
+
ref_right_flank_seq: str = ""
|
|
414
|
+
ref_right_flank_seq_plus_1: str = ""
|
|
415
|
+
ref_seq: str = ""
|
|
416
|
+
raised: bool = False
|
|
416
417
|
|
|
417
418
|
n_alleles: Optional[int] = get_n_alleles(2, sex_chroms, contig)
|
|
418
419
|
if n_alleles is None: # Sex chromosome, but we don't have a specified sex chromosome karyotype
|
|
@@ -424,7 +425,9 @@ def call_locus(
|
|
|
424
425
|
|
|
425
426
|
try:
|
|
426
427
|
ref_left_flank_seq = ref.fetch(ref_contig, left_flank_coord, left_coord)
|
|
427
|
-
|
|
428
|
+
ref_right_flank_seq_plus_1 = ref.fetch(ref_contig, right_coord, right_flank_coord + 1)
|
|
429
|
+
# ref_right_flank_seq = ref.fetch(ref_contig, right_coord, right_flank_coord)
|
|
430
|
+
ref_right_flank_seq = ref_right_flank_seq_plus_1[:-1]
|
|
428
431
|
ref_seq = ref.fetch(ref_contig, left_coord, right_coord)
|
|
429
432
|
except IndexError:
|
|
430
433
|
logger_.warning(
|
|
@@ -477,32 +480,6 @@ def call_locus(
|
|
|
477
480
|
|
|
478
481
|
n_overlapping_reads = len(overlapping_segments)
|
|
479
482
|
|
|
480
|
-
call_dict_base = {
|
|
481
|
-
"locus_index": t_idx,
|
|
482
|
-
"contig": contig,
|
|
483
|
-
"start": left_coord,
|
|
484
|
-
"end": right_coord,
|
|
485
|
-
**({} if respect_ref else {
|
|
486
|
-
"start_adj": left_coord_adj,
|
|
487
|
-
"end_adj": right_coord_adj,
|
|
488
|
-
}),
|
|
489
|
-
"motif": motif,
|
|
490
|
-
"ref_cn": ref_cn,
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
# Check now if we definitely don't have enough reads to make a call
|
|
494
|
-
# We also check again later when we calculate all the flanking stuff
|
|
495
|
-
if n_overlapping_reads < min_reads:
|
|
496
|
-
return {
|
|
497
|
-
**call_dict_base,
|
|
498
|
-
"call": None,
|
|
499
|
-
"call_95_cis": None,
|
|
500
|
-
"call_99_cis": None,
|
|
501
|
-
"peaks": None,
|
|
502
|
-
"read_peaks_called": False,
|
|
503
|
-
"time": (datetime.now() - call_timer).total_seconds(),
|
|
504
|
-
}
|
|
505
|
-
|
|
506
483
|
sorted_read_lengths = np.sort(read_lengths)
|
|
507
484
|
|
|
508
485
|
# Build the read dictionary with segment information, copy number, weight, & more. ---------------------------------
|
|
@@ -515,11 +492,20 @@ def call_locus(
|
|
|
515
492
|
|
|
516
493
|
read_pairs: dict[str, list] = {}
|
|
517
494
|
|
|
495
|
+
# Keep track of left-most and right-most coordinates
|
|
496
|
+
# If SNV-based peak calling is enabled, we can use this to pre-fetch reference data for all reads to reduce the
|
|
497
|
+
# fairly significant overhead involved in reading from the reference genome for each read to identifify SNVs.
|
|
498
|
+
left_most_coord: int = 99999999999999
|
|
499
|
+
right_most_coord: int = 0
|
|
500
|
+
|
|
518
501
|
for segment, read_len in zip(overlapping_segments, read_lengths):
|
|
519
502
|
rn = segment.query_name
|
|
520
503
|
segment_start = segment.reference_start
|
|
521
504
|
segment_end = segment.reference_end
|
|
522
505
|
|
|
506
|
+
left_most_coord = min(left_most_coord, segment_start)
|
|
507
|
+
right_most_coord = max(right_most_coord, segment_end)
|
|
508
|
+
|
|
523
509
|
# While .query_sequence is Optional[str], we know (because we skipped all segments with query_sequence is None
|
|
524
510
|
# above) that this is guaranteed to be, in fact, not None.
|
|
525
511
|
qs: str = segment.query_sequence
|
|
@@ -529,14 +515,14 @@ def call_locus(
|
|
|
529
515
|
|
|
530
516
|
fqqs: Optional[list[int]] = segment.query_qualities
|
|
531
517
|
|
|
532
|
-
realigned = False
|
|
518
|
+
realigned: bool = False
|
|
533
519
|
pairs = None
|
|
534
520
|
|
|
535
521
|
# Soft-clipping in large insertions can result from mapping difficulties.
|
|
536
522
|
# If we have a soft clip which overlaps with our TR region (+ flank), we can try to recover it
|
|
537
523
|
# via realignment with parasail.
|
|
538
524
|
# 4: BAM code for soft clip
|
|
539
|
-
# TODO: if some
|
|
525
|
+
# TODO: if some alignment is present, use it to reduce realignment overhead?
|
|
540
526
|
# - use start point + flank*3 or end point - flank*3 or something like that
|
|
541
527
|
if realign and (force_realign or (
|
|
542
528
|
(c1[0] == 4 and segment_start > left_flank_coord >= segment_start - c1[1]) or
|
|
@@ -548,7 +534,7 @@ def call_locus(
|
|
|
548
534
|
q = mp.Queue()
|
|
549
535
|
proc = mp.Process(target=realign_read, kwargs=dict(
|
|
550
536
|
# fetch an extra base for the right flank coordinate check later (needs to be >= the exclusive coord)
|
|
551
|
-
ref_seq=ref_left_flank_seq + ref_seq +
|
|
537
|
+
ref_seq=ref_left_flank_seq + ref_seq + ref_right_flank_seq_plus_1, # TODO: plus 1, really?
|
|
552
538
|
query_seq=calculate_seq_with_wildcards(qs, fqqs),
|
|
553
539
|
left_flank_coord=left_flank_coord,
|
|
554
540
|
flank_size=flank_size,
|
|
@@ -659,6 +645,8 @@ def call_locus(
|
|
|
659
645
|
|
|
660
646
|
crs_cir = chimeric_read_status[rn] == 3 # Chimera within the TR region, indicating a potential large expansion
|
|
661
647
|
read_dict[rn] = {
|
|
648
|
+
"_ref_start": segment_start,
|
|
649
|
+
"_ref_end": segment_end,
|
|
662
650
|
"s": "-" if segment.is_reverse else "+",
|
|
663
651
|
"cn": read_cn,
|
|
664
652
|
"w": read_weight,
|
|
@@ -670,18 +658,29 @@ def call_locus(
|
|
|
670
658
|
# Reads can show up more than once - TODO - cache this information across loci
|
|
671
659
|
|
|
672
660
|
if should_incorporate_snvs:
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
read_dict[rn]["
|
|
661
|
+
# Store the segment sequence in the read dict for the next go-around if we've enabled SNV incorporation,
|
|
662
|
+
# in order to pass the query sequence to the get_read_snvs function with the cached ref string.
|
|
663
|
+
read_dict[rn]["_qs"] = qs
|
|
676
664
|
|
|
677
|
-
# End of read loop
|
|
665
|
+
# End of first read loop -------------------------------------------------------------------------------------------
|
|
678
666
|
|
|
679
667
|
n_reads_in_dict: int = len(read_dict)
|
|
680
668
|
|
|
681
|
-
|
|
682
|
-
|
|
669
|
+
call_dict_base = {
|
|
670
|
+
"locus_index": t_idx,
|
|
671
|
+
"contig": contig,
|
|
672
|
+
"start": left_coord,
|
|
673
|
+
"end": right_coord,
|
|
674
|
+
**({} if respect_ref else {
|
|
675
|
+
"start_adj": left_coord_adj,
|
|
676
|
+
"end_adj": right_coord_adj,
|
|
677
|
+
}),
|
|
678
|
+
"motif": motif,
|
|
679
|
+
"ref_cn": ref_cn,
|
|
680
|
+
"reads": read_dict,
|
|
681
|
+
}
|
|
683
682
|
|
|
684
|
-
# Check
|
|
683
|
+
# Check now if we don't have enough reads to make a call. We can still return some read-level information!
|
|
685
684
|
if n_reads_in_dict < min_reads:
|
|
686
685
|
return {
|
|
687
686
|
**call_dict_base,
|
|
@@ -706,8 +705,22 @@ def call_locus(
|
|
|
706
705
|
|
|
707
706
|
# LIMITATION: Currently can only use SNVs for haplotyping with haploid/diploid
|
|
708
707
|
if should_incorporate_snvs:
|
|
708
|
+
# Loop through a second time if we are using SNVs. We do a second loop rather than just using the first loop
|
|
709
|
+
# in order to have collected the edges of the reference sequence we can cache for faster SNV calculation.
|
|
710
|
+
|
|
711
|
+
ref_cache = ref.fetch(contig, left_most_coord, right_most_coord + 1).upper()
|
|
712
|
+
|
|
713
|
+
for rn, read in read_dict_items:
|
|
714
|
+
snvs = get_read_snvs(
|
|
715
|
+
read["_qs"], read_pairs[rn], ref_cache, left_most_coord, left_coord_adj,
|
|
716
|
+
right_coord_adj)
|
|
717
|
+
locus_snvs.update(snvs.keys())
|
|
718
|
+
read_dict[rn]["snv"] = snvs
|
|
719
|
+
|
|
720
|
+
# End of second read loop --------------------------------------------------------------------------------------
|
|
721
|
+
|
|
709
722
|
useful_snvs: list[tuple[int, int]] = (
|
|
710
|
-
calculate_useful_snvs(n_reads_in_dict,
|
|
723
|
+
calculate_useful_snvs(n_reads_in_dict, read_dict, read_dict_items, read_pairs, locus_snvs)
|
|
711
724
|
if n_reads_in_dict >= min_snv_read_coverage else []
|
|
712
725
|
)
|
|
713
726
|
n_useful_snvs: int = len(useful_snvs)
|
|
@@ -787,6 +800,12 @@ def call_locus(
|
|
|
787
800
|
del rd["snv"]
|
|
788
801
|
if "snv_bases" in rd:
|
|
789
802
|
del rd["snv_bases"]
|
|
803
|
+
if "_ref_start" in rd:
|
|
804
|
+
del rd["_ref_start"]
|
|
805
|
+
if "_ref_end" in rd:
|
|
806
|
+
del rd["_ref_end"]
|
|
807
|
+
if "_qs" in rd:
|
|
808
|
+
del rd["_qs"]
|
|
790
809
|
|
|
791
810
|
# Extract data from call_data --------------------------------------------------------------------------------------
|
|
792
811
|
|
|
@@ -138,7 +138,7 @@ def progress_worker(
|
|
|
138
138
|
try:
|
|
139
139
|
lg.info(
|
|
140
140
|
f"{sample_id}: processed {num_loci - max(locus_queue.qsize(), num_workers) + num_workers} loci in "
|
|
141
|
-
f"{
|
|
141
|
+
f"{(datetime.now() - start_time).total_seconds():.1f} seconds")
|
|
142
142
|
except NotImplementedError:
|
|
143
143
|
pass
|
|
144
144
|
|
|
@@ -297,7 +297,7 @@ def call_sample(
|
|
|
297
297
|
str(res["end"]),
|
|
298
298
|
res["motif"],
|
|
299
299
|
_cn_to_str(res["ref_cn"]),
|
|
300
|
-
",".join(map(_cn_to_str, sorted(r["cn"] for r in res["reads"].values()))),
|
|
300
|
+
",".join(map(_cn_to_str, sorted(r["cn"] for r in res["reads"].values()))) if res["reads"] else ".",
|
|
301
301
|
"|".join(map(_cn_to_str, res["call"])) if has_call else ".",
|
|
302
302
|
("|".join("-".join(map(_cn_to_str, gc)) for gc in res["call_95_cis"]) if has_call else "."),
|
|
303
303
|
*((res["assign_method"] if has_call else ".",) if incorporate_snvs else ()),
|
|
@@ -23,8 +23,8 @@ SNV_OUT_OF_RANGE_CHAR = "-"
|
|
|
23
23
|
def _get_read_snvs_meticulous(
|
|
24
24
|
query_sequence: str,
|
|
25
25
|
pairs: list[tuple[int, int], ...],
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
ref_seq: str,
|
|
27
|
+
ref_coord_start: int,
|
|
28
28
|
tr_start_pos: int,
|
|
29
29
|
tr_end_pos: int,
|
|
30
30
|
contiguous_threshold: int = 5,
|
|
@@ -38,11 +38,6 @@ def _get_read_snvs_meticulous(
|
|
|
38
38
|
|
|
39
39
|
snvs: dict[int, str] = {}
|
|
40
40
|
|
|
41
|
-
fm_qp, fm_rp = pairs[0]
|
|
42
|
-
lm_qp, lm_rp = pairs[-1]
|
|
43
|
-
|
|
44
|
-
ref_sequence: str = ref.fetch(contig, fm_rp, lm_rp + 1).upper()
|
|
45
|
-
|
|
46
41
|
lhs_contiguous: int = 0
|
|
47
42
|
rhs_contiguous: int = 0
|
|
48
43
|
last_rp: int = -1
|
|
@@ -54,7 +49,7 @@ def _get_read_snvs_meticulous(
|
|
|
54
49
|
continue
|
|
55
50
|
|
|
56
51
|
read_base = query_sequence[read_pos]
|
|
57
|
-
ref_base =
|
|
52
|
+
ref_base = ref_seq[ref_pos - ref_coord_start]
|
|
58
53
|
|
|
59
54
|
if read_base == ref_base and (ref_pos - last_rp == 1 or last_rp == -1):
|
|
60
55
|
if snv_group:
|
|
@@ -89,8 +84,8 @@ def _get_read_snvs_meticulous(
|
|
|
89
84
|
def get_read_snvs(
|
|
90
85
|
query_sequence: str,
|
|
91
86
|
pairs: list[tuple[int, int], ...],
|
|
92
|
-
|
|
93
|
-
|
|
87
|
+
ref_seq: str,
|
|
88
|
+
ref_coord_start: int,
|
|
94
89
|
tr_start_pos: int,
|
|
95
90
|
tr_end_pos: int,
|
|
96
91
|
contiguous_threshold: int = 5,
|
|
@@ -105,24 +100,18 @@ def get_read_snvs(
|
|
|
105
100
|
|
|
106
101
|
snvs: dict[int, str] = {}
|
|
107
102
|
|
|
108
|
-
fm_qp, fm_rp = pairs[0]
|
|
109
|
-
lm_qp, lm_rp = pairs[-1]
|
|
110
|
-
|
|
111
|
-
# query_sequence = query_sequence.upper()
|
|
112
|
-
ref_sequence: str = ref.fetch(contig, fm_rp, lm_rp + 1).upper()
|
|
113
|
-
|
|
114
103
|
for read_pos, ref_pos in pairs:
|
|
115
104
|
if tr_start_pos <= ref_pos < tr_end_pos: # base is in the tandem repeat itself; skip it
|
|
116
105
|
continue
|
|
117
|
-
if (read_base := query_sequence[read_pos]) !=
|
|
106
|
+
if (read_base := query_sequence[read_pos]) != ref_seq[ref_pos - ref_coord_start]:
|
|
118
107
|
snvs[ref_pos] = read_base
|
|
119
108
|
|
|
120
109
|
if len(snvs) >= too_many_snvs_threshold: # TOO MANY, some kind of mismapping going on
|
|
121
110
|
return _get_read_snvs_meticulous(
|
|
122
111
|
query_sequence,
|
|
123
112
|
pairs,
|
|
124
|
-
|
|
125
|
-
|
|
113
|
+
ref_seq,
|
|
114
|
+
ref_coord_start,
|
|
126
115
|
tr_start_pos,
|
|
127
116
|
tr_end_pos,
|
|
128
117
|
contiguous_threshold,
|
|
@@ -134,26 +123,22 @@ def get_read_snvs(
|
|
|
134
123
|
|
|
135
124
|
def calculate_useful_snvs(
|
|
136
125
|
n_reads: int,
|
|
137
|
-
overlapping_segments: list[pysam.AlignedSegment],
|
|
138
126
|
read_dict: dict[str, ReadDict],
|
|
127
|
+
read_dict_items: tuple[tuple[str, ReadDict], ...],
|
|
139
128
|
read_match_pairs: dict[str, list[tuple[int, int]]],
|
|
140
129
|
locus_snvs: set[int],
|
|
141
130
|
) -> list[tuple[int, int]]:
|
|
142
131
|
sorted_snvs: list[int] = sorted(locus_snvs)
|
|
143
132
|
snv_counters: dict[int, Counter] = {sp: Counter() for sp in sorted_snvs}
|
|
144
133
|
|
|
145
|
-
for
|
|
146
|
-
rn = segment.query_name
|
|
147
|
-
if rn not in read_dict:
|
|
148
|
-
continue
|
|
149
|
-
|
|
134
|
+
for rn, read in read_dict_items:
|
|
150
135
|
snvs: dict[int, str] = read_dict[rn]["snv"]
|
|
151
136
|
|
|
152
137
|
# Know this to not be None since we were passed only segments with non-None strings earlier
|
|
153
|
-
qs: str =
|
|
138
|
+
qs: str = read["_qs"]
|
|
154
139
|
|
|
155
|
-
segment_start: int =
|
|
156
|
-
segment_end: int =
|
|
140
|
+
segment_start: int = read["_ref_start"]
|
|
141
|
+
segment_end: int = read["_ref_end"]
|
|
157
142
|
|
|
158
143
|
snv_list: list[str] = []
|
|
159
144
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import pysam
|
|
1
2
|
from typing import Literal, TypedDict, Union
|
|
2
3
|
|
|
3
4
|
|
|
@@ -26,6 +27,13 @@ class ReadDict(_ReadDictBase, total=False):
|
|
|
26
27
|
|
|
27
28
|
kmers: dict[str, int] # Dictionary of {kmer: count}
|
|
28
29
|
|
|
30
|
+
# Below are only added if SNVs are being incorporated:
|
|
31
|
+
|
|
29
32
|
snv: dict[int, str] # Intermediate result: dictionary of a bunch of SNVs for this read {position: base}
|
|
30
33
|
snv_bases: tuple[str, ...] # Intermediate result: tuple of bases for the set of SNVs across all reads
|
|
31
34
|
snvu: tuple[str, ...] # After including only useful SNVs, this contains a tuple of bases for just those
|
|
35
|
+
|
|
36
|
+
_ref_start: int # Read start in ref coordinates
|
|
37
|
+
_ref_end: int # Read end in ref coordinates
|
|
38
|
+
|
|
39
|
+
_qs: str # Query (read) sequence... only added if SNVs are being incorporated
|
strkit-0.8.0a5/strkit/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.8.0a5
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|