Skip to content

Commit 248ebca

Browse files
committed
Pass additional TSM starts and ends through to context.
1 parent 4631c45 commit 248ebca

9 files changed

Lines changed: 203 additions & 26 deletions

File tree

lib_tsalign/src/a_star_aligner.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ use traitsequence::interface::Sequence;
2222
use crate::{
2323
a_star_aligner::{
2424
alignment_result::alignment::Alignment,
25-
template_switch_distance::context::DynamicStrategies,
25+
template_switch_distance::{
26+
context::DynamicStrategies,
27+
strategies::allow_ts_14_out_of_range::AdditionalExplicitTSMStartsAndEnds,
28+
},
2629
},
2730
config,
2831
};
@@ -188,6 +191,7 @@ pub fn template_switch_distance_a_star_align<
188191
reference_name: &str,
189192
query_name: &str,
190193
mut range: AlignmentRange,
194+
additional_tsm_starts_and_ends: AdditionalExplicitTSMStartsAndEnds,
191195
config: &config::TemplateSwitchConfig<
192196
Strategies::Alphabet,
193197
<Strategies as AlignmentStrategySelector>::Cost,
@@ -226,6 +230,7 @@ where
226230
reference_name,
227231
query_name,
228232
range.clone(),
233+
additional_tsm_starts_and_ends,
229234
config.clone(),
230235
memory,
231236
dynamic_strategies,

