1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/// Data structure for fiberseq data
pub mod fiber;

/// Add and remove base modifications from a bam record
pub mod basemods;
/// Center fiberseq information around a reference position
pub mod center;
#[cfg(feature = "cli")]
/// Command line interface for fibertools-rs.
pub mod cli;
/// Extract fiberseq data into plain text formats
pub mod extract;
/// Add nucleosomes to a bam file
pub mod nucleosomes;
#[cfg(feature = "predict")]
/// m6A prediction
pub mod predict_m6a;
/// Remove base modifications from a bam record
pub mod strip_basemods;

/// add fire data
pub mod fire;

/// add decorators
pub mod decorator;

pub mod footprint;

pub mod bamlift;

pub mod bio_io;

pub mod bamranges;

use anyhow::Result;
use bio_io::*;
#[cfg(feature = "predict")]
use itertools::Itertools;
use rust_htslib::{bam, bam::Read};
use std::env;
use std::io::Write;

pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub const GIT_HASH: &str = env!("CARGO_GIT_HASH");
pub const LONG_VERSION: &str = env!("CARGO_LONG_VERSION");
// if this string (bar)gets too long it displays weird when writing to stdout
const PROGRESS_STYLE: &str =
    "[{elapsed_precise:.yellow}] {bar:>35.cyan/blue} {human_pos:>5.cyan}/{human_len:.blue} {percent:>3.green}% {per_sec:<10.cyan}";

/// COLORS
pub const NUC_COLOR: &str = "169,169,169";
pub const M6A_COLOR: &str = "128,0,128";
pub const CPG_COLOR: &str = "139,69,19";
pub const LINKER_COLOR: &str = "147,112,219";
pub const FIRE_COLORS: [(f32, &str); 9] = [
    (1.0, "139,0,0"),
    (2.0, "175,0,0"),
    (3.0, "200,0,0"),
    (4.0, "225,0,0"),
    (5.0, "255,0,0"),
    (10.0, "255,140,0"),
    (25.0, "225,225,0"),
    (100.0, LINKER_COLOR),
    (200.0, NUC_COLOR),
];

/// unzip a vector of tuples
pub fn unzip_to_vectors<T, U>(vec: Vec<(T, U)>) -> (Vec<T>, Vec<U>) {
    vec.into_iter().unzip()
}

/// join a vector with commas
pub fn join_by_str<'a, I, Z>(vals: I, sep: &str) -> String
where
    I: IntoIterator<Item = Z>,
    Z: ToString + 'a,
{
    vals.into_iter().map(|v| v.to_string() + sep).collect()
}

/// join a vector with commas
pub fn join_by_str_option(vals: &[Option<i64>], sep: &str) -> String {
    vals.iter()
        .map(|v| match v {
            Some(v) => v.to_string(),
            None => String::from("NA"),
        })
        .map(|v| v + sep)
        .collect()
}

/// join a vector with commas
pub fn join_by_str_option_can_skip(vals: &[Option<i64>], sep: &str, skip_none: bool) -> String {
    vals.iter()
        .map(|v| match v {
            Some(v) => v.to_string(),
            None => {
                if skip_none {
                    String::from("")
                } else {
                    String::from("NA")
                }
            }
        })
        .filter(|v| !v.is_empty())
        .map(|v| v + sep)
        .collect()
}

/// clear kinetics from a hifi bam
pub fn clear_kinetics(bam: &mut bam::Reader, out: &mut bam::Writer) {
    let bar = bio_io::no_length_progress_bar();
    for rec in bam.records() {
        let mut record = rec.unwrap();
        record.remove_aux(b"fp").unwrap_or(());
        record.remove_aux(b"fi").unwrap_or(());
        record.remove_aux(b"rp").unwrap_or(());
        record.remove_aux(b"ri").unwrap_or(());
        out.write(&record).unwrap();
        bar.inc_length(1);
        bar.inc(1);
    }
    bar.finish();
}

/// Write to a bam file.
pub fn bam_writer(out: &str, template_bam: &bam::Reader, threads: usize) -> bam::Writer {
    let program_name = "fibertools-rs";
    let program_id = "ft";
    let program_version = VERSION;
    program_bam_writer(
        out,
        template_bam,
        threads,
        program_name,
        program_id,
        program_version,
    )
}