strkit 0.8.0a6__tar.gz → 0.8.0a8__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.
Files changed (62) hide show
  1. {strkit-0.8.0a6/strkit.egg-info → strkit-0.8.0a8}/PKG-INFO +1 -1
  2. strkit-0.8.0a8/strkit/VERSION +1 -0
  3. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/caller/call_locus.py +12 -21
  4. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/caller/snvs.py +10 -22
  5. {strkit-0.8.0a6 → strkit-0.8.0a8/strkit.egg-info}/PKG-INFO +1 -1
  6. strkit-0.8.0a6/strkit/VERSION +0 -1
  7. {strkit-0.8.0a6 → strkit-0.8.0a8}/LICENSE +0 -0
  8. {strkit-0.8.0a6 → strkit-0.8.0a8}/MANIFEST.in +0 -0
  9. {strkit-0.8.0a6 → strkit-0.8.0a8}/README.md +0 -0
  10. {strkit-0.8.0a6 → strkit-0.8.0a8}/pyproject.toml +0 -0
  11. {strkit-0.8.0a6 → strkit-0.8.0a8}/setup.cfg +0 -0
  12. {strkit-0.8.0a6 → strkit-0.8.0a8}/setup.py +0 -0
  13. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/__init__.py +0 -0
  14. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/__init__.py +0 -0
  15. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/allele.py +0 -0
  16. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/caller/__init__.py +0 -0
  17. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/caller/align_matrix.py +0 -0
  18. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/caller/call_sample.py +0 -0
  19. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/caller/cigar.py +0 -0
  20. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/caller/realign.py +0 -0
  21. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/caller/repeats.py +0 -0
  22. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/caller/types.py +0 -0
  23. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/caller/utils.py +0 -0
  24. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/re_caller.py +0 -0
  25. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/repeathmm.py +0 -0
  26. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/straglr.py +0 -0
  27. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/call/tandem_genotypes.py +0 -0
  28. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/catalog/__init__.py +0 -0
  29. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/catalog/combine.py +0 -0
  30. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/constants.py +0 -0
  31. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/convert/__init__.py +0 -0
  32. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/convert/_bed_4.py +0 -0
  33. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/convert/converter.py +0 -0
  34. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/convert/expansionhunter.py +0 -0
  35. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/convert/gangstr.py +0 -0
  36. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/convert/hipstr.py +0 -0
  37. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/convert/straglr.py +0 -0
  38. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/convert/tandem_genotypes.py +0 -0
  39. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/entry.py +0 -0
  40. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/exceptions.py +0 -0
  41. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/json.py +0 -0
  42. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/logger.py +0 -0
  43. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/mi/__init__.py +0 -0
  44. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/mi/base.py +0 -0
  45. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/mi/expansionhunter.py +0 -0
  46. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/mi/gangstr.py +0 -0
  47. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/mi/repeathmm.py +0 -0
  48. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/mi/result.py +0 -0
  49. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/mi/straglr.py +0 -0
  50. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/mi/strkit.py +0 -0
  51. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/mi/tandem_genotypes.py +0 -0
  52. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/mi/vcf_utils.py +0 -0
  53. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/utils.py +0 -0
  54. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/viz/__init__.py +0 -0
  55. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/viz/server.py +0 -0
  56. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/viz/static/logo.png +0 -0
  57. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit/viz/templates/browser.html +0 -0
  58. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit.egg-info/SOURCES.txt +0 -0
  59. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit.egg-info/dependency_links.txt +0 -0
  60. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit.egg-info/entry_points.txt +0 -0
  61. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit.egg-info/requires.txt +0 -0
  62. {strkit-0.8.0a6 → strkit-0.8.0a8}/strkit.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: strkit
3
- Version: 0.8.0a6
3
+ Version: 0.8.0a8
4
4
  Summary: A toolkit for analyzing variation in short(ish) tandem repeats.
5
5
  Home-page: https://github.com/davidlougheed/strkit
6
6
  Author: David Lougheed
