diff --git a/lib_tsalign/src/a_star_aligner/alignment_result.rs b/lib_tsalign/src/a_star_aligner/alignment_result.rs index 101a15b6..57818fda 100644 --- a/lib_tsalign/src/a_star_aligner/alignment_result.rs +++ b/lib_tsalign/src/a_star_aligner/alignment_result.rs @@ -1,7 +1,7 @@ use std::fmt::{Display, Formatter, Result, Write}; use a_star_sequences::SequencePair; -use alignment::{Alignment, stream::AlignmentStream}; +use alignment::Alignment; use compact_genome::interface::{alphabet::Alphabet, sequence::GenomeSequence}; use generic_a_star::{AStarResult, cost::AStarCost}; use log::{trace, warn}; @@ -392,7 +392,6 @@ impl> return; } - let mut stream = AlignmentStream::new(); let reference_offset = range .as_ref() .map(|range| range.reference_offset()) @@ -403,7 +402,6 @@ impl> .unwrap_or(0); for i in 0..alignment.inner_mut().len() { - let multiplicity = alignment.inner_mut()[i].0; let alignment_type = alignment.inner_mut()[i].1; match alignment_type { @@ -552,8 +550,6 @@ impl> } _ => { /* Do nothing. */ } } - - stream.push(multiplicity, alignment_type); } } } diff --git a/lib_tsalign/src/a_star_aligner/alignment_result/alignment/stream.rs b/lib_tsalign/src/a_star_aligner/alignment_result/alignment/stream.rs index a5ffdbe3..2456f6c4 100644 --- a/lib_tsalign/src/a_star_aligner/alignment_result/alignment/stream.rs +++ b/lib_tsalign/src/a_star_aligner/alignment_result/alignment/stream.rs @@ -5,7 +5,7 @@ use crate::a_star_aligner::{ template_switch_distance::{AlignmentType, TemplateSwitchPrimary}, }; -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone)] pub struct AlignmentStream { stream: VecDeque<(usize, AlignmentType)>, length: usize, @@ -16,7 +16,7 @@ pub struct AlignmentStream { tail_coordinates: AlignmentStreamCoordinates, } -#[derive(Debug, Default, Clone, Copy)] +#[derive(Debug, Clone, Copy)] pub struct AlignmentStreamCoordinates { reference: usize, query: usize, @@ -24,17 +24,25 @@ pub struct AlignmentStreamCoordinates { } impl AlignmentStream { + #[deprecated = "our alignments typically have offsets nowadays"] + #[expect(clippy::new_without_default)] pub fn new() -> Self { - Default::default() + Self::new_with_offset(0, 0) } pub fn new_with_offset(reference_offset: usize, query_offset: usize) -> Self { - let mut result = Self::new(); - result.head_coordinates.reference = reference_offset; - result.head_coordinates.query = query_offset; - result.tail_coordinates.reference = reference_offset; - result.tail_coordinates.query = query_offset; - result + Self { + stream: Default::default(), + length: 0, + head_coordinates: AlignmentStreamCoordinates::new_with_offset( + reference_offset, + query_offset, + ), + tail_coordinates: AlignmentStreamCoordinates::new_with_offset( + reference_offset, + query_offset, + ), + } } pub fn len(&self) -> usize { @@ -178,6 +186,14 @@ impl AlignmentStream { } impl AlignmentStreamCoordinates { + pub fn new_with_offset(reference_offset: usize, query_offset: usize) -> Self { + Self { + reference: reference_offset, + query: query_offset, + template_switch_primary: None, + } + } + pub fn reference(&self) -> usize { self.reference } diff --git a/lib_tsalign/src/a_star_aligner/alignment_result/alignment/template_switch_specifics.rs b/lib_tsalign/src/a_star_aligner/alignment_result/alignment/template_switch_specifics.rs index 51b65f2a..363eb8bd 100644 --- a/lib_tsalign/src/a_star_aligner/alignment_result/alignment/template_switch_specifics.rs +++ b/lib_tsalign/src/a_star_aligner/alignment_result/alignment/template_switch_specifics.rs @@ -54,22 +54,16 @@ impl Alignment { )) ) { // Compute TS inner first indices. - let mut stream = AlignmentStream::new(); + let mut stream = AlignmentStream::new_with_offset(reference_offset, query_offset); stream.push_all(self.iter_compact_cloned().take(*compact_index)); let ts_inner_primary_index = match primary { - TemplateSwitchPrimary::Reference => { - stream.head_coordinates().reference() + reference_offset - } - TemplateSwitchPrimary::Query => stream.head_coordinates().query() + query_offset, + TemplateSwitchPrimary::Reference => stream.head_coordinates().reference(), + TemplateSwitchPrimary::Query => stream.head_coordinates().query(), }; let ts_inner_secondary_index = usize::try_from( isize::try_from(match secondary { - TemplateSwitchSecondary::Reference => { - stream.head_coordinates().reference() + reference_offset - } - TemplateSwitchSecondary::Query => { - stream.head_coordinates().query() + query_offset - } + TemplateSwitchSecondary::Reference => stream.head_coordinates().reference(), + TemplateSwitchSecondary::Query => stream.head_coordinates().query(), }) .unwrap() .checked_add(first_offset) @@ -197,10 +191,10 @@ impl Alignment { self.alignment.get(*compact_index + 1) { // Compute TS outer first indices. - let mut stream = AlignmentStream::new(); + let mut stream = AlignmentStream::new_with_offset(reference_offset, query_offset); stream.push_all(self.iter_compact_cloned().take(*compact_index)); - let ts_outer_reference_index = stream.head_coordinates().reference() + reference_offset; - let ts_outer_query_index = stream.head_coordinates().query() + query_offset; + let ts_outer_reference_index = stream.head_coordinates().reference(); + let ts_outer_query_index = stream.head_coordinates().query(); // Check if indices can be moved while staying in bounds. if ts_outer_reference_index == reference.len() || ts_outer_query_index == query.len() { @@ -321,7 +315,7 @@ impl Alignment { self.alignment.get(exit_index + 1) { // Compute TS inner last indices. - let mut stream = AlignmentStream::new(); + let mut stream = AlignmentStream::new_with_offset(reference_offset, query_offset); stream.push_all(self.iter_compact_cloned().take(compact_index)); stream.clear(); stream.push_all( @@ -330,19 +324,13 @@ impl Alignment { .skip(compact_index), ); let ts_inner_primary_index = match primary { - TemplateSwitchPrimary::Reference => { - stream.head_coordinates().reference() + reference_offset - } - TemplateSwitchPrimary::Query => stream.head_coordinates().query() + query_offset, + TemplateSwitchPrimary::Reference => stream.head_coordinates().reference(), + TemplateSwitchPrimary::Query => stream.head_coordinates().query(), }; let ts_inner_secondary_index = usize::try_from( isize::try_from(match secondary { - TemplateSwitchSecondary::Reference => { - stream.tail_coordinates().reference() + reference_offset - } - TemplateSwitchSecondary::Query => { - stream.tail_coordinates().query() + query_offset - } + TemplateSwitchSecondary::Reference => stream.tail_coordinates().reference(), + TemplateSwitchSecondary::Query => stream.tail_coordinates().query(), }) .unwrap() .checked_add(first_offset) @@ -474,10 +462,10 @@ impl Alignment { self.alignment.get(exit_index - 1) { // Compute TS outer first indices. - let mut stream = AlignmentStream::new(); + let mut stream = AlignmentStream::new_with_offset(reference_offset, query_offset); stream.push_all(self.iter_compact_cloned().take(exit_index + 1)); - let ts_outer_reference_index = stream.head_coordinates().reference() + reference_offset; - let ts_outer_query_index = stream.head_coordinates().query() + query_offset; + let ts_outer_reference_index = stream.head_coordinates().reference(); + let ts_outer_query_index = stream.head_coordinates().query(); // Check if indices can be moved while staying in bounds. if ts_outer_reference_index == 0 || ts_outer_query_index == 0 { diff --git a/test_files/config/experiments/config.tsa b/test_files/config/experiments/config.tsa index c5470f67..6a5f88c4 100644 --- a/test_files/config/experiments/config.tsa +++ b/test_files/config/experiments/config.tsa @@ -5,10 +5,14 @@ right_flank_length = 0 # Base Cost -rr_cost = 3 -rq_cost = 2 -qr_cost = 2 -qq_cost = 3 +rrf_cost = 31 +rqf_cost = 30 +qrf_cost = 30 +qqf_cost = 31 +rrr_cost = 3 +rqr_cost = 2 +qrr_cost = 2 +qqr_cost = 3 # Jump Costs @@ -24,6 +28,14 @@ LengthDifference -inf -100 -20 -10 11 21 101 inf 4 2 0 2 4 inf +ForwardAntiPrimaryGap + -inf 1 + 0 inf + +ReverseAntiPrimaryGap + -inf + 0 + # Primary Edit Costs SubstitutionCostTable @@ -43,16 +55,35 @@ GapExtendCostVector A C G T N 1 1 1 1 1 -# Secondary Edit Costs +# Secondary Forward Edit Costs SubstitutionCostTable | A C G T N --+--------------- -A | 0 4 4 4 0 -C | 4 0 4 4 0 -G | 4 4 0 4 0 -T | 4 4 4 0 0 -N | 0 0 0 0 0 +A | 0 4 4 4 1 +C | 4 0 4 4 1 +G | 4 4 0 4 1 +T | 4 4 4 0 1 +N | 1 1 1 1 1 + +GapOpenCostVector + A C G T N + 3 3 3 3 3 + +GapExtendCostVector + A C G T N + 2 2 2 2 2 + +# Secondary Reverse Edit Costs + +SubstitutionCostTable + | A C G T N +--+--------------- +A | 0 4 4 4 1 +C | 4 0 4 4 1 +G | 4 4 0 4 1 +T | 4 4 4 0 1 +N | 1 1 1 1 1 GapOpenCostVector A C G T N