From cc1e138271d02a182155bedb88de0cb428fcef4a Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Wed, 27 May 2026 09:35:37 +0300 Subject: [PATCH 1/4] Rename TSM primary and secondary to descendant and ancestor. --- README.md | 7 +- lib_ts_chainalign/src/alignment/ts_kind.rs | 14 +- lib_ts_chainalign/src/chain_align.rs | 6 +- lib_ts_chainalign/src/costs/compat.rs | 5 +- .../alignment_result/alignment/stream.rs | 35 +- .../alignment/template_switch_specifics.rs | 368 +++++++++--------- .../template_switch_distance.rs | 131 +++---- .../alignment_type.rs | 42 +- .../template_switch_distance/context.rs | 139 +++---- .../template_switch_distance/display.rs | 50 +-- .../template_switch_distance/identifier.rs | 148 +++---- .../lower_bounds/template_switch.rs | 22 +- .../lower_bounds/template_switch_alignment.rs | 4 +- .../strategies/descendant.rs | 12 +- .../strategies/template_switch_min_length.rs | 146 ++++--- lib_tsalign/src/config.rs | 88 ++--- lib_tsalign/src/config/io.rs | 20 +- lib_tsshow/src/error.rs | 4 +- lib_tsshow/src/plain_text.rs | 49 +-- lib_tsshow/src/plain_text/alignment_stream.rs | 229 ----------- .../src/plain_text/parse_template_switches.rs | 48 ++- lib_tsshow/src/svg.rs | 110 +++--- lib_tsshow/src/ts_arrangement.rs | 22 +- lib_tsshow/src/ts_arrangement/complement.rs | 42 +- lib_tsshow/src/ts_arrangement/inner.rs | 90 ++--- lib_tsshow/src/ts_arrangement/source.rs | 186 ++++----- .../src/ts_arrangement/template_switch.rs | 10 +- python_bindings/README.md | 4 +- python_bindings/python/tsalign/_types.py | 12 +- sample_tsa_config/config.tsa | 4 +- test_files/config/bench/config.tsa | 4 +- test_files/config/chainalign/config.tsa | 4 +- test_files/config/chainalignn/config.tsa | 4 +- test_files/config/experiments/config.tsa | 4 +- .../config/no_intra_forward_jump/config.tsa | 4 +- test_files/config/range/config.tsa | 4 +- test_files/config/small/config.tsa | 4 +- 37 files changed, 940 insertions(+), 1135 deletions(-) delete mode 100644 lib_tsshow/src/plain_text/alignment_stream.rs diff --git a/README.md b/README.md index 9bb224db..1a3415a0 100644 --- a/README.md +++ b/README.md @@ -156,7 +156,7 @@ The costs are a piecewise constant function, where the first row is the first in `RQQROffset` is applied to TSMs where ancestor and descendant are different, while `RRQQOffset` is applied to TSMs where ancestor and descendant are the same. `Length` is the cost based on the length of the 2-3-alignment of the TSM. `LengthDifference` is the cost based on the difference between the length of the 2-3-alignment and the difference between points 1 and 4. -`ForwardAntiPrimaryGap` is the cost based on the difference between points 1 and 4, specifically `SP4 - SP1`. +`ForwardAntiDescendantGap` is the cost based on the difference between points 1 and 4, specifically `SP4 - SP1`. ```txt # Jump Costs @@ -177,11 +177,11 @@ LengthDifference -inf -100 101 inf 0 inf -ForwardAntiPrimaryGap +ForwardAntiDescendantGap -inf 1 0 inf -ReverseAntiPrimaryGap +ReverseAntiDescendantGap -inf 0 ``` @@ -248,6 +248,7 @@ Then, create the visualisation in SVG format as follows: ```bash tsalign show -i alignment.toml -n alignment-no-ts.toml -s alignment.svg ``` + Since SVGs are not always well supported, you can also use the switch `-p` to render the visualisation also as PNG. Note that the `-p` switch requires setting the `-s` parameter. diff --git a/lib_ts_chainalign/src/alignment/ts_kind.rs b/lib_ts_chainalign/src/alignment/ts_kind.rs index 69560f31..a5866b60 100644 --- a/lib_ts_chainalign/src/alignment/ts_kind.rs +++ b/lib_ts_chainalign/src/alignment/ts_kind.rs @@ -1,7 +1,7 @@ use std::fmt::Display; use lib_tsalign::a_star_aligner::template_switch_distance::{ - TemplateSwitchPrimary, TemplateSwitchSecondary, + TemplateSwitchAncestor, TemplateSwitchDescendant, }; #[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash)] @@ -77,19 +77,19 @@ impl TsKind { } impl TsAncestor { - pub fn into_tsalign_secondary(self) -> TemplateSwitchSecondary { + pub fn into_tsalign_secondary(self) -> TemplateSwitchAncestor { match self { - TsAncestor::Seq1 => TemplateSwitchSecondary::Reference, - TsAncestor::Seq2 => TemplateSwitchSecondary::Query, + TsAncestor::Seq1 => TemplateSwitchAncestor::Reference, + TsAncestor::Seq2 => TemplateSwitchAncestor::Query, } } } impl TsDescendant { - pub fn into_tsalign_primary(self) -> TemplateSwitchPrimary { + pub fn into_tsalign_primary(self) -> TemplateSwitchDescendant { match self { - TsDescendant::Seq1 => TemplateSwitchPrimary::Reference, - TsDescendant::Seq2 => TemplateSwitchPrimary::Query, + TsDescendant::Seq1 => TemplateSwitchDescendant::Reference, + TsDescendant::Seq2 => TemplateSwitchDescendant::Query, } } } diff --git a/lib_ts_chainalign/src/chain_align.rs b/lib_ts_chainalign/src/chain_align.rs index b62a94fd..033dec2e 100644 --- a/lib_ts_chainalign/src/chain_align.rs +++ b/lib_ts_chainalign/src/chain_align.rs @@ -409,8 +409,8 @@ fn actually_align< TsAlignAlignmentType::TemplateSwitchEntrance { first_offset: jump, equal_cost_range: EqualCostRange::new_invalid(), - primary: ts_kind.descendant.into_tsalign_primary(), - secondary: ts_kind.ancestor.into_tsalign_secondary(), + descendant: ts_kind.descendant.into_tsalign_primary(), + ancestor: ts_kind.ancestor.into_tsalign_secondary(), direction: TemplateSwitchDirection::Reverse, }, ); @@ -423,7 +423,7 @@ fn actually_align< tsalign_alignment.push_n( multiplicity, TsAlignAlignmentType::TemplateSwitchExit { - anti_primary_gap: anti_primary_gap + jump, + anti_descendant_gap: anti_primary_gap + jump, }, ) } diff --git a/lib_ts_chainalign/src/costs/compat.rs b/lib_ts_chainalign/src/costs/compat.rs index 58542f1b..bffa1643 100644 --- a/lib_ts_chainalign/src/costs/compat.rs +++ b/lib_ts_chainalign/src/costs/compat.rs @@ -38,7 +38,10 @@ impl From, + template_switch_descendant: Option, } impl AlignmentStream { @@ -190,7 +190,7 @@ impl AlignmentStreamCoordinates { Self { reference: reference_offset, query: query_offset, - template_switch_primary: None, + template_switch_descendant: None, } } @@ -210,34 +210,37 @@ impl AlignmentStreamCoordinates { | AlignmentType::PrimaryMatch | AlignmentType::PrimaryFlankSubstitution | AlignmentType::PrimaryFlankMatch => (1, 1), - AlignmentType::TemplateSwitchEntrance { primary, .. } => { + AlignmentType::TemplateSwitchEntrance { descendant, .. } => { assert!( - self.template_switch_primary.is_none(), + self.template_switch_descendant.is_none(), "Encountered template switch entrance within template switch" ); - self.template_switch_primary = Some(primary); + self.template_switch_descendant = Some(descendant); (0, 0) } AlignmentType::SecondaryInsertion | AlignmentType::SecondarySubstitution - | AlignmentType::SecondaryMatch => match self.template_switch_primary.unwrap() { - TemplateSwitchPrimary::Reference => (1, 0), - TemplateSwitchPrimary::Query => (0, 1), + | AlignmentType::SecondaryMatch => match self.template_switch_descendant.unwrap() { + TemplateSwitchDescendant::Reference => (1, 0), + TemplateSwitchDescendant::Query => (0, 1), }, - AlignmentType::TemplateSwitchExit { anti_primary_gap } => { - let Some(template_switch_primary) = self.template_switch_primary.take() else { + AlignmentType::TemplateSwitchExit { + anti_descendant_gap, + } => { + let Some(template_switch_descendant) = self.template_switch_descendant.take() + else { panic!( "Encountered template switch exit without first encountering a template switch entrance" ) }; - match template_switch_primary { - TemplateSwitchPrimary::Reference => { + match template_switch_descendant { + TemplateSwitchDescendant::Reference => { self.query = - usize::try_from(self.query as isize + anti_primary_gap).unwrap() + usize::try_from(self.query as isize + anti_descendant_gap).unwrap() } - TemplateSwitchPrimary::Query => { + TemplateSwitchDescendant::Query => { self.reference = - usize::try_from(self.reference as isize + anti_primary_gap).unwrap() + usize::try_from(self.reference as isize + anti_descendant_gap).unwrap() } } (0, 0) 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 e639182c..00d30153 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 @@ -9,7 +9,8 @@ use crate::{ a_star_aligner::{ alignment_result::{IAlignmentType, alignment::stream::AlignmentStream}, template_switch_distance::{ - AlignmentType, TemplateSwitchDirection, TemplateSwitchPrimary, TemplateSwitchSecondary, + AlignmentType, TemplateSwitchAncestor, TemplateSwitchDescendant, + TemplateSwitchDirection, }, }, config::TemplateSwitchConfig, @@ -42,8 +43,8 @@ impl Alignment { _, AlignmentType::TemplateSwitchEntrance { first_offset, - primary, - secondary, + descendant, + ancestor, direction, .. }, @@ -67,31 +68,31 @@ impl Alignment { // Compute TS inner first indices. 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(), - TemplateSwitchPrimary::Query => stream.head_coordinates().query(), + let ts_inner_descendant_index = match descendant { + TemplateSwitchDescendant::Reference => stream.head_coordinates().reference(), + TemplateSwitchDescendant::Query => stream.head_coordinates().query(), }; - if ts_inner_primary_index == 0 { + if ts_inner_descendant_index == 0 { // We cannot extend more backwards. return false; } - let Some(ts_inner_secondary_index) = isize::try_from(match secondary { - TemplateSwitchSecondary::Reference => stream.head_coordinates().reference(), - TemplateSwitchSecondary::Query => stream.head_coordinates().query(), + let Some(ts_inner_ancestor_index) = isize::try_from(match ancestor { + TemplateSwitchAncestor::Reference => stream.head_coordinates().reference(), + TemplateSwitchAncestor::Query => stream.head_coordinates().query(), }) .ok() .and_then(|i| usize::try_from(i.checked_add(first_offset)?).ok()) else { error!( - "(Programming) Error: finding inner secondary index -- integer math does not check out" + "(Programming) Error: finding inner ancestor index -- integer math does not check out" ); return false; }; // Check if indices can be moved while staying in bounds. match direction { - TemplateSwitchDirection::Forward if ts_inner_secondary_index == 0 => return false, + TemplateSwitchDirection::Forward if ts_inner_ancestor_index == 0 => return false, TemplateSwitchDirection::Reverse - if ts_inner_secondary_index >= secondary.get(reference, query).len() => + if ts_inner_ancestor_index >= ancestor.get(reference, query).len() => { return false; } @@ -113,18 +114,19 @@ impl Alignment { } // Check if the new inner pair is a match or a substitution. - // ts_inner_primary_index > 0, otherwise we would've returned false earlier - let primary_char = primary.get(reference, query)[ts_inner_primary_index - 1].clone(); - let secondary_char = match direction { + // ts_inner_descendant_index > 0, otherwise we would've returned false earlier + let descendant_char = + descendant.get(reference, query)[ts_inner_descendant_index - 1].clone(); + let ancestor_char = match direction { TemplateSwitchDirection::Forward => { - // ts_inner_secondary_index > 0, otherwise we would've returned false earlier - secondary.get(reference, query)[ts_inner_secondary_index - 1].clone() + // ts_inner_ancestor_index > 0, otherwise we would've returned false earlier + ancestor.get(reference, query)[ts_inner_ancestor_index - 1].clone() } TemplateSwitchDirection::Reverse => { - secondary.get(reference, query)[ts_inner_secondary_index].complement() + ancestor.get(reference, query)[ts_inner_ancestor_index].complement() } }; - let inner_alignment_type = if primary_char == secondary_char { + let inner_alignment_type = if descendant_char == ancestor_char { AlignmentType::SecondaryMatch } else { AlignmentType::SecondarySubstitution @@ -153,15 +155,19 @@ impl Alignment { *first_offset += 2; } - // Fix anti-primary gap. - let Some((_, AlignmentType::TemplateSwitchExit { anti_primary_gap })) = self.alignment - [*compact_index..] + // Fix anti-descendant gap. + let Some(( + _, + AlignmentType::TemplateSwitchExit { + anti_descendant_gap, + }, + )) = self.alignment[*compact_index..] .iter_mut() .find(|(_, alignment_type)| alignment_type.is_template_switch_exit()) else { unreachable!("There should be a TS exit.."); }; - *anti_primary_gap += 1; + *anti_descendant_gap += 1; true } else { @@ -277,15 +283,19 @@ impl Alignment { *first_offset -= 2; } - // Fix anti-primary gap. - let Some((_, AlignmentType::TemplateSwitchExit { anti_primary_gap })) = self.alignment - [*compact_index..] + // Fix anti-descendant gap. + let Some(( + _, + AlignmentType::TemplateSwitchExit { + anti_descendant_gap, + }, + )) = self.alignment[*compact_index..] .iter_mut() .find(|(_, alignment_type)| alignment_type.is_template_switch_exit()) else { unreachable!(); }; - *anti_primary_gap -= 1; + *anti_descendant_gap -= 1; true } else { @@ -315,8 +325,8 @@ impl Alignment { ) -> bool { let AlignmentType::TemplateSwitchEntrance { first_offset, - primary, - secondary, + descendant, + ancestor, direction, .. } = self.alignment[compact_index].1 @@ -337,18 +347,18 @@ impl Alignment { return false; }; let mut exit_index = compact_index + exit_index_offset; - let inner_secondary_length = self + let inner_ancestor_length = self .alignment .iter() .take(exit_index) .skip(compact_index + 1) .fold( 0, - |secondary_length, (multiplicity, alignment_type)| match alignment_type { - AlignmentType::SecondaryInsertion => secondary_length, + |ancestor_length, (multiplicity, alignment_type)| match alignment_type { + AlignmentType::SecondaryInsertion => ancestor_length, AlignmentType::SecondaryDeletion | AlignmentType::SecondarySubstitution - | AlignmentType::SecondaryMatch => secondary_length + *multiplicity, + | AlignmentType::SecondaryMatch => ancestor_length + *multiplicity, _ => unreachable!(), }, ); @@ -365,50 +375,50 @@ impl Alignment { .take(exit_index + 1) .skip(compact_index), ); - let ts_inner_primary_index = match primary { - TemplateSwitchPrimary::Reference => stream.head_coordinates().reference(), - TemplateSwitchPrimary::Query => stream.head_coordinates().query(), + let ts_inner_descendant_index = match descendant { + TemplateSwitchDescendant::Reference => stream.head_coordinates().reference(), + TemplateSwitchDescendant::Query => stream.head_coordinates().query(), }; - let Some(ts_inner_secondary_index) = isize::try_from(match secondary { - TemplateSwitchSecondary::Reference => stream.tail_coordinates().reference(), - TemplateSwitchSecondary::Query => stream.tail_coordinates().query(), + let Some(ts_inner_ancestor_index) = isize::try_from(match ancestor { + TemplateSwitchAncestor::Reference => stream.tail_coordinates().reference(), + TemplateSwitchAncestor::Query => stream.tail_coordinates().query(), }) .ok() .and_then(|i| usize::try_from(i.checked_add(first_offset)?).ok()) else { - error!("Error finding inner secondary index -- integer math does not check out"); + error!("Error finding inner ancestor index -- integer math does not check out"); return false; }; - let ts_inner_secondary_index = match direction { + let ts_inner_ancestor_index = match direction { TemplateSwitchDirection::Forward => { - let Some(ts_inner_secondary_index) = - ts_inner_secondary_index.checked_add(inner_secondary_length) + let Some(ts_inner_ancestor_index) = + ts_inner_ancestor_index.checked_add(inner_ancestor_length) else { error!( - "ts_inner_secondary_index {ts_inner_secondary_index} should be at least {inner_secondary_length} away from any boundary" + "ts_inner_ancestor_index {ts_inner_ancestor_index} should be at least {inner_ancestor_length} away from any boundary" ); return false; }; // Check if indices can be moved while staying in bounds. - if ts_inner_secondary_index >= secondary.get(reference, query).len() { + if ts_inner_ancestor_index >= ancestor.get(reference, query).len() { return false; } - ts_inner_secondary_index + ts_inner_ancestor_index } TemplateSwitchDirection::Reverse => { - let Some(ts_inner_secondary_index) = - ts_inner_secondary_index.checked_sub(inner_secondary_length) + let Some(ts_inner_ancestor_index) = + ts_inner_ancestor_index.checked_sub(inner_ancestor_length) else { error!( - "ts_inner_secondary_index {ts_inner_secondary_index} should be at least {inner_secondary_length} away from any boundary" + "ts_inner_ancestor_index {ts_inner_ancestor_index} should be at least {inner_ancestor_length} away from any boundary" ); return false; }; // Check if indices can be moved while staying in bounds. - if ts_inner_secondary_index == 0 { + if ts_inner_ancestor_index == 0 { return false; } - ts_inner_secondary_index + ts_inner_ancestor_index } }; @@ -426,17 +436,18 @@ impl Alignment { } // Check if the new inner pair is a match or a substitution. - let primary_char = primary.get(reference, query)[ts_inner_primary_index].clone(); - let secondary_char = match direction { + let descendant_char = + descendant.get(reference, query)[ts_inner_descendant_index].clone(); + let ancestor_char = match direction { TemplateSwitchDirection::Forward => { - secondary.get(reference, query)[ts_inner_secondary_index].clone() + ancestor.get(reference, query)[ts_inner_ancestor_index].clone() } TemplateSwitchDirection::Reverse => { - // ts_inner_secondary_index > 0 since we checked that earlier and would have returned otherwise. - secondary.get(reference, query)[ts_inner_secondary_index - 1].complement() + // ts_inner_ancestor_index > 0 since we checked that earlier and would have returned otherwise. + ancestor.get(reference, query)[ts_inner_ancestor_index - 1].complement() } }; - let inner_alignment_type = if primary_char == secondary_char { + let inner_alignment_type = if descendant_char == ancestor_char { AlignmentType::SecondaryMatch } else { AlignmentType::SecondarySubstitution @@ -450,13 +461,14 @@ impl Alignment { exit_index += 1; } - // Fix anti-primary gap. - let AlignmentType::TemplateSwitchExit { anti_primary_gap } = - &mut self.alignment[exit_index].1 + // Fix anti-descendant gap. + let AlignmentType::TemplateSwitchExit { + anti_descendant_gap, + } = &mut self.alignment[exit_index].1 else { unreachable!("Merely a reborrow"); }; - *anti_primary_gap += 1; + *anti_descendant_gap += 1; true } else { @@ -569,15 +581,19 @@ impl Alignment { .insert(exit_index + 1, (1, outer_alignment_type)); } - // Fix anti-primary gap. - let Some((_, AlignmentType::TemplateSwitchExit { anti_primary_gap })) = self.alignment - [compact_index..] + // Fix anti-descendant gap. + let Some(( + _, + AlignmentType::TemplateSwitchExit { + anti_descendant_gap, + }, + )) = self.alignment[compact_index..] .iter_mut() .find(|(_, alignment_type)| alignment_type.is_template_switch_exit()) else { unreachable!("Just a reborrow"); }; - *anti_primary_gap -= 1; + *anti_descendant_gap -= 1; true } else { @@ -605,10 +621,10 @@ impl Alignment { let mut last_alignment_type = None; let mut reference_index = reference_offset; let mut query_index = query_offset; - let mut primary_index = 0; - let mut secondary_index = 0; - let mut primary = TemplateSwitchPrimary::Reference; - let mut secondary = TemplateSwitchSecondary::Reference; + let mut descendant_index = 0; + let mut ancestor_index = 0; + let mut descendant = TemplateSwitchDescendant::Reference; + let mut ancestor = TemplateSwitchAncestor::Reference; let mut direction = TemplateSwitchDirection::Forward; for alignment_type in self.iter_flat_cloned() { let cost_increment = match alignment_type { @@ -654,85 +670,85 @@ impl Alignment { todo!("Flanks are not yet supported") } AlignmentType::SecondaryInsertion => { - let primary_character = match primary { - TemplateSwitchPrimary::Reference => reference[primary_index].clone(), - TemplateSwitchPrimary::Query => query[primary_index].clone(), + let descendant_character = match descendant { + TemplateSwitchDescendant::Reference => reference[descendant_index].clone(), + TemplateSwitchDescendant::Query => query[descendant_index].clone(), }; let cost_increment = if Some(alignment_type) == last_alignment_type { config .secondary_edit_costs(direction) - .gap_extend_cost(primary_character) + .gap_extend_cost(descendant_character) } else { config .secondary_edit_costs(direction) - .gap_open_cost(primary_character) + .gap_open_cost(descendant_character) }; - primary_index += 1; + descendant_index += 1; cost_increment } AlignmentType::SecondaryDeletion => { - let secondary_character = match (secondary, direction) { - (TemplateSwitchSecondary::Reference, TemplateSwitchDirection::Forward) => { - reference[secondary_index].clone() + let ancestor_character = match (ancestor, direction) { + (TemplateSwitchAncestor::Reference, TemplateSwitchDirection::Forward) => { + reference[ancestor_index].clone() } - (TemplateSwitchSecondary::Reference, TemplateSwitchDirection::Reverse) => { - reference[secondary_index - 1].complement() + (TemplateSwitchAncestor::Reference, TemplateSwitchDirection::Reverse) => { + reference[ancestor_index - 1].complement() } - (TemplateSwitchSecondary::Query, TemplateSwitchDirection::Forward) => { - query[secondary_index].clone() + (TemplateSwitchAncestor::Query, TemplateSwitchDirection::Forward) => { + query[ancestor_index].clone() } - (TemplateSwitchSecondary::Query, TemplateSwitchDirection::Reverse) => { - query[secondary_index - 1].complement() + (TemplateSwitchAncestor::Query, TemplateSwitchDirection::Reverse) => { + query[ancestor_index - 1].complement() } }; let cost_increment = if Some(alignment_type) == last_alignment_type { config .secondary_edit_costs(direction) - .gap_extend_cost(secondary_character) + .gap_extend_cost(ancestor_character) } else { config .secondary_edit_costs(direction) - .gap_open_cost(secondary_character) + .gap_open_cost(ancestor_character) }; match direction { - TemplateSwitchDirection::Forward => secondary_index += 1, - TemplateSwitchDirection::Reverse => secondary_index -= 1, + TemplateSwitchDirection::Forward => ancestor_index += 1, + TemplateSwitchDirection::Reverse => ancestor_index -= 1, } cost_increment } AlignmentType::SecondarySubstitution | AlignmentType::SecondaryMatch => { - let primary_character = match primary { - TemplateSwitchPrimary::Reference => reference[primary_index].clone(), - TemplateSwitchPrimary::Query => query[primary_index].clone(), + let descendant_character = match descendant { + TemplateSwitchDescendant::Reference => reference[descendant_index].clone(), + TemplateSwitchDescendant::Query => query[descendant_index].clone(), }; - let secondary_character = match (secondary, direction) { - (TemplateSwitchSecondary::Reference, TemplateSwitchDirection::Forward) => { - reference[secondary_index].clone() + let ancestor_character = match (ancestor, direction) { + (TemplateSwitchAncestor::Reference, TemplateSwitchDirection::Forward) => { + reference[ancestor_index].clone() } - (TemplateSwitchSecondary::Reference, TemplateSwitchDirection::Reverse) => { - reference[secondary_index - 1].complement() + (TemplateSwitchAncestor::Reference, TemplateSwitchDirection::Reverse) => { + reference[ancestor_index - 1].complement() } - (TemplateSwitchSecondary::Query, TemplateSwitchDirection::Forward) => { - query[secondary_index].clone() + (TemplateSwitchAncestor::Query, TemplateSwitchDirection::Forward) => { + query[ancestor_index].clone() } - (TemplateSwitchSecondary::Query, TemplateSwitchDirection::Reverse) => { - query[secondary_index - 1].complement() + (TemplateSwitchAncestor::Query, TemplateSwitchDirection::Reverse) => { + query[ancestor_index - 1].complement() } }; let cost_increment = config .secondary_edit_costs(direction) - .match_or_substitution_cost(primary_character, secondary_character); - primary_index += 1; + .match_or_substitution_cost(descendant_character, ancestor_character); + descendant_index += 1; match direction { - TemplateSwitchDirection::Forward => secondary_index += 1, - TemplateSwitchDirection::Reverse => secondary_index -= 1, + TemplateSwitchDirection::Forward => ancestor_index += 1, + TemplateSwitchDirection::Reverse => ancestor_index -= 1, } cost_increment } AlignmentType::TemplateSwitchEntrance { first_offset, - primary: ts_primary, - secondary: ts_secondary, + descendant: ts_descendant, + ancestor: ts_ancestor, direction: ts_direction, .. } => { @@ -740,25 +756,25 @@ impl Alignment { last_alignment_type, Some(AlignmentType::TemplateSwitchEntrance { .. }) )); - primary = ts_primary; - secondary = ts_secondary; + descendant = ts_descendant; + ancestor = ts_ancestor; direction = ts_direction; - let cost_increment = config.base_cost.get(primary, secondary, direction); + let cost_increment = config.base_cost.get(descendant, ancestor, direction); let Some(cost_increment) = cost_increment.checked_add( &config - .offset_costs(primary, secondary) + .offset_costs(descendant, ancestor) .evaluate(&first_offset), ) else { return Cost::max_value(); }; - primary_index = match primary { - TemplateSwitchPrimary::Reference => reference_index, - TemplateSwitchPrimary::Query => query_index, + descendant_index = match descendant { + TemplateSwitchDescendant::Reference => reference_index, + TemplateSwitchDescendant::Query => query_index, }; - secondary_index = usize::try_from( - isize::try_from(match secondary { - TemplateSwitchSecondary::Reference => reference_index, - TemplateSwitchSecondary::Query => query_index, + ancestor_index = usize::try_from( + isize::try_from(match ancestor { + TemplateSwitchAncestor::Reference => reference_index, + TemplateSwitchAncestor::Query => query_index, }) .unwrap() .checked_add(first_offset) @@ -767,41 +783,43 @@ impl Alignment { .unwrap(); cost_increment } - AlignmentType::TemplateSwitchExit { anti_primary_gap } => { + AlignmentType::TemplateSwitchExit { + anti_descendant_gap, + } => { assert!(!matches!( last_alignment_type, Some(AlignmentType::TemplateSwitchExit { .. }) )); - let length = match primary { - TemplateSwitchPrimary::Reference => { - let length = primary_index - reference_index; - reference_index = primary_index; + let length = match descendant { + TemplateSwitchDescendant::Reference => { + let length = descendant_index - reference_index; + reference_index = descendant_index; query_index = usize::try_from( isize::try_from(query_index) .unwrap() - .checked_add(anti_primary_gap) + .checked_add(anti_descendant_gap) .unwrap(), ) .unwrap(); length } - TemplateSwitchPrimary::Query => { - let length = primary_index - query_index; - query_index = primary_index; + TemplateSwitchDescendant::Query => { + let length = descendant_index - query_index; + query_index = descendant_index; reference_index = usize::try_from( isize::try_from(reference_index) .unwrap() - .checked_add(anti_primary_gap) + .checked_add(anti_descendant_gap) .unwrap(), ) .unwrap(); length } }; - let length_difference = anti_primary_gap - isize::try_from(length).unwrap(); + let length_difference = anti_descendant_gap - isize::try_from(length).unwrap(); let cost_increment = config - .anti_primary_gap_costs(direction) - .evaluate(&anti_primary_gap); + .anti_descendant_gap_costs(direction) + .evaluate(&anti_descendant_gap); let Some(cost_increment) = cost_increment.checked_add(&config.length_costs.evaluate(&length)) else { @@ -852,8 +870,8 @@ mod tests { a_star_aligner::{ alignment_result::alignment::Alignment, template_switch_distance::{ - AlignmentType, EqualCostRange, TemplateSwitchDirection, TemplateSwitchPrimary, - TemplateSwitchSecondary, + AlignmentType, EqualCostRange, TemplateSwitchAncestor, TemplateSwitchDescendant, + TemplateSwitchDirection, }, }, config::{BaseCost, TemplateSwitchConfig}, @@ -866,17 +884,17 @@ mod tests { [ CONFIG.base_cost.rqr + CONFIG.rq_qr_offset_costs.evaluate(&-6) - + CONFIG.reverse_anti_primary_gap_costs.evaluate(&2) + + CONFIG.reverse_anti_descendant_gap_costs.evaluate(&2) + CONFIG.length_costs.evaluate(&2) + CONFIG.length_difference_costs.evaluate(&0), CONFIG.base_cost.rqr + CONFIG.rq_qr_offset_costs.evaluate(&-4) - + CONFIG.reverse_anti_primary_gap_costs.evaluate(&3) + + CONFIG.reverse_anti_descendant_gap_costs.evaluate(&3) + CONFIG.length_costs.evaluate(&3) + CONFIG.length_difference_costs.evaluate(&0), CONFIG.base_cost.rqr + CONFIG.rq_qr_offset_costs.evaluate(&-2) - + CONFIG.reverse_anti_primary_gap_costs.evaluate(&4) + + CONFIG.reverse_anti_descendant_gap_costs.evaluate(&4) + CONFIG.length_costs.evaluate(&4) + CONFIG.length_difference_costs.evaluate(&0), CONFIG.base_cost.rqr @@ -885,7 +903,7 @@ mod tests { DnaAlphabet::ascii_to_character(b'G').unwrap(), DnaAlphabet::ascii_to_character(b'T').unwrap(), ) - + CONFIG.reverse_anti_primary_gap_costs.evaluate(&5) + + CONFIG.reverse_anti_descendant_gap_costs.evaluate(&5) + CONFIG.length_costs.evaluate(&5) + CONFIG.length_difference_costs.evaluate(&0), CONFIG.base_cost.rqr @@ -898,7 +916,7 @@ mod tests { DnaAlphabet::ascii_to_character(b'A').unwrap(), DnaAlphabet::ascii_to_character(b'C').unwrap(), ) - + CONFIG.reverse_anti_primary_gap_costs.evaluate(&6) + + CONFIG.reverse_anti_descendant_gap_costs.evaluate(&6) + CONFIG.length_costs.evaluate(&6) + CONFIG.length_difference_costs.evaluate(&0), ] @@ -912,8 +930,8 @@ mod tests { AlignmentType::TemplateSwitchEntrance { first_offset: -6, equal_cost_range: EqualCostRange::new_invalid(), - primary: TemplateSwitchPrimary::Reference, - secondary: TemplateSwitchSecondary::Query, + descendant: TemplateSwitchDescendant::Reference, + ancestor: TemplateSwitchAncestor::Query, direction: TemplateSwitchDirection::Reverse, }, ), @@ -921,7 +939,7 @@ mod tests { ( 1, AlignmentType::TemplateSwitchExit { - anti_primary_gap: 2, + anti_descendant_gap: 2, }, ), (2, AlignmentType::PrimaryMatch), @@ -933,8 +951,8 @@ mod tests { AlignmentType::TemplateSwitchEntrance { first_offset: -4, equal_cost_range: EqualCostRange::new_invalid(), - primary: TemplateSwitchPrimary::Reference, - secondary: TemplateSwitchSecondary::Query, + descendant: TemplateSwitchDescendant::Reference, + ancestor: TemplateSwitchAncestor::Query, direction: TemplateSwitchDirection::Reverse, }, ), @@ -942,7 +960,7 @@ mod tests { ( 1, AlignmentType::TemplateSwitchExit { - anti_primary_gap: 3, + anti_descendant_gap: 3, }, ), (2, AlignmentType::PrimaryMatch), @@ -954,8 +972,8 @@ mod tests { AlignmentType::TemplateSwitchEntrance { first_offset: -2, equal_cost_range: EqualCostRange::new_invalid(), - primary: TemplateSwitchPrimary::Reference, - secondary: TemplateSwitchSecondary::Query, + descendant: TemplateSwitchDescendant::Reference, + ancestor: TemplateSwitchAncestor::Query, direction: TemplateSwitchDirection::Reverse, }, ), @@ -963,7 +981,7 @@ mod tests { ( 1, AlignmentType::TemplateSwitchExit { - anti_primary_gap: 4, + anti_descendant_gap: 4, }, ), (2, AlignmentType::PrimaryMatch), @@ -975,8 +993,8 @@ mod tests { AlignmentType::TemplateSwitchEntrance { first_offset: 0, equal_cost_range: EqualCostRange::new_invalid(), - primary: TemplateSwitchPrimary::Reference, - secondary: TemplateSwitchSecondary::Query, + descendant: TemplateSwitchDescendant::Reference, + ancestor: TemplateSwitchAncestor::Query, direction: TemplateSwitchDirection::Reverse, }, ), @@ -985,7 +1003,7 @@ mod tests { ( 1, AlignmentType::TemplateSwitchExit { - anti_primary_gap: 5, + anti_descendant_gap: 5, }, ), (2, AlignmentType::PrimaryMatch), @@ -997,8 +1015,8 @@ mod tests { AlignmentType::TemplateSwitchEntrance { first_offset: 2, equal_cost_range: EqualCostRange::new_invalid(), - primary: TemplateSwitchPrimary::Reference, - secondary: TemplateSwitchSecondary::Query, + descendant: TemplateSwitchDescendant::Reference, + ancestor: TemplateSwitchAncestor::Query, direction: TemplateSwitchDirection::Reverse, }, ), @@ -1007,7 +1025,7 @@ mod tests { ( 1, AlignmentType::TemplateSwitchExit { - anti_primary_gap: 6, + anti_descendant_gap: 6, }, ), (2, AlignmentType::PrimaryMatch), @@ -1020,17 +1038,17 @@ mod tests { [ CONFIG.base_cost.rqr + CONFIG.rq_qr_offset_costs.evaluate(&10) - + CONFIG.reverse_anti_primary_gap_costs.evaluate(&2) + + CONFIG.reverse_anti_descendant_gap_costs.evaluate(&2) + CONFIG.length_costs.evaluate(&2) + CONFIG.length_difference_costs.evaluate(&0), CONFIG.base_cost.rqr + CONFIG.rq_qr_offset_costs.evaluate(&10) - + CONFIG.reverse_anti_primary_gap_costs.evaluate(&3) + + CONFIG.reverse_anti_descendant_gap_costs.evaluate(&3) + CONFIG.length_costs.evaluate(&3) + CONFIG.length_difference_costs.evaluate(&0), CONFIG.base_cost.rqr + CONFIG.rq_qr_offset_costs.evaluate(&10) - + CONFIG.reverse_anti_primary_gap_costs.evaluate(&4) + + CONFIG.reverse_anti_descendant_gap_costs.evaluate(&4) + CONFIG.length_costs.evaluate(&4) + CONFIG.length_difference_costs.evaluate(&0), CONFIG.base_cost.rqr @@ -1039,7 +1057,7 @@ mod tests { DnaAlphabet::ascii_to_character(b'A').unwrap(), DnaAlphabet::ascii_to_character(b'C').unwrap(), ) - + CONFIG.reverse_anti_primary_gap_costs.evaluate(&5) + + CONFIG.reverse_anti_descendant_gap_costs.evaluate(&5) + CONFIG.length_costs.evaluate(&5) + CONFIG.length_difference_costs.evaluate(&0), CONFIG.base_cost.rqr @@ -1052,7 +1070,7 @@ mod tests { DnaAlphabet::ascii_to_character(b'G').unwrap(), DnaAlphabet::ascii_to_character(b'T').unwrap(), ) - + CONFIG.reverse_anti_primary_gap_costs.evaluate(&6) + + CONFIG.reverse_anti_descendant_gap_costs.evaluate(&6) + CONFIG.length_costs.evaluate(&6) + CONFIG.length_difference_costs.evaluate(&0), ] @@ -1066,8 +1084,8 @@ mod tests { AlignmentType::TemplateSwitchEntrance { first_offset: 10, equal_cost_range: EqualCostRange::new_invalid(), - primary: TemplateSwitchPrimary::Reference, - secondary: TemplateSwitchSecondary::Query, + descendant: TemplateSwitchDescendant::Reference, + ancestor: TemplateSwitchAncestor::Query, direction: TemplateSwitchDirection::Reverse, }, ), @@ -1075,7 +1093,7 @@ mod tests { ( 1, AlignmentType::TemplateSwitchExit { - anti_primary_gap: 2, + anti_descendant_gap: 2, }, ), (6, AlignmentType::PrimaryMatch), @@ -1087,8 +1105,8 @@ mod tests { AlignmentType::TemplateSwitchEntrance { first_offset: 10, equal_cost_range: EqualCostRange::new_invalid(), - primary: TemplateSwitchPrimary::Reference, - secondary: TemplateSwitchSecondary::Query, + descendant: TemplateSwitchDescendant::Reference, + ancestor: TemplateSwitchAncestor::Query, direction: TemplateSwitchDirection::Reverse, }, ), @@ -1096,7 +1114,7 @@ mod tests { ( 1, AlignmentType::TemplateSwitchExit { - anti_primary_gap: 3, + anti_descendant_gap: 3, }, ), (5, AlignmentType::PrimaryMatch), @@ -1108,8 +1126,8 @@ mod tests { AlignmentType::TemplateSwitchEntrance { first_offset: 10, equal_cost_range: EqualCostRange::new_invalid(), - primary: TemplateSwitchPrimary::Reference, - secondary: TemplateSwitchSecondary::Query, + descendant: TemplateSwitchDescendant::Reference, + ancestor: TemplateSwitchAncestor::Query, direction: TemplateSwitchDirection::Reverse, }, ), @@ -1117,7 +1135,7 @@ mod tests { ( 1, AlignmentType::TemplateSwitchExit { - anti_primary_gap: 4, + anti_descendant_gap: 4, }, ), (4, AlignmentType::PrimaryMatch), @@ -1129,8 +1147,8 @@ mod tests { AlignmentType::TemplateSwitchEntrance { first_offset: 10, equal_cost_range: EqualCostRange::new_invalid(), - primary: TemplateSwitchPrimary::Reference, - secondary: TemplateSwitchSecondary::Query, + descendant: TemplateSwitchDescendant::Reference, + ancestor: TemplateSwitchAncestor::Query, direction: TemplateSwitchDirection::Reverse, }, ), @@ -1139,7 +1157,7 @@ mod tests { ( 1, AlignmentType::TemplateSwitchExit { - anti_primary_gap: 5, + anti_descendant_gap: 5, }, ), (3, AlignmentType::PrimaryMatch), @@ -1151,8 +1169,8 @@ mod tests { AlignmentType::TemplateSwitchEntrance { first_offset: 10, equal_cost_range: EqualCostRange::new_invalid(), - primary: TemplateSwitchPrimary::Reference, - secondary: TemplateSwitchSecondary::Query, + descendant: TemplateSwitchDescendant::Reference, + ancestor: TemplateSwitchAncestor::Query, direction: TemplateSwitchDirection::Reverse, }, ), @@ -1161,7 +1179,7 @@ mod tests { ( 1, AlignmentType::TemplateSwitchExit { - anti_primary_gap: 6, + anti_descendant_gap: 6, }, ), (2, AlignmentType::PrimaryMatch), @@ -1233,13 +1251,13 @@ mod tests { .collect::>(), ) .unwrap(), - forward_anti_primary_gap_costs: CostFunction::try_from( + forward_anti_descendant_gap_costs: CostFunction::try_from( (-20..=20) .map(|i| (i, U64Cost::from(29 * u64::try_from(i + 21).unwrap()))) .collect::>(), ) .unwrap(), - reverse_anti_primary_gap_costs: CostFunction::try_from( + reverse_anti_descendant_gap_costs: CostFunction::try_from( (-20..=20) .map(|i| (i, U64Cost::from(31 * u64::try_from(i + 21).unwrap()))) .collect::>(), diff --git a/lib_tsalign/src/a_star_aligner/template_switch_distance.rs b/lib_tsalign/src/a_star_aligner/template_switch_distance.rs index 0b2f11be..5d197408 100644 --- a/lib_tsalign/src/a_star_aligner/template_switch_distance.rs +++ b/lib_tsalign/src/a_star_aligner/template_switch_distance.rs @@ -20,7 +20,7 @@ pub mod strategies; pub use alignment_type::{AlignmentType, equal_cost_range::EqualCostRange}; pub use context::Context; pub use identifier::{ - GapType, Identifier, TemplateSwitchDirection, TemplateSwitchPrimary, TemplateSwitchSecondary, + GapType, Identifier, TemplateSwitchAncestor, TemplateSwitchDescendant, TemplateSwitchDirection, }; use crate::{ @@ -244,8 +244,8 @@ impl Node { .generate_initial_template_switch_entrance_successors() .filter_map(move |identifier| { let Identifier::TemplateSwitchEntrance { - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, template_switch_first_offset, .. @@ -258,23 +258,24 @@ impl Node { if !self .strategies .descendant_strategy - .is_descendant_allowed(*template_switch_primary) + .is_descendant_allowed(*template_switch_descendant) { return None; } let base_cost = base_cost.get( - *template_switch_primary, - *template_switch_secondary, + *template_switch_descendant, + *template_switch_ancestor, *template_switch_direction, ); - let cost_increment = match (*template_switch_primary, *template_switch_secondary) { - (TemplateSwitchPrimary::Reference, TemplateSwitchSecondary::Query) - | (TemplateSwitchPrimary::Query, TemplateSwitchSecondary::Reference) => { + let cost_increment = match (*template_switch_descendant, *template_switch_ancestor) + { + (TemplateSwitchDescendant::Reference, TemplateSwitchAncestor::Query) + | (TemplateSwitchDescendant::Query, TemplateSwitchAncestor::Reference) => { rq_qr_cost_increment } - (TemplateSwitchPrimary::Reference, TemplateSwitchSecondary::Reference) - | (TemplateSwitchPrimary::Query, TemplateSwitchSecondary::Query) => { + (TemplateSwitchDescendant::Reference, TemplateSwitchAncestor::Reference) + | (TemplateSwitchDescendant::Query, TemplateSwitchAncestor::Query) => { rr_qq_cost_increment } }; @@ -286,8 +287,8 @@ impl Node { identifier, base_cost + cost_increment, AlignmentType::TemplateSwitchEntrance { - primary: *template_switch_primary, - secondary: *template_switch_secondary, + descendant: *template_switch_descendant, + ancestor: *template_switch_ancestor, direction: *template_switch_direction, equal_cost_range: EqualCostRange::new_invalid(), first_offset: *template_switch_first_offset, @@ -313,8 +314,8 @@ impl Node { let Identifier::TemplateSwitchEntrance { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, .. } = self.node_data.identifier @@ -326,15 +327,15 @@ impl Node { Identifier::TemplateSwitchEntrance { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, template_switch_first_offset: successor_template_switch_first_offset, }, cost_increment, AlignmentType::TemplateSwitchEntrance { - primary: template_switch_primary, - secondary: template_switch_secondary, + descendant: template_switch_descendant, + ancestor: template_switch_ancestor, direction: template_switch_direction, equal_cost_range: EqualCostRange::new_invalid(), first_offset: successor_template_switch_first_offset, @@ -360,8 +361,8 @@ impl Node { let Identifier::TemplateSwitchEntrance { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, template_switch_first_offset, } = self.node_data.identifier @@ -369,23 +370,23 @@ impl Node { unreachable!("This method is only called on template switch entrance nodes.") }; - let primary_index = match template_switch_primary { - TemplateSwitchPrimary::Reference => entrance_reference_index, - TemplateSwitchPrimary::Query => entrance_query_index, + let descendant_index = match template_switch_descendant { + TemplateSwitchDescendant::Reference => entrance_reference_index, + TemplateSwitchDescendant::Query => entrance_query_index, }; - let secondary_index = (match template_switch_secondary { - TemplateSwitchSecondary::Reference => entrance_reference_index, - TemplateSwitchSecondary::Query => entrance_query_index, + let ancestor_index = (match template_switch_ancestor { + TemplateSwitchAncestor::Reference => entrance_reference_index, + TemplateSwitchAncestor::Query => entrance_query_index, } as isize + template_switch_first_offset) as usize; - match template_switch_secondary { - TemplateSwitchSecondary::Reference => { - debug_assert!(secondary_index <= context.reference.len(), "{self}") + match template_switch_ancestor { + TemplateSwitchAncestor::Reference => { + debug_assert!(ancestor_index <= context.reference.len(), "{self}") } - TemplateSwitchSecondary::Query => { - debug_assert!(secondary_index <= context.query.len(), "{self}") + TemplateSwitchAncestor::Query => { + debug_assert!(ancestor_index <= context.query.len(), "{self}") } } @@ -393,12 +394,12 @@ impl Node { Identifier::Secondary { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, length: 0, - primary_index, - secondary_index, + descendant_index, + ancestor_index, gap_type: GapType::None, }, Strategies::Cost::zero(), @@ -440,7 +441,7 @@ impl Node { )) } - /// The secondary contains a base missing in the primary. + /// The ancestor contains a base missing in the descendant. fn generate_secondary_deletion_successor< SubsequenceType: GenomeSequence + ?Sized, >( @@ -465,7 +466,7 @@ impl Node { )) } - /// The secondary contains a base missing in the primary. + /// The descendant contains a base missing in the ancestor. fn generate_secondary_insertion_successor< SubsequenceType: GenomeSequence + ?Sized, >( @@ -504,10 +505,10 @@ impl Node { let Identifier::Secondary { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, - primary_index, + descendant_index, length, .. } = self.node_data.identifier @@ -519,15 +520,15 @@ impl Node { Identifier::TemplateSwitchExit { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, - primary_index, - anti_primary_gap: length.try_into().unwrap(), + descendant_index, + anti_descendant_gap: length.try_into().unwrap(), }, cost_increment, AlignmentType::TemplateSwitchExit { - anti_primary_gap: length.try_into().unwrap(), + anti_descendant_gap: length.try_into().unwrap(), }, context, )) @@ -538,7 +539,7 @@ impl Node { >( &self, cost_increment: Strategies::Cost, - successor_anti_primary_gap: isize, + successor_anti_descendant_gap: isize, context: &Context, ) -> Option { if cost_increment == Strategies::Cost::max_value() { @@ -548,10 +549,10 @@ impl Node { let Identifier::TemplateSwitchExit { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, - primary_index, + descendant_index, .. } = self.node_data.identifier else { @@ -562,15 +563,15 @@ impl Node { Identifier::TemplateSwitchExit { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, - primary_index, - anti_primary_gap: successor_anti_primary_gap, + descendant_index, + anti_descendant_gap: successor_anti_descendant_gap, }, cost_increment, AlignmentType::TemplateSwitchExit { - anti_primary_gap: successor_anti_primary_gap, + anti_descendant_gap: successor_anti_descendant_gap, }, context, )) @@ -590,35 +591,35 @@ impl Node { let identifier @ Identifier::TemplateSwitchExit { entrance_reference_index, entrance_query_index, - template_switch_primary, - primary_index, - anti_primary_gap, + template_switch_descendant, + descendant_index, + anti_descendant_gap, .. } = self.node_data.identifier else { unreachable!("This method is only called on template switch exit nodes.") }; - let (reference_index, query_index) = match template_switch_primary { - TemplateSwitchPrimary::Reference => { - let query_index = entrance_query_index as isize + anti_primary_gap; + let (reference_index, query_index) = match template_switch_descendant { + TemplateSwitchDescendant::Reference => { + let query_index = entrance_query_index as isize + anti_descendant_gap; // TODO the latter condition should never be true if we generate TS exit nodes correctly. if query_index < 0 || query_index as usize >= context.query.len() { return None; } - (primary_index, query_index as usize) + (descendant_index, query_index as usize) } - TemplateSwitchPrimary::Query => { - let reference_index = entrance_reference_index as isize + anti_primary_gap; + TemplateSwitchDescendant::Query => { + let reference_index = entrance_reference_index as isize + anti_descendant_gap; // TODO the latter condition should never be true if we generate TS exit nodes correctly. if reference_index < 0 || reference_index as usize >= context.reference.len() { return None; } - (reference_index as usize, primary_index) + (reference_index as usize, descendant_index) } }; diff --git a/lib_tsalign/src/a_star_aligner/template_switch_distance/alignment_type.rs b/lib_tsalign/src/a_star_aligner/template_switch_distance/alignment_type.rs index c55a6379..b3491f6f 100644 --- a/lib_tsalign/src/a_star_aligner/template_switch_distance/alignment_type.rs +++ b/lib_tsalign/src/a_star_aligner/template_switch_distance/alignment_type.rs @@ -2,7 +2,9 @@ use equal_cost_range::EqualCostRange; use crate::a_star_aligner::alignment_result::IAlignmentType; -use super::identifier::{TemplateSwitchDirection, TemplateSwitchPrimary, TemplateSwitchSecondary}; +use super::identifier::{ + TemplateSwitchAncestor, TemplateSwitchDescendant, TemplateSwitchDirection, +}; pub mod equal_cost_range; @@ -33,31 +35,31 @@ pub enum AlignmentType { /// /// This happens inside a TS flank. PrimaryFlankMatch, - /// The TS secondary is missing a base present in the TS primary. + /// The TS ancestor is missing a base present in the TS descendant. SecondaryInsertion, - /// The TS secondary contains a base that is missing from the TS primary. + /// The TS ancestor contains a base that is missing from the TS descendant. SecondaryDeletion, - /// The TS secondary contains a different base than the TS primary. + /// The TS ancestor contains a different base than the TS descendant. SecondarySubstitution, - /// The TS secondary contains the same base as the TS primary. + /// The TS ancestor contains the same base as the TS descendant. SecondaryMatch, /// A template switch entrance. TemplateSwitchEntrance { first_offset: isize, equal_cost_range: EqualCostRange, - primary: TemplateSwitchPrimary, - secondary: TemplateSwitchSecondary, + descendant: TemplateSwitchDescendant, + ancestor: TemplateSwitchAncestor, direction: TemplateSwitchDirection, }, /// A template switch exit. TemplateSwitchExit { - /// The number of characters that are skipped on the anti-primary sequence. - /// If negative, it is the number of characters that are repeated on the anti-primary sequence. + /// The number of characters that are skipped on the anti-descendant sequence. + /// If negative, it is the number of characters that are repeated on the anti-descendant sequence. /// /// In terms of switchpoints, this is the difference `SP4 - SP1`. /// - /// Note that the anti-primary sequence is not necessarily equal to the secondary sequence. - anti_primary_gap: isize, + /// Note that the anti-descendant sequence is not necessarily equal to the ancestor sequence. + anti_descendant_gap: isize, }, /// This node is the root node, hence it was not generated via alignment. Root, @@ -122,16 +124,16 @@ impl IAlignmentType for AlignmentType { match (self, previous) { ( Self::TemplateSwitchEntrance { - primary: primary_a, - secondary: secondary_a, + descendant: descendant_a, + ancestor: ancestor_a, .. }, Self::TemplateSwitchEntrance { - primary: primary_b, - secondary: secondary_b, + descendant: descendant_b, + ancestor: ancestor_b, .. }, - ) => primary_a == primary_b && secondary_a == secondary_b, + ) => descendant_a == descendant_b && ancestor_a == ancestor_b, (Self::TemplateSwitchExit { .. }, Self::TemplateSwitchExit { .. }) => true, (Self::PrimaryShortcut { .. }, Self::PrimaryShortcut { .. }) => false, (a, b) => a == b, @@ -164,14 +166,14 @@ impl AlignmentType { Self::SecondaryInsertion => Self::SecondaryDeletion, Self::SecondaryDeletion => Self::SecondaryInsertion, Self::TemplateSwitchEntrance { - primary, - secondary, + descendant, + ancestor, direction, equal_cost_range, first_offset, } => Self::TemplateSwitchEntrance { - primary: primary.inverted(), - secondary: secondary.inverted(), + descendant: descendant.inverted(), + ancestor: ancestor.inverted(), direction: direction.inverted(), equal_cost_range: *equal_cost_range, first_offset: *first_offset, diff --git a/lib_tsalign/src/a_star_aligner/template_switch_distance/context.rs b/lib_tsalign/src/a_star_aligner/template_switch_distance/context.rs index fb84962c..e4f5e293 100644 --- a/lib_tsalign/src/a_star_aligner/template_switch_distance/context.rs +++ b/lib_tsalign/src/a_star_aligner/template_switch_distance/context.rs @@ -12,7 +12,7 @@ use crate::a_star_aligner::template_switch_distance::{Node, TemplateSwitchDirect use crate::a_star_aligner::{AlignmentContext, AlignmentRange}; use crate::config::TemplateSwitchConfig; -use super::identifier::{GapType, TemplateSwitchPrimary, TemplateSwitchSecondary}; +use super::identifier::{GapType, TemplateSwitchAncestor, TemplateSwitchDescendant}; use super::strategies::chaining::ChainingStrategy; use super::strategies::primary_match::PrimaryMatchStrategy; use super::strategies::secondary_deletion::SecondaryDeletionStrategy; @@ -377,8 +377,8 @@ impl< Identifier::TemplateSwitchEntrance { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, template_switch_first_offset, .. @@ -389,33 +389,33 @@ impl< .can_start_another_template_switch(self) ); - let (secondary_entrance_index, secondary_length) = match template_switch_secondary { - TemplateSwitchSecondary::Reference => { + let (ancestor_entrance_index, ancestor_length) = match template_switch_ancestor { + TemplateSwitchAncestor::Reference => { (entrance_reference_index, self.reference.len()) } - TemplateSwitchSecondary::Query => (entrance_query_index, self.query.len()), + TemplateSwitchAncestor::Query => (entrance_query_index, self.query.len()), }; - let secondary_index = - secondary_entrance_index as isize + template_switch_first_offset; + let ancestor_index = + ancestor_entrance_index as isize + template_switch_first_offset; if template_switch_first_offset >= 0 && match template_switch_direction { TemplateSwitchDirection::Forward => { - (secondary_index + self.config.template_switch_min_length as isize) - < secondary_length as isize + (ancestor_index + self.config.template_switch_min_length as isize) + < ancestor_length as isize } TemplateSwitchDirection::Reverse => { - secondary_index < secondary_length as isize + ancestor_index < ancestor_length as isize } } { let new_cost = config - .offset_costs(template_switch_primary, template_switch_secondary) + .offset_costs(template_switch_descendant, template_switch_ancestor) .evaluate(&(&template_switch_first_offset + 1)); if new_cost != Strategies::Cost::max_value() { let old_cost = config - .offset_costs(template_switch_primary, template_switch_secondary) + .offset_costs(template_switch_descendant, template_switch_ancestor) .evaluate(&template_switch_first_offset); assert!(new_cost >= old_cost); let cost_increment = new_cost - old_cost; @@ -433,19 +433,19 @@ impl< if template_switch_first_offset <= 0 && match template_switch_direction { - TemplateSwitchDirection::Forward => secondary_index > 0, + TemplateSwitchDirection::Forward => ancestor_index > 0, TemplateSwitchDirection::Reverse => { - secondary_index > self.config.template_switch_min_length as isize + ancestor_index > self.config.template_switch_min_length as isize } } { let new_cost = config - .offset_costs(template_switch_primary, template_switch_secondary) + .offset_costs(template_switch_descendant, template_switch_ancestor) .evaluate(&(&template_switch_first_offset - 1)); if new_cost != Strategies::Cost::max_value() { let old_cost = config - .offset_costs(template_switch_primary, template_switch_secondary) + .offset_costs(template_switch_descendant, template_switch_ancestor) .evaluate(&template_switch_first_offset); assert!(new_cost >= old_cost); let cost_increment = new_cost - old_cost; @@ -463,13 +463,13 @@ impl< if match template_switch_direction { TemplateSwitchDirection::Forward => { - secondary_index >= 0 - && (secondary_index + self.config.template_switch_min_length as isize) - <= secondary_length as isize + ancestor_index >= 0 + && (ancestor_index + self.config.template_switch_min_length as isize) + <= ancestor_length as isize } TemplateSwitchDirection::Reverse => { - secondary_index >= self.config.template_switch_min_length as isize - && secondary_index <= secondary_length as isize + ancestor_index >= self.config.template_switch_min_length as isize + && ancestor_index <= ancestor_length as isize } } { // Temporarily unpack opened_nodes_output because it borrows self, @@ -489,18 +489,18 @@ impl< } Identifier::Secondary { - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, length, - primary_index, - secondary_index, + descendant_index, + ancestor_index, gap_type, .. } => { // TODO Some of the nodes generated here are unable to reach the target: - // TODO * nodes who get closer than `right_flank_length` to the end of the primary sequence - // TODO * nodes who get closer than `right_flank_length` to the end of the not-primary sequence, + // TODO * nodes who get closer than `right_flank_length` to the end of the descendant sequence + // TODO * nodes who get closer than `right_flank_length` to the end of the anti-descendant sequence, // TODO assuming a `length_difference` of zero let output = false; @@ -509,34 +509,34 @@ impl< println!("Generating successors for node {node}"); } - let primary_sequence = match template_switch_primary { - TemplateSwitchPrimary::Reference => self.reference, - TemplateSwitchPrimary::Query => self.query, + let descendant_sequence = match template_switch_descendant { + TemplateSwitchDescendant::Reference => self.reference, + TemplateSwitchDescendant::Query => self.query, }; - let secondary_sequence = match template_switch_secondary { - TemplateSwitchSecondary::Reference => self.reference, - TemplateSwitchSecondary::Query => self.query, + let ancestor_sequence = match template_switch_ancestor { + TemplateSwitchAncestor::Reference => self.reference, + TemplateSwitchAncestor::Query => self.query, }; // Only generate secondary successors if they can ever exit the template switch based on their length. let min_length_cost = config.length_costs.min(length..).unwrap(); if min_length_cost != Strategies::Cost::max_value() { - if primary_index < primary_sequence.len() + if descendant_index < descendant_sequence.len() && match template_switch_direction { TemplateSwitchDirection::Forward => { - secondary_index < secondary_sequence.len() + ancestor_index < ancestor_sequence.len() } - TemplateSwitchDirection::Reverse => secondary_index > 0, + TemplateSwitchDirection::Reverse => ancestor_index > 0, } { // Diagonal characters - let p = primary_sequence[primary_index].clone(); + let p = descendant_sequence[descendant_index].clone(); let s = match template_switch_direction { TemplateSwitchDirection::Forward => { - secondary_sequence[secondary_index].clone() + ancestor_sequence[ancestor_index].clone() } TemplateSwitchDirection::Reverse => { - secondary_sequence[secondary_index - 1].complement() + ancestor_sequence[ancestor_index - 1].complement() } }; @@ -566,17 +566,17 @@ impl< if match template_switch_direction { TemplateSwitchDirection::Forward => { - secondary_index < secondary_sequence.len() + ancestor_index < ancestor_sequence.len() } - TemplateSwitchDirection::Reverse => secondary_index > 0, + TemplateSwitchDirection::Reverse => ancestor_index > 0, } && Strategies::SecondaryDeletion::allow_secondary_deletions() { if match template_switch_direction { TemplateSwitchDirection::Forward => { - secondary_index >= secondary_sequence.len() + ancestor_index >= ancestor_sequence.len() } TemplateSwitchDirection::Reverse => { - secondary_index > secondary_sequence.len() + ancestor_index > ancestor_sequence.len() } } { panic!("Secondary index out of bounds for node {node}"); @@ -585,10 +585,10 @@ impl< // Deleted character let s = match template_switch_direction { TemplateSwitchDirection::Forward => { - secondary_sequence[secondary_index].clone() + ancestor_sequence[ancestor_index].clone() } TemplateSwitchDirection::Reverse => { - secondary_sequence[secondary_index - 1].complement() + ancestor_sequence[ancestor_index - 1].complement() } }; @@ -603,9 +603,9 @@ impl< ); } - if primary_index < primary_sequence.len() { + if descendant_index < descendant_sequence.len() { // Inserted character - let p = primary_sequence[primary_index].clone(); + let p = descendant_sequence[descendant_index].clone(); opened_nodes_output.extend( node.generate_secondary_insertion_successor( @@ -636,31 +636,32 @@ impl< Identifier::TemplateSwitchExit { entrance_reference_index, entrance_query_index, - template_switch_primary, + template_switch_descendant, template_switch_direction, - primary_index, - anti_primary_gap, + descendant_index, + anti_descendant_gap, .. } => { - let anti_primary_range = match template_switch_primary { - TemplateSwitchPrimary::Reference => { + let anti_descendant_range = match template_switch_descendant { + TemplateSwitchDescendant::Reference => { ::query_range(self) } - TemplateSwitchPrimary::Query => { + TemplateSwitchDescendant::Query => { ::reference_range(self) } }; - let entrance_primary_index = match template_switch_primary { - TemplateSwitchPrimary::Reference => entrance_reference_index, - TemplateSwitchPrimary::Query => entrance_query_index, + let entrance_descendant_index = match template_switch_descendant { + TemplateSwitchDescendant::Reference => entrance_reference_index, + TemplateSwitchDescendant::Query => entrance_query_index, }; - let primary_inner_length = primary_index - entrance_primary_index; + let descendant_inner_length = descendant_index - entrance_descendant_index; let length_difference = - anti_primary_gap - isize::try_from(primary_inner_length).unwrap(); + anti_descendant_gap - isize::try_from(descendant_inner_length).unwrap(); if length_difference >= 0 - && primary_index as isize + length_difference < anti_primary_range.end as isize + && descendant_index as isize + length_difference + < anti_descendant_range.end as isize { let new_cost = config .length_difference_costs @@ -674,7 +675,7 @@ impl< opened_nodes_output.extend( node.generate_template_switch_exit_successor( cost_increment, - anti_primary_gap + 1, + anti_descendant_gap + 1, self, ) .map(Into::into), @@ -683,8 +684,8 @@ impl< } if length_difference <= 0 - && primary_index as isize + length_difference - > anti_primary_range.start as isize + && descendant_index as isize + length_difference + > anti_descendant_range.start as isize { let new_cost = config .length_difference_costs @@ -698,7 +699,7 @@ impl< opened_nodes_output.extend( node.generate_template_switch_exit_successor( cost_increment, - anti_primary_gap - 1, + anti_descendant_gap - 1, self, ) .map(Into::into), @@ -707,13 +708,13 @@ impl< } // Generate reentry successor. - // Evaluate anti-primary gap cost only here, because it may not be non-decreasing. - let anti_primary_gap_cost = config - .anti_primary_gap_costs(template_switch_direction) - .evaluate(&anti_primary_gap); + // Evaluate anti-descendant gap cost only here, because it may not be non-decreasing. + let anti_descendant_gap_cost = config + .anti_descendant_gap_costs(template_switch_direction) + .evaluate(&anti_descendant_gap); opened_nodes_output.extend( - node.generate_primary_reentry_successor(self, anti_primary_gap_cost) + node.generate_primary_reentry_successor(self, anti_descendant_gap_cost) .map(|mut node| { node.strategies.template_switch_count.increment_count(); node.into() diff --git a/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs b/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs index 3d916acf..bc448d85 100644 --- a/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs +++ b/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs @@ -1,7 +1,7 @@ use std::fmt::{Display, Formatter, Result}; use super::{ - AlignmentType, GapType, Identifier, TemplateSwitchPrimary, TemplateSwitchSecondary, + AlignmentType, GapType, Identifier, TemplateSwitchAncestor, TemplateSwitchDescendant, alignment_type::equal_cost_range::EqualCostRange, identifier::TemplateSwitchDirection, }; @@ -19,16 +19,18 @@ impl Display for AlignmentType { | Self::SecondarySubstitution => write!(f, "X"), Self::PrimaryMatch | Self::PrimaryFlankMatch | Self::SecondaryMatch => write!(f, "="), Self::TemplateSwitchEntrance { - primary, - secondary, + descendant, + ancestor, direction, equal_cost_range, first_offset, } => write!( f, - "[TS{primary}{secondary}{direction}:{equal_cost_range}:{first_offset}:" + "[TS{descendant}{ancestor}{direction}:{equal_cost_range}:{first_offset}:" ), - Self::TemplateSwitchExit { anti_primary_gap } => write!(f, ":{anti_primary_gap}]"), + Self::TemplateSwitchExit { + anti_descendant_gap, + } => write!(f, ":{anti_descendant_gap}]"), Self::Root => Ok(()), Self::SecondaryRoot => Ok(()), Self::PrimaryReentry => Ok(()), @@ -50,7 +52,7 @@ impl Display for GapType { } } -impl Display for TemplateSwitchPrimary { +impl Display for TemplateSwitchDescendant { fn fmt(&self, f: &mut Formatter<'_>) -> Result { match self { Self::Reference => write!(f, "R"), @@ -59,7 +61,7 @@ impl Display for TemplateSwitchPrimary { } } -impl Display for TemplateSwitchSecondary { +impl Display for TemplateSwitchAncestor { fn fmt(&self, f: &mut Formatter<'_>) -> Result { match self { Self::Reference => write!(f, "R"), @@ -121,14 +123,14 @@ impl Display for Identifier { Self::TemplateSwitchEntrance { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, template_switch_first_offset, } => { write!( f, - "TemplateSwitchEntrance({entrance_reference_index}R, {entrance_query_index}Q, {template_switch_primary}P, {template_switch_secondary}S, {template_switch_direction}D, {template_switch_first_offset}O)", + "TemplateSwitchEntrance({entrance_reference_index}R, {entrance_query_index}Q, {template_switch_descendant}D, {template_switch_ancestor}A, {template_switch_direction}D, {template_switch_first_offset}O)", ) } @@ -136,12 +138,12 @@ impl Display for Identifier { Self::Secondary { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, length, - primary_index, - secondary_index, + descendant_index, + ancestor_index, gap_type, } => write!( f, @@ -149,10 +151,10 @@ impl Display for Identifier { entrance_reference_index, entrance_query_index, length, - primary_index, - secondary_index, - template_switch_primary, - template_switch_secondary, + descendant_index, + ancestor_index, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, gap_type, ), @@ -161,11 +163,11 @@ impl Display for Identifier { Self::TemplateSwitchExit { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, - primary_index, - anti_primary_gap, + descendant_index: primary_index, + anti_descendant_gap: anti_primary_gap, } => write!( f, "TemplateSwitchExit({}R, {}Q, {}P, {}G, {}, {}, {})", @@ -173,8 +175,8 @@ impl Display for Identifier { entrance_query_index, primary_index, anti_primary_gap, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, ), } diff --git a/lib_tsalign/src/a_star_aligner/template_switch_distance/identifier.rs b/lib_tsalign/src/a_star_aligner/template_switch_distance/identifier.rs index cdcdba7c..1c15985a 100644 --- a/lib_tsalign/src/a_star_aligner/template_switch_distance/identifier.rs +++ b/lib_tsalign/src/a_star_aligner/template_switch_distance/identifier.rs @@ -29,33 +29,33 @@ pub enum Identifier { TemplateSwitchEntrance { entrance_reference_index: usize, entrance_query_index: usize, - template_switch_primary: TemplateSwitchPrimary, - template_switch_secondary: TemplateSwitchSecondary, + template_switch_descendant: TemplateSwitchDescendant, + template_switch_ancestor: TemplateSwitchAncestor, template_switch_direction: TemplateSwitchDirection, template_switch_first_offset: isize, }, Secondary { entrance_reference_index: usize, entrance_query_index: usize, - template_switch_primary: TemplateSwitchPrimary, - template_switch_secondary: TemplateSwitchSecondary, + template_switch_descendant: TemplateSwitchDescendant, + template_switch_ancestor: TemplateSwitchAncestor, template_switch_direction: TemplateSwitchDirection, length: usize, /// The index that does not jump. - primary_index: usize, + descendant_index: usize, /// The index that jumps. - secondary_index: usize, + ancestor_index: usize, gap_type: GapType, }, TemplateSwitchExit { entrance_reference_index: usize, entrance_query_index: usize, - template_switch_primary: TemplateSwitchPrimary, - template_switch_secondary: TemplateSwitchSecondary, + template_switch_descendant: TemplateSwitchDescendant, + template_switch_ancestor: TemplateSwitchAncestor, template_switch_direction: TemplateSwitchDirection, /// The index that does not jump. - primary_index: usize, - anti_primary_gap: isize, + descendant_index: usize, + anti_descendant_gap: isize, }, } @@ -66,23 +66,23 @@ pub enum GapType { None, } -/// The primary sequence is the sequence for which the template switch does not jump. +/// The descendant sequence is the sequence for which the template switch does not jump. #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub enum TemplateSwitchPrimary { +pub enum TemplateSwitchDescendant { Reference, Query, } -/// The secondary sequence is the sequence for which the template switch jumps. +/// The ancestor sequence is the sequence for which the template switch jumps. #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub enum TemplateSwitchSecondary { +pub enum TemplateSwitchAncestor { Reference, Query, } -/// The secondary sequence is the sequence for which the template switch jumps. +/// A reverse TSM is a TSM, while a forward TSM is a repeat. #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum TemplateSwitchDirection { @@ -252,25 +252,25 @@ impl Identifier { query_index: entrance_query_index, .. } => [ - TemplateSwitchPrimary::Reference, - TemplateSwitchPrimary::Reference, - TemplateSwitchPrimary::Query, - TemplateSwitchPrimary::Query, - TemplateSwitchPrimary::Reference, - TemplateSwitchPrimary::Reference, - TemplateSwitchPrimary::Query, - TemplateSwitchPrimary::Query, + TemplateSwitchDescendant::Reference, + TemplateSwitchDescendant::Reference, + TemplateSwitchDescendant::Query, + TemplateSwitchDescendant::Query, + TemplateSwitchDescendant::Reference, + TemplateSwitchDescendant::Reference, + TemplateSwitchDescendant::Query, + TemplateSwitchDescendant::Query, ] .into_iter() .zip([ - TemplateSwitchSecondary::Reference, - TemplateSwitchSecondary::Query, - TemplateSwitchSecondary::Reference, - TemplateSwitchSecondary::Query, - TemplateSwitchSecondary::Reference, - TemplateSwitchSecondary::Query, - TemplateSwitchSecondary::Reference, - TemplateSwitchSecondary::Query, + TemplateSwitchAncestor::Reference, + TemplateSwitchAncestor::Query, + TemplateSwitchAncestor::Reference, + TemplateSwitchAncestor::Query, + TemplateSwitchAncestor::Reference, + TemplateSwitchAncestor::Query, + TemplateSwitchAncestor::Reference, + TemplateSwitchAncestor::Query, ]) .zip([ TemplateSwitchDirection::Forward, @@ -284,7 +284,7 @@ impl Identifier { ]) .flat_map( move |( - (template_switch_primary, template_switch_secondary), + (template_switch_descendant, template_switch_ancestor), template_switch_direction, )| { match template_switch_direction { @@ -292,16 +292,16 @@ impl Identifier { Identifier::TemplateSwitchEntrance { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, template_switch_first_offset: -1, }, Identifier::TemplateSwitchEntrance { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, template_switch_first_offset: 1, }, @@ -310,8 +310,8 @@ impl Identifier { vec![Identifier::TemplateSwitchEntrance { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, template_switch_first_offset: 0, }] @@ -331,24 +331,24 @@ impl Identifier { Self::Secondary { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, length, - primary_index, - secondary_index, + descendant_index, + ancestor_index, .. } => Self::Secondary { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, length: length + 1, - primary_index: primary_index + 1, - secondary_index: match template_switch_direction { - TemplateSwitchDirection::Forward => secondary_index + 1, - TemplateSwitchDirection::Reverse => secondary_index - 1, + descendant_index: descendant_index + 1, + ancestor_index: match template_switch_direction { + TemplateSwitchDirection::Forward => ancestor_index + 1, + TemplateSwitchDirection::Reverse => ancestor_index - 1, }, gap_type: GapType::None, }, @@ -358,30 +358,30 @@ impl Identifier { } } - /// The secondary contains a base missing in the primary. + /// The ancestor contains a base missing in the descendant. pub fn generate_secondary_deletion_successor(self) -> Self { match self { Self::Secondary { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, length, - primary_index, - secondary_index, + descendant_index, + ancestor_index, .. } => Self::Secondary { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, length, - primary_index, - secondary_index: match template_switch_direction { - TemplateSwitchDirection::Forward => secondary_index + 1, - TemplateSwitchDirection::Reverse => secondary_index - 1, + descendant_index, + ancestor_index: match template_switch_direction { + TemplateSwitchDirection::Forward => ancestor_index + 1, + TemplateSwitchDirection::Reverse => ancestor_index - 1, }, gap_type: GapType::Deletion, }, @@ -391,28 +391,28 @@ impl Identifier { } } - /// The secondary misses a base present in the primary. + /// The ancestor misses a base present in the descendant. pub fn generate_secondary_insertion_successor(self) -> Self { match self { Self::Secondary { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, length, - primary_index, - secondary_index, + descendant_index, + ancestor_index, .. } => Self::Secondary { entrance_reference_index, entrance_query_index, - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, length: length + 1, - primary_index: primary_index + 1, - secondary_index, + descendant_index: descendant_index + 1, + ancestor_index, gap_type: GapType::Insertion, }, other => unreachable!( @@ -441,7 +441,7 @@ impl Identifier { } } -impl TemplateSwitchPrimary { +impl TemplateSwitchDescendant { pub fn inverted(&self) -> Self { match self { Self::Reference => Self::Query, @@ -461,13 +461,13 @@ impl TemplateSwitchPrimary { query: &'query SubsequenceType, ) -> &'result SubsequenceType { match self { - TemplateSwitchPrimary::Reference => reference, - TemplateSwitchPrimary::Query => query, + TemplateSwitchDescendant::Reference => reference, + TemplateSwitchDescendant::Query => query, } } } -impl TemplateSwitchSecondary { +impl TemplateSwitchAncestor { pub fn inverted(&self) -> Self { match self { Self::Reference => Self::Query, @@ -487,8 +487,8 @@ impl TemplateSwitchSecondary { query: &'query SubsequenceType, ) -> &'result SubsequenceType { match self { - TemplateSwitchSecondary::Reference => reference, - TemplateSwitchSecondary::Query => query, + TemplateSwitchAncestor::Reference => reference, + TemplateSwitchAncestor::Query => query, } } } diff --git a/lib_tsalign/src/a_star_aligner/template_switch_distance/lower_bounds/template_switch.rs b/lib_tsalign/src/a_star_aligner/template_switch_distance/lower_bounds/template_switch.rs index a49833ba..2ff46172 100644 --- a/lib_tsalign/src/a_star_aligner/template_switch_distance/lower_bounds/template_switch.rs +++ b/lib_tsalign/src/a_star_aligner/template_switch_distance/lower_bounds/template_switch.rs @@ -198,24 +198,24 @@ impl TemplateSwitchLowerBoundMatrix { == string_length_isize - 1 } Identifier::Secondary { - primary_index, - secondary_index, + descendant_index, + ancestor_index, .. } => { - primary_index == 0 - || primary_index == genome_length - 1 - || secondary_index == 0 - || secondary_index == genome_length - 1 + descendant_index == 0 + || descendant_index == genome_length - 1 + || ancestor_index == 0 + || ancestor_index == genome_length - 1 } Identifier::TemplateSwitchExit { template_switch_direction, - anti_primary_gap, + anti_descendant_gap, .. } => { let cost_increment = context .config - .anti_primary_gap_costs(template_switch_direction) - .evaluate(&anti_primary_gap); + .anti_descendant_gap_costs(template_switch_direction) + .evaluate(&anti_descendant_gap); node.generate_primary_reentry_successor(context, cost_increment) .is_none() } @@ -357,8 +357,8 @@ fn generate_template_switch_lower_bound_config bool; + fn is_descendant_allowed(&self, descendant: TemplateSwitchDescendant) -> bool; } #[derive(Debug, Clone, Copy, Eq, PartialEq)] @@ -16,17 +16,17 @@ pub struct AnyTemplateSwitchDescendantStrategy; #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub struct OnlyEqualTemplateSwitchDescendantStrategy { - allowed_descendant: Option, + allowed_descendant: Option, } impl TemplateSwitchDescendantStrategy for AnyTemplateSwitchDescendantStrategy { - fn is_descendant_allowed(&self, _descendant: TemplateSwitchPrimary) -> bool { + fn is_descendant_allowed(&self, _descendant: TemplateSwitchDescendant) -> bool { true } } impl TemplateSwitchDescendantStrategy for OnlyEqualTemplateSwitchDescendantStrategy { - fn is_descendant_allowed(&self, descendant: TemplateSwitchPrimary) -> bool { + fn is_descendant_allowed(&self, descendant: TemplateSwitchDescendant) -> bool { if let Some(allowed_descendant) = self.allowed_descendant { allowed_descendant == descendant } else { @@ -89,7 +89,7 @@ impl AlignmentStrategy for OnlyEqualTemplateSwitchDescendantStrategy { ) -> Self { let mut successor = *self; if let Identifier::TemplateSwitchEntrance { - template_switch_primary: descendant, + template_switch_descendant: descendant, .. } = identifier { diff --git a/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/template_switch_min_length.rs b/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/template_switch_min_length.rs index 3d85162a..a0f7a47f 100644 --- a/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/template_switch_min_length.rs +++ b/lib_tsalign/src/a_star_aligner/template_switch_distance/strategies/template_switch_min_length.rs @@ -13,7 +13,7 @@ use template_switch_error_free_inners::MatchTable; use crate::a_star_aligner::template_switch_distance::{AlignmentType, TemplateSwitchDirection}; use crate::a_star_aligner::template_switch_distance::{ Context, Identifier, Node, - identifier::{GapType, TemplateSwitchPrimary, TemplateSwitchSecondary}, + identifier::{GapType, TemplateSwitchAncestor, TemplateSwitchDescendant}, }; use crate::config::TemplateSwitchConfig; @@ -111,11 +111,11 @@ impl TemplateSwitchMinLengthStrategy #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] pub struct LookaheadMemoryKey { - template_switch_primary: TemplateSwitchPrimary, - template_switch_secondary: TemplateSwitchSecondary, + template_switch_descendant: TemplateSwitchDescendant, + template_switch_ancestor: TemplateSwitchAncestor, template_switch_direction: TemplateSwitchDirection, - primary_index: usize, - secondary_index: usize, + descendant_index: usize, + ancestor_index: usize, } impl TemplateSwitchMinLengthStrategy @@ -143,12 +143,12 @@ impl TemplateSwitchMinLengthStrategy context: &mut Context, ) -> impl IntoIterator> { let Identifier::Secondary { - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, length: 0, - primary_index, - secondary_index, + descendant_index, + ancestor_index, gap_type: GapType::None, .. } = secondary_root_node.node_data.identifier @@ -159,21 +159,21 @@ impl TemplateSwitchMinLengthStrategy let output = false; let memory_key = LookaheadMemoryKey { - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, - primary_index, - secondary_index, + descendant_index, + ancestor_index, }; if output { println!( "Lookahead {}{}{} at {}/{} with cost {}", - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, - primary_index, - secondary_index, + descendant_index, + ancestor_index, secondary_root_node.cost(), ); } @@ -264,12 +264,12 @@ impl TemplateSwitchMinL context: &mut Context, ) -> impl IntoIterator> { let Identifier::Secondary { - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, length: 0, - primary_index, - secondary_index, + descendant_index, + ancestor_index, gap_type: GapType::None, .. } = *secondary_root_node.identifier() @@ -287,44 +287,42 @@ impl TemplateSwitchMinL ); } return Some(secondary_root_node); - } else if secondary_index < context.config.template_switch_min_length - || primary_index - > match template_switch_primary { - TemplateSwitchPrimary::Reference => { + } else if ancestor_index < context.config.template_switch_min_length + || descendant_index + > match template_switch_descendant { + TemplateSwitchDescendant::Reference => { context.reference.len() - context.config.template_switch_min_length } - TemplateSwitchPrimary::Query => { + TemplateSwitchDescendant::Query => { context.query.len() - context.config.template_switch_min_length } } { - // There are not enough characters in the primary or secondary sequence for a match of minimum length. + // There are not enough characters in the descendant or ancestor sequence for a match of minimum length. false } else { - let secondary_rc_index = match template_switch_secondary { - TemplateSwitchSecondary::Reference => context - .reference - .len() - .checked_sub(secondary_index) - .unwrap(), - TemplateSwitchSecondary::Query => { - context.query.len().checked_sub(secondary_index).unwrap() + let ancestor_rc_index = match template_switch_ancestor { + TemplateSwitchAncestor::Reference => { + context.reference.len().checked_sub(ancestor_index).unwrap() + } + TemplateSwitchAncestor::Query => { + context.query.len().checked_sub(ancestor_index).unwrap() } }; let match_table = context.memory.template_switch_min_length.as_ref().unwrap(); - match (template_switch_primary, template_switch_secondary) { - (TemplateSwitchPrimary::Reference, TemplateSwitchSecondary::Reference) => { - match_table.has_reference_reference_match(primary_index, secondary_rc_index) + match (template_switch_descendant, template_switch_ancestor) { + (TemplateSwitchDescendant::Reference, TemplateSwitchAncestor::Reference) => { + match_table.has_reference_reference_match(descendant_index, ancestor_rc_index) } - (TemplateSwitchPrimary::Reference, TemplateSwitchSecondary::Query) => { - match_table.has_reference_query_match(primary_index, secondary_rc_index) + (TemplateSwitchDescendant::Reference, TemplateSwitchAncestor::Query) => { + match_table.has_reference_query_match(descendant_index, ancestor_rc_index) } - (TemplateSwitchPrimary::Query, TemplateSwitchSecondary::Reference) => { - match_table.has_query_reference_match(primary_index, secondary_rc_index) + (TemplateSwitchDescendant::Query, TemplateSwitchAncestor::Reference) => { + match_table.has_query_reference_match(descendant_index, ancestor_rc_index) } - (TemplateSwitchPrimary::Query, TemplateSwitchSecondary::Query) => { - match_table.has_query_query_match(primary_index, secondary_rc_index) + (TemplateSwitchDescendant::Query, TemplateSwitchAncestor::Query) => { + match_table.has_query_query_match(descendant_index, ancestor_rc_index) } } }; @@ -379,12 +377,12 @@ impl TemplateSwitchMinLengthStrategy context: &mut Context, ) -> impl IntoIterator> { let Identifier::Secondary { - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, length: 0, - primary_index, - secondary_index, + descendant_index, + ancestor_index, gap_type: GapType::None, .. } = *secondary_root_node.identifier() @@ -402,28 +400,26 @@ impl TemplateSwitchMinLengthStrategy ); } return Some(secondary_root_node); - } else if secondary_index < context.config.template_switch_min_length - || primary_index - > match template_switch_primary { - TemplateSwitchPrimary::Reference => { + } else if ancestor_index < context.config.template_switch_min_length + || descendant_index + > match template_switch_descendant { + TemplateSwitchDescendant::Reference => { context.reference.len() - context.config.template_switch_min_length } - TemplateSwitchPrimary::Query => { + TemplateSwitchDescendant::Query => { context.query.len() - context.config.template_switch_min_length } } { - // There are not enough characters in the primary or secondary sequence for a match of minimum length. + // There are not enough characters in the descendant or ancestor sequence for a match of minimum length. false } else { - let secondary_rc_index = match template_switch_secondary { - TemplateSwitchSecondary::Reference => context - .reference - .len() - .checked_sub(secondary_index) - .unwrap(), - TemplateSwitchSecondary::Query => { - context.query.len().checked_sub(secondary_index).unwrap() + let ancestor_rc_index = match template_switch_ancestor { + TemplateSwitchAncestor::Reference => { + context.reference.len().checked_sub(ancestor_index).unwrap() + } + TemplateSwitchAncestor::Query => { + context.query.len().checked_sub(ancestor_index).unwrap() } }; let match_table = context @@ -433,18 +429,18 @@ impl TemplateSwitchMinLengthStrategy .as_ref() .unwrap(); - match (template_switch_primary, template_switch_secondary) { - (TemplateSwitchPrimary::Reference, TemplateSwitchSecondary::Reference) => { - match_table.has_reference_reference_match(primary_index, secondary_rc_index) + match (template_switch_descendant, template_switch_ancestor) { + (TemplateSwitchDescendant::Reference, TemplateSwitchAncestor::Reference) => { + match_table.has_reference_reference_match(descendant_index, ancestor_rc_index) } - (TemplateSwitchPrimary::Reference, TemplateSwitchSecondary::Query) => { - match_table.has_reference_query_match(primary_index, secondary_rc_index) + (TemplateSwitchDescendant::Reference, TemplateSwitchAncestor::Query) => { + match_table.has_reference_query_match(descendant_index, ancestor_rc_index) } - (TemplateSwitchPrimary::Query, TemplateSwitchSecondary::Reference) => { - match_table.has_query_reference_match(primary_index, secondary_rc_index) + (TemplateSwitchDescendant::Query, TemplateSwitchAncestor::Reference) => { + match_table.has_query_reference_match(descendant_index, ancestor_rc_index) } - (TemplateSwitchPrimary::Query, TemplateSwitchSecondary::Query) => { - match_table.has_query_query_match(primary_index, secondary_rc_index) + (TemplateSwitchDescendant::Query, TemplateSwitchAncestor::Query) => { + match_table.has_query_query_match(descendant_index, ancestor_rc_index) } } }; @@ -454,11 +450,11 @@ impl TemplateSwitchMinLengthStrategy } else { // Use lookahead strategy as a fallback. let memory_key = LookaheadMemoryKey { - template_switch_primary, - template_switch_secondary, + template_switch_descendant, + template_switch_ancestor, template_switch_direction, - primary_index, - secondary_index, + descendant_index, + ancestor_index, }; let secondary_root_node = if let Some(a_star_lower_bound) = diff --git a/lib_tsalign/src/config.rs b/lib_tsalign/src/config.rs index b43d6a83..68987ceb 100644 --- a/lib_tsalign/src/config.rs +++ b/lib_tsalign/src/config.rs @@ -4,7 +4,7 @@ use num_traits::{Bounded, bounds::UpperBounded}; use crate::{ a_star_aligner::template_switch_distance::{ - TemplateSwitchDirection, TemplateSwitchPrimary, TemplateSwitchSecondary, + TemplateSwitchAncestor, TemplateSwitchDescendant, TemplateSwitchDirection, }, costs::{cost_function::CostFunction, gap_affine::GapAffineAlignmentCostTable}, error::{Error, Result}, @@ -44,28 +44,28 @@ pub struct TemplateSwitchConfig { pub rr_qq_offset_costs: CostFunction, pub length_costs: CostFunction, pub length_difference_costs: CostFunction, - pub forward_anti_primary_gap_costs: CostFunction, - pub reverse_anti_primary_gap_costs: CostFunction, + pub forward_anti_descendant_gap_costs: CostFunction, + pub reverse_anti_descendant_gap_costs: CostFunction, } #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] #[derive(Debug, Clone, Eq, PartialEq)] pub struct BaseCost { - /// Primary: reference; secondary: reference; direction: forward. + /// Descendant: reference; ancestor: reference; direction: forward. pub rrf: Cost, - /// Primary: reference; secondary: query; direction: forward. + /// Descendant: reference; ancestor: query; direction: forward. pub rqf: Cost, - /// Primary: query; secondary: reference; direction: forward. + /// Descendant: query; ancestor: reference; direction: forward. pub qrf: Cost, - /// Primary: query; secondary: query; direction: forward. + /// Descendant: query; ancestor: query; direction: forward. pub qqf: Cost, - /// Primary: reference; secondary: reference; direction: reverse. + /// Descendant: reference; ancestor: reference; direction: reverse. pub rrr: Cost, - /// Primary: reference; secondary: query; direction: reverse. + /// Descendant: reference; ancestor: query; direction: reverse. pub rqr: Cost, - /// Primary: query; secondary: reference; direction: reverse. + /// Descendant: query; ancestor: reference; direction: reverse. pub qrr: Cost, - /// Primary: query; secondary: query; direction: reverse. + /// Descendant: query; ancestor: query; direction: reverse. pub qqr: Cost, } @@ -95,32 +95,32 @@ impl TemplateSwitchConfig { } } - pub fn anti_primary_gap_costs( + pub fn anti_descendant_gap_costs( &self, direction: TemplateSwitchDirection, ) -> &CostFunction { match direction { - TemplateSwitchDirection::Forward => &self.forward_anti_primary_gap_costs, - TemplateSwitchDirection::Reverse => &self.reverse_anti_primary_gap_costs, + TemplateSwitchDirection::Forward => &self.forward_anti_descendant_gap_costs, + TemplateSwitchDirection::Reverse => &self.reverse_anti_descendant_gap_costs, } } pub fn offset_costs( &self, - primary: TemplateSwitchPrimary, - secondary: TemplateSwitchSecondary, + descendant: TemplateSwitchDescendant, + ancestor: TemplateSwitchAncestor, ) -> &CostFunction { - match (primary, secondary) { - (TemplateSwitchPrimary::Reference, TemplateSwitchSecondary::Reference) => { + match (descendant, ancestor) { + (TemplateSwitchDescendant::Reference, TemplateSwitchAncestor::Reference) => { &self.rr_qq_offset_costs } - (TemplateSwitchPrimary::Reference, TemplateSwitchSecondary::Query) => { + (TemplateSwitchDescendant::Reference, TemplateSwitchAncestor::Query) => { &self.rq_qr_offset_costs } - (TemplateSwitchPrimary::Query, TemplateSwitchSecondary::Reference) => { + (TemplateSwitchDescendant::Query, TemplateSwitchAncestor::Reference) => { &self.rq_qr_offset_costs } - (TemplateSwitchPrimary::Query, TemplateSwitchSecondary::Query) => { + (TemplateSwitchDescendant::Query, TemplateSwitchAncestor::Query) => { &self.rr_qq_offset_costs } } @@ -145,49 +145,49 @@ impl BaseCost { impl BaseCost { pub fn get( &self, - primary: TemplateSwitchPrimary, - secondary: TemplateSwitchSecondary, + descendant: TemplateSwitchDescendant, + ancestor: TemplateSwitchAncestor, direction: TemplateSwitchDirection, ) -> Cost { - match (primary, secondary, direction) { + match (descendant, ancestor, direction) { ( - TemplateSwitchPrimary::Reference, - TemplateSwitchSecondary::Reference, + TemplateSwitchDescendant::Reference, + TemplateSwitchAncestor::Reference, TemplateSwitchDirection::Forward, ) => self.rrf.clone(), ( - TemplateSwitchPrimary::Reference, - TemplateSwitchSecondary::Reference, + TemplateSwitchDescendant::Reference, + TemplateSwitchAncestor::Reference, TemplateSwitchDirection::Reverse, ) => self.rrr.clone(), ( - TemplateSwitchPrimary::Reference, - TemplateSwitchSecondary::Query, + TemplateSwitchDescendant::Reference, + TemplateSwitchAncestor::Query, TemplateSwitchDirection::Forward, ) => self.rqf.clone(), ( - TemplateSwitchPrimary::Reference, - TemplateSwitchSecondary::Query, + TemplateSwitchDescendant::Reference, + TemplateSwitchAncestor::Query, TemplateSwitchDirection::Reverse, ) => self.rqr.clone(), ( - TemplateSwitchPrimary::Query, - TemplateSwitchSecondary::Reference, + TemplateSwitchDescendant::Query, + TemplateSwitchAncestor::Reference, TemplateSwitchDirection::Forward, ) => self.qrf.clone(), ( - TemplateSwitchPrimary::Query, - TemplateSwitchSecondary::Reference, + TemplateSwitchDescendant::Query, + TemplateSwitchAncestor::Reference, TemplateSwitchDirection::Reverse, ) => self.qrr.clone(), ( - TemplateSwitchPrimary::Query, - TemplateSwitchSecondary::Query, + TemplateSwitchDescendant::Query, + TemplateSwitchAncestor::Query, TemplateSwitchDirection::Forward, ) => self.qqf.clone(), ( - TemplateSwitchPrimary::Query, - TemplateSwitchSecondary::Query, + TemplateSwitchDescendant::Query, + TemplateSwitchAncestor::Query, TemplateSwitchDirection::Reverse, ) => self.qqr.clone(), } @@ -210,8 +210,8 @@ impl Clone for TemplateSwitchConfig Default for TemplateSwitchConfig TemplateSwitchConfig TemplateSwitchConfig std::fmt::Display writeln!(f, "{}", self.length_costs)?; writeln!(f, "LengthDifference")?; writeln!(f, "{}", self.length_difference_costs)?; - writeln!(f, "ForwardAntiPrimaryGap")?; - writeln!(f, "{}", self.forward_anti_primary_gap_costs)?; - writeln!(f, "ReverseAntiPrimaryGap")?; - writeln!(f, "{}", self.reverse_anti_primary_gap_costs)?; + writeln!(f, "ForwardAntiDescendantGap")?; + writeln!(f, "{}", self.forward_anti_descendant_gap_costs)?; + writeln!(f, "ReverseAntiDescendantGap")?; + writeln!(f, "{}", self.reverse_anti_descendant_gap_costs)?; writeln!(f, "{}", self.primary_edit_costs)?; writeln!(f, "{}", self.secondary_forward_edit_costs)?; diff --git a/lib_tsshow/src/error.rs b/lib_tsshow/src/error.rs index c7556a1c..00891311 100644 --- a/lib_tsshow/src/error.rs +++ b/lib_tsshow/src/error.rs @@ -13,8 +13,8 @@ pub enum Error { #[error("No-TS alignment is incomplete, and hence cannot be rendered.")] NoTsAlignmentHasNoTarget, - #[error("A negative anti-primary gap is not supported for SVG generation.")] - SvgNegativeAntiPrimaryGap, + #[error("A negative anti-descendant gap is not supported for SVG generation.")] + SvgNegativeAntiDescendantGap, #[error("Forward TSes are not yet supported.")] ForwardTsNotSupported, diff --git a/lib_tsshow/src/plain_text.rs b/lib_tsshow/src/plain_text.rs index 232da49a..9aba8ff8 100644 --- a/lib_tsshow/src/plain_text.rs +++ b/lib_tsshow/src/plain_text.rs @@ -7,7 +7,9 @@ use lib_tsalign::{ a_star_sequences::SequencePair, alignment::stream::{AlignmentStream, AlignmentStreamCoordinates}, }, - template_switch_distance::{AlignmentType, TemplateSwitchPrimary, TemplateSwitchSecondary}, + template_switch_distance::{ + AlignmentType, TemplateSwitchAncestor, TemplateSwitchDescendant, + }, }, costs::U64Cost, }; @@ -76,7 +78,7 @@ fn show_template_switch( ) { trace!("Showing template switch\n{template_switch:?}"); - let forward = template_switch.sp2_secondary_offset < template_switch.sp3_secondary_offset; + let forward = template_switch.sp2_ancestor_offset < template_switch.sp3_ancestor_offset; let reference = &sequences.reference; let reference_c: String = sequences.reference_rc.chars().rev().collect(); let query = &sequences.query; @@ -94,8 +96,8 @@ fn show_template_switch( anti_primary_c, anti_primary_coordinate_picker, invert_alignment, - ) = match template_switch.primary { - TemplateSwitchPrimary::Reference => ( + ) = match template_switch.descendant { + TemplateSwitchDescendant::Reference => ( "Parent".to_string(), &sequences.reference_name, reference, @@ -112,7 +114,7 @@ fn show_template_switch( }) as Box usize>, true, ), - TemplateSwitchPrimary::Query => ( + TemplateSwitchDescendant::Query => ( "Child".to_string(), &sequences.query_name, query, @@ -130,10 +132,11 @@ fn show_template_switch( false, ), }; - let primary_equals_secondary = (template_switch.primary == TemplateSwitchPrimary::Reference - && template_switch.secondary == TemplateSwitchSecondary::Reference) - || (template_switch.primary == TemplateSwitchPrimary::Query - && template_switch.secondary == TemplateSwitchSecondary::Query); + let primary_equals_secondary = (template_switch.descendant + == TemplateSwitchDescendant::Reference + && template_switch.ancestor == TemplateSwitchAncestor::Reference) + || (template_switch.descendant == TemplateSwitchDescendant::Query + && template_switch.ancestor == TemplateSwitchAncestor::Query); let primary_forward_label = format!("{primary_label}F"); let primary_reverse_label = format!("{primary_label}R"); @@ -188,25 +191,25 @@ fn show_template_switch( debug!("Anti-primary len: {}", anti_primary.len()); debug!( "SP2 secondary offset: {}", - template_switch.sp2_secondary_offset + template_switch.sp2_ancestor_offset ); debug!( "SP3 secondary offset: {}", - template_switch.sp3_secondary_offset + template_switch.sp3_ancestor_offset ); if primary_equals_secondary { let primary_extended_offset = primary_offset.min( template_switch - .sp3_secondary_offset - .min(template_switch.sp2_secondary_offset) + .sp3_ancestor_offset + .min(template_switch.sp2_ancestor_offset) .saturating_sub(STREAM_PADDING), ); let primary_extended_limit = primary_limit.max( primary.chars().count().min( template_switch - .sp2_secondary_offset - .max(template_switch.sp3_secondary_offset) + .sp2_ancestor_offset + .max(template_switch.sp3_ancestor_offset) + STREAM_PADDING, ), ); @@ -281,8 +284,8 @@ fn show_template_switch( &primary_reverse_label }, template_switch - .sp3_secondary_offset - .min(template_switch.sp2_secondary_offset) + .sp3_ancestor_offset + .min(template_switch.sp2_ancestor_offset) - primary_extended_offset, f2_label.clone(), ts_inner.chars(), @@ -321,15 +324,15 @@ fn show_template_switch( } else { let anti_primary_extended_offset = anti_primary_offset.min( template_switch - .sp3_secondary_offset - .min(template_switch.sp2_secondary_offset) + .sp3_ancestor_offset + .min(template_switch.sp2_ancestor_offset) .saturating_sub(STREAM_PADDING), ); let anti_primary_extended_limit = anti_primary_f3_limit.max( anti_primary.chars().count().min( template_switch - .sp2_secondary_offset - .max(template_switch.sp3_secondary_offset) + .sp2_ancestor_offset + .max(template_switch.sp3_ancestor_offset) + STREAM_PADDING, ), ); @@ -389,8 +392,8 @@ fn show_template_switch( &anti_primary_reverse_label }, template_switch - .sp3_secondary_offset - .min(template_switch.sp2_secondary_offset) + .sp3_ancestor_offset + .min(template_switch.sp2_ancestor_offset) - anti_primary_extended_offset, f2_label.clone(), ts_inner.chars(), diff --git a/lib_tsshow/src/plain_text/alignment_stream.rs b/lib_tsshow/src/plain_text/alignment_stream.rs deleted file mode 100644 index 272b27d1..00000000 --- a/lib_tsshow/src/plain_text/alignment_stream.rs +++ /dev/null @@ -1,229 +0,0 @@ -use std::{collections::VecDeque, iter}; - -use lib_tsalign::a_star_aligner::{ - alignment_result::alignment::Alignment, - template_switch_distance::{AlignmentType, TemplateSwitchPrimary}, -}; - -#[derive(Debug, Clone, Default)] -pub struct AlignmentStream { - stream: VecDeque<(usize, AlignmentType)>, - length: usize, - - /// The alignment coordinates of the first alignment after the head of the queue. - head_coordinates: AlignmentCoordinates, - /// The alignment coordinates of the tailmost element in the queue. - tail_coordinates: AlignmentCoordinates, -} - -#[derive(Debug, Default, Clone, Copy)] -pub struct AlignmentCoordinates { - reference: usize, - query: usize, - template_switch_primary: Option, -} - -impl AlignmentStream { - pub fn new() -> Self { - Default::default() - } - - 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 - } - - pub fn len(&self) -> usize { - self.length - } - - pub fn stream_iter(&self) -> impl use<'_> + Iterator { - self.stream.iter().copied() - } - - pub fn stream_iter_flat(&self) -> impl use<'_> + Iterator { - self.stream_iter() - .flat_map(|(multiplicity, alignment_type)| iter::repeat_n(alignment_type, multiplicity)) - } - - fn stream_vec(&self) -> Vec<(usize, AlignmentType)> { - self.stream_iter().collect() - } - - pub fn stream_alignment(&self) -> Alignment { - self.stream_vec().into() - } - - pub fn head_coordinates(&self) -> AlignmentCoordinates { - self.head_coordinates - } - - pub fn tail_coordinates(&self) -> AlignmentCoordinates { - self.tail_coordinates - } - - pub fn push_until_full( - &mut self, - multiplicity: &mut usize, - alignment_type: AlignmentType, - requested_length: usize, - ) { - let available_length = requested_length - self.length; - let push_length = *multiplicity * Self::stream_length(alignment_type); - - if available_length >= push_length { - self.push(*multiplicity, alignment_type); - *multiplicity = 0; - } else { - let push_multiplicity = available_length.div_ceil(Self::stream_length(alignment_type)); - self.push(push_multiplicity, alignment_type); - *multiplicity -= push_multiplicity; - } - } - - pub fn clear(&mut self) { - self.pop(0); - } - - pub fn is_full(&self, requested_length: usize) -> bool { - self.length >= requested_length - } - - pub fn is_empty(&self) -> bool { - self.stream_iter().next().is_none() - } - - pub fn push(&mut self, multiplicity: usize, alignment_type: AlignmentType) { - self.stream.push_back((multiplicity, alignment_type)); - self.head_coordinates.advance(multiplicity, alignment_type); - self.length += multiplicity * Self::stream_length(alignment_type); - } - - /// Pops one unit of length from the tail of the stream. - pub fn pop_one(&mut self) { - self.pop(self.length.saturating_sub(1)); - } - - pub fn pop(&mut self, requested_length: usize) { - while self.length > requested_length { - let requested_pop_length = self.length - requested_length; - let (multiplicity, alignment_type) = self.stream.front_mut().unwrap(); - let front_length = *multiplicity * Self::stream_length(*alignment_type); - - if front_length <= requested_pop_length { - self.tail_coordinates - .advance(*multiplicity, *alignment_type); - self.stream.pop_front(); - self.length -= front_length; - } else { - let pop_multiplicity = requested_pop_length / Self::stream_length(*alignment_type); - self.tail_coordinates - .advance(pop_multiplicity, *alignment_type); - *multiplicity -= pop_multiplicity; - self.length -= pop_multiplicity * Self::stream_length(*alignment_type); - break; - } - } - - while let Some((multiplicity, alignment_type)) = self.stream.front().copied() { - if Self::stream_length(alignment_type) == 0 { - self.tail_coordinates.advance(multiplicity, alignment_type); - self.stream.pop_front(); - } else { - break; - } - } - } - - fn stream_length(alignment_type: AlignmentType) -> usize { - match alignment_type { - AlignmentType::PrimaryInsertion - | AlignmentType::PrimaryDeletion - | AlignmentType::PrimarySubstitution - | AlignmentType::PrimaryMatch - | AlignmentType::PrimaryFlankInsertion - | AlignmentType::PrimaryFlankDeletion - | AlignmentType::PrimaryFlankSubstitution - | AlignmentType::PrimaryFlankMatch - | AlignmentType::SecondaryInsertion - | AlignmentType::SecondaryDeletion - | AlignmentType::SecondarySubstitution - | AlignmentType::SecondaryMatch => 1, - AlignmentType::TemplateSwitchEntrance { .. } - | AlignmentType::TemplateSwitchExit { .. } - | AlignmentType::Root - | AlignmentType::SecondaryRoot - | AlignmentType::PrimaryReentry => 0, - AlignmentType::PrimaryShortcut { .. } => { - unreachable!("Shortcut alignments are not supported for show") - } - } - } -} - -impl AlignmentCoordinates { - pub fn reference(&self) -> usize { - self.reference - } - - pub fn query(&self) -> usize { - self.query - } - - fn advance(&mut self, multiplicity: usize, alignment_type: AlignmentType) { - let (reference_length, query_length) = match alignment_type { - AlignmentType::PrimaryInsertion | AlignmentType::PrimaryFlankInsertion => (0, 1), - AlignmentType::PrimaryDeletion | AlignmentType::PrimaryFlankDeletion => (1, 0), - AlignmentType::PrimarySubstitution - | AlignmentType::PrimaryMatch - | AlignmentType::PrimaryFlankSubstitution - | AlignmentType::PrimaryFlankMatch => (1, 1), - AlignmentType::TemplateSwitchEntrance { primary, .. } => { - assert!( - self.template_switch_primary.is_none(), - "Encountered template switch entrance within template switch" - ); - self.template_switch_primary = Some(primary); - (0, 0) - } - AlignmentType::SecondaryInsertion - | AlignmentType::SecondarySubstitution - | AlignmentType::SecondaryMatch => match self.template_switch_primary.unwrap() { - TemplateSwitchPrimary::Reference => (1, 0), - TemplateSwitchPrimary::Query => (0, 1), - }, - AlignmentType::TemplateSwitchExit { anti_primary_gap } => { - let Some(template_switch_primary) = self.template_switch_primary.take() else { - panic!( - "Encountered template switch exit without first encountering a template switch entrance" - ) - }; - match template_switch_primary { - TemplateSwitchPrimary::Reference => { - self.query = - usize::try_from(self.query as isize + anti_primary_gap).unwrap() - } - TemplateSwitchPrimary::Query => { - self.reference = - usize::try_from(self.reference as isize + anti_primary_gap).unwrap() - } - } - (0, 0) - } - AlignmentType::SecondaryDeletion - | AlignmentType::Root - | AlignmentType::SecondaryRoot - | AlignmentType::PrimaryReentry => (0, 0), - AlignmentType::PrimaryShortcut { .. } => { - unreachable!("Shortcut alignments are not supported for show") - } - }; - - self.reference += multiplicity * reference_length; - self.query += multiplicity * query_length; - } -} diff --git a/lib_tsshow/src/plain_text/parse_template_switches.rs b/lib_tsshow/src/plain_text/parse_template_switches.rs index e8696976..4279ac0e 100644 --- a/lib_tsshow/src/plain_text/parse_template_switches.rs +++ b/lib_tsshow/src/plain_text/parse_template_switches.rs @@ -5,7 +5,7 @@ use lib_tsalign::a_star_aligner::{ stream::{AlignmentStream, AlignmentStreamCoordinates}, }, template_switch_distance::{ - AlignmentType, TemplateSwitchDirection, TemplateSwitchPrimary, TemplateSwitchSecondary, + AlignmentType, TemplateSwitchAncestor, TemplateSwitchDescendant, TemplateSwitchDirection, }, }; use log::{debug, trace}; @@ -20,11 +20,11 @@ pub struct TSShow { pub upstream_offset: AlignmentStreamCoordinates, pub downstream_limit: AlignmentStreamCoordinates, pub sp1_offset: AlignmentStreamCoordinates, - pub sp2_secondary_offset: usize, - pub sp3_secondary_offset: usize, + pub sp2_ancestor_offset: usize, + pub sp3_ancestor_offset: usize, pub sp4_offset: AlignmentStreamCoordinates, - pub primary: TemplateSwitchPrimary, - pub secondary: TemplateSwitchSecondary, + pub descendant: TemplateSwitchDescendant, + pub ancestor: TemplateSwitchAncestor, pub upstream: Alignment, pub template_switch: Alignment, pub downstream: Alignment, @@ -60,8 +60,8 @@ fn parse_template_switch( let ( multiplicity, alignment_type @ AlignmentType::TemplateSwitchEntrance { - primary, - secondary, + descendant, + ancestor, direction, first_offset, .. @@ -79,15 +79,15 @@ fn parse_template_switch( stream.push(multiplicity, alignment_type); alignment.next().unwrap(); - let sp2_secondary_offset: usize = match secondary { - TemplateSwitchSecondary::Reference => (sp1_offset.reference() as isize + first_offset) + let sp2_ancestor_offset: usize = match ancestor { + TemplateSwitchAncestor::Reference => (sp1_offset.reference() as isize + first_offset) .try_into() .unwrap(), - TemplateSwitchSecondary::Query => (sp1_offset.query() as isize + first_offset) + TemplateSwitchAncestor::Query => (sp1_offset.query() as isize + first_offset) .try_into() .unwrap(), }; - let mut sp3_secondary_offset = sp2_secondary_offset; + let mut sp3_ancestor_offset = sp2_ancestor_offset; while let Some((multiplicity, alignment_type)) = alignment.next() { debug!("alignment type: {alignment_type}"); @@ -105,7 +105,7 @@ fn parse_template_switch( sp1_offset .reference() .max(sp1_offset.query()) - .saturating_sub(sp2_secondary_offset.min(sp3_secondary_offset)) + .saturating_sub(sp2_ancestor_offset.min(sp3_ancestor_offset)) + STREAM_PADDING, ), ); @@ -121,11 +121,9 @@ fn parse_template_switch( alignment, stream, STREAM_DEFAULT_LENGTH.max( - sp3_secondary_offset - .max(sp2_secondary_offset) - .saturating_sub( - sp4_offset.reference().min(sp4_offset.query()) + STREAM_PADDING, - ), + sp3_ancestor_offset.max(sp2_ancestor_offset).saturating_sub( + sp4_offset.reference().min(sp4_offset.query()) + STREAM_PADDING, + ), ), ); let downstream_limit = stream.head_coordinates(); @@ -135,11 +133,11 @@ fn parse_template_switch( upstream_offset, downstream_limit, sp1_offset, - sp2_secondary_offset, - sp3_secondary_offset, + sp2_ancestor_offset, + sp3_ancestor_offset, sp4_offset, - primary, - secondary, + descendant, + ancestor, upstream, template_switch, downstream, @@ -156,12 +154,12 @@ fn parse_template_switch( ) { match direction { TemplateSwitchDirection::Forward => { - sp3_secondary_offset += multiplicity; - assert!(sp3_secondary_offset > sp2_secondary_offset); + sp3_ancestor_offset += multiplicity; + assert!(sp3_ancestor_offset > sp2_ancestor_offset); } TemplateSwitchDirection::Reverse => { - sp3_secondary_offset -= multiplicity; - assert!(sp3_secondary_offset < sp2_secondary_offset); + sp3_ancestor_offset -= multiplicity; + assert!(sp3_ancestor_offset < sp2_ancestor_offset); } } } diff --git a/lib_tsshow/src/svg.rs b/lib_tsshow/src/svg.rs index 64b508bb..44339d38 100644 --- a/lib_tsshow/src/svg.rs +++ b/lib_tsshow/src/svg.rs @@ -6,7 +6,9 @@ use indexed_str::IndexedStr; use lib_tsalign::{ a_star_aligner::{ alignment_result::AlignmentResult, - template_switch_distance::{AlignmentType, TemplateSwitchPrimary, TemplateSwitchSecondary}, + template_switch_distance::{ + AlignmentType, TemplateSwitchAncestor, TemplateSwitchDescendant, + }, }, costs::U64Cost, }; @@ -174,19 +176,19 @@ pub fn create_ts_svg( inner_identifier, TemplateSwitch { index: ts_index, - primary, - secondary, + descendant, + ancestor, sp1_reference, sp1_query, - sp2_secondary, - sp3_secondary, + sp2_ancestor, + sp3_ancestor, sp4_reference, sp4_query, .. }, ) in ts_arrangement.template_switches() { - /*let anti_primary_sp4_minus_one = match primary { + /*let anti_descendant_sp4_minus_one = match descendant { TemplateSwitchPrimary::Reference => sp4_query.checked_sub(1).map(|column| { ts_arrangement.query_arrangement_char_to_arrangement_column(column) + 1usize }), @@ -195,7 +197,7 @@ pub fn create_ts_svg( }), }; - let (anti_primary_sp4, anti_primary_row) = match primary { + let (anti_descendant_sp4, anti_descendant_row) = match descendant { TemplateSwitchPrimary::Reference => ( ts_arrangement .query() @@ -205,7 +207,7 @@ pub fn create_ts_svg( ts_arrangement.query_arrangement_char_to_arrangement_column(*sp4_query), ) + 1usize, ) - .skip(anti_primary_sp4_minus_one.unwrap_or(0.into()).into()) + .skip(anti_descendant_sp4_minus_one.unwrap_or(0.into()).into()) .find(|(_, c)| !c.is_blank()) .unwrap() .0, @@ -221,7 +223,7 @@ pub fn create_ts_svg( .reference_arrangement_char_to_arrangement_column(*sp4_reference), ) + 1usize, ) - .skip(anti_primary_sp4_minus_one.unwrap_or(0.into()).into()) + .skip(anti_descendant_sp4_minus_one.unwrap_or(0.into()).into()) .find(|(_, c)| !c.is_blank()) .unwrap() .0, @@ -229,27 +231,27 @@ pub fn create_ts_svg( ), }; - if let Some(anti_primary_sp4_minus_one) = anti_primary_sp4_minus_one { - if (anti_primary_sp4 - anti_primary_sp4_minus_one) > ArrangementColumn::ZERO { + if let Some(anti_descendant_sp4_minus_one) = anti_descendant_sp4_minus_one { + if (anti_descendant_sp4 - anti_descendant_sp4_minus_one) > ArrangementColumn::ZERO { arrows.push(Arrow::new_skip( - anti_primary_sp4_minus_one, - anti_primary_sp4, - anti_primary_row, + anti_descendant_sp4_minus_one, + anti_descendant_sp4, + anti_descendant_row, )); } }*/ - let primary_sp4_minus_one = match primary { - TemplateSwitchPrimary::Reference => sp4_reference.checked_sub(1).map(|column| { + let descendant_sp4_minus_one = match descendant { + TemplateSwitchDescendant::Reference => sp4_reference.checked_sub(1).map(|column| { ts_arrangement.reference_arrangement_char_to_arrangement_column(column) + 1usize }), - TemplateSwitchPrimary::Query => sp4_query.checked_sub(1).map(|column| { + TemplateSwitchDescendant::Query => sp4_query.checked_sub(1).map(|column| { ts_arrangement.query_arrangement_char_to_arrangement_column(column) + 1usize }), }; - let (primary_sp1, primary_sp4, primary_row) = match primary { - TemplateSwitchPrimary::Reference => ( + let (descendant_sp1, descendant_sp4, descendant_row) = match descendant { + TemplateSwitchDescendant::Reference => ( ts_arrangement.reference_arrangement_char_to_arrangement_column(*sp1_reference), ts_arrangement .reference() @@ -260,13 +262,13 @@ pub fn create_ts_svg( .reference_arrangement_char_to_arrangement_column(*sp4_reference), ) + 1usize, ) - .skip(primary_sp4_minus_one.unwrap_or(0.into()).into()) + .skip(descendant_sp4_minus_one.unwrap_or(0.into()).into()) .find(|(_, c)| !c.is_blank()) .unwrap() .0, TsArrangementRow::Reference, ), - TemplateSwitchPrimary::Query => ( + TemplateSwitchDescendant::Query => ( ts_arrangement.query_arrangement_char_to_arrangement_column(*sp1_query), ts_arrangement .query() @@ -276,7 +278,7 @@ pub fn create_ts_svg( ts_arrangement.query_arrangement_char_to_arrangement_column(*sp4_query), ) + 1usize, ) - .skip(primary_sp4_minus_one.unwrap_or(0.into()).into()) + .skip(descendant_sp4_minus_one.unwrap_or(0.into()).into()) .find(|(_, c)| !c.is_blank()) .map(|(column, _)| column) .unwrap_or(ts_arrangement.query().len().into()), @@ -284,16 +286,16 @@ pub fn create_ts_svg( ), }; - let forward = sp2_secondary < sp3_secondary; - let (secondary_limit, secondary_offset, inner_row) = match secondary { - TemplateSwitchSecondary::Reference => ( + let forward = sp2_ancestor < sp3_ancestor; + let (ancestor_limit, ancestor_offset, inner_row) = match ancestor { + TemplateSwitchAncestor::Reference => ( ts_arrangement.inner_last_non_blank_column(inner_identifier) + 1usize, ts_arrangement.inner_first_non_blank_column(inner_identifier), TsArrangementRow::Inner { index: inner_identifier, }, ), - TemplateSwitchSecondary::Query => ( + TemplateSwitchAncestor::Query => ( ts_arrangement.inner_last_non_blank_column(inner_identifier) + 1usize, ts_arrangement.inner_first_non_blank_column(inner_identifier), TsArrangementRow::Inner { @@ -305,17 +307,17 @@ pub fn create_ts_svg( let running_number = TS_RUNNING_NUMBER.chars().nth(*ts_index).unwrap(); let number1 = Number::new( format!("{running_number}1"), - primary_sp1, - primary_row, + descendant_sp1, + descendant_row, NumberAlignment::Left, 0.5, ); let number2 = Number::new( format!("{running_number}2"), if forward { - secondary_offset + ancestor_offset } else { - secondary_limit + ancestor_limit }, inner_row, if forward { @@ -328,9 +330,9 @@ pub fn create_ts_svg( let number3 = Number::new( format!("{running_number}3"), if forward { - secondary_limit + ancestor_limit } else { - secondary_offset + ancestor_offset }, inner_row, if forward { @@ -342,22 +344,22 @@ pub fn create_ts_svg( ); let number4 = Number::new( format!("{running_number}4"), - primary_sp4, - primary_row, + descendant_sp4, + descendant_row, NumberAlignment::Right, 0.5, ); if config.render_arrows { arrows.push(Arrow::new_curved( - primary_sp1, + descendant_sp1, number1.width(), - primary_row, + descendant_row, ArrowEndpointDirection::Forward, if forward { - secondary_offset + ancestor_offset } else { - secondary_limit + ancestor_limit }, number2.width(), inner_row, @@ -370,9 +372,9 @@ pub fn create_ts_svg( arrows.push(Arrow::new_curved( if forward { - secondary_limit + ancestor_limit } else { - secondary_offset + ancestor_offset }, number3.width(), inner_row, @@ -381,9 +383,9 @@ pub fn create_ts_svg( } else { ArrowEndpointDirection::Backward }, - primary_sp4, + descendant_sp4, number4.width(), - primary_row, + descendant_row, ArrowEndpointDirection::Backward, )); } @@ -411,9 +413,9 @@ pub fn create_ts_svg( .sequence() .iter_values() .map(render_inner_char( - match reference_inner.template_switch().primary { - TemplateSwitchPrimary::Reference => &reference, - TemplateSwitchPrimary::Query => &query, + match reference_inner.template_switch().descendant { + TemplateSwitchDescendant::Reference => &reference, + TemplateSwitchDescendant::Query => &query, }, )), &SvgLocation { x: 0.0, y }, @@ -468,9 +470,9 @@ pub fn create_ts_svg( .sequence() .iter_values() .map(render_inner_char( - match reference_inner.template_switch().primary { - TemplateSwitchPrimary::Reference => &reference, - TemplateSwitchPrimary::Query => &query, + match reference_inner.template_switch().descendant { + TemplateSwitchDescendant::Reference => &reference, + TemplateSwitchDescendant::Query => &query, }, )), &SvgLocation { x: 0.0, y }, @@ -544,9 +546,9 @@ pub fn create_ts_svg( for (identifier, query_inner) in ts_arrangement.query_inners() { ts_group = ts_group.add(svg_string( query_inner.sequence().iter_values().map(render_inner_char( - match query_inner.template_switch().primary { - TemplateSwitchPrimary::Reference => &reference, - TemplateSwitchPrimary::Query => &query, + match query_inner.template_switch().descendant { + TemplateSwitchDescendant::Reference => &reference, + TemplateSwitchDescendant::Query => &query, }, )), &SvgLocation { x: 0.0, y }, @@ -598,9 +600,9 @@ pub fn create_ts_svg( for (identifier, query_inner) in ts_arrangement.query_complement_inners() { ts_group = ts_group.add(svg_string( query_inner.sequence().iter_values().map(render_inner_char( - match query_inner.template_switch().primary { - TemplateSwitchPrimary::Reference => &reference, - TemplateSwitchPrimary::Query => &query, + match query_inner.template_switch().descendant { + TemplateSwitchDescendant::Reference => &reference, + TemplateSwitchDescendant::Query => &query, }, )), &SvgLocation { x: 0.0, y }, diff --git a/lib_tsshow/src/ts_arrangement.rs b/lib_tsshow/src/ts_arrangement.rs index 82cfceba..0413299b 100644 --- a/lib_tsshow/src/ts_arrangement.rs +++ b/lib_tsshow/src/ts_arrangement.rs @@ -8,7 +8,7 @@ use complement::{ComplementChar, TsComplementArrangement}; use index_types::{ArrangementCharColumn, ArrangementColumn, SourceColumn, TsInnerIdentifier}; use inner::{TsInner, TsInnerArrangement}; use lib_tsalign::a_star_aligner::template_switch_distance::{ - AlignmentType, TemplateSwitchSecondary, + AlignmentType, TemplateSwitchAncestor, }; use log::debug; use source::{SourceChar, TsSourceArrangement}; @@ -279,18 +279,16 @@ impl TsArrangement { self.source.try_query_arrangement_to_source_column(column) } - pub fn secondary_source_to_arrangement_column( + pub fn ancestor_source_to_arrangement_column( &self, column: SourceColumn, - secondary: TemplateSwitchSecondary, + ancestor: TemplateSwitchAncestor, ) -> ArrangementColumn { - match secondary { - TemplateSwitchSecondary::Reference => { + match ancestor { + TemplateSwitchAncestor::Reference => { self.source.reference_source_to_arrangement_column(column) } - TemplateSwitchSecondary::Query => { - self.source.query_source_to_arrangement_column(column) - } + TemplateSwitchAncestor::Query => self.source.query_source_to_arrangement_column(column), } } @@ -333,8 +331,8 @@ impl TsArrangement { inner.template_switch().sp1_reference, ), self.query_arrangement_char_to_source_column(inner.template_switch().sp1_query), - inner.template_switch().sp2_secondary, - inner.template_switch().sp3_secondary, + inner.template_switch().sp2_ancestor, + inner.template_switch().sp3_ancestor, self.reference_arrangement_char_to_source_column( inner.template_switch().sp4_reference, ), @@ -372,8 +370,8 @@ impl TsArrangement { .saturating_sub(1), self.query_arrangement_char_to_source_column(inner.template_switch().sp1_query) .saturating_sub(1), - inner.template_switch().sp2_secondary.saturating_sub(1), - inner.template_switch().sp3_secondary.saturating_sub(1), + inner.template_switch().sp2_ancestor.saturating_sub(1), + inner.template_switch().sp3_ancestor.saturating_sub(1), self.reference_arrangement_char_to_source_column( inner.template_switch().sp4_reference, ) diff --git a/lib_tsshow/src/ts_arrangement/complement.rs b/lib_tsshow/src/ts_arrangement/complement.rs index b49b62e0..b31c9259 100644 --- a/lib_tsshow/src/ts_arrangement/complement.rs +++ b/lib_tsshow/src/ts_arrangement/complement.rs @@ -1,4 +1,4 @@ -use lib_tsalign::a_star_aligner::template_switch_distance::TemplateSwitchSecondary; +use lib_tsalign::a_star_aligner::template_switch_distance::TemplateSwitchAncestor; use tagged_vec::TaggedVec; use super::{ @@ -81,13 +81,13 @@ impl TsComplementArrangement { self.reference_c.len() } - pub fn secondary_complement( + pub fn ancestor_complement( &self, - secondary: TemplateSwitchSecondary, + ancestor: TemplateSwitchAncestor, ) -> &TaggedVec { - match secondary { - TemplateSwitchSecondary::Reference => self.reference_complement(), - TemplateSwitchSecondary::Query => self.query_complement(), + match ancestor { + TemplateSwitchAncestor::Reference => self.reference_complement(), + TemplateSwitchAncestor::Query => self.query_complement(), } } @@ -109,14 +109,14 @@ impl TsComplementArrangement { &mut self.query_c } - pub fn show_secondary_character( + pub fn show_ancestor_character( &mut self, - secondary: TemplateSwitchSecondary, + ancestor: TemplateSwitchAncestor, column: ArrangementColumn, ) { - match secondary { - TemplateSwitchSecondary::Reference => self.show_reference_character(column), - TemplateSwitchSecondary::Query => self.show_query_character(column), + match ancestor { + TemplateSwitchAncestor::Reference => self.show_reference_character(column), + TemplateSwitchAncestor::Query => self.show_query_character(column), } } @@ -128,14 +128,14 @@ impl TsComplementArrangement { self.query_c[column].show(); } - pub fn secondary_to_lower_case( + pub fn ancestor_to_lower_case( &mut self, - secondary: TemplateSwitchSecondary, + ancestor: TemplateSwitchAncestor, column: ArrangementColumn, ) { - match secondary { - TemplateSwitchSecondary::Reference => self.reference_complement_to_lower_case(column), - TemplateSwitchSecondary::Query => self.query_complement_to_lower_case(column), + match ancestor { + TemplateSwitchAncestor::Reference => self.reference_complement_to_lower_case(column), + TemplateSwitchAncestor::Query => self.query_complement_to_lower_case(column), } } @@ -147,14 +147,14 @@ impl TsComplementArrangement { self.query_c[column].to_lower_case(); } - pub fn insert_secondary_complement_gap( + pub fn insert_ancestor_complement_gap( &mut self, - secondary: TemplateSwitchSecondary, + ancestor: TemplateSwitchAncestor, column: ArrangementColumn, ) { - match secondary { - TemplateSwitchSecondary::Reference => self.insert_reference_complement_gap(column), - TemplateSwitchSecondary::Query => self.insert_query_complement_gap(column), + match ancestor { + TemplateSwitchAncestor::Reference => self.insert_reference_complement_gap(column), + TemplateSwitchAncestor::Query => self.insert_query_complement_gap(column), } } diff --git a/lib_tsshow/src/ts_arrangement/inner.rs b/lib_tsshow/src/ts_arrangement/inner.rs index aaa7e15d..bb3c74c6 100644 --- a/lib_tsshow/src/ts_arrangement/inner.rs +++ b/lib_tsshow/src/ts_arrangement/inner.rs @@ -1,7 +1,7 @@ use std::iter; use lib_tsalign::a_star_aligner::template_switch_distance::{ - AlignmentType, TemplateSwitchSecondary, + AlignmentType, TemplateSwitchAncestor, }; use log::{trace, warn}; use tagged_vec::TaggedVec; @@ -71,41 +71,41 @@ impl TsInnerArrangement { ); trace!("inner_alignment: {:?}", ts.inner_alignment.cigar()); - let (mut sp2_secondary, mut sp3_secondary) = match ts.secondary { - TemplateSwitchSecondary::Reference => ( + let (mut sp2_ancestor, mut sp3_ancestor) = match ts.ancestor { + TemplateSwitchAncestor::Reference => ( source_arrangement - .try_reference_source_to_arrangement_column(ts.sp2_secondary) + .try_reference_source_to_arrangement_column(ts.sp2_ancestor) .unwrap_or_else(|| { trace!("SP2 is at reference end"); source_arrangement.reference().len().into() }), source_arrangement - .try_reference_source_to_arrangement_column(ts.sp3_secondary) + .try_reference_source_to_arrangement_column(ts.sp3_ancestor) .unwrap_or_else(|| { trace!("SP3 is at reference end"); source_arrangement.reference().len().into() }), ), - TemplateSwitchSecondary::Query => ( + TemplateSwitchAncestor::Query => ( source_arrangement - .try_query_source_to_arrangement_column(ts.sp2_secondary) + .try_query_source_to_arrangement_column(ts.sp2_ancestor) .unwrap_or_else(|| { trace!("SP2 is at query end"); source_arrangement.query().len().into() }), source_arrangement - .try_query_source_to_arrangement_column(ts.sp3_secondary) + .try_query_source_to_arrangement_column(ts.sp3_ancestor) .unwrap_or_else(|| { trace!("SP3 is at query end"); source_arrangement.query().len().into() }), ), }; - let forward = sp2_secondary < sp3_secondary; + let forward = sp2_ancestor < sp3_ancestor; trace!( - "sp2_secondary: {} -> {sp2_secondary}; sp3_secondary: {} -> {sp3_secondary}; {}", - ts.sp2_secondary, - ts.sp3_secondary, + "sp2_ancestor: {} -> {sp2_ancestor}; sp3_ancestor: {} -> {sp3_ancestor}; {}", + ts.sp2_ancestor, + ts.sp3_ancestor, if forward { "forward" } else { "reverse" } ); @@ -113,9 +113,9 @@ impl TsInnerArrangement { let mut inner = TaggedVec::::default(); inner.extend(iter::repeat_n( InnerChar::Blank, - sp3_secondary.min(sp2_secondary).into(), + sp3_ancestor.min(sp2_ancestor).into(), )); - let mut current_arrangement_column = sp3_secondary.min(sp2_secondary); + let mut current_arrangement_column = sp3_ancestor.min(sp2_ancestor); debug_assert!(current_arrangement_column.primitive() < source_arrangement.width()); debug_assert!(current_arrangement_column.primitive() < complement_arrangement.width()); @@ -125,13 +125,13 @@ impl TsInnerArrangement { match alignment_type { AlignmentType::SecondaryInsertion => { let is_gap = loop { - if source_arrangement.secondary(ts.secondary).len() + if source_arrangement.ancestor(ts.ancestor).len() <= current_arrangement_column.primitive() { break false; } - let c = source_arrangement.secondary(ts.secondary) + let c = source_arrangement.ancestor(ts.ancestor) [current_arrangement_column]; if c.is_gap() || c.is_source_char() { @@ -143,8 +143,8 @@ impl TsInnerArrangement { }; if !is_gap { - source_arrangement.insert_secondary_gap_with_minimum_copy_depth( - ts.secondary, + source_arrangement.insert_ancestor_gap_with_minimum_copy_depth( + ts.ancestor, current_arrangement_column, ); @@ -155,14 +155,14 @@ impl TsInnerArrangement { .insert(current_arrangement_column, InnerChar::Blank); } - sp3_secondary += 1; + sp3_ancestor += 1; } inner.push(source_inner.next().unwrap().into()); current_arrangement_column += 1; } AlignmentType::SecondaryDeletion => { - while !source_arrangement.secondary(ts.secondary) + while !source_arrangement.ancestor(ts.ancestor) [current_arrangement_column] .is_source_char() { @@ -171,14 +171,14 @@ impl TsInnerArrangement { } inner.push(InnerChar::Gap { - copy_depth: source_arrangement.secondary(ts.secondary) + copy_depth: source_arrangement.ancestor(ts.ancestor) [current_arrangement_column] .copy_depth(), }); current_arrangement_column += 1; } AlignmentType::SecondarySubstitution | AlignmentType::SecondaryMatch => { - while !source_arrangement.secondary(ts.secondary) + while !source_arrangement.ancestor(ts.ancestor) [current_arrangement_column] .is_source_char() { @@ -188,8 +188,8 @@ impl TsInnerArrangement { let mut inner_char: InnerChar = source_inner.next().unwrap().into(); if alignment_type == AlignmentType::SecondarySubstitution { - source_arrangement.secondary_to_lower_case( - ts.secondary, + source_arrangement.ancestor_to_lower_case( + ts.ancestor, current_arrangement_column, ); inner_char.to_lower_case(); @@ -202,14 +202,14 @@ impl TsInnerArrangement { } } - // We skip further secondary non-source chars for the assertion below. + // We skip further ancestor non-source chars for the assertion below. while current_arrangement_column.primitive() < source_arrangement.width() - && !source_arrangement.secondary(ts.secondary)[current_arrangement_column] + && !source_arrangement.ancestor(ts.ancestor)[current_arrangement_column] .is_source_char() { current_arrangement_column += 1; } - assert_eq!(current_arrangement_column, sp3_secondary); + assert_eq!(current_arrangement_column, sp3_ancestor); } else { // Align inner against source complement in reverse. let mut source_inner = source_inner.rev(); @@ -220,14 +220,14 @@ impl TsInnerArrangement { AlignmentType::SecondaryInsertion => { let is_gap = loop { if complement_arrangement - .secondary_complement(ts.secondary) + .ancestor_complement(ts.ancestor) .len() <= current_arrangement_column.primitive() { break false; } - let c = complement_arrangement.secondary_complement(ts.secondary) + let c = complement_arrangement.ancestor_complement(ts.ancestor) [current_arrangement_column]; if c.is_gap() || c.is_source_char() { @@ -240,8 +240,8 @@ impl TsInnerArrangement { }; if !is_gap { - complement_arrangement.insert_secondary_complement_gap( - ts.secondary, + complement_arrangement.insert_ancestor_complement_gap( + ts.ancestor, current_arrangement_column, ); @@ -252,14 +252,14 @@ impl TsInnerArrangement { .insert(current_arrangement_column, InnerChar::Blank); } - sp2_secondary += 1; + sp2_ancestor += 1; } inner.push(source_inner.next().unwrap().into()); current_arrangement_column += 1; } AlignmentType::SecondaryDeletion => { - while !complement_arrangement.secondary_complement(ts.secondary) + while !complement_arrangement.ancestor_complement(ts.ancestor) [current_arrangement_column] .is_source_char() { @@ -268,16 +268,16 @@ impl TsInnerArrangement { } complement_arrangement - .show_secondary_character(ts.secondary, current_arrangement_column); + .show_ancestor_character(ts.ancestor, current_arrangement_column); inner.push(InnerChar::Gap { - copy_depth: source_arrangement.secondary(ts.secondary) + copy_depth: source_arrangement.ancestor(ts.ancestor) [current_arrangement_column] .copy_depth(), }); current_arrangement_column += 1; } AlignmentType::SecondarySubstitution | AlignmentType::SecondaryMatch => { - while !source_arrangement.secondary(ts.secondary) + while !source_arrangement.ancestor(ts.ancestor) [current_arrangement_column] .is_source_char() { @@ -286,12 +286,12 @@ impl TsInnerArrangement { } complement_arrangement - .show_secondary_character(ts.secondary, current_arrangement_column); + .show_ancestor_character(ts.ancestor, current_arrangement_column); let mut inner_char: InnerChar = source_inner.next().unwrap().into(); if alignment_type == AlignmentType::SecondarySubstitution { - complement_arrangement.secondary_to_lower_case( - ts.secondary, + complement_arrangement.ancestor_to_lower_case( + ts.ancestor, current_arrangement_column, ); inner_char.to_lower_case(); @@ -304,14 +304,14 @@ impl TsInnerArrangement { } } - // We skip further secondary non-source chars for the assertion below. + // We skip further ancestor non-source chars for the assertion below. while current_arrangement_column.primitive() < source_arrangement.width() - && !source_arrangement.secondary(ts.secondary)[current_arrangement_column] + && !source_arrangement.ancestor(ts.ancestor)[current_arrangement_column] .is_source_char() { current_arrangement_column += 1; } - assert_eq!(current_arrangement_column, sp2_secondary); + assert_eq!(current_arrangement_column, sp2_ancestor); } let suffix_blanks = @@ -413,9 +413,9 @@ impl TsInnerArrangement { } } - let is_reference = match ts.secondary { - TemplateSwitchSecondary::Reference => true, - TemplateSwitchSecondary::Query => false, + let is_reference = match ts.ancestor { + TemplateSwitchAncestor::Reference => true, + TemplateSwitchAncestor::Query => false, }; result .inners diff --git a/lib_tsshow/src/ts_arrangement/source.rs b/lib_tsshow/src/ts_arrangement/source.rs index d031cd95..a8721e9e 100644 --- a/lib_tsshow/src/ts_arrangement/source.rs +++ b/lib_tsshow/src/ts_arrangement/source.rs @@ -3,8 +3,8 @@ use std::{cmp::Ordering, iter}; use lib_tsalign::a_star_aligner::{ alignment_result::alignment::Alignment, template_switch_distance::{ - AlignmentType, EqualCostRange, TemplateSwitchDirection, TemplateSwitchPrimary, - TemplateSwitchSecondary, + AlignmentType, EqualCostRange, TemplateSwitchAncestor, TemplateSwitchDescendant, + TemplateSwitchDirection, }, }; use log::{debug, trace}; @@ -141,8 +141,8 @@ impl TsSourceArrangement { current_query_index += 1; } AlignmentType::TemplateSwitchEntrance { - primary, - secondary, + descendant, + ancestor, direction, first_offset, equal_cost_range, @@ -150,8 +150,8 @@ impl TsSourceArrangement { } => { template_switches_out.extend([result.align_ts( ts_index, - primary, - secondary, + descendant, + ancestor, direction, first_offset, equal_cost_range, @@ -218,8 +218,8 @@ impl TsSourceArrangement { fn align_ts( &mut self, ts_index: usize, - ts_primary: TemplateSwitchPrimary, - ts_secondary: TemplateSwitchSecondary, + ts_descendant: TemplateSwitchDescendant, + ts_ancestor: TemplateSwitchAncestor, ts_direction: TemplateSwitchDirection, first_offset: isize, equal_cost_range: EqualCostRange, @@ -231,8 +231,8 @@ impl TsSourceArrangement { let sp1_reference = self.reference_arrangement_to_arrangement_char_column(*current_reference_index); let sp1_query = self.query_arrangement_to_arrangement_char_column(*current_query_index); - let sp2_secondary = match ts_secondary { - TemplateSwitchSecondary::Reference => { + let sp2_ancestor = match ts_ancestor { + TemplateSwitchAncestor::Reference => { let source_current_reference_index = self.reference_arrangement_to_source_column(*current_reference_index); let adjusted_source_current_reference_index = @@ -246,7 +246,7 @@ impl TsSourceArrangement { ); adjusted_source_current_reference_index } - TemplateSwitchSecondary::Query => { + TemplateSwitchAncestor::Query => { let source_current_query_index = self.query_arrangement_to_source_column(*current_query_index); let adjusted_source_current_query_index = source_current_query_index @@ -261,56 +261,58 @@ impl TsSourceArrangement { } } + first_offset; trace!("first_offset: {first_offset}"); - trace!("sp2_secondary: {sp2_secondary}"); + trace!("sp2_ancestor: {sp2_ancestor}"); - let mut sp3_secondary = sp2_secondary; - let mut primary_inner_length = 0; + let mut sp3_ancestor = sp2_ancestor; + let mut descendant_inner_length = 0; let mut inner_alignment = Alignment::new(); - let anti_primary_gap = loop { + let anti_descendant_gap = loop { let alignment_type = alignment.next().unwrap_or_else(|| unreachable!()); trace!("Secondary alignment type: {alignment_type}"); match alignment_type { - AlignmentType::TemplateSwitchExit { anti_primary_gap } => { - break anti_primary_gap; + AlignmentType::TemplateSwitchExit { + anti_descendant_gap, + } => { + break anti_descendant_gap; } AlignmentType::SecondaryDeletion => { match ts_direction { - TemplateSwitchDirection::Forward => sp3_secondary += 1, - TemplateSwitchDirection::Reverse => sp3_secondary -= 1, + TemplateSwitchDirection::Forward => sp3_ancestor += 1, + TemplateSwitchDirection::Reverse => sp3_ancestor -= 1, } inner_alignment.push(alignment_type); } AlignmentType::SecondarySubstitution | AlignmentType::SecondaryMatch => { match ts_direction { - TemplateSwitchDirection::Forward => sp3_secondary += 1, - TemplateSwitchDirection::Reverse => sp3_secondary -= 1, + TemplateSwitchDirection::Forward => sp3_ancestor += 1, + TemplateSwitchDirection::Reverse => sp3_ancestor -= 1, } - primary_inner_length += 1; + descendant_inner_length += 1; inner_alignment.push(alignment_type); } AlignmentType::SecondaryInsertion => { - primary_inner_length += 1; + descendant_inner_length += 1; inner_alignment.push(alignment_type); } AlignmentType::SecondaryRoot => { /* Do nothing */ } _ => unreachable!(), } }; - let sp3_secondary = sp3_secondary; - let primary_inner_length = primary_inner_length; + let sp3_ancestor = sp3_ancestor; + let descendant_inner_length = descendant_inner_length; - let (primary, anti_primary, current_primary_index, current_anti_primary_index) = - match ts_primary { - TemplateSwitchPrimary::Reference => ( + let (descendant, anti_descendant, current_descendant_index, current_anti_descendant_index) = + match ts_descendant { + TemplateSwitchDescendant::Reference => ( &mut self.reference, &mut self.query, current_reference_index, current_query_index, ), - TemplateSwitchPrimary::Query => ( + TemplateSwitchDescendant::Query => ( &mut self.query, &mut self.reference, current_query_index, @@ -320,10 +322,10 @@ impl TsSourceArrangement { // Mark the TS inner in the source arrangement as hidden. // Take a copy of the unhidden characters at the same time. - let inner = primary + let inner = descendant .iter_values_mut() - .skip(current_primary_index.primitive()) - .take(primary_inner_length) + .skip(current_descendant_index.primitive()) + .take(descendant_inner_length) .map(|c| { let result = *c; c.hide(); @@ -331,13 +333,13 @@ impl TsSourceArrangement { }) .collect(); - *current_primary_index += primary_inner_length; + *current_descendant_index += descendant_inner_length; - let anti_primary_inner_length = if anti_primary_gap < 0 { + let anti_descendant_inner_length = if anti_descendant_gap < 0 { // Insert copies. - let duplicate_rev: Vec<_> = anti_primary + let duplicate_rev: Vec<_> = anti_descendant .iter_values() - .take(current_anti_primary_index.primitive()) + .take(current_anti_descendant_index.primitive()) .rev() .filter_map(|c| { if c.is_char() { @@ -346,63 +348,67 @@ impl TsSourceArrangement { None } }) - .take(usize::try_from(-anti_primary_gap).unwrap()) + .take(usize::try_from(-anti_descendant_gap).unwrap()) .collect(); - anti_primary.splice( - *current_anti_primary_index..*current_anti_primary_index, + anti_descendant.splice( + *current_anti_descendant_index..*current_anti_descendant_index, duplicate_rev.into_iter().rev(), ); 0 } else { - *current_anti_primary_index += usize::try_from(anti_primary_gap).unwrap(); - usize::try_from(anti_primary_gap).unwrap() + *current_anti_descendant_index += usize::try_from(anti_descendant_gap).unwrap(); + usize::try_from(anti_descendant_gap).unwrap() }; // Insert spacers. - let mut required_spacer_count = 4usize.saturating_sub(anti_primary_inner_length); + let mut required_spacer_count = 4usize.saturating_sub(anti_descendant_inner_length); - match primary_inner_length.cmp(&anti_primary_inner_length) { + match descendant_inner_length.cmp(&anti_descendant_inner_length) { Ordering::Less => { - let delta = anti_primary_inner_length - .checked_sub(primary_inner_length) + let delta = anti_descendant_inner_length + .checked_sub(descendant_inner_length) .unwrap(); - primary.splice( - *current_primary_index..*current_primary_index, + descendant.splice( + *current_descendant_index..*current_descendant_index, iter::repeat_n(SourceChar::Blank, delta), ); - *current_primary_index += delta; + *current_descendant_index += delta; } Ordering::Equal => { /* Do nothing */ } Ordering::Greater => { - let delta = primary_inner_length - .checked_sub(anti_primary_inner_length) + let delta = descendant_inner_length + .checked_sub(anti_descendant_inner_length) .unwrap(); - anti_primary.splice( - *current_anti_primary_index..*current_anti_primary_index, + anti_descendant.splice( + *current_anti_descendant_index..*current_anti_descendant_index, iter::repeat_n(SourceChar::Spacer, required_spacer_count) .chain(iter::repeat(SourceChar::Blank)) .take(delta), ); required_spacer_count = required_spacer_count.saturating_sub(delta); - *current_anti_primary_index += delta; + *current_anti_descendant_index += delta; } } - primary.splice( - *current_primary_index..*current_primary_index, + descendant.splice( + *current_descendant_index..*current_descendant_index, iter::repeat_n(SourceChar::Blank, required_spacer_count), ); - anti_primary.splice( - *current_anti_primary_index..*current_anti_primary_index, + anti_descendant.splice( + *current_anti_descendant_index..*current_anti_descendant_index, iter::repeat_n(SourceChar::Spacer, required_spacer_count), ); - *current_primary_index += required_spacer_count; - *current_anti_primary_index += required_spacer_count; + *current_descendant_index += required_spacer_count; + *current_anti_descendant_index += required_spacer_count; - let (current_reference_index, current_query_index) = match ts_primary { - TemplateSwitchPrimary::Reference => (current_primary_index, current_anti_primary_index), - TemplateSwitchPrimary::Query => (current_anti_primary_index, current_primary_index), + let (current_reference_index, current_query_index) = match ts_descendant { + TemplateSwitchDescendant::Reference => { + (current_descendant_index, current_anti_descendant_index) + } + TemplateSwitchDescendant::Query => { + (current_anti_descendant_index, current_descendant_index) + } }; let sp4_reference = @@ -411,27 +417,27 @@ impl TsSourceArrangement { TemplateSwitch { index: ts_index, - primary: ts_primary, - secondary: ts_secondary, + descendant: ts_descendant, + ancestor: ts_ancestor, sp1_reference, sp1_query, sp4_reference, sp4_query, - sp2_secondary, - sp3_secondary, + sp2_ancestor, + sp3_ancestor, inner, inner_alignment, equal_cost_range, } } - pub fn secondary( + pub fn ancestor( &self, - secondary: TemplateSwitchSecondary, + ancestor: TemplateSwitchAncestor, ) -> &TaggedVec { - match secondary { - TemplateSwitchSecondary::Reference => self.reference(), - TemplateSwitchSecondary::Query => self.query(), + match ancestor { + TemplateSwitchAncestor::Reference => self.reference(), + TemplateSwitchAncestor::Query => self.query(), } } @@ -448,30 +454,30 @@ impl TsSourceArrangement { self.reference.len() } - pub fn secondary_to_lower_case( + pub fn ancestor_to_lower_case( &mut self, - secondary: TemplateSwitchSecondary, + ancestor: TemplateSwitchAncestor, column: ArrangementColumn, ) { - match secondary { - TemplateSwitchSecondary::Reference => self.reference[column].to_lower_case(), - TemplateSwitchSecondary::Query => self.query[column].to_lower_case(), + match ancestor { + TemplateSwitchAncestor::Reference => self.reference[column].to_lower_case(), + TemplateSwitchAncestor::Query => self.query[column].to_lower_case(), } } - pub fn insert_secondary_gap_with_minimum_copy_depth( + pub fn insert_ancestor_gap_with_minimum_copy_depth( &mut self, - secondary: TemplateSwitchSecondary, + ancestor: TemplateSwitchAncestor, column: ArrangementColumn, ) { - let secondary_sequence = self.secondary(secondary); + let ancestor_sequence = self.ancestor(ancestor); let copy_depth = if column == ArrangementColumn::ZERO { - secondary_sequence[column].copy_depth() - } else if column == ArrangementColumn::from(secondary_sequence.len()) { - secondary_sequence[column - 1usize].copy_depth() + ancestor_sequence[column].copy_depth() + } else if column == ArrangementColumn::from(ancestor_sequence.len()) { + ancestor_sequence[column - 1usize].copy_depth() } else { - let copy_depth_1 = secondary_sequence[column - 1usize].copy_depth(); - let copy_depth_2 = secondary_sequence[column].copy_depth(); + let copy_depth_1 = ancestor_sequence[column - 1usize].copy_depth(); + let copy_depth_2 = ancestor_sequence[column].copy_depth(); if let (Some(copy_depth_1), Some(copy_depth_2)) = (copy_depth_1, copy_depth_2) { Some(copy_depth_1.min(copy_depth_2)) @@ -480,18 +486,18 @@ impl TsSourceArrangement { } }; - self.insert_secondary_gap(secondary, column, copy_depth); + self.insert_ancestor_gap(ancestor, column, copy_depth); } - pub fn insert_secondary_gap( + pub fn insert_ancestor_gap( &mut self, - secondary: TemplateSwitchSecondary, + ancestor: TemplateSwitchAncestor, column: ArrangementColumn, copy_depth: Option, ) { - match secondary { - TemplateSwitchSecondary::Reference => self.insert_reference_gap(column, copy_depth), - TemplateSwitchSecondary::Query => self.insert_query_gap(column, copy_depth), + match ancestor { + TemplateSwitchAncestor::Reference => self.insert_reference_gap(column, copy_depth), + TemplateSwitchAncestor::Query => self.insert_query_gap(column, copy_depth), } } diff --git a/lib_tsshow/src/ts_arrangement/template_switch.rs b/lib_tsshow/src/ts_arrangement/template_switch.rs index 15b6529f..d5b6c719 100644 --- a/lib_tsshow/src/ts_arrangement/template_switch.rs +++ b/lib_tsshow/src/ts_arrangement/template_switch.rs @@ -5,21 +5,21 @@ use super::{ use lib_tsalign::a_star_aligner::{ alignment_result::alignment::Alignment, template_switch_distance::{ - AlignmentType, EqualCostRange, TemplateSwitchPrimary, TemplateSwitchSecondary, + AlignmentType, EqualCostRange, TemplateSwitchAncestor, TemplateSwitchDescendant, }, }; #[derive(Debug, Clone)] pub struct TemplateSwitch { pub index: usize, - pub primary: TemplateSwitchPrimary, - pub secondary: TemplateSwitchSecondary, + pub descendant: TemplateSwitchDescendant, + pub ancestor: TemplateSwitchAncestor, pub sp1_reference: ArrangementCharColumn, pub sp1_query: ArrangementCharColumn, pub sp4_reference: ArrangementCharColumn, pub sp4_query: ArrangementCharColumn, - pub sp2_secondary: SourceColumn, - pub sp3_secondary: SourceColumn, + pub sp2_ancestor: SourceColumn, + pub sp3_ancestor: SourceColumn, pub inner: Vec, pub inner_alignment: Alignment, pub equal_cost_range: EqualCostRange, diff --git a/python_bindings/README.md b/python_bindings/README.md index 3315aab1..ac884fa2 100644 --- a/python_bindings/README.md +++ b/python_bindings/README.md @@ -95,9 +95,9 @@ from tsalign import align, TemplateSwitchEntranceOp, TemplateSwitchExitOp result = align(reference, query) for count, op in result.alignments(): if isinstance(op, TemplateSwitchEntranceOp): - print(f"Template switch: {op.direction}, primary={op.primary}, offset={op.first_offset}") + print(f"Template switch: {op.direction}, descendant={op.descendant}, offset={op.first_offset}") elif isinstance(op, TemplateSwitchExitOp): - print(f"Exit, anti-primary gap: {op.anti_primary_gap}") + print(f"Exit, anti-descendant gap: {op.anti_descendant_gap}") else: # SimpleAlignmentOp — a basic edit in the primary or secondary track print(f"{count}x {op.kind}") diff --git a/python_bindings/python/tsalign/_types.py b/python_bindings/python/tsalign/_types.py index 5cfb4332..932b8271 100644 --- a/python_bindings/python/tsalign/_types.py +++ b/python_bindings/python/tsalign/_types.py @@ -34,8 +34,8 @@ class TemplateSwitchEntranceOp: kind: str # always "TemplateSwitchEntrance" first_offset: int - primary: str # "Reference" or "Query" - secondary: str # "Reference" or "Query" + descendant: str # "Reference" or "Query" + ancestor: str # "Reference" or "Query" direction: str # "Forward" or "Reverse" equal_cost_range: dict # {min_start, max_start, min_end, max_end} @@ -45,7 +45,7 @@ class TemplateSwitchExitOp: """Exit from a template switch region.""" kind: str # always "TemplateSwitchExit" - anti_primary_gap: int + anti_descendant_gap: int AlignmentOp = Union[SimpleAlignmentOp, TemplateSwitchEntranceOp, TemplateSwitchExitOp] @@ -60,14 +60,14 @@ def _parse_op(raw: object) -> AlignmentOp: return TemplateSwitchEntranceOp( kind="TemplateSwitchEntrance", first_offset=d["first_offset"], - primary=d["primary"], - secondary=d["secondary"], + descendant=d["descendant"], + ancestor=d["ancestor"], direction=d["direction"], equal_cost_range=d["equal_cost_range"], ) if "TemplateSwitchExit" in raw: return TemplateSwitchExitOp( kind="TemplateSwitchExit", - anti_primary_gap=raw["TemplateSwitchExit"]["anti_primary_gap"], + anti_descendant_gap=raw["TemplateSwitchExit"]["anti_descendant_gap"], ) raise ValueError(f"Unknown alignment op: {raw!r}") diff --git a/sample_tsa_config/config.tsa b/sample_tsa_config/config.tsa index 23f0b626..0b0ac66b 100644 --- a/sample_tsa_config/config.tsa +++ b/sample_tsa_config/config.tsa @@ -32,11 +32,11 @@ LengthDifference -inf -100 101 inf 0 inf -ForwardAntiPrimaryGap +ForwardAntiDescendantGap -inf 1 0 inf -ReverseAntiPrimaryGap +ReverseAntiDescendantGap -inf 0 diff --git a/test_files/config/bench/config.tsa b/test_files/config/bench/config.tsa index fe672639..8a2776fc 100644 --- a/test_files/config/bench/config.tsa +++ b/test_files/config/bench/config.tsa @@ -32,11 +32,11 @@ LengthDifference -inf -100 -20 -10 11 21 101 inf 4 2 0 2 4 inf -ForwardAntiPrimaryGap +ForwardAntiDescendantGap -inf 1 0 inf -ReverseAntiPrimaryGap +ReverseAntiDescendantGap -inf 0 diff --git a/test_files/config/chainalign/config.tsa b/test_files/config/chainalign/config.tsa index 1bbe3b1f..f0479d90 100644 --- a/test_files/config/chainalign/config.tsa +++ b/test_files/config/chainalign/config.tsa @@ -32,11 +32,11 @@ LengthDifference -inf -100 -20 -10 11 21 101 inf 0 0 0 0 0 inf -ForwardAntiPrimaryGap +ForwardAntiDescendantGap -inf 1 0 inf -ReverseAntiPrimaryGap +ReverseAntiDescendantGap -inf 0 diff --git a/test_files/config/chainalignn/config.tsa b/test_files/config/chainalignn/config.tsa index dd78debf..c0eaf007 100644 --- a/test_files/config/chainalignn/config.tsa +++ b/test_files/config/chainalignn/config.tsa @@ -32,11 +32,11 @@ LengthDifference -inf -100 -20 -10 11 21 101 inf 0 0 0 0 0 inf -ForwardAntiPrimaryGap +ForwardAntiDescendantGap -inf 1 0 inf -ReverseAntiPrimaryGap +ReverseAntiDescendantGap -inf 0 diff --git a/test_files/config/experiments/config.tsa b/test_files/config/experiments/config.tsa index 650fcb81..ebf6605b 100644 --- a/test_files/config/experiments/config.tsa +++ b/test_files/config/experiments/config.tsa @@ -32,11 +32,11 @@ LengthDifference -inf -100 -20 -10 11 21 101 inf 4 2 0 2 4 inf -ForwardAntiPrimaryGap +ForwardAntiDescendantGap -inf 1 0 inf -ReverseAntiPrimaryGap +ReverseAntiDescendantGap -inf 0 diff --git a/test_files/config/no_intra_forward_jump/config.tsa b/test_files/config/no_intra_forward_jump/config.tsa index a40b2403..5261be7f 100644 --- a/test_files/config/no_intra_forward_jump/config.tsa +++ b/test_files/config/no_intra_forward_jump/config.tsa @@ -32,11 +32,11 @@ LengthDifference -inf -100 -20 -10 11 21 101 inf 4 2 0 2 4 inf -ForwardAntiPrimaryGap +ForwardAntiDescendantGap -inf 1 0 inf -ReverseAntiPrimaryGap +ReverseAntiDescendantGap -inf 0 diff --git a/test_files/config/range/config.tsa b/test_files/config/range/config.tsa index 9b45b925..9c03a965 100644 --- a/test_files/config/range/config.tsa +++ b/test_files/config/range/config.tsa @@ -32,11 +32,11 @@ LengthDifference -inf -100 101 inf 0 inf -ForwardAntiPrimaryGap +ForwardAntiDescendantGap -inf 1 0 inf -ReverseAntiPrimaryGap +ReverseAntiDescendantGap -inf 0 diff --git a/test_files/config/small/config.tsa b/test_files/config/small/config.tsa index eb14122a..2daac553 100644 --- a/test_files/config/small/config.tsa +++ b/test_files/config/small/config.tsa @@ -32,11 +32,11 @@ LengthDifference -inf -100 11 inf 0 inf -ForwardAntiPrimaryGap +ForwardAntiDescendantGap -inf 1 0 inf -ReverseAntiPrimaryGap +ReverseAntiDescendantGap -inf 0 From 75ecfdd43b66e2991719b2ce0a53c2ddf7e767f2 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt <61014855+sebschmi@users.noreply.github.com> Date: Wed, 27 May 2026 10:33:10 +0300 Subject: [PATCH 2/4] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../src/a_star_aligner/template_switch_distance/display.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs b/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs index bc448d85..59024225 100644 --- a/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs +++ b/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs @@ -130,7 +130,7 @@ impl Display for Identifier { } => { write!( f, - "TemplateSwitchEntrance({entrance_reference_index}R, {entrance_query_index}Q, {template_switch_descendant}D, {template_switch_ancestor}A, {template_switch_direction}D, {template_switch_first_offset}O)", + "TemplateSwitchEntrance(Ref={entrance_reference_index}, Query={entrance_query_index}, Desc={template_switch_descendant}, Anc={template_switch_ancestor}, Dir={template_switch_direction}, Offset={template_switch_first_offset})", ) } From d8645bd70a5c88d16677a81ca4ca721b08391247 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Wed, 27 May 2026 10:34:22 +0300 Subject: [PATCH 3/4] Fix forgotten renaming. --- .../a_star_aligner/template_switch_distance/display.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs b/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs index 59024225..4b4f0348 100644 --- a/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs +++ b/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs @@ -166,15 +166,15 @@ impl Display for Identifier { template_switch_descendant, template_switch_ancestor, template_switch_direction, - descendant_index: primary_index, - anti_descendant_gap: anti_primary_gap, + descendant_index, + anti_descendant_gap, } => write!( f, - "TemplateSwitchExit({}R, {}Q, {}P, {}G, {}, {}, {})", + "TemplateSwitchExit({}R, {}Q, {}D, {}G, {}, {}, {})", entrance_reference_index, entrance_query_index, - primary_index, - anti_primary_gap, + descendant_index, + anti_descendant_gap, template_switch_descendant, template_switch_ancestor, template_switch_direction, From 26e191fc8d12831b7f269249665e14e17fafaa59 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Wed, 27 May 2026 10:36:44 +0300 Subject: [PATCH 4/4] Fix forgotten renamings. --- .../src/a_star_aligner/template_switch_distance/display.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs b/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs index 4b4f0348..45970276 100644 --- a/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs +++ b/lib_tsalign/src/a_star_aligner/template_switch_distance/display.rs @@ -147,7 +147,7 @@ impl Display for Identifier { gap_type, } => write!( f, - "Secondary({}R, {}Q, {}L, {}P, {}S, {}, {}, {}, {})", + "Secondary({}R, {}Q, {}L, {}D, {}S, {}, {}, {}, {})", entrance_reference_index, entrance_query_index, length,