Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: improved readability for read orientation inference #439

Merged
merged 5 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
68 changes: 50 additions & 18 deletions src/bam/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use std::rc::Rc;
use std::slice;
use std::str;
use std::u32;

Check warning on line 17 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

importing legacy numeric constants

warning: importing legacy numeric constants --> src/bam/record.rs:17:5 | 17 | use std::u32; | ^^^^^^^^ | = help: remove this import = note: then `u32::<CONST>` will resolve to the respective associated constant = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#legacy_numeric_constants

use byteorder::{LittleEndian, ReadBytesExt};

Expand Down Expand Up @@ -137,7 +137,7 @@
Record {
inner: {
#[allow(clippy::uninit_assumed_init)]
let mut inner = unsafe { MaybeUninit::uninit().assume_init() };

Check warning on line 140 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / Testing-Features (no-default-features)

the type `hts_sys::bam1_t` does not permit being left uninitialized

Check warning on line 140 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

the type `hts_sys::bam1_t` does not permit being left uninitialized

warning: the type `hts_sys::bam1_t` does not permit being left uninitialized --> src/bam/record.rs:140:42 | 140 | let mut inner = unsafe { MaybeUninit::uninit().assume_init() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | this code causes undefined behavior when executed | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | = note: integers must be initialized = note: `#[warn(invalid_value)]` on by default

Check warning on line 140 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / Testing-Features (all-features)

the type `hts_sys::bam1_t` does not permit being left uninitialized
unsafe {
::libc::memcpy(
&mut inner as *mut htslib::bam1_t as *mut ::libc::c_void,
Expand Down Expand Up @@ -811,7 +811,7 @@
ctag,
b'A' as c_char,
size_of::<u8>() as i32,
[v].as_mut_ptr() as *mut u8,

Check warning on line 814 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

casting raw pointers to the same type and constness is unnecessary (`*mut u8` -> `*mut u8`)

warning: casting raw pointers to the same type and constness is unnecessary (`*mut u8` -> `*mut u8`) --> src/bam/record.rs:814:21 | 814 | [v].as_mut_ptr() as *mut u8, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[v].as_mut_ptr()` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast = note: `#[warn(clippy::unnecessary_cast)]` on by default
),
Aux::I8(v) => htslib::bam_aux_append(
self.inner_ptr_mut(),
Expand All @@ -825,7 +825,7 @@
ctag,
b'C' as c_char,
size_of::<u8>() as i32,
[v].as_mut_ptr() as *mut u8,

Check warning on line 828 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

casting raw pointers to the same type and constness is unnecessary (`*mut u8` -> `*mut u8`)

warning: casting raw pointers to the same type and constness is unnecessary (`*mut u8` -> `*mut u8`) --> src/bam/record.rs:828:21 | 828 | [v].as_mut_ptr() as *mut u8, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[v].as_mut_ptr()` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_cast
),
Aux::I16(v) => htslib::bam_aux_append(
self.inner_ptr_mut(),
Expand Down Expand Up @@ -1088,30 +1088,36 @@
return SequenceReadPairOrientation::None;
}

let (is_reverse, is_first_in_template, is_mate_reverse) = if self.pos() < self.mpos() {
// given record is the left one
let (pos_1, pos_2, fwd_1, fwd_2) = if self.is_first_in_template() {
(
self.is_reverse(),
self.is_first_in_template(),
self.is_mate_reverse(),
self.pos(),
self.mpos(),
!self.is_reverse(),
!self.is_mate_reverse(),
)
} else {
// given record is the right one
(
self.is_mate_reverse(),
self.is_last_in_template(),
self.is_reverse(),
self.mpos(),
self.pos(),
!self.is_mate_reverse(),
!self.is_reverse(),
)
};
match (is_reverse, is_first_in_template, is_mate_reverse) {
(false, false, false) => SequenceReadPairOrientation::F2F1,
(false, false, true) => SequenceReadPairOrientation::F2R1,
(false, true, false) => SequenceReadPairOrientation::F1F2,
(true, false, false) => SequenceReadPairOrientation::R2F1,
(false, true, true) => SequenceReadPairOrientation::F1R2,
(true, false, true) => SequenceReadPairOrientation::R2R1,
(true, true, false) => SequenceReadPairOrientation::R1F2,
(true, true, true) => SequenceReadPairOrientation::R1R2,

if pos_1 < pos_2 {
match (fwd_1, fwd_2) {
(true, true) => SequenceReadPairOrientation::F1F2,
(true, false) => SequenceReadPairOrientation::F1R2,
(false, true) => SequenceReadPairOrientation::R1F2,
(false, false) => SequenceReadPairOrientation::R1R2,
}
} else {
match (fwd_2, fwd_1) {
(true, true) => SequenceReadPairOrientation::F2F1,
(true, false) => SequenceReadPairOrientation::F2R1,
(false, true) => SequenceReadPairOrientation::R2F1,
(false, false) => SequenceReadPairOrientation::R2R1,
}
}
} else {
SequenceReadPairOrientation::None
Expand Down Expand Up @@ -1565,7 +1571,7 @@
self.aux = &self.aux[offset..];
(tag, aux)
})
.map_err(|e| {

Check warning on line 1574 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

using `map_err` over `inspect_err`

warning: using `map_err` over `inspect_err` --> src/bam/record.rs:1574:18 | 1574 | .map_err(|e| { | ^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_inspect = note: `#[warn(clippy::manual_inspect)]` on by default help: try | 1574 ~ .inspect_err(|e| { 1575 | // In the case of an error, we can not safely advance in the aux data, so we terminate the Iteration 1576 ~ self.aux = &[]; |
// In the case of an error, we can not safely advance in the aux data, so we terminate the Iteration
self.aux = &[];
e
Expand Down Expand Up @@ -1620,7 +1626,7 @@

/// Return encoded base. Complexity: O(1).
#[inline]
pub unsafe fn encoded_base_unchecked(&self, i: usize) -> u8 {

Check warning on line 1629 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

unsafe function's docs are missing a `# Safety` section

warning: unsafe function's docs are missing a `# Safety` section --> src/bam/record.rs:1629:5 | 1629 | pub unsafe fn encoded_base_unchecked(&self, i: usize) -> u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc = note: `#[warn(clippy::missing_safety_doc)]` on by default
encoded_base_unchecked(self.encoded, i)
}

Expand All @@ -1628,7 +1634,7 @@
/// Use index based access seq()[i], for checked, safe access.
/// Complexity: O(1).
#[inline]
pub unsafe fn decoded_base_unchecked(&self, i: usize) -> u8 {

Check warning on line 1637 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

unsafe function's docs are missing a `# Safety` section

warning: unsafe function's docs are missing a `# Safety` section --> src/bam/record.rs:1637:5 | 1637 | pub unsafe fn decoded_base_unchecked(&self, i: usize) -> u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc
*decode_base_unchecked(self.encoded_base_unchecked(i))
}

Expand Down Expand Up @@ -2250,7 +2256,7 @@
/// This function allocates memory for the state structure
/// and initializes the iterator to the start of the modification
/// records.
fn new<'a>(r: &'a Record) -> Result<BaseModificationState<'a>> {

Check warning on line 2259 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

the following explicit lifetimes could be elided: 'a

warning: the following explicit lifetimes could be elided: 'a --> src/bam/record.rs:2259:12 | 2259 | fn new<'a>(r: &'a Record) -> Result<BaseModificationState<'a>> { | ^^ ^^ ^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes = note: `#[warn(clippy::needless_lifetimes)]` on by default help: elide the lifetimes | 2259 - fn new<'a>(r: &'a Record) -> Result<BaseModificationState<'a>> { 2259 + fn new(r: &Record) -> Result<BaseModificationState<'_>> { |
let mut bm = unsafe {
BaseModificationState {
record: r,
Expand All @@ -2274,7 +2280,7 @@

let types = bm.recorded();
bm.buffer.reserve(types.len());
return Ok(bm);

Check warning on line 2283 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> src/bam/record.rs:2283:9 | 2283 | return Ok(bm); | ^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return = note: `#[warn(clippy::needless_return)]` on by default help: remove `return` | 2283 - return Ok(bm); 2283 + Ok(bm) |
}

pub fn buffer_next_mods(&mut self) -> Result<usize> {
Expand Down Expand Up @@ -2302,7 +2308,7 @@
// not update the length so needs to be manually set
self.buffer.set_len(ret as usize);

return Ok(ret as usize);

Check warning on line 2311 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> src/bam/record.rs:2311:13 | 2311 | return Ok(ret as usize); | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return help: remove `return` | 2311 - return Ok(ret as usize); 2311 + Ok(ret as usize) |
}
}

Expand All @@ -2327,7 +2333,7 @@
/// and the ascii code for the canonical base.
/// If there are multiple modifications with the same code this will return the data
/// for the first mod. See https://github.com/samtools/htslib/issues/1635
pub fn query_type<'a>(&self, code: i32) -> Result<BaseModificationMetadata> {

Check warning on line 2336 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

this lifetime isn't used in the function definition

warning: this lifetime isn't used in the function definition --> src/bam/record.rs:2336:23 | 2336 | pub fn query_type<'a>(&self, code: i32) -> Result<BaseModificationMetadata> { | ^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_lifetimes = note: `#[warn(clippy::extra_unused_lifetimes)]` on by default
unsafe {
let mut strand: i32 = 0;
let mut implicit: i32 = 0;
Expand All @@ -2342,13 +2348,13 @@
&mut canonical,
);
if ret == -1 {
return Err(Error::BamBaseModificationTypeNotFound);

Check warning on line 2351 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> src/bam/record.rs:2351:17 | 2351 | return Err(Error::BamBaseModificationTypeNotFound); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return help: remove `return` | 2351 - return Err(Error::BamBaseModificationTypeNotFound); 2351 + Err(Error::BamBaseModificationTypeNotFound) |
} else {
return Ok(BaseModificationMetadata {
strand,
implicit,
canonical: canonical.try_into().unwrap(),
});

Check warning on line 2357 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> src/bam/record.rs:2353:17 | 2353 | / return Ok(BaseModificationMetadata { 2354 | | strand, 2355 | | implicit, 2356 | | canonical: canonical.try_into().unwrap(), 2357 | | }); | |__________________^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return help: remove `return` | 2353 ~ Ok(BaseModificationMetadata { 2354 + strand, 2355 + implicit, 2356 + canonical: canonical.try_into().unwrap(), 2357 ~ }) |
}
}
}
Expand All @@ -2369,7 +2375,7 @@
}

impl BaseModificationsPositionIter<'_> {
fn new<'a>(r: &'a Record) -> Result<BaseModificationsPositionIter<'a>> {

Check warning on line 2378 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

the following explicit lifetimes could be elided: 'a

warning: the following explicit lifetimes could be elided: 'a --> src/bam/record.rs:2378:12 | 2378 | fn new<'a>(r: &'a Record) -> Result<BaseModificationsPositionIter<'a>> { | ^^ ^^ ^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes help: elide the lifetimes | 2378 - fn new<'a>(r: &'a Record) -> Result<BaseModificationsPositionIter<'a>> { 2378 + fn new(r: &Record) -> Result<BaseModificationsPositionIter<'_>> { |
let state = BaseModificationState::new(r)?;
Ok(BaseModificationsPositionIter { mod_state: state })
}
Expand All @@ -2378,8 +2384,8 @@
return self.mod_state.recorded();
}

pub fn query_type<'a>(&self, code: i32) -> Result<BaseModificationMetadata> {

Check warning on line 2387 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

this lifetime isn't used in the function definition

warning: this lifetime isn't used in the function definition --> src/bam/record.rs:2387:23 | 2387 | pub fn query_type<'a>(&self, code: i32) -> Result<BaseModificationMetadata> { | ^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_lifetimes
return self.mod_state.query_type(code);

Check warning on line 2388 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> src/bam/record.rs:2388:9 | 2388 | return self.mod_state.query_type(code); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return help: remove `return` | 2388 - return self.mod_state.query_type(code); 2388 + self.mod_state.query_type(code) |
}
}

Expand All @@ -2396,13 +2402,13 @@
match ret {
Ok(num_mods) => {
if num_mods == 0 {
return None;

Check warning on line 2405 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> src/bam/record.rs:2405:21 | 2405 | return None; | ^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return help: remove `return` | 2405 - return None; 2405 + None |
} else {
let data = (self.mod_state.buffer_pos, self.mod_state.buffer.clone());
return Some(Ok(data));

Check warning on line 2408 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> src/bam/record.rs:2408:21 | 2408 | return Some(Ok(data)); | ^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return help: remove `return` | 2408 - return Some(Ok(data)); 2408 + Some(Ok(data)) |
}
}
Err(e) => return Some(Err(e)),

Check warning on line 2411 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> src/bam/record.rs:2411:23 | 2411 | Err(e) => return Some(Err(e)), | ^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return help: remove `return` | 2411 | Err(e) => Some(Err(e)), | ~~~~~~~~~~~~
}
}
}
Expand All @@ -2415,7 +2421,7 @@
}

