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.
Files changed (62) hide show
  1. {strkit-0.8.0a5/strkit.egg-info → strkit-0.8.0a7}/PKG-INFO +1 -1
  2. strkit-0.8.0a7/strkit/VERSION +1 -0
  3. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/call_locus.py +71 -52
  4. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/call_sample.py +2 -2
  5. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/snvs.py +13 -28
  6. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/types.py +8 -0
  7. {strkit-0.8.0a5 → strkit-0.8.0a7/strkit.egg-info}/PKG-INFO +1 -1
  8. strkit-0.8.0a5/strkit/VERSION +0 -1
  9. {strkit-0.8.0a5 → strkit-0.8.0a7}/LICENSE +0 -0
  10. {strkit-0.8.0a5 → strkit-0.8.0a7}/MANIFEST.in +0 -0
  11. {strkit-0.8.0a5 → strkit-0.8.0a7}/README.md +0 -0
  12. {strkit-0.8.0a5 → strkit-0.8.0a7}/pyproject.toml +0 -0
  13. {strkit-0.8.0a5 → strkit-0.8.0a7}/setup.cfg +0 -0
  14. {strkit-0.8.0a5 → strkit-0.8.0a7}/setup.py +0 -0
  15. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/__init__.py +0 -0
  16. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/__init__.py +0 -0
  17. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/allele.py +0 -0
  18. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/__init__.py +0 -0
  19. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/align_matrix.py +0 -0
  20. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/cigar.py +0 -0
  21. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/realign.py +0 -0
  22. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/repeats.py +0 -0
  23. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/caller/utils.py +0 -0
  24. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/re_caller.py +0 -0
  25. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/repeathmm.py +0 -0
  26. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/straglr.py +0 -0
  27. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/call/tandem_genotypes.py +0 -0
  28. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/catalog/__init__.py +0 -0
  29. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/catalog/combine.py +0 -0
  30. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/constants.py +0 -0
  31. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/__init__.py +0 -0
  32. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/_bed_4.py +0 -0
  33. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/converter.py +0 -0
  34. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/expansionhunter.py +0 -0
  35. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/gangstr.py +0 -0
  36. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/hipstr.py +0 -0
  37. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/straglr.py +0 -0
  38. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/convert/tandem_genotypes.py +0 -0
  39. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/entry.py +0 -0
  40. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/exceptions.py +0 -0
  41. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/json.py +0 -0
  42. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/logger.py +0 -0
  43. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/__init__.py +0 -0
  44. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/base.py +0 -0
  45. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/expansionhunter.py +0 -0
  46. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/gangstr.py +0 -0
  47. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/repeathmm.py +0 -0
  48. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/result.py +0 -0
  49. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/straglr.py +0 -0
  50. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/strkit.py +0 -0
  51. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/tandem_genotypes.py +0 -0
  52. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/mi/vcf_utils.py +0 -0
  53. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/utils.py +0 -0
  54. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/viz/__init__.py +0 -0
  55. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/viz/server.py +0 -0
  56. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/viz/static/logo.png +0 -0
  57. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit/viz/templates/browser.html +0 -0
  58. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit.egg-info/SOURCES.txt +0 -0
  59. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit.egg-info/dependency_links.txt +0 -0
  60. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit.egg-info/entry_points.txt +0 -0
  61. {strkit-0.8.0a5 → strkit-0.8.0a7}/strkit.egg-info/requires.txt +0 -0
  62. {strkit-0.8.0a5 → strkit-0.8.0a7}/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.0a5
3
+ Version: 0.8.0a7
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.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[Optional[CallDict]] = [
314
- call_alleles(
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
- if any((cd is None) for cd in cdd):
334
- # One of the calls could not be made... what to do?
335
- # TODO: !!!!
336
- # For now, revert to dist
337
- return "dist", None
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
- # Otherwise, cdd is confirmed list[CallDict] - no Nones
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
- ref_seq = ""
415
- raised = False
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
- ref_right_flank_seq = ref.fetch(ref_contig, right_coord, right_flank_coord)
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 of the BAM alignment is present, use it to reduce realignment overhead?
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 + ref.fetch(ref_contig, right_coord, right_flank_coord + 1),
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
- snvs = get_read_snvs(qs, pairs, contig, ref, left_coord_adj, right_coord_adj)
674
- locus_snvs.update(snvs.keys())
675
- read_dict[rn]["snv"] = snvs
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
- # Have read dict now, so add it to the base call information dictionary
682
- call_dict_base["reads"] = read_dict
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 again if we don't have enough reads to make a call, now that we've maybe filtered a few more out.
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, overlapping_segments, read_dict, read_pairs, locus_snvs)
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"{round((datetime.now() - start_time).total_seconds())} seconds")
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
- contig: str,
27
- ref: pysam.FastaFile,
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 = ref_sequence[ref_pos - fm_rp]
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
- contig: str,
93
- ref: pysam.FastaFile,
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]) != ref_sequence[ref_pos - fm_rp]:
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
- contig,
125
- ref,
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 segment in overlapping_segments:
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 = segment.query_sequence
138
+ qs: str = read["_qs"]
154
139
 
155
- segment_start: int = segment.reference_start
156
- segment_end: int = segment.reference_end
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: strkit
3
- Version: 0.8.0a5
3
+ Version: 0.8.0a7
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.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