lib_tsalign/src/a_star_aligner/configurable_a_star_align.rs

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ use crate::{
1313
context::DynamicStrategies,
1414
strategies::{
1515
AlignmentStrategySelection,
16+
allow_ts_14_out_of_range::{
17+
AdditionalExplicitTSMStartsAndEnds, Ts14OutOfRangeStrategy,
18+
},
1619
descendant::{
1720
AnyTemplateSwitchDescendantStrategy, OnlyEqualTemplateSwitchDescendantStrategy,
1821
TemplateSwitchDescendantStrategy,
@@ -112,6 +115,7 @@ struct QueryData<'a> {
112115
query_name: &'a str,
113116
query: &'a [u8],
114117
ranges: Option<AlignmentRange>,
118+
gap_characters: &'a [u8],
115119
cost_limit: Option<u64>,
116120
memory_limit: Option<usize>,
117121
extend_beyond_range: bool,
@@ -127,6 +131,7 @@ pub struct Aligner<AlphabetType: Alphabet = DnaAlphabetOrN> {
127131
chaining_strategy: ChainingStrategySelector,
128132
total_length_strategy: TotalLengthStrategySelector,
129133
descendant_strategy: DescendantStrategySelector,
134+
ts_14_out_of_range_strategy: Ts14OutOfRangeStrategy,
130135
no_ts: bool,
131136
}
132137

@@ -143,10 +148,11 @@ impl<AlphabetType: Alphabet> Default for Aligner<AlphabetType> {
143148
fn default() -> Self {
144149
Self {
145150
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(),
150156
no_ts: false,
151157
}
152158
}
@@ -204,7 +210,20 @@ impl<AlphabetType: Alphabet> Aligner<AlphabetType> {
204210
self
205211
}
206212

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.
208227
/// Consider spawning tasks to not block the user application.
209228
#[allow(
210229
clippy::too_many_arguments,
@@ -218,6 +237,7 @@ impl<AlphabetType: Alphabet> Aligner<AlphabetType> {
218237
query_name: &str,
219238
query: &[u8],
220239
ranges: Option<AlignmentRange>,
240+
gap_characters: &[u8],
221241
cost_limit: Option<u64>,
222242
memory_limit: Option<usize>,
223243
extend_beyond_range: bool,
@@ -228,6 +248,7 @@ impl<AlphabetType: Alphabet> Aligner<AlphabetType> {
228248
query_name,
229249
query,
230250
ranges,
251+
gap_characters,
231252
cost_limit,
232253
memory_limit,
233254
extend_beyond_range,
@@ -336,9 +357,48 @@ impl<AlphabetType: Alphabet> Aligner<AlphabetType> {
336357
count_strategy_memory: TC::Memory,
337358
) -> AlignmentResult<AlignmentType, U64Cost> {
338359
// 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+
341400
let cost_limit = data.cost_limit.map(U64Cost::from);
401+
342402
template_switch_distance_a_star_align::<
343403
AlignmentStrategySelection<
344404
AlphabetType,
@@ -360,8 +420,8 @@ impl<AlphabetType: Alphabet> Aligner<AlphabetType> {
360420
query.as_genome_subsequence(),
361421
data.reference_name,
362422
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,
365425
&self.costs,
366426
DynamicStrategies {},
367427
cost_limit,
@@ -395,6 +455,7 @@ mod tests {
395455
AlignmentCoordinates::new(27, 200),
396456
AlignmentCoordinates::new(33, 214)
397457
).into(),
458+
&[],
398459
None,
399460
None,
400461
true);

lib_tsalign/src/a_star_aligner/template_switch_distance/context.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use generic_a_star::reset::Reset;
77
use generic_a_star::{AStarBuffers, AStarContext};
88
use num_traits::{Bounded, Zero};
99

10+
use crate::a_star_aligner::template_switch_distance::strategies::allow_ts_14_out_of_range::AdditionalExplicitTSMStartsAndEnds;
1011
use crate::a_star_aligner::template_switch_distance::strategies::primary_range::PrimaryRangeStrategy;
1112
use crate::a_star_aligner::template_switch_distance::{Node, TemplateSwitchDirection};
1213
use crate::a_star_aligner::{AlignmentContext, AlignmentRange};
@@ -35,6 +36,7 @@ pub struct Context<
3536
pub query_name: String,
3637

3738
pub range: AlignmentRange,
39+
pub additional_tsm_starts_and_ends: AdditionalExplicitTSMStartsAndEnds,
3840

3941
pub config: TemplateSwitchConfig<Strategies::Alphabet, Strategies::Cost>,
4042

@@ -77,6 +79,7 @@ impl<
7779
reference_name: &str,
7880
query_name: &str,
7981
range: AlignmentRange,
82+
additional_tsm_starts_and_ends: AdditionalExplicitTSMStartsAndEnds,
8083
config: TemplateSwitchConfig<Strategies::Alphabet, Strategies::Cost>,
8184
memory: Memory<Strategies>,
8285
dynamic_strategies: DynamicStrategies,
@@ -90,6 +93,7 @@ impl<
9093
reference_name: reference_name.to_owned(),
9194
query_name: query_name.to_owned(),
9295
range,
96+
additional_tsm_starts_and_ends,
9397
config,
9498
a_star_buffers: Default::default(),
9599
memory,

lib_tsalign/src/a_star_aligner/template_switch_distance/lower_bounds/template_switch.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ impl<Cost: AStarCost> TemplateSwitchLowerBoundMatrix<Cost> {
100100
"",
101101
"",
102102
AlignmentRange::new_complete(genome.len(), genome.len()),
103+
Default::default(),
103104
lower_bound_config.clone(),
104105
Memory {
105106
template_switch_min_length: (),

lib_tsalign/src/a_star_aligner/template_switch_distance/lower_bounds/template_switch_alignment.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ impl<Cost: AStarCost> TemplateSwitchAlignmentLowerBoundMatrix<Cost> {
100100
"",
101101
"",
102102
AlignmentRange::new_complete(genome.len(), genome.len()),
103+
Default::default(),
103104
lower_bound_config.clone(),
104105
Memory {
105106
template_switch_min_length: (),

lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/allow_ts_14_out_of_range.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ use thiserror::Error;
22

33
use crate::a_star_aligner::alignment_geometry::{AlignmentCoordinates, AlignmentRange};
44

5-
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
5+
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
6+
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
7+
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
68
pub enum Ts14OutOfRangeStrategy {
79
/// TSMs are not allowed to start or end outside of the specified alignment ranges.
10+
#[default]
811
Disallow,
912
/// TSMs are allowed to start or end outside of the specified alignment ranges.
1013
Allow,
@@ -30,7 +33,7 @@ impl AdditionalExplicitTSMStartsAndEnds {
3033
original_reference: &str,
3134
original_query: &str,
3235
range: &AlignmentRange,
33-
skip_characters: Vec<char>,
36+
skip_characters: &[char],
3437
has_embedded_rq_ranges: bool,
3538
) -> Result<Self, AdditionalExplicitTSMStartsAndEndsError> {
3639
let mut explicit_tsm_starts = Vec::new();
@@ -234,7 +237,7 @@ mod tests {
234237
original_reference,
235238
original_query,
236239
&range,
237-
skip_characters,
240+
&skip_characters,
238241
true,
239242
)
240243
.unwrap();

lib_tsalign/src/tests.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ fn test_tsnax_disc1_473() {
7272
"ref",
7373
"qry",
7474
range.clone(),
75+
Default::default(),
7576
&config,
7677
DynamicStrategies {},
7778
None,
@@ -115,6 +116,7 @@ fn test_tsnax_disc1_473() {
115116
"ref",
116117
"qry",
117118
range.clone(),
119+
Default::default(),
118120
&config,
119121
DynamicStrategies {},
120122
None,
@@ -148,6 +150,7 @@ fn test_tsnax_disc1_473() {
148150
"ref",
149151
"qry",
150152
range.clone(),
153+
Default::default(),
151154
&config,
152155
DynamicStrategies {},
153156
None,
@@ -181,6 +184,7 @@ fn test_tsnax_disc1_473() {
181184
"ref",
182185
"qry",
183186
range.clone(),
187+
Default::default(),
184188
&config,
185189
DynamicStrategies {},
186190
None,

tsalign/src/align.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,13 +412,13 @@ fn execute_with_alphabet<AlphabetType: Alphabet + Debug + Clone + Eq + 'static>(
412412
};
413413

414414
// If requested, compute the additional starts and ends of TSMs outside of the given ranges.
415-
let _additional_tsm_starts_and_ends =
415+
let additional_tsm_starts_and_ends =
416416
if cli.allow_ts_14_out_of_range == Ts14OutOfRangeStrategy::Allow {
417417
AdditionalExplicitTSMStartsAndEnds::new(
418418
&original_reference,
419419
&original_query,
420420
&range,
421-
skip_characters,
421+
&skip_characters,
422422
cli.use_embedded_rq_ranges,
423423
)?
424424
} else {
@@ -455,6 +455,7 @@ fn execute_with_alphabet<AlphabetType: Alphabet + Debug + Clone + Eq + 'static>(
455455
reference_sequence,
456456
query_sequence,
457457
range,
458+
additional_tsm_starts_and_ends,
458459
&format!("{} {}", reference_record.id, reference_record.comment),
459460
&format!("{} {}", query_record.id, query_record.comment),
460461
),

0 commit comments

Comments
 (0)