impl BaseModificationsIter<'_> {
fn new<'a>(r: &'a Record) -> Result<BaseModificationsIter<'a>> {

Check warning on line 2424 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

the following explicit lifetimes could be elided: 'a

warning: the following explicit lifetimes could be elided: 'a --> src/bam/record.rs:2424:12 | 2424 | fn new<'a>(r: &'a Record) -> Result<BaseModificationsIter<'a>> { | ^^ ^^ ^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes help: elide the lifetimes | 2424 - fn new<'a>(r: &'a Record) -> Result<BaseModificationsIter<'a>> { 2424 + fn new(r: &Record) -> Result<BaseModificationsIter<'_>> { |
let state = BaseModificationState::new(r)?;
Ok(BaseModificationsIter {
mod_state: state,
Expand All @@ -2427,8 +2433,8 @@
return self.mod_state.recorded();
}

pub fn query_type<'a>(&self, code: i32) -> Result<BaseModificationMetadata> {

Check warning on line 2436 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

this lifetime isn't used in the function definition

warning: this lifetime isn't used in the function definition --> src/bam/record.rs:2436:23 | 2436 | pub fn query_type<'a>(&self, code: i32) -> Result<BaseModificationMetadata> { | ^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_lifetimes
return self.mod_state.query_type(code);

Check warning on line 2437 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> src/bam/record.rs:2437:9 | 2437 | return self.mod_state.query_type(code); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return help: remove `return` | 2437 - return self.mod_state.query_type(code); 2437 + self.mod_state.query_type(code) |
}
}

Expand Down Expand Up @@ -2462,7 +2468,7 @@
self.mod_state.buffer[self.buffer_idx],
);
self.buffer_idx += 1;
return Some(Ok(data));

Check warning on line 2471 in src/bam/record.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> src/bam/record.rs:2471:9 | 2471 | return Some(Ok(data)); | ^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return help: remove `return` | 2471 - return Some(Ok(data)); 2471 + Some(Ok(data)) |
}
}

