tsalign 3.0.0__tar.gz → 4.0.0__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 (102) hide show
  1. {tsalign-3.0.0 → tsalign-4.0.0}/Cargo.lock +8 -8
  2. {tsalign-3.0.0 → tsalign-4.0.0}/Cargo.toml +5 -1
  3. {tsalign-3.0.0 → tsalign-4.0.0}/PKG-INFO +1 -1
  4. {tsalign-3.0.0 → tsalign-4.0.0}/generic_a_star/Cargo.toml +1 -1
  5. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/Cargo.toml +3 -3
  6. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/alignment_geometry.rs +30 -0
  7. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/alignment_result/alignment/stream.rs +19 -3
  8. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/alignment_result/alignment/template_switch_specifics.rs +17 -3
  9. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/alignment_result.rs +34 -14
  10. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/configurable_a_star_align.rs +75 -12
  11. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/gap_affine_edit_distance.rs +8 -0
  12. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/alignment_type.rs +57 -6
  13. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/context.rs +105 -11
  14. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs +7 -1
  15. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/identifier.rs +17 -0
  16. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/lower_bounds/template_switch.rs +8 -4
  17. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/lower_bounds/template_switch_alignment.rs +6 -1
  18. tsalign-4.0.0/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/allow_ts_14_out_of_range.rs +279 -0
  19. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies.rs +1 -0
  20. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance.rs +3 -3
  21. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner.rs +37 -9
  22. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/tests.rs +21 -8
  23. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/Cargo.toml +2 -2
  24. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/plain_text/mutlipair_alignment_renderer.rs +2 -1
  25. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/ts_arrangement/source.rs +3 -1
  26. {tsalign-3.0.0 → tsalign-4.0.0}/python_bindings/Cargo.toml +3 -3
  27. {tsalign-3.0.0 → tsalign-4.0.0}/python_bindings/src/lib.rs +11 -1
  28. {tsalign-3.0.0 → tsalign-4.0.0}/seed_chain/Cargo.toml +2 -2
  29. {tsalign-3.0.0 → tsalign-4.0.0}/README.md +0 -0
  30. {tsalign-3.0.0 → tsalign-4.0.0}/generic_a_star/clippy.toml +0 -0
  31. {tsalign-3.0.0 → tsalign-4.0.0}/generic_a_star/src/closed_lists.rs +0 -0
  32. {tsalign-3.0.0 → tsalign-4.0.0}/generic_a_star/src/comparator.rs +0 -0
  33. {tsalign-3.0.0 → tsalign-4.0.0}/generic_a_star/src/cost.rs +0 -0
  34. {tsalign-3.0.0 → tsalign-4.0.0}/generic_a_star/src/lib.rs +0 -0
  35. {tsalign-3.0.0 → tsalign-4.0.0}/generic_a_star/src/open_lists/linear_heap.rs +0 -0
  36. {tsalign-3.0.0 → tsalign-4.0.0}/generic_a_star/src/open_lists.rs +0 -0
  37. {tsalign-3.0.0 → tsalign-4.0.0}/generic_a_star/src/reset.rs +0 -0
  38. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/alignment_result/a_star_sequences.rs +0 -0
  39. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/alignment_result/alignment/iter.rs +0 -0
  40. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/alignment_result/alignment.rs +0 -0
  41. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/alignment_type/equal_cost_range.rs +0 -0
  42. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/lower_bounds.rs +0 -0
  43. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/chaining.rs +0 -0
  44. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/descendant.rs +0 -0
  45. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/node_ord.rs +0 -0
  46. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/primary_match.rs +0 -0
  47. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/primary_range.rs +0 -0
  48. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/secondary_deletion.rs +0 -0
  49. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/shortcut.rs +0 -0
  50. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/template_switch_count.rs +0 -0
  51. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/template_switch_min_length.rs +0 -0
  52. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/template_switch_total_length.rs +0 -0
  53. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/a_star_aligner/tests.rs +0 -0
  54. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/alignment_configuration.rs +0 -0
  55. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/alignment_matrix/index/iterators.rs +0 -0
  56. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/alignment_matrix/index.rs +0 -0
  57. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/alignment_matrix.rs +0 -0
  58. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/config/io.rs +0 -0
  59. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/config.rs +0 -0
  60. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/costs/cost_function/io.rs +0 -0
  61. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/costs/cost_function.rs +0 -0
  62. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/costs/gap_affine/io/tests.rs +0 -0
  63. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/costs/gap_affine/io.rs +0 -0
  64. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/costs/gap_affine.rs +0 -0
  65. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/costs.rs +0 -0
  66. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/error.rs +0 -0
  67. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/io.rs +0 -0
  68. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsalign/src/lib.rs +0 -0
  69. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/error.rs +0 -0
  70. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/lib.rs +0 -0
  71. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/plain_text/mutlipair_alignment_renderer/tests.rs +0 -0
  72. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/plain_text/parse_template_switches.rs +0 -0
  73. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/plain_text.rs +0 -0
  74. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/svg/arrows.rs +0 -0
  75. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/svg/font/sans_serif_mono.rs +0 -0
  76. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/svg/font/typewriter.rs +0 -0
  77. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/svg/font.rs +0 -0
  78. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/svg/indexed_str.rs +0 -0
  79. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/svg/labelled_sequence.rs +0 -0
  80. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/svg/numbers.rs +0 -0
  81. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/svg.rs +0 -0
  82. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/ts_arrangement/character.rs +0 -0
  83. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/ts_arrangement/complement.rs +0 -0
  84. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/ts_arrangement/index_types.rs +0 -0
  85. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/ts_arrangement/inner.rs +0 -0
  86. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/ts_arrangement/row.rs +0 -0
  87. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/ts_arrangement/template_switch.rs +0 -0
  88. {tsalign-3.0.0 → tsalign-4.0.0}/lib_tsshow/src/ts_arrangement.rs +0 -0
  89. {tsalign-3.0.0 → tsalign-4.0.0}/pyproject.toml +0 -0
  90. {tsalign-3.0.0 → tsalign-4.0.0}/python/tsalign/__init__.py +0 -0
  91. {tsalign-3.0.0 → tsalign-4.0.0}/python/tsalign/_types.py +0 -0
  92. {tsalign-3.0.0 → tsalign-4.0.0}/python/tsalign/py.typed +0 -0
  93. {tsalign-3.0.0 → tsalign-4.0.0}/python_bindings/.gitignore +0 -0
  94. {tsalign-3.0.0 → tsalign-4.0.0}/python_bindings/BUILD.md +0 -0
  95. {tsalign-3.0.0 → tsalign-4.0.0}/python_bindings/README.md +0 -0
  96. {tsalign-3.0.0 → tsalign-4.0.0}/seed_chain/src/chain/context.rs +0 -0
  97. {tsalign-3.0.0 → tsalign-4.0.0}/seed_chain/src/chain/display.rs +0 -0
  98. {tsalign-3.0.0 → tsalign-4.0.0}/seed_chain/src/chain/node/display.rs +0 -0
  99. {tsalign-3.0.0 → tsalign-4.0.0}/seed_chain/src/chain/node.rs +0 -0
  100. {tsalign-3.0.0 → tsalign-4.0.0}/seed_chain/src/chain.rs +0 -0
  101. {tsalign-3.0.0 → tsalign-4.0.0}/seed_chain/src/lib.rs +0 -0
  102. {tsalign-3.0.0 → tsalign-4.0.0}/seed_chain/src/seed.rs +0 -0
