|
|
@@ -1,18 +1,12 @@
|
|
|
use std::{
|
|
|
fs,
|
|
|
- io::{BufRead, BufReader, Read, Write},
|
|
|
+ io::{Read, Write},
|
|
|
path::Path,
|
|
|
- process::{ChildStderr, Command, Stdio},
|
|
|
- sync::{
|
|
|
- mpsc::{self, Sender},
|
|
|
- Arc, Mutex,
|
|
|
- },
|
|
|
- thread,
|
|
|
- time::{Duration, SystemTime},
|
|
|
+ time::SystemTime,
|
|
|
};
|
|
|
|
|
|
use duct::cmd;
|
|
|
-use log::info;
|
|
|
+use log::{info, warn};
|
|
|
|
|
|
pub trait Run {
|
|
|
fn run(self) -> anyhow::Result<()>;
|
|
|
@@ -50,9 +44,7 @@ impl Dorado {
|
|
|
}
|
|
|
fn create_reference_mmi(&self, ref_mmi: &str, ref_fa: &str) -> anyhow::Result<()> {
|
|
|
if !std::path::Path::new(ref_mmi).exists() {
|
|
|
- Command::new("minimap2")
|
|
|
- .args(["-x", "map-ont", "-d", ref_mmi, ref_fa])
|
|
|
- .output()?;
|
|
|
+ cmd!("minimap2", "-x", "map-ont", "-d", ref_mmi, ref_fa).run()?;
|
|
|
}
|
|
|
Ok(())
|
|
|
}
|
|
|
@@ -73,7 +65,6 @@ impl Dorado {
|
|
|
pod_dir: &str,
|
|
|
ref_mmi: &str,
|
|
|
bam: &str,
|
|
|
- dorado_threads: u16,
|
|
|
samtools_view_threads: u16,
|
|
|
samtools_sort_threads: u16,
|
|
|
) -> anyhow::Result<()> {
|
|
|
@@ -83,7 +74,8 @@ impl Dorado {
|
|
|
let samtools_view = format!("samtools view -h -@ {samtools_view_threads} -b /dev/stdin");
|
|
|
let samtools_sort = format!("samtools sort -@ {samtools_sort_threads} /dev/stdin -o {bam}");
|
|
|
let pipe = format!("{dorado} | {samtools_view} | {samtools_sort}");
|
|
|
- let pipe_cmd = duct::cmd!("bash", "-c", pipe);
|
|
|
+ info!("Running: {pipe}");
|
|
|
+ let pipe_cmd = cmd!("bash", "-c", pipe);
|
|
|
let mut reader = pipe_cmd.stdout_capture().reader()?;
|
|
|
|
|
|
let mut buffer = [0; 1];
|
|
|
@@ -106,7 +98,7 @@ impl Dorado {
|
|
|
}
|
|
|
}
|
|
|
Err(err) => {
|
|
|
- eprintln!("Error reading from stderr: {}", err);
|
|
|
+ warn!("Error reading from stderr: {}", err);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
@@ -118,7 +110,7 @@ impl Dorado {
|
|
|
fn run_cramino(&self, bam: &str, time_dir: &str, name: &str, time: &str) -> anyhow::Result<()> {
|
|
|
let cramino_out = format!("{}/{}_{}_hs1_cramino.txt", time_dir, name, time);
|
|
|
if !Path::new(&cramino_out).exists() {
|
|
|
- println!("[pipe] Quality control of BAM: {}", bam);
|
|
|
+ info!("Quality control of BAM: {}", bam);
|
|
|
let output = duct::cmd!(
|
|
|
"cramino",
|
|
|
"-t",
|
|
|
@@ -140,7 +132,7 @@ impl Dorado {
|
|
|
fn run_modkit(&self, bam: &str, time_dir: &str, name: &str, time: &str) -> anyhow::Result<()> {
|
|
|
let mod_summary = format!("{}/{}_{}_5mC_5hmC_summary.txt", time_dir, name, time);
|
|
|
if !Path::new(&mod_summary).exists() {
|
|
|
- println!("[pipe] Generating modification summary for BAM: {}", bam);
|
|
|
+ info!("Generating base modification summary for BAM: {}", bam);
|
|
|
let output = cmd!("modkit", "summary", "-t", "50", bam)
|
|
|
.stdout_capture()
|
|
|
.unchecked()
|
|
|
@@ -160,70 +152,15 @@ impl Dorado {
|
|
|
) -> anyhow::Result<()> {
|
|
|
let fastq = format!("{}/{}/{}/{}_{}.fastq.gz", case_dir, name, time, name, time);
|
|
|
if !std::path::Path::new(&fastq).exists() {
|
|
|
- // samtools fastq -@ 150 "$bam" | crabz -f bgzf - -o "$fastq"
|
|
|
let samtools = format!("samtools fastq -@ 150 {bam}");
|
|
|
let crabz = format!("crabz -f bgzf - -o {fastq}");
|
|
|
let pipe = format!("{samtools} | {crabz}");
|
|
|
+ info!("Running: {pipe}");
|
|
|
let pipe_cmd = duct::cmd!("bash", "-c", pipe);
|
|
|
- pipe_cmd.run();
|
|
|
+ pipe_cmd.run()?;
|
|
|
}
|
|
|
Ok(())
|
|
|
}
|
|
|
-
|
|
|
- fn print_stderr<R: BufRead>(
|
|
|
- &mut self,
|
|
|
- reader: R,
|
|
|
- sender: Sender<String>,
|
|
|
- ) -> anyhow::Result<()> {
|
|
|
- for line in reader.lines() {
|
|
|
- let line = line?;
|
|
|
- eprintln!("{}", line);
|
|
|
- sender.send(line.clone()).unwrap();
|
|
|
- self.log.push(line);
|
|
|
- }
|
|
|
- Ok(())
|
|
|
- }
|
|
|
-
|
|
|
- fn print_stderr_live(
|
|
|
- stderr: Arc<Mutex<ChildStderr>>,
|
|
|
- sender: Sender<String>,
|
|
|
- ) -> anyhow::Result<()> {
|
|
|
- let mut lock = stderr.lock().unwrap();
|
|
|
- let mut reader = BufReader::new(&mut *lock);
|
|
|
- // let mut reader = BufReader::new(stderr.lock().unwrap());
|
|
|
- let mut buffer = [0; 1];
|
|
|
- let mut line = String::new();
|
|
|
-
|
|
|
- loop {
|
|
|
- match reader.read(&mut buffer) {
|
|
|
- Ok(0) => break, // End of output
|
|
|
- Ok(_) => {
|
|
|
- let char = buffer[0] as char;
|
|
|
- eprint!("{}", char);
|
|
|
- std::io::stderr().flush()?;
|
|
|
-
|
|
|
- if char == '\n' {
|
|
|
- // Send the complete line
|
|
|
- sender.send(line.trim().to_string())?;
|
|
|
- line.clear();
|
|
|
- } else {
|
|
|
- line.push(char);
|
|
|
- }
|
|
|
- }
|
|
|
- Err(err) => {
|
|
|
- eprintln!("Error reading from stderr: {}", err);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Send any remaining content in the line
|
|
|
- if !line.is_empty() {
|
|
|
- sender.send(line.trim().to_string())?;
|
|
|
- }
|
|
|
-
|
|
|
- Ok(())
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
impl Run for Dorado {
|
|
|
@@ -239,7 +176,7 @@ impl Run for Dorado {
|
|
|
pod_dir,
|
|
|
ref_fa,
|
|
|
ref_mmi,
|
|
|
- dorado_threads,
|
|
|
+ dorado_threads: _,
|
|
|
samtools_view_threads,
|
|
|
samtools_sort_threads,
|
|
|
} = self.config.clone();
|
|
|
@@ -253,7 +190,7 @@ impl Run for Dorado {
|
|
|
self.create_reference_mmi(&ref_mmi, &ref_fa)?;
|
|
|
self.create_directories(&case_dir, &time_dir)?;
|
|
|
|
|
|
- println!("Reading {} pod5 from: {}", time, pod_dir);
|
|
|
+ info!("Reading {} pod5 from: {}", time, pod_dir);
|
|
|
|
|
|
if !std::path::Path::new(&bam).exists() {
|
|
|
self.run_dorado_and_samtools(
|
|
|
@@ -261,7 +198,6 @@ impl Run for Dorado {
|
|
|
&pod_dir,
|
|
|
&ref_mmi,
|
|
|
&bam,
|
|
|
- dorado_threads,
|
|
|
samtools_view_threads,
|
|
|
samtools_sort_threads,
|
|
|
)?;
|
|
|
@@ -274,7 +210,7 @@ impl Run for Dorado {
|
|
|
let end_time = std::time::SystemTime::now();
|
|
|
self.end_time = end_time;
|
|
|
let execution_time = end_time.duration_since(start_time).unwrap().as_secs_f64();
|
|
|
- eprintln!(
|
|
|
+ info!(
|
|
|
"Dorado and Minimap2 execution time: {} seconds",
|
|
|
execution_time
|
|
|
);
|
|
|
@@ -283,16 +219,3 @@ impl Run for Dorado {
|
|
|
Ok(())
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-// fn print_stderr(stderr: std::process::ChildStderr, save: &mut Vec<String>) {
|
|
|
-// let stderr_reader = BufReader::new(stderr);
|
|
|
-// for line in stderr_reader.lines() {
|
|
|
-// match line {
|
|
|
-// Ok(line) => {
|
|
|
-// eprintln!("{}", line);
|
|
|
-// save.push(line);
|
|
|
-// }
|
|
|
-// Err(err) => eprintln!("Error reading stderr: {}", err),
|
|
|
-// }
|
|
|
-// }
|
|
|
-// }
|