Expand Down Expand Up @@ -2844,6 +2850,32 @@
}
}

#[test]
fn test_read_orientation_f2r1() {
let mut bam = Reader::from_path(&"test/test_nonstandard_orientation.sam").unwrap();

for res in bam.records() {
let record = res.unwrap();
assert_eq!(
record.read_pair_orientation(),
SequenceReadPairOrientation::F2R1
);
}
}

#[test]
fn test_read_orientation_supplementary() {
let mut bam = Reader::from_path(&"test/test_orientation_supplementary.sam").unwrap();

for res in bam.records() {
let record = res.unwrap();
assert_eq!(
record.read_pair_orientation(),
SequenceReadPairOrientation::F2R1
);
}
}

#[test]
pub fn test_cigar_parsing_non_ascii_error() {
let cigar_str = "43ጷ";
Expand Down
203 changes: 203 additions & 0 deletions test/test_nonstandard_orientation.sam
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
@HD VN:1.6 SO:coordinate
@SQ SN:1 LN:248956422
@SQ SN:10 LN:133797422
@SQ SN:11 LN:135086622
@SQ SN:12 LN:133275309
@SQ SN:13 LN:114364328
@SQ SN:14 LN:107043718
@SQ SN:15 LN:101991189
@SQ SN:16 LN:90338345
@SQ SN:17 LN:83257441
@SQ SN:18 LN:80373285
@SQ SN:19 LN:58617616
@SQ SN:2 LN:242193529
@SQ SN:20 LN:64444167
@SQ SN:21 LN:46709983
@SQ SN:22 LN:50818468
@SQ SN:3 LN:198295559
@SQ SN:4 LN:190214555
@SQ SN:5 LN:181538259
@SQ SN:6 LN:170805979
@SQ SN:7 LN:159345973
@SQ SN:8 LN:145138636
@SQ SN:9 LN:138394717
@SQ SN:MT LN:16569
@SQ SN:X LN:156040895
@SQ SN:Y LN:57227415
@SQ SN:KI270728.1 LN:1872759
@SQ SN:KI270727.1 LN:448248
@SQ SN:KI270442.1 LN:392061
@SQ SN:KI270729.1 LN:280839
@SQ SN:GL000225.1 LN:211173
@SQ SN:KI270743.1 LN:210658
@SQ SN:GL000008.2 LN:209709
@SQ SN:GL000009.2 LN:201709
@SQ SN:KI270747.1 LN:198735
@SQ SN:KI270722.1 LN:194050
@SQ SN:GL000194.1 LN:191469
@SQ SN:KI270742.1 LN:186739
@SQ SN:GL000205.2 LN:185591
@SQ SN:GL000195.1 LN:182896
@SQ SN:KI270736.1 LN:181920
@SQ SN:KI270733.1 LN:179772
@SQ SN:GL000224.1 LN:179693
@SQ SN:GL000219.1 LN:179198
@SQ SN:KI270719.1 LN:176845
@SQ SN:GL000216.2 LN:176608
@SQ SN:KI270712.1 LN:176043
@SQ SN:KI270706.1 LN:175055
@SQ SN:KI270725.1 LN:172810
@SQ SN:KI270744.1 LN:168472
@SQ SN:KI270734.1 LN:165050
@SQ SN:GL000213.1 LN:164239
@SQ SN:GL000220.1 LN:161802
@SQ SN:KI270715.1 LN:161471
@SQ SN:GL000218.1 LN:161147
@SQ SN:KI270749.1 LN:158759
@SQ SN:KI270741.1 LN:157432
@SQ SN:GL000221.1 LN:155397
@SQ SN:KI270716.1 LN:153799
@SQ SN:KI270731.1 LN:150754
@SQ SN:KI270751.1 LN:150742
@SQ SN:KI270750.1 LN:148850
@SQ SN:KI270519.1 LN:138126
@SQ SN:GL000214.1 LN:137718
@SQ SN:KI270708.1 LN:127682
@SQ SN:KI270730.1 LN:112551
@SQ SN:KI270438.1 LN:112505
@SQ SN:KI270737.1 LN:103838
@SQ SN:KI270721.1 LN:100316
@SQ SN:KI270738.1 LN:99375
@SQ SN:KI270748.1 LN:93321
@SQ SN:KI270435.1 LN:92983
@SQ SN:GL000208.1 LN:92689
@SQ SN:KI270538.1 LN:91309
@SQ SN:KI270756.1 LN:79590
@SQ SN:KI270739.1 LN:73985
@SQ SN:KI270757.1 LN:71251
@SQ SN:KI270709.1 LN:66860
@SQ SN:KI270746.1 LN:66486
@SQ SN:KI270753.1 LN:62944
@SQ SN:KI270589.1 LN:44474
@SQ SN:KI270726.1 LN:43739
@SQ SN:KI270735.1 LN:42811
@SQ SN:KI270711.1 LN:42210
@SQ SN:KI270745.1 LN:41891
@SQ SN:KI270714.1 LN:41717
@SQ SN:KI270732.1 LN:41543
@SQ SN:KI270713.1 LN:40745
@SQ SN:KI270754.1 LN:40191
@SQ SN:KI270710.1 LN:40176
@SQ SN:KI270717.1 LN:40062
@SQ SN:KI270724.1 LN:39555
@SQ SN:KI270720.1 LN:39050
@SQ SN:KI270723.1 LN:38115
@SQ SN:KI270718.1 LN:38054
@SQ SN:KI270317.1 LN:37690
@SQ SN:KI270740.1 LN:37240
@SQ SN:KI270755.1 LN:36723
@SQ SN:KI270707.1 LN:32032
@SQ SN:KI270579.1 LN:31033
@SQ SN:KI270752.1 LN:27745
@SQ SN:KI270512.1 LN:22689
@SQ SN:KI270322.1 LN:21476
@SQ SN:GL000226.1 LN:15008
@SQ SN:KI270311.1 LN:12399
@SQ SN:KI270366.1 LN:8320
@SQ SN:KI270511.1 LN:8127
@SQ SN:KI270448.1 LN:7992
@SQ SN:KI270521.1 LN:7642
@SQ SN:KI270581.1 LN:7046
@SQ SN:KI270582.1 LN:6504
@SQ SN:KI270515.1 LN:6361
@SQ SN:KI270588.1 LN:6158
@SQ SN:KI270591.1 LN:5796
@SQ SN:KI270522.1 LN:5674
@SQ SN:KI270507.1 LN:5353
@SQ SN:KI270590.1 LN:4685
@SQ SN:KI270584.1 LN:4513
@SQ SN:KI270320.1 LN:4416
@SQ SN:KI270382.1 LN:4215
@SQ SN:KI270468.1 LN:4055
@SQ SN:KI270467.1 LN:3920
@SQ SN:KI270362.1 LN:3530
@SQ SN:KI270517.1 LN:3253
@SQ SN:KI270593.1 LN:3041
@SQ SN:KI270528.1 LN:2983
@SQ SN:KI270587.1 LN:2969
@SQ SN:KI270364.1 LN:2855
@SQ SN:KI270371.1 LN:2805
@SQ SN:KI270333.1 LN:2699
@SQ SN:KI270374.1 LN:2656
@SQ SN:KI270411.1 LN:2646
@SQ SN:KI270414.1 LN:2489
@SQ SN:KI270510.1 LN:2415
@SQ SN:KI270390.1 LN:2387
@SQ SN:KI270375.1 LN:2378
@SQ SN:KI270420.1 LN:2321
@SQ SN:KI270509.1 LN:2318
@SQ SN:KI270315.1 LN:2276
@SQ SN:KI270302.1 LN:2274
@SQ SN:KI270518.1 LN:2186
@SQ SN:KI270530.1 LN:2168
@SQ SN:KI270304.1 LN:2165
@SQ SN:KI270418.1 LN:2145
@SQ SN:KI270424.1 LN:2140
@SQ SN:KI270417.1 LN:2043
@SQ SN:KI270508.1 LN:1951
@SQ SN:KI270303.1 LN:1942
@SQ SN:KI270381.1 LN:1930
@SQ SN:KI270529.1 LN:1899
@SQ SN:KI270425.1 LN:1884
@SQ SN:KI270396.1 LN:1880
@SQ SN:KI270363.1 LN:1803
@SQ SN:KI270386.1 LN:1788
@SQ SN:KI270465.1 LN:1774
@SQ SN:KI270383.1 LN:1750
@SQ SN:KI270384.1 LN:1658
@SQ SN:KI270330.1 LN:1652
@SQ SN:KI270372.1 LN:1650
@SQ SN:KI270548.1 LN:1599
@SQ SN:KI270580.1 LN:1553
@SQ SN:KI270387.1 LN:1537
@SQ SN:KI270391.1 LN:1484
@SQ SN:KI270305.1 LN:1472
@SQ SN:KI270373.1 LN:1451
@SQ SN:KI270422.1 LN:1445
@SQ SN:KI270316.1 LN:1444
@SQ SN:KI270340.1 LN:1428
@SQ SN:KI270338.1 LN:1428
@SQ SN:KI270583.1 LN:1400
@SQ SN:KI270334.1 LN:1368
@SQ SN:KI270429.1 LN:1361
@SQ SN:KI270393.1 LN:1308
@SQ SN:KI270516.1 LN:1300
@SQ SN:KI270389.1 LN:1298
@SQ SN:KI270466.1 LN:1233
@SQ SN:KI270388.1 LN:1216
@SQ SN:KI270544.1 LN:1202
@SQ SN:KI270310.1 LN:1201
@SQ SN:KI270412.1 LN:1179
@SQ SN:KI270395.1 LN:1143
@SQ SN:KI270376.1 LN:1136
@SQ SN:KI270337.1 LN:1121
@SQ SN:KI270335.1 LN:1048
@SQ SN:KI270378.1 LN:1048
@SQ SN:KI270379.1 LN:1045
@SQ SN:KI270329.1 LN:1040
@SQ SN:KI270419.1 LN:1029
@SQ SN:KI270336.1 LN:1026
@SQ SN:KI270312.1 LN:998
@SQ SN:KI270539.1 LN:993
@SQ SN:KI270385.1 LN:990
@SQ SN:KI270423.1 LN:981
@SQ SN:KI270392.1 LN:971
@SQ SN:KI270394.1 LN:970
@RG ID:chm SM:chm PL:ILLUMINA
@PG ID:bwa PN:bwa VN:0.7.17-r1188 CL:bwa mem -t 8 -R @RG\tID:chm\tSM:chm\tPL:ILLUMINA resources/genome.fasta results/merged/chm_R1.fastq.gz results/merged/chm_R2.fastq.gz
@PG ID:GATK ApplyBQSR VN:4.1.4.1 CL:ApplyBQSR --output results/recal/chm.sorted.bam --bqsr-recal-file /tmp/tmpuhppums6/recal_table.grp --input results/mapped/chm.sorted.bam --reference resources/genome.fasta --preserve-qscores-less-than 6 --use-original-qualities false --quantize-quals 0 --round-down-quantized false --emit-original-quals false --global-qscore-prior -1.0 --interval-set-rule UNION --interval-padding 0 --interval-exclusion-padding 0 --interval-merging-rule ALL --read-validation-stringency SILENT --seconds-between-progress-updates 10.0 --disable-sequence-dictionary-validation false --create-output-bam-index true --create-output-bam-md5 false --create-output-variant-index true --create-output-variant-md5 false --lenient false --add-output-sam-program-record true --add-output-vcf-command-line true --cloud-prefetch-buffer 40 --cloud-index-prefetch-buffer -1 --disable-bam-index-caching false --sites-only-vcf-output false --help false --version false --showHidden false --verbosity INFO --QUIET false --use-jdk-deflater false --use-jdk-inflater false --gcs-max-retries 20 --gcs-project-for-requester-pays --disable-tool-default-read-filters false PN:GATK ApplyBQSR
@PG ID:samtools PN:samtools PP:GATK ApplyBQSR VN:1.20 CL:samtools view -H chm.bam
@PG ID:samtools.1 PN:samtools PP:samtools VN:1.20 CL:samtools view -b nonstandard_orientation.sam
@PG ID:samtools.2 PN:samtools PP:samtools.1 VN:1.20 CL:samtools view -h test_nonstandard_orientation.bam
HK35WCCXX160124:1:2117:25885:46859 163 1 231 46 113M38S = 351 271 CAACCTCAGTTGACTTGGGGGACAAGGCAGCAGGAGCACCAGACCCCTGCACCACCTCCTTCTGGGTGGGAGATGAGGCAGCAGGAGCACCAGGGCCCTTCACGACCTCTTTCCAGGTGGGGGGGGAGGGAGCAGGGGCAGGAGAGCGCGT =BB?BCBCABD@C@?D@AAABD@CB?B@C@ACABCAAC@BDAC@BCCCBBD@CD@CDCCCEC;BCCCBCCE?CCCBCDCECCECDDCCEA(.<BAADDBFCEA%C=DECEEFB</=C@################################# XA:Z:1,+26345079,15S108M28S,3;1,+26344930,19S102M30S,2; MC:Z:151M MD:Z:90A0G11A9 RG:Z:chm NM:i:3 AS:i:98 XS:i:93
HK35WCCXX160124:1:2117:25885:46859 83 1 351 49 151M = 231 -271 GGGATGAGGTAGCAGCGGCACCAGGGCCCTTCACAACCTCTTTTGAGGTGGGGGACGAGGCAGCAGGAGCACCAGACCCCTGCACCACCTCCTTCTGGGTGGGAGATGAGGCAGCAGGAGCACCAGGGCCCTTCACGACCTCTTTCCAGGT ##########################DA4ADCDCFDDCE;/BB.(10@DCB<CCC/1DCBBCBBDCCDBBCCB>:BBCBBDAABBABBACCADCBCBB?CBBA1BABAAA@@B@AABBAAACB?9BBABA@DDAC2BBBBCBCDBCCFA=? XA:Z:1,-26345048,17S134M,8; MC:Z:113M38S MD:Z:1C7C5G0A28G5T4A46G32A14 RG:Z:chm NM:i:9 AS:i:109 XS:i:94
35 changes: 35 additions & 0 deletions test/test_orientation_supplementary.sam
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@HD VN:1.3 SO:coordinate
@SQ SN:chr10 LN:135374737
@SQ SN:chr11 LN:134452384
@SQ SN:chr12 LN:132349534
@SQ SN:chr13 LN:114142980
@SQ SN:chr14 LN:106368585
@SQ SN:chr15 LN:100338915
@SQ SN:chr16 LN:88827254
@SQ SN:chr17 LN:78774742
@SQ SN:chr18 LN:76117153
@SQ SN:chr19 LN:63811651
@SQ SN:chr1 LN:247249719
@SQ SN:chr20 LN:62435964
@SQ SN:chr21 LN:46944323
@SQ SN:chr22 LN:49691432
@SQ SN:chr2 LN:242951149
@SQ SN:chr3 LN:199501827
@SQ SN:chr4 LN:191273063
@SQ SN:chr5 LN:180857866
@SQ SN:chr6 LN:170899992
@SQ SN:chr7 LN:158821424
@SQ SN:chr8 LN:146274826
@SQ SN:chr9 LN:140273252
@SQ SN:chrM LN:16571
@SQ SN:chrX LN:154913754
@SQ SN:chrY LN:57772954
@RG ID:tumor SM:tumor
@PG ID:bwa PN:bwa VN:0.7.16a-r1187-dirty CL:resources/bwa mem -t 8 -Y -R @RG\tID:tumor\tSM:tumor index/hg18/genome reads/simulated.tumor.1.fastq reads/simulated.tumor.2.fastq
@PG ID:samtools PN:samtools PP:bwa VN:1.20 CL:samtools sort -n -o tests/resources/testcases/test16/tumor.bam.namesorted.bam tests/resources/testcases/test16/tumor.bam
@PG ID:samtools.1 PN:samtools PP:samtools VN:1.20 CL:samtools fixmate tests/resources/testcases/test16/tumor.bam.namesorted.bam tests/resources/testcases/test16/tumor.bam.fixed.bam
@PG ID:samtools.2 PN:samtools PP:samtools.1 VN:1.20 CL:samtools sort -o tests/resources/testcases/test16/tumor.bam tests/resources/testcases/test16/tumor.bam.fixed.bam
@PG ID:samtools.3 PN:samtools PP:samtools.2 VN:1.20 CL:samtools view -H tumor.bam
sim_Som2-5-1_chr1_1_1b5889 163 chr1 938 60 100M = 1143 264 CACTATACCACTTGAATGCTCAGAAGAAAAAAAAAAGAATTCAGAATATGTGTATTAAAATGGGTACAATAATGAGTAAAAAACTTGAAAGAAGCTGGAG GFGDECGFE?AA>FGADEEF)BDC>FDEC5EEBFEEB?D@BGDCAB:FBGGDE;DF-CBDDCD+>:ED@#?=?#>EADE,B#?A#FFC;CC@#:5DBA## NM:i:1 MD:Z:69A30 AS:i:95 XS:i:23 ZT:Z:95,1,72,72,0,0,69,0,1,0,0,0,1379,0 RG:Z:tumor MQ:i:60 MC:Z:59M41S
sim_Som2-5-1_chr1_1_1b5889 83 chr1 1143 60 59M41S = 938 -264 ATCTTTCCTTTATCAACTATTGGTGTTAACCTTTGATTATATTTTTGCATAAGCATACAAAATATTGATCTTTAATTATACTAAGGAATCAATAGCCAAA F:##.##D#DFDA5D#*#:D?E7B?.>?GA>6?=CE:EEBEDAE=AF:5GF:G#ABGDGGAGEG=DAE?FF?GG7AGEG-BDEGDAGEDDEDF=>F5E*@ NM:i:2 MD:Z:2G13A42 AS:i:51 XS:i:20 SA:Z:chr1,73497948,-,58S42M,60,1; ZT:Z:51,2,31,11,0,0,42,0,3,0,0,0,419,0 RG:Z:tumor MQ:i:60 MC:Z:100M
sim_Som2-5-1_chr1_1_1b5889 2131 chr1 1263 60 58S42M = 938 -367 ATCTTTCCTTTATCAACTATTGGTGTTAACCTTTGATTATATTTTTGCATAAGCATACAAAATATTGATCTTTAATTATACTAAGGAATCAATAGCCAAA F:##.##D#DFDA5D#*#:D?E7B?.>?GA>6?=CE:EEBEDAE=AF:5GF:G#ABGDGGAGEG=DAE?FF?GG7AGEG-BDEGDAGEDDEDF=>F5E*@ NM:i:1 MD:Z:40C1 MC:Z:100M AS:i:40 XS:i:0 SA:Z:chr1,73497828,-,59M41S,60,2; ZT:Z:40,1,40,40,0,0,40,0,0,0,0,0,400,0 RG:Z:tumor
Loading