@@ -0,0 +1 @@
1
+ 0.8.0a8
@@ -218,6 +218,7 @@ def call_alleles_with_incorporated_snvs(
218
218
  fractional: bool,
219
219
  read_dict: dict[str, ReadDict],
220
220
  read_dict_items: tuple[tuple[str, ReadDict], ...], # We could derive this again, but we already have before...
221
+ read_dict_extra: dict[str, dict],
221
222
  n_reads_in_dict: int, # We could derive this again, but we already have before...
222
223
  useful_snvs: list[tuple[int, int]],
223
224
  rng: np.random.Generator,
@@ -235,7 +236,7 @@ def call_alleles_with_incorporated_snvs(
235
236
  print_snvs = False
236
237
 
237
238
  for rn, read in read_dict_items:
238
- read_useful_snv_bases = tuple(read["snv_bases"][bi] for bi, _pos in useful_snvs)
239
+ read_useful_snv_bases = tuple(read_dict_extra[rn]["snv_bases"][bi] for bi, _pos in useful_snvs)
239
240
  non_blank_read_useful_snv_bases = [bb for bb in read_useful_snv_bases if bb != SNV_OUT_OF_RANGE_CHAR]
240
241
 
241
242
  if (nbr := len(non_blank_read_useful_snv_bases)) >= 2: # TODO: parametrize
@@ -485,6 +486,7 @@ def call_locus(
485
486
  # Build the read dictionary with segment information, copy number, weight, & more. ---------------------------------
486
487
 
487
488
  read_dict: dict[str, ReadDict] = {}
489
+ read_dict_extra: dict[str, dict] = {}
488
490
 
489
491
  # Aggregations for additional read-level data
490
492
  read_kmers = Counter()
@@ -645,8 +647,6 @@ def call_locus(
645
647
 
646
648
  crs_cir = chimeric_read_status[rn] == 3 # Chimera within the TR region, indicating a potential large expansion
647
649
  read_dict[rn] = {
648
- "_ref_start": segment_start,
649
- "_ref_end": segment_end,
650
650
  "s": "-" if segment.is_reverse else "+",
651
651
  "cn": read_cn,
652
652
  "w": read_weight,
@@ -654,13 +654,17 @@ def call_locus(
654
654
  **({"chimeric_in_region": crs_cir} if crs_cir else {}),
655
655
  **({"kmers": dict(read_kmers)} if count_kmers != "none" else {}),
656
656
  }
657
+ read_dict_extra[rn] = {
658
+ "_ref_start": segment_start,
659
+ "_ref_end": segment_end,
660
+ }
657
661
 
658
662
  # Reads can show up more than once - TODO - cache this information across loci
659
663
 
660
664
  if should_incorporate_snvs:
661
665
  # Store the segment sequence in the read dict for the next go-around if we've enabled SNV incorporation,
662
666
  # in order to pass the query sequence to the get_read_snvs function with the cached ref string.
663
- read_dict[rn]["_qs"] = qs
667
+ read_dict_extra[rn]["_qs"] = qs
664
668
 
665
669
  # End of first read loop -------------------------------------------------------------------------------------------
666
670
 
@@ -712,15 +716,15 @@ def call_locus(
712
716
 
713
717
  for rn, read in read_dict_items:
714
718
  snvs = get_read_snvs(
715
- read["_qs"], read_pairs[rn], ref_cache, left_most_coord, right_most_coord, left_coord_adj,
719
+ read_dict_extra[rn]["_qs"], read_pairs[rn], ref_cache, left_most_coord, left_coord_adj,
716
720
  right_coord_adj)
717
721
  locus_snvs.update(snvs.keys())
718
- read_dict[rn]["snv"] = snvs
722
+ read_dict_extra[rn]["snv"] = snvs
719
723
 
720
724
  # End of second read loop --------------------------------------------------------------------------------------
721
725
 
722
726
  useful_snvs: list[tuple[int, int]] = (
723
- calculate_useful_snvs(n_reads_in_dict, read_dict, read_dict_items, read_pairs, locus_snvs)
727
+ calculate_useful_snvs(n_reads_in_dict, read_dict_items, read_dict_extra, read_pairs, locus_snvs)
724
728
  if n_reads_in_dict >= min_snv_read_coverage else []
725
729
  )
726
730
  n_useful_snvs: int = len(useful_snvs)
@@ -736,6 +740,7 @@ def call_locus(
736
740
  fractional=fractional,
737
741
  read_dict=read_dict,
738
742
  read_dict_items=read_dict_items,
743
+ read_dict_extra=read_dict_extra,
739
744
  n_reads_in_dict=n_reads_in_dict,
740
745
  useful_snvs=useful_snvs,
741
746
  rng=rng,
@@ -793,20 +798,6 @@ def call_locus(
793
798
  debug_str=f"{contig}:{left_coord}-{right_coord}",
794
799
  ) or {} # Still false-y
795
800
 
796
- # Clean up read dict TODO: nicer way to do this -------------------------------------------------------------------
797
-
798
- for rn, rd in read_dict_items:
799
- if "snv" in rd:
800
- del rd["snv"]
801
- if "snv_bases" in rd:
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"]
809
-
810
801
  # Extract data from call_data --------------------------------------------------------------------------------------
811
802
 
812
803
  call = call_data.get("call")
@@ -1,5 +1,4 @@
1
1
  import numpy as np
2
- import pysam
3
2
  from collections import Counter
4
3
 
5
4
  from numpy.typing import NDArray
@@ -25,7 +24,6 @@ def _get_read_snvs_meticulous(
25
24
  pairs: list[tuple[int, int], ...],
26
25
  ref_seq: str,
27
26
  ref_coord_start: int,
28
- ref_coord_end: int,
29
27
  tr_start_pos: int,
30
28
  tr_end_pos: int,
31
29
  contiguous_threshold: int = 5,
@@ -39,11 +37,6 @@ def _get_read_snvs_meticulous(
39
37
 
40
38
  snvs: dict[int, str] = {}
41
39
 
42
- fm_qp, fm_rp = pairs[0]
43
- lm_qp, lm_rp = pairs[-1]
44
-
45
- read_ref_sequence: str = ref_seq[fm_rp-ref_coord_start:lm_rp-ref_coord_end+1]
46
-
47
40
  lhs_contiguous: int = 0
48
41
  rhs_contiguous: int = 0
49
42
  last_rp: int = -1
@@ -55,7 +48,7 @@ def _get_read_snvs_meticulous(
55
48
  continue
56
49
 
57
50
  read_base = query_sequence[read_pos]
58
- ref_base = read_ref_sequence[ref_pos - fm_rp]
51
+ ref_base = ref_seq[ref_pos - ref_coord_start]
59
52
 
60
53
  if read_base == ref_base and (ref_pos - last_rp == 1 or last_rp == -1):
61
54
  if snv_group:
@@ -92,7 +85,6 @@ def get_read_snvs(
92
85
  pairs: list[tuple[int, int], ...],
93
86
  ref_seq: str,
94
87
  ref_coord_start: int,
95
- ref_coord_end: int,
96
88
  tr_start_pos: int,
97
89
  tr_end_pos: int,
98
90
  contiguous_threshold: int = 5,
@@ -107,15 +99,10 @@ def get_read_snvs(
107
99
 
108
100
  snvs: dict[int, str] = {}
109
101
 
110
- fm_qp, fm_rp = pairs[0]
111
- lm_qp, lm_rp = pairs[-1]
112
-
113
- read_ref_sequence: str = ref_seq[fm_rp-ref_coord_start:lm_rp-ref_coord_end]
114
-
115
102
  for read_pos, ref_pos in pairs:
116
103
  if tr_start_pos <= ref_pos < tr_end_pos: # base is in the tandem repeat itself; skip it
117
104
  continue
118
- if (read_base := query_sequence[read_pos]) != read_ref_sequence[ref_pos - fm_rp]:
105
+ if (read_base := query_sequence[read_pos]) != ref_seq[ref_pos - ref_coord_start]:
119
106
  snvs[ref_pos] = read_base
120
107
 
121
108
  if len(snvs) >= too_many_snvs_threshold: # TOO MANY, some kind of mismapping going on
@@ -124,7 +111,6 @@ def get_read_snvs(
124
111
  pairs,
125
112
  ref_seq,
126
113
  ref_coord_start,
127
- ref_coord_end,
128
114
  tr_start_pos,
129
115
  tr_end_pos,
130
116
  contiguous_threshold,
@@ -136,8 +122,8 @@ def get_read_snvs(
136
122
 
137
123
  def calculate_useful_snvs(
138
124
  n_reads: int,
139
- read_dict: dict[str, ReadDict],
140
125
  read_dict_items: tuple[tuple[str, ReadDict], ...],
126
+ read_dict_extra: dict[str, dict],
141
127
  read_match_pairs: dict[str, list[tuple[int, int]]],
142
128
  locus_snvs: set[int],
143
129
  ) -> list[tuple[int, int]]:
@@ -145,13 +131,15 @@ def calculate_useful_snvs(
145
131
  snv_counters: dict[int, Counter] = {sp: Counter() for sp in sorted_snvs}
146
132
 
147
133
  for rn, read in read_dict_items:
148
- snvs: dict[int, str] = read_dict[rn]["snv"]
134
+ extra_data = read_dict_extra[rn]
135
+
136
+ snvs: dict[int, str] = extra_data["snv"]
149
137
 
150
138
  # Know this to not be None since we were passed only segments with non-None strings earlier
151
- qs: str = read["_qs"]
139
+ qs: str = extra_data["_qs"]
152
140
 
153
- segment_start: int = read["_ref_start"]
154
- segment_end: int = read["_ref_end"]
141
+ segment_start: int = extra_data["_ref_start"]
142
+ segment_end: int = extra_data["_ref_end"]
155
143
 
156
144
  snv_list: list[str] = []
157
145
 
@@ -191,7 +179,7 @@ def calculate_useful_snvs(
191
179
  snv_list.append(base)
192
180
  snv_counters[snv_pos][base] += 1
193
181
 
194
- read_dict[rn]["snv_bases"] = tuple(snv_list)
182
+ extra_data["snv_bases"] = tuple(snv_list)
195
183
 
196
184
  # Enough reads to try for SNV based separation
197
185
  useful_snvs: list[int] = []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: strkit
3
- Version: 0.8.0a6
3
+ Version: 0.8.0a8
4
4
  Summary: A toolkit for analyzing variation in short(ish) tandem repeats.
5
5
  Home-page: https://github.com/davidlougheed/strkit
6
6
  Author: David Lougheed
@@ -1 +0,0 @@
1
- 0.8.0a6
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