use anyhow::Result;
use chrono::Local;
use clap::crate_version;
use std::{io::Write, path::PathBuf};
pub mod build;
pub mod clades;
pub mod explore;
pub mod finder;
pub mod plot;
pub mod search;
pub mod utils;
pub enum SubCommand {
Find,
Explore,
Search,
}
const DATE_FORMAT_STR: &str = "%Y-%m-%d: %H:%M:%S";
impl SubCommand {
pub fn log(&self, matches: &clap::ArgMatches) -> Result<()> {
if matches.get_flag("log") {
match self {
SubCommand::Find => {
let output = matches
.get_one::<PathBuf>("output")
.expect("errored by clap");
let outdir = matches.get_one::<PathBuf>("dir").expect("errored by clap");
let input_fasta = matches
.get_one::<PathBuf>("fasta")
.expect("errored by clap");
let clade = matches.get_one::<String>("clade").expect("errored by clap");
let clade_info = clades::return_telomere_sequence(clade.clone());
let window_size = *matches.get_one::<usize>("window").expect("errored by clap");
let file_name = format!(
"{}/{}{}",
outdir.display(),
output.display(),
"_telomeric_repeat_windows.csv"
);
let log_string = format!(
r#"tidk version: {}
Log information for output file: {}
Date: {}
`tidk find` was run with the following parameters:
Input fasta: {}
Window size: {}
Clade chosen: {}
Telomeric repeats queried: {}"#,
crate_version!(),
file_name,
Local::now().format(DATE_FORMAT_STR),
input_fasta.display(),
window_size,
clade,
clade_info?.seq.get_inner().join(", ")
);
let log_file_name =
format!("{}/{}{}", outdir.display(), output.display(), ".log");
let log_file = std::fs::File::create(&log_file_name)?;
let mut log_file = std::io::LineWriter::new(log_file);
writeln!(log_file, "{}", log_string)?;
Ok(eprintln!("[+]\tLog file written to: {}", log_file_name))
}
SubCommand::Explore => {
let input_fasta = matches
.get_one::<PathBuf>("fasta")
.expect("errored by clap");
let length = matches.get_one::<usize>("length");
let minimum = matches.get_one::<usize>("minimum");
let maximum = matches.get_one::<usize>("maximum");
let threshold = matches.get_one::<i32>("threshold");
let dist_from_chromosome_end = matches.get_one::<f64>("distance");
let log_string = format!(
r#"tidk version: {}
Log information for output files: printed to STDOUT
Date: {}
`tidk explore` was run with the following parameters:
Input fasta: {}
Explored telomeric repeat units of length: {}
Or from length: {}
To length: {}
Threshold: {}
Searching at {}% distance from chromosome end"#,
crate_version!(),
Local::now().format(DATE_FORMAT_STR),
input_fasta.display(),
{
if let Some(l) = length {
l.to_string()
} else {
"None".into()
}
},
{
if let Some(min) = minimum {
min.to_string()
} else {
"None".into()
}
},
{
if let Some(max) = maximum {
max.to_string()
} else {
"None".into()
}
},
threshold.unwrap(),
*dist_from_chromosome_end.unwrap() * 100.0,
);
let log_file_name = "tidk-explore.log".to_string();
let log_file = std::fs::File::create(&log_file_name)?;
let mut log_file = std::io::LineWriter::new(log_file);
writeln!(log_file, "{}", log_string)?;
Ok(eprintln!("[+]\tLog file written to: {}", log_file_name))
}
SubCommand::Search => {
let input_fasta = matches
.get_one::<PathBuf>("fasta")
.expect("errored by clap");
let telomeric_repeat = matches
.get_one::<String>("string")
.expect("errored by clap");
let extension = matches
.get_one::<String>("extension")
.expect("errored by clap");
let window_size = matches.get_one::<usize>("window").expect("errored by clap");
let outdir = matches.get_one::<PathBuf>("dir").expect("errored by clap");
let output = matches
.get_one::<PathBuf>("output")
.expect("errored by clap");
let file_name = format!(
"{}/{}{}{}",
outdir.display(),
output.display(),
"_telomeric_repeat_windows.",
extension
);
let log_string = format!(
r#"tidk version: {}
Log information for output file: {}
Date: {}
`tidk search` was run with the following parameters:
Input fasta: {}
Telomeric repeat search string: {}
Window size: {}
"#,
crate_version!(),
file_name,
Local::now().format(DATE_FORMAT_STR),
input_fasta.display(),
telomeric_repeat,
window_size
);
let log_file_name =
format!("{}/{}{}", outdir.display(), output.display(), ".log");
let log_file = std::fs::File::create(&log_file_name)?;
let mut log_file = std::io::LineWriter::new(log_file);
writeln!(log_file, "{}", log_string)?;
Ok(eprintln!("[+]\tLog file written to: {}", log_file_name))
}
}
} else {
Ok(())
}
}
}