@@ -417,7 +417,7 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
417
417
 
418
418
  [[package]]
419
419
  name = "generic_a_star"
420
- version = "3.0.0"
420
+ version = "4.0.0"
421
421
  dependencies = [
422
422
  "binary-heap-plus",
423
423
  "compare",
@@ -548,7 +548,7 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
548
548
 
549
549
  [[package]]
550
550
  name = "lib_ts_chainalign"
551
- version = "3.0.0"
551
+ version = "4.0.0"
552
552
  dependencies = [
553
553
  "binary-heap-plus",
554
554
  "bincode",
@@ -568,7 +568,7 @@ dependencies = [
568
568
 
569
569
  [[package]]
570
570
  name = "lib_tsalign"
571
- version = "3.0.0"
571
+ version = "4.0.0"
572
572
  dependencies = [
573
573
  "binary-heap-plus",
574
574
  "compact-genome",
@@ -589,7 +589,7 @@ dependencies = [
589
589
 
590
590
  [[package]]
591
591
  name = "lib_tsshow"
592
- version = "3.0.0"
592
+ version = "4.0.0"
593
593
  dependencies = [
594
594
  "ena",
595
595
  "itertools",
@@ -804,7 +804,7 @@ dependencies = [
804
804
 
805
805
  [[package]]
806
806
  name = "py_lib_tsalign"
807
- version = "3.0.0"
807
+ version = "4.0.0"
808
808
  dependencies = [
809
809
  "compact-genome",
810
810
  "lib_tsalign",
@@ -1008,7 +1008,7 @@ dependencies = [
1008
1008
 
1009
1009
  [[package]]
1010
1010
  name = "seed_chain"
1011
- version = "3.0.0"
1011
+ version = "4.0.0"
1012
1012
  dependencies = [
1013
1013
  "compact-genome",
1014
1014
  "generic_a_star",
@@ -1360,7 +1360,7 @@ checksum = "2b939c825d0c4295ac520f7b479927c1e5b458c9107a9d6f5ba65bc867bb93a5"
1360
1360
 
1361
1361
  [[package]]
1362
1362
  name = "tsalign"
1363
- version = "3.0.0"
1363
+ version = "4.0.0"
1364
1364
  dependencies = [
1365
1365
  "anyhow",
1366
1366
  "bincode",
@@ -1381,7 +1381,7 @@ dependencies = [
1381
1381
 
1382
1382
  [[package]]
1383
1383
  name = "tsalign-tests"
1384
- version = "3.0.0"
1384
+ version = "4.0.0"
1385
1385
  dependencies = [
1386
1386
  "anyhow",
1387
1387
  "clap",
@@ -18,5 +18,9 @@ num-traits = "0.2.19"
18
18
  rustc-hash = "2.1.1"
19
19
  binary-heap-plus = "0.5.0"
20
20
 
21
+ [profile.dev]
22
+ debug = 1 # or "line-tables-only" instead of full debug info
23
+ split-debuginfo = "unpacked" # Keeps symbols out of the main object file
24
+
21
25
  [profile.release]
22
- debug = true
26
+ debug = 1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tsalign
3
- Version: 3.0.0
3
+ Version: 4.0.0
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -1,7 +1,7 @@
1
1
  [package]
2
2
  name = "generic_a_star"
3
3
  description = "A generic implementation of the A* algorithm"
4
- version = "3.0.0"
4
+ version = "4.0.0"
5
5
  edition.workspace = true
6
6
  rust-version.workspace = true
7
7
  license.workspace = true
@@ -2,7 +2,7 @@
2
2
  name = "lib_tsalign"
3
3
  description = "A sequence-to-sequence aligner that accounts for template switches"
4
4
  authors = ["Sebastian Schmidt <sebastian.schmidt@helsinki.fi>"]
5
- version = "3.0.0"
5
+ version = "4.0.0"
6
6
  license.workspace = true
7
7
  edition.workspace = true
8
8
  rust-version.workspace = true
@@ -26,9 +26,9 @@ thiserror = "2.0.3"
26
26
  num-traits.workspace = true
27
27
  serde = { workspace = true, features = ["derive"], optional = true }
28
28
  noisy_float = { version = "0.2.0" }
29
- generic_a_star = { version = "3.0.0", path = "../generic_a_star" }
29
+ generic_a_star = { version = "4.0.0", path = "../generic_a_star" }
30
30
  log.workspace = true
31
31
  rustc-hash = "2.1.1"
32
- seed_chain = { version = "3.0.0", path = "../seed_chain" }
32
+ seed_chain = { version = "4.0.0", path = "../seed_chain" }
33
33
  extend_map = "0.14.3"
34
34
  template-switch-error-free-inners = "0.1.1"
@@ -17,6 +17,18 @@ pub struct AlignmentCoordinates {
17
17
  }
18
18
 
19
19
  impl AlignmentRange {
20
+ pub fn new(
21
+ reference_offset: usize,
22
+ query_offset: usize,
23
+ reference_limit: usize,
24
+ query_limit: usize,
25
+ ) -> Self {
26
+ Self {
27
+ offset: AlignmentCoordinates::new(reference_offset, query_offset),
28
+ limit: AlignmentCoordinates::new(reference_limit, query_limit),
29
+ }
30
+ }
31
+
20
32
  pub fn new_complete(reference: usize, query: usize) -> Self {
21
33
  Self {
22
34
  offset: AlignmentCoordinates::new_zero(),
@@ -102,6 +114,16 @@ impl AlignmentRange {
102
114
  ),
103
115
  ))
104
116
  }
117
+
118
+ #[must_use]
119
+ pub fn with_offset(&self, offset: AlignmentCoordinates) -> Self {
120
+ Self::new_offset_limit(offset, self.limit)
121
+ }
122
+
123
+ #[must_use]
124
+ pub fn with_limit(&self, limit: AlignmentCoordinates) -> Self {
125
+ Self::new_offset_limit(self.offset, limit)
126
+ }
105
127
  }
106
128
 
107
129
  impl AlignmentCoordinates {
@@ -112,6 +134,14 @@ impl AlignmentCoordinates {
112
134
  pub fn new_zero() -> Self {
113
135
  Self::new(0, 0)
114
136
  }
137
+
138
+ pub fn reference(&self) -> usize {
139
+ self.reference
140
+ }
141
+
142
+ pub fn query(&self) -> usize {
143
+ self.query
144
+ }
115
145
  }
116
146
 
117
147
  impl Display for AlignmentRange {
@@ -176,8 +176,9 @@ impl AlignmentStream {
176
176
  AlignmentType::TemplateSwitchEntrance { .. }
177
177
  | AlignmentType::TemplateSwitchExit { .. }
178
178
  | AlignmentType::Root
179
+ | AlignmentType::AlternativeStart { .. }
179
180
  | AlignmentType::SecondaryRoot
180
- | AlignmentType::PrimaryReentry => 0,
181
+ | AlignmentType::PrimaryReentry { .. } => 0,
181
182
  AlignmentType::PrimaryShortcut { .. } => {
182
183
  unreachable!("Shortcut alignments are not supported for show")
183
184
  }
@@ -245,10 +246,25 @@ impl AlignmentStreamCoordinates {
245
246
  }
246
247
  (0, 0)
247
248
  }
249
+ AlignmentType::AlternativeStart {
250
+ reference_index,
251
+ query_index,
252
+ } => {
253
+ assert_eq!(self.reference, reference_index);
254
+ assert_eq!(self.query, query_index);
255
+ (0, 0)
256
+ }
257
+ AlignmentType::PrimaryReentry {
258
+ reference_index,
259
+ query_index,
260
+ } => {
261
+ assert_eq!(self.reference, reference_index);
262
+ assert_eq!(self.query, query_index);
263
+ (0, 0)
264
+ }
248
265
  AlignmentType::SecondaryDeletion
249
266
  | AlignmentType::Root
250
- | AlignmentType::SecondaryRoot
251
- | AlignmentType::PrimaryReentry => (0, 0),
267
+ | AlignmentType::SecondaryRoot => (0, 0),
252
268
  AlignmentType::PrimaryShortcut { .. } => {
253
269
  unreachable!("Shortcut alignments are not supported for show")
254
270
  }
@@ -832,9 +832,23 @@ impl Alignment<AlignmentType> {
832
832
  };
833
833
  cost_increment
834
834
  }
835
- AlignmentType::Root
836
- | AlignmentType::SecondaryRoot
837
- | AlignmentType::PrimaryReentry => {
835
+ AlignmentType::AlternativeStart {
836
+ reference_index: reference_start,
837
+ query_index: query_start,
838
+ } => {
839
+ assert_eq!(reference_index, reference_start);
840
+ assert_eq!(query_index, query_start);
841
+ Cost::zero()
842
+ }
843
+ AlignmentType::PrimaryReentry {
844
+ reference_index: reference_reentry_index,
845
+ query_index: query_reentry_index,
846
+ } => {
847
+ assert_eq!(reference_index, reference_reentry_index);
848
+ assert_eq!(query_index, query_reentry_index);
849
+ Cost::zero()
850
+ }
851
+ AlignmentType::Root | AlignmentType::SecondaryRoot => {
838
852
  // Do nothing
839
853
  Cost::zero()
840
854
  }
@@ -9,7 +9,10 @@ use noisy_float::types::{R64, r64};
9
9
  use num_traits::{Float, Zero};
10
10
 
11
11
  use crate::{
12
- a_star_aligner::template_switch_distance::AlignmentType, config::TemplateSwitchConfig,
12
+ a_star_aligner::{
13
+ alignment_geometry::AlignmentCoordinates, template_switch_distance::AlignmentType,
14
+ },
15
+ config::TemplateSwitchConfig,
13
16
  };
14
17
 
15
18
  use super::alignment_geometry::AlignmentRange;
@@ -17,7 +20,7 @@ use super::alignment_geometry::AlignmentRange;
17
20
  pub mod a_star_sequences;
18
21
  pub mod alignment;
19
22
 
20
- pub trait IAlignmentType {
23
+ pub trait IAlignmentType: Clone {
21
24
  fn is_repeatable(&self) -> bool;
22
25
 
23
26
  fn is_repeated(&self, previous: &Self) -> bool;
@@ -27,6 +30,10 @@ pub trait IAlignmentType {
27
30
  fn is_template_switch_entrance(&self) -> bool;
28
31
 
29
32
  fn is_template_switch_exit(&self) -> bool;
33
+
34
+ fn alternative_start(&self) -> Option<AlignmentCoordinates>;
35
+
36
+ fn alternative_end(&self) -> Option<AlignmentCoordinates>;
30
37
  }
31
38
 
32
39
  #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
@@ -57,6 +64,8 @@ pub struct AlignmentStatistics<Cost> {
57
64
  pub sequences: SequencePair,
58
65
  pub reference_offset: usize,
59
66
  pub query_offset: usize,
67
+ pub reference_limit: usize,
68
+ pub query_limit: usize,
60
69
 
61
70
  pub cost: R64,
62
71
  pub cost_per_base: R64,
@@ -106,8 +115,7 @@ impl<AlignmentType: IAlignmentType, Cost: AStarCost> AlignmentResult<AlignmentTy
106
115
  query: &SubsequenceType,
107
116
  reference_name: &str,
108
117
  query_name: &str,
109
- reference_offset: usize,
110
- query_offset: usize,
118
+ alignment_range: AlignmentRange,
111
119
  result: AStarResult<(), Cost>,
112
120
  duration_seconds: f64,
113
121
  opened_nodes: usize,
@@ -122,8 +130,7 @@ impl<AlignmentType: IAlignmentType, Cost: AStarCost> AlignmentResult<AlignmentTy
122
130
  query,
123
131
  reference_name,
124
132
  query_name,
125
- reference_offset,
126
- query_offset,
133
+ alignment_range,
127
134
  result,
128
135
  duration_seconds,
129
136
  opened_nodes,
@@ -144,8 +151,7 @@ impl<AlignmentType: IAlignmentType, Cost: AStarCost> AlignmentResult<AlignmentTy
144
151
  query: &SubsequenceType,
145
152
  reference_name: &str,
146
153
  query_name: &str,
147
- reference_offset: usize,
148
- query_offset: usize,
154
+ alignment_range: AlignmentRange,
149
155
  duration_seconds: f64,
150
156
  opened_nodes: usize,
151
157
  closed_nodes: usize,
@@ -159,8 +165,7 @@ impl<AlignmentType: IAlignmentType, Cost: AStarCost> AlignmentResult<AlignmentTy
159
165
  query,
160
166
  reference_name,
161
167
  query_name,
162
- reference_offset,
163
- query_offset,
168
+ alignment_range,
164
169
  result,
165
170
  duration_seconds,
166
171
  opened_nodes,
@@ -181,8 +186,7 @@ impl<AlignmentType: IAlignmentType, Cost: AStarCost> AlignmentResult<AlignmentTy
181
186
  query: &SubsequenceType,
182
187
  reference_name: &str,
183
188
  query_name: &str,
184
- reference_offset: usize,
185
- query_offset: usize,
189
+ alignment_range: AlignmentRange,
186
190
  result: AStarResult<(), Cost>,
187
191
  duration_seconds: f64,
188
192
  opened_nodes: usize,
@@ -195,8 +199,10 @@ impl<AlignmentType: IAlignmentType, Cost: AStarCost> AlignmentResult<AlignmentTy
195
199
  let statistics = AlignmentStatistics {
196
200
  result,
197
201
  sequences: SequencePair::new(reference, query, reference_name, query_name),
198
- reference_offset,
199
- query_offset,
202
+ reference_offset: alignment_range.reference_offset(),
203
+ query_offset: alignment_range.query_offset(),
204
+ reference_limit: alignment_range.reference_limit(),
205
+ query_limit: alignment_range.query_limit(),
200
206
 
201
207
  cost: (cost.as_f64()).try_into().unwrap(),
202
208
  cost_per_base: ((cost.as_f64() * 2.0) / (reference_length + query_length) as f64)
@@ -235,6 +241,18 @@ impl<AlignmentType: IAlignmentType, Cost: AStarCost> AlignmentResult<AlignmentTy
235
241
  Self::WithoutTarget { statistics }
236
242
  }
237
243
  }
244
+
245
+ pub fn alignment_range(&self) -> AlignmentRange {
246
+ let (reference_offset, query_offset, reference_limit, query_limit) = match self {
247
+ Self::WithTarget { statistics, .. } | Self::WithoutTarget { statistics } => (
248
+ statistics.reference_offset,
249
+ statistics.query_offset,
250
+ statistics.reference_limit,
251
+ statistics.query_limit,
252
+ ),
253
+ };
254
+ AlignmentRange::new(reference_offset, query_offset, reference_limit, query_limit)
255
+ }
238
256
  }
239
257
 
240
258
  impl<Cost: AStarCost + From<u64>>
@@ -783,6 +801,8 @@ impl<Cost> Default for AlignmentStatistics<Cost> {
783
801
  sequences: Default::default(),
784
802
  reference_offset: Default::default(),
785
803
  query_offset: Default::default(),
804
+ reference_limit: usize::MAX,
805
+ query_limit: usize::MAX,
786
806
  cost: Default::default(),
787
807
  cost_per_base: Default::default(),
788
808
  duration_seconds: Default::default(),
@@ -13,11 +13,14 @@ use crate::{
13
13
  context::DynamicStrategies,
14
14
  strategies::{
15
15
  AlignmentStrategySelection,
16
+ allow_ts_14_out_of_range::{
17
+ AdditionalExplicitTSMStartsAndEnds, Ts14OutOfRangeStrategy,
18
+ },
16
19
  descendant::{
17
20
  AnyTemplateSwitchDescendantStrategy, OnlyEqualTemplateSwitchDescendantStrategy,
18
21
  TemplateSwitchDescendantStrategy,
19
22
  },
20
- primary_range::NoPrunePrimaryRangeStrategy,
23
+ primary_range::RangePrunePrimaryRangeStrategy,
21
24
  secondary_deletion::AllowSecondaryDeletionStrategy,
22
25
  shortcut::NoShortcutStrategy,
23
26
  template_switch_min_length::{
@@ -112,6 +115,7 @@ struct QueryData<'a> {
112
115
  query_name: &'a str,
113
116
  query: &'a [u8],
114
117
  ranges: Option<AlignmentRange>,
118
+ gap_characters: &'a [u8],
115
119
  cost_limit: Option<u64>,
116
120
  memory_limit: Option<usize>,
117
121
  extend_beyond_range: bool,
@@ -127,6 +131,7 @@ pub struct Aligner<AlphabetType: Alphabet = DnaAlphabetOrN> {
127
131
  chaining_strategy: ChainingStrategySelector,
128
132
  total_length_strategy: TotalLengthStrategySelector,
129
133
  descendant_strategy: DescendantStrategySelector,
134
+ ts_14_out_of_range_strategy: Ts14OutOfRangeStrategy,
130
135
  no_ts: bool,
131
136
  }
132
137
 
@@ -143,10 +148,11 @@ impl<AlphabetType: Alphabet> Default for Aligner<AlphabetType> {
143
148
  fn default() -> Self {
144
149
  Self {
145
150
  costs: TemplateSwitchConfig::<AlphabetType, U64Cost>::default(),
146
- min_length_strategy: MinLengthStrategySelector::default(),
147
- chaining_strategy: ChainingStrategySelector::default(),
148
- total_length_strategy: TotalLengthStrategySelector::default(),
149
- descendant_strategy: DescendantStrategySelector::default(),
151
+ min_length_strategy: Default::default(),
152
+ chaining_strategy: Default::default(),
153
+ total_length_strategy: Default::default(),
154
+ descendant_strategy: Default::default(),
155
+ ts_14_out_of_range_strategy: Default::default(),
150
156
  no_ts: false,
151
157
  }
152
158
  }
@@ -204,7 +210,20 @@ impl<AlphabetType: Alphabet> Aligner<AlphabetType> {
204
210
  self
205
211
  }
206
212
 
207
- /// This performs the actual alignment and is, depending on the inputs, potentially taking quite long.
213
+ pub fn set_ts_14_out_of_range_strategy(
214
+ &mut self,
215
+ ts_14_out_of_range_strategy: Ts14OutOfRangeStrategy,
216
+ ) -> &mut Self {
217
+ self.ts_14_out_of_range_strategy = ts_14_out_of_range_strategy;
218
+ self
219
+ }
220
+
221
+ /// Perform the actual alignment.
222
+ ///
223
+ /// Special gap characters can be specified in order to interpret the given sequences as an alignment with gaps instead of raw sequences.
224
+ /// In this case, the range coordinates must refer to the ungapped sequences.
225
+ ///
226
+ /// Depending on the inputs, this takes quite long.
208
227
  /// Consider spawning tasks to not block the user application.
209
228
  #[allow(
210
229
  clippy::too_many_arguments,
@@ -218,6 +237,7 @@ impl<AlphabetType: Alphabet> Aligner<AlphabetType> {
218
237
  query_name: &str,
219
238
  query: &[u8],
220
239
  ranges: Option<AlignmentRange>,
240
+ gap_characters: &[u8],
221
241
  cost_limit: Option<u64>,
222
242
  memory_limit: Option<usize>,
223
243
  extend_beyond_range: bool,
@@ -228,6 +248,7 @@ impl<AlphabetType: Alphabet> Aligner<AlphabetType> {
228
248
  query_name,
229
249
  query,
230
250
  ranges,
251
+ gap_characters,
231
252
  cost_limit,
232
253
  memory_limit,
233
254
  extend_beyond_range,
@@ -336,9 +357,48 @@ impl<AlphabetType: Alphabet> Aligner<AlphabetType> {
336
357
  count_strategy_memory: TC::Memory,
337
358
  ) -> AlignmentResult<AlignmentType, U64Cost> {
338
359
  // TODO error handling
339
- let reference = VectorGenome::<AlphabetType>::from_slice_u8(data.reference).unwrap();
340
- let query = VectorGenome::from_slice_u8(data.query).unwrap();
360
+ let reference = VectorGenome::<AlphabetType>::from_iter_u8(
361
+ data.reference
362
+ .iter()
363
+ .copied()
364
+ .filter(|c| !data.gap_characters.contains(c)),
365
+ )
366
+ .unwrap();
367
+ let query = VectorGenome::from_iter_u8(
368
+ data.query
369
+ .iter()
370
+ .copied()
371
+ .filter(|c| !data.gap_characters.contains(c)),
372
+ )
373
+ .unwrap();
374
+
375
+ let range = data
376
+ .ranges
377
+ .unwrap_or_else(|| AlignmentRange::new_complete(reference.len(), query.len()));
378
+ let additional_tsm_starts_and_ends =
379
+ if self.ts_14_out_of_range_strategy == Ts14OutOfRangeStrategy::Allow {
380
+ AdditionalExplicitTSMStartsAndEnds::new(
381
+ &data
382
+ .reference
383
+ .iter()
384
+ .map(|c| *c as char)
385
+ .collect::<String>(),
386
+ &data.query.iter().map(|c| *c as char).collect::<String>(),
387
+ &range,
388
+ &data
389
+ .gap_characters
390
+ .iter()
391
+ .map(|c| *c as char)
392
+ .collect::<Vec<_>>(),
393
+ false,
394
+ )
395
+ .unwrap()
396
+ } else {
397
+ AdditionalExplicitTSMStartsAndEnds::default()
398
+ };
399
+
341
400
  let cost_limit = data.cost_limit.map(U64Cost::from);
401
+
342
402
  template_switch_distance_a_star_align::<
343
403
  AlignmentStrategySelection<
344
404
  AlphabetType,
@@ -350,7 +410,7 @@ impl<AlphabetType: Alphabet> Aligner<AlphabetType> {
350
410
  AllowSecondaryDeletionStrategy,
351
411
  NoShortcutStrategy<U64Cost>,
352
412
  AllowPrimaryMatchStrategy,
353
- NoPrunePrimaryRangeStrategy,
413
+ RangePrunePrimaryRangeStrategy,
354
414
  TL,
355
415
  DS,
356
416
  >,
@@ -360,10 +420,12 @@ impl<AlphabetType: Alphabet> Aligner<AlphabetType> {
360
420
  query.as_genome_subsequence(),
361
421
  data.reference_name,
362
422
  data.query_name,
363
- data.ranges
364
- .unwrap_or_else(|| AlignmentRange::new_complete(reference.len(), query.len())),
423
+ range,
424
+ additional_tsm_starts_and_ends,
365
425
  &self.costs,
366
- DynamicStrategies {},
426
+ DynamicStrategies {
427
+ ts_14_out_of_range: self.ts_14_out_of_range_strategy,
428
+ },
367
429
  cost_limit,
368
430
  data.memory_limit,
369
431
  false,
@@ -395,6 +457,7 @@ mod tests {
395
457
  AlignmentCoordinates::new(27, 200),
396
458
  AlignmentCoordinates::new(33, 214)
397
459
  ).into(),
460
+ &[],
398
461
  None,
399
462
  None,
400
463
  true);
@@ -385,6 +385,14 @@ impl IAlignmentType for AlignmentType {
385
385
  fn is_template_switch_exit(&self) -> bool {
386
386
  false
387
387
  }
388
+
389
+ fn alternative_start(&self) -> Option<super::alignment_geometry::AlignmentCoordinates> {
390
+ None
391
+ }
392
+
393
+ fn alternative_end(&self) -> Option<super::alignment_geometry::AlignmentCoordinates> {
394
+ None
395
+ }
388
396
  }
389
397
 
390
398
  impl AStarIdentifier for Identifier {}
@@ -1,6 +1,8 @@
1
1
  use equal_cost_range::EqualCostRange;
2
2
 
3
- use crate::a_star_aligner::alignment_result::IAlignmentType;
3
+ use crate::a_star_aligner::{
4
+ alignment_geometry::AlignmentCoordinates, alignment_result::IAlignmentType,
5
+ };
4
6
 
5
7
  use super::identifier::{
6
8
  TemplateSwitchAncestor, TemplateSwitchDescendant, TemplateSwitchDirection,
@@ -63,10 +65,18 @@ pub enum AlignmentType {
63
65
  },
64
66
  /// This node is the root node, hence it was not generated via alignment.
65
67
  Root,
68
+ /// The alignment starts from a different position than given by the alignment ranges.
69
+ AlternativeStart {
70
+ reference_index: usize,
71
+ query_index: usize,
72
+ },
66
73
  /// The root node of a secondary graph.
67
74
  SecondaryRoot,
68
75
  /// A reentry node into the primary graph, treated like a root.
69
- PrimaryReentry,
76
+ PrimaryReentry {
77
+ reference_index: usize,
78
+ query_index: usize,
79
+ },
70
80
  /// A shortcut in the primary matrix.
71
81
  ///
72
82
  /// Used only for computing lower bounds.
@@ -92,8 +102,9 @@ impl IAlignmentType for AlignmentType {
92
102
  | Self::PrimaryFlankMatch
93
103
  | Self::SecondaryMatch
94
104
  | Self::Root
105
+ | Self::AlternativeStart { .. }
95
106
  | Self::SecondaryRoot
96
- | Self::PrimaryReentry => true,
107
+ | Self::PrimaryReentry { .. } => true,
97
108
  Self::TemplateSwitchEntrance { .. }
98
109
  | Self::TemplateSwitchExit { .. }
99
110
  | Self::PrimaryShortcut { .. } => false,
@@ -143,7 +154,10 @@ impl IAlignmentType for AlignmentType {
143
154
  fn is_internal(&self) -> bool {
144
155
  matches!(
145
156
  self,
146
- Self::Root | Self::SecondaryRoot | Self::PrimaryReentry
157
+ Self::Root
158
+ | Self::AlternativeStart { .. }
159
+ | Self::SecondaryRoot
160
+ | Self::PrimaryReentry { .. }
147
161
  )
148
162
  }
149
163
 
@@ -154,6 +168,30 @@ impl IAlignmentType for AlignmentType {
154
168
  fn is_template_switch_exit(&self) -> bool {
155
169
  matches!(self, Self::TemplateSwitchExit { .. })
156
170
  }
171
+
172
+ fn alternative_start(&self) -> Option<AlignmentCoordinates> {
173
+ if let Self::AlternativeStart {
174
+ reference_index,
175
+ query_index,
176
+ } = self
177
+ {
178
+ Some(AlignmentCoordinates::new(*reference_index, *query_index))
179
+ } else {
180
+ None
181
+ }
182
+ }
183
+
184
+ fn alternative_end(&self) -> Option<AlignmentCoordinates> {
185
+ if let Self::PrimaryReentry {
186
+ reference_index,
187
+ query_index,
188
+ } = self
189
+ {
190
+ Some(AlignmentCoordinates::new(*reference_index, *query_index))
191
+ } else {
192
+ None
193
+ }
194
+ }
157
195
  }
158
196
 
159
197
  impl AlignmentType {
@@ -178,6 +216,20 @@ impl AlignmentType {
178
216
  equal_cost_range: *equal_cost_range,
179
217
  first_offset: *first_offset,
180
218
  },
219
+ Self::AlternativeStart {
220
+ reference_index,
221
+ query_index,
222
+ } => Self::AlternativeStart {
223
+ reference_index: *query_index,
224
+ query_index: *reference_index,
225
+ },
226
+ Self::PrimaryReentry {
227
+ reference_index,
228
+ query_index,
229
+ } => Self::PrimaryReentry {
230
+ reference_index: *query_index,
231
+ query_index: *reference_index,
232
+ },
181
233
  Self::PrimaryShortcut {
182
234
  delta_reference,
183
235
  delta_query,
@@ -194,8 +246,7 @@ impl AlignmentType {
194
246
  | Self::SecondaryMatch
195
247
  | Self::TemplateSwitchExit { .. }
196
248
  | Self::Root
197
- | Self::SecondaryRoot
198
- | Self::PrimaryReentry) => *symmetric,
249
+ | Self::SecondaryRoot) => *symmetric,
199
250
  }
200
251
  }
201
252
  }