use anyhow::Context; use std::fs; use uuid::Uuid; use crate::runners::{run_wait, CommandRun, RunReport}; #[derive(Debug)] pub struct BcftoolsConfig { pub bin: String, pub threads: u8, } impl Default for BcftoolsConfig { fn default() -> Self { Self { bin: "/data/tools/bcftools-1.21/bcftools".to_string(), threads: 20, } } } pub fn bcftools_keep_pass( input: &str, output: &str, config: BcftoolsConfig, ) -> anyhow::Result { let tmp_file = format!("/tmp/{}", Uuid::new_v4()); // First sort let mut cmd_run = CommandRun::new(&config.bin, &["sort", input, "-o", &tmp_file]); let _ = run_wait(&mut cmd_run)?; // Then filter let mut cmd_run = CommandRun::new( &config.bin, &[ "view", "--write-index", "--threads", &config.threads.to_string(), "-i", "FILTER='PASS'", &tmp_file, "-o", output, ], ); let res = run_wait(&mut cmd_run)?; fs::remove_file(tmp_file)?; Ok(res) } pub fn bcftools_concat( inputs: Vec, output: &str, config: BcftoolsConfig, ) -> anyhow::Result { let tmp_file = format!("/tmp/{}", Uuid::new_v4()); fs::write(&tmp_file, inputs.join("\n"))?; let args = [ "concat", "--write-index", "--threads", &config.threads.to_string(), "-a", "-D", "-f", &tmp_file, "-o", output, ]; // Then filter let mut cmd_run = CommandRun::new(&config.bin, &args); let res = run_wait(&mut cmd_run)?; fs::remove_file(tmp_file)?; Ok(res) } pub fn bcftools_keep_only_in_a(a: &str, b: &str, out: &str, config: &BcftoolsConfig) -> anyhow::Result<()> { let args = ["isec", "-C", "-w", "1", a, b, "-o", out]; let mut cmd_run = CommandRun::new(&config.bin, &args); let _ = run_wait(&mut cmd_run).context(format!( "Error while running bcftools isec {}", args.join(" ") ))?; Ok(()) }