Skip to content

Commit

Permalink
feat: Revised calculation of leading- and trailing-softclips (#375)
Browse files Browse the repository at this point in the history
* feat:refactor_softclips

* set tarpaulin version

* Update rust.yml

* add internal function

* add internal function

* move to CigarString

* Add testcases

* fix tests

* fixed ownership

* refactoring

* fix clippy

* try removing version arg from tarpaulin

---------

Co-authored-by: Felix Wiegand <fxwiegand@gmail.com>
Co-authored-by: Johannes Köster <johannes.koester@uni-due.de>
  • Loading branch information
3 people authored Mar 2, 2023
1 parent 5f4fc6e commit b61dd2c
Showing 1 changed file with 40 additions and 15 deletions.
55 changes: 40 additions & 15 deletions src/bam/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1699,6 +1699,7 @@ custom_derive! {
/// ```
#[cfg_attr(feature = "serde_feature", derive(Serialize, Deserialize))]
#[derive(NewtypeDeref,
NewtypeDerefMut,
NewtypeIndex(usize),
NewtypeIndexMut(usize),
NewtypeFrom,
Expand Down Expand Up @@ -1911,7 +1912,7 @@ impl<'a> IntoIterator for &'a CigarString {
type IntoIter = ::std::slice::Iter<'a, Cigar>;

fn into_iter(self) -> Self::IntoIter {
(&(self.0)).iter()
self.0.iter()
}
}

Expand All @@ -1924,6 +1925,16 @@ impl fmt::Display for CigarString {
}
}

// Get number of leading/trailing softclips if a CigarString taking hardclips into account
fn calc_softclips<'a>(mut cigar: impl DoubleEndedIterator<Item = &'a Cigar>) -> i64 {
match (cigar.next(), cigar.next()) {
(Some(Cigar::HardClip(_)), Some(Cigar::SoftClip(s))) | (Some(Cigar::SoftClip(s)), _) => {
*s as i64
}
_ => 0,
}
}

#[derive(Eq, PartialEq, Clone, Debug)]
pub struct CigarStringView {
inner: CigarString,
Expand Down Expand Up @@ -1960,24 +1971,12 @@ impl CigarStringView {

/// Get number of bases softclipped at the beginning of the alignment.
pub fn leading_softclips(&self) -> i64 {
self.first().map_or(0, |cigar| {
if let Cigar::SoftClip(s) = cigar {
*s as i64
} else {
0
}
})
calc_softclips(self.iter())
}

/// Get number of bases softclipped at the end of the alignment.
pub fn trailing_softclips(&self) -> i64 {
self.last().map_or(0, |cigar| {
if let Cigar::SoftClip(s) = cigar {
*s as i64
} else {
0
}
})
calc_softclips(self.iter().rev())
}

/// Get number of bases hardclipped at the beginning of the alignment.
Expand Down Expand Up @@ -2193,6 +2192,32 @@ mod tests {
assert_eq!(cigar.pos(), 5);
}

#[test]
fn test_cigar_string_leading_softclips() {
let cigar = CigarString(vec![Cigar::SoftClip(10), Cigar::Match(100)]).into_view(0);
assert_eq!(cigar.leading_softclips(), 10);
let cigar2 = CigarString(vec![
Cigar::HardClip(5),
Cigar::SoftClip(10),
Cigar::Match(100),
])
.into_view(0);
assert_eq!(cigar2.leading_softclips(), 10);
}

#[test]
fn test_cigar_string_trailing_softclips() {
let cigar = CigarString(vec![Cigar::Match(100), Cigar::SoftClip(10)]).into_view(0);
assert_eq!(cigar.trailing_softclips(), 10);
let cigar2 = CigarString(vec![
Cigar::Match(100),
Cigar::SoftClip(10),
Cigar::HardClip(5),
])
.into_view(0);
assert_eq!(cigar2.trailing_softclips(), 10);
}

#[test]
fn test_cigar_read_pos() {
let vpos = 5; // variant position
Expand Down

0 comments on commit b61dd2c

Please sign in to comment.