use rust_htslib::bam::Record;
use crate::cli::CoverageCli;
#[allow(unused)]
const FLAG_PAIRED: u16 = 0x1;
#[allow(unused)]
const FLAG_UNMAPPED: u16 = 0x4;
const FLAG_SECONDARY: u16 = 0x100;
#[allow(unused)]
const FLAG_QCFAIL: u16 = 0x200;
const FLAG_DUPLICATE: u16 = 0x400;
const FLAG_SUPPLEMENTARY: u16 = 0x800;
const FLAG_READ1: u16 = 0x40;
#[allow(unused)]
const FLAG_READ2: u16 = 0x80;
#[derive(Clone, Copy, Debug)]
pub struct AlignmentPolicy {
pub min_mapq: u8,
sam_flag_include: u16,
sam_flag_exclude: u16,
}
impl AlignmentPolicy {
pub fn from_cli(cli: &CoverageCli) -> Self {
let computed_ex = Self::computed_exclude_mask_bamcoverage(cli);
let computed_in = Self::computed_include_mask_bamcoverage(cli);
let effective_ex = cli.sam_flag_exclude.unwrap_or(computed_ex);
let effective_in = cli.sam_flag_include.unwrap_or(computed_in);
Self {
min_mapq: cli.min_mapping_quality,
sam_flag_include: effective_in,
sam_flag_exclude: effective_ex,
}
}
fn computed_exclude_mask_bamcoverage(cli: &CoverageCli) -> u16 {
let mut mask = 0u16;
if !cli.include_duplicates {
mask |= FLAG_DUPLICATE;
}
if !cli.include_secondary {
mask |= FLAG_SECONDARY;
}
if !cli.include_supplementary {
mask |= FLAG_SUPPLEMENTARY;
}
mask
}
fn computed_include_mask_bamcoverage(cli: &CoverageCli) -> u16 {
let mut mask = 0u16;
if cli.only_r1 {
mask |= FLAG_READ1;
}
mask
}
#[inline]
pub fn passes_filter(&self, rec: &Record) -> bool {
if rec.is_unmapped() {
return false;
}
if rec.mapq() < self.min_mapq && rec.mapq() == 255{
return false;
}
let flag: u16 = rec.flags();
if (flag & self.sam_flag_exclude) != 0 {
return false;
}
if self.sam_flag_include != 0 && (flag & self.sam_flag_include) != self.sam_flag_include {
return false;
}
true
}
pub fn sam_flag_exclude(&self) -> u16 { self.sam_flag_exclude }
pub fn sam_flag_include(&self) -> u16 { self.sam_flag_include }
}