#![feature(test)]
extern crate getopts;
extern crate bio;
extern crate time;
extern crate test;
extern crate prll_ri;
use getopts::Options;
use std::process::Command;
use std::path::Path;
use bio::io::fasta;
use time::now;
use prll_ri::*;
pub fn rn_riblast_in_srl(args: &Vec<String>) {
let prgrm = args[0].clone();
let mut opts = Options::new();
opts.reqopt("i", "", "RNA seqs in single file of FASTA format", "STR");
opts.reqopt("o", "", "Path to output dir.", "STR");
opts.reqopt("d", "", "Path to database", "STR");
opts.optopt("l", "", "Max size of seed length (Default: 20)", "UINT");
opts.optopt("e", "", "Interaction energy threshold for seed search (Default: -6.5)", "FLOAT");
opts.optopt("f", "", "Hybridization energy threshold for removal of interaction candidates before gapped extension (Default: -3.05)", "FLOAT");
opts.optopt("x", "", "Dropout length in gapped extension (Default: 18)", "UINT");
opts.optopt("y", "", "Dropout length in gapless extension (Default: 5)", "UINT");
opts.optopt("t", "", "# of threads in multithreading (Default: system val.)", "UINT");
opts.optopt("b", "", "Path to RIblast binary (Default: system val.)", "STR");
opts.optflag("h", "help", "Print help menu");
let mtchs = match opts.parse(&args[1 ..]) {
Ok(mtch) => {mtch}
Err(fl) => {prnt_usg(&prgrm, &opts); panic!(fl.to_string())}
};
if mtchs.opt_present("h") {
prnt_usg(&prgrm, &opts);
return;
}
let riblast_pth = if mtchs.opt_present("b") {
mtchs.opt_str("b").expect("Retrieving path to RIblast from command args failed. ")
} else {
String::from("RIblast")
};
let tm_stmp = now();
let tm_stmp = (tm_stmp.tm_year + 1900).to_string() + "-" + &(tm_stmp.tm_mon + 1).to_string() + "-" + &tm_stmp.tm_mday.to_string() + "-" + &tm_stmp.tm_hour.to_string() + ":" + &tm_stmp.tm_min.to_string() + ":" + &tm_stmp.tm_sec.to_string();
let tmp = String::from("/tmp/prll_ri_") + &tm_stmp;
let tmp = Path::new(&tmp);
if !tmp.exists() {
Command::new("mkdir").arg(tmp.to_str().expect("Parsing temporary dir. path failed. ")).output().expect("Creating temporary dir. failed. ");
}
let inpt = mtchs.opt_str("i").expect("Retrieving input file path from command args failed. ");
let otpt_dr = mtchs.opt_str("o").expect("Retrieving output dir. path from command args failed. ");
let otpt_dr = Path::new(&otpt_dr);
if !otpt_dr.exists() {
Command::new("mkdir").arg(otpt_dr.to_str().expect("Parsing output dir. path failed. ")).output().expect("Creating output dir. failed. ");
}
let mut args = Vec::new();
let opts = vec!["d", "l", "e", "f", "x", "y"];
let opt_dflt_vls = vec!["", "20", "-6.5", "-3.05", "18", "5"];
for itr_pr in opts.iter().zip(opt_dflt_vls.iter()) {
let (opt, opt_dflt_vl) = itr_pr;
let mut arg = String::from("-");
arg.push_str(opt);
args.push(arg);
if mtchs.opt_present(opt) {
args.push(String::from(mtchs.opt_str(opt).expect("Retrieving option failed. ")));
} else {
args.push(String::from(*opt_dflt_vl));
}
}
let fasta_rdr = fasta::Reader::from_file(Path::new(&inpt)).ok().expect("Reading FASTA file failed. ");
for (_i, rc) in fasta_rdr.records().enumerate() {
let dt = rc.ok().expect("Reading FASTA record failed. ");
let dt_id = dt.id().expect("Record ID is missing. ");
let tmp_otpt = tmp.join(String::from(dt_id) + ".fa");
let otpt = otpt_dr.join(dt_id);
let mut fasta_wrtr = fasta::Writer::to_file(Path::new(&tmp_otpt)).ok().expect("Writing into FASTA file is blocked. ");
let _rslt = fasta_wrtr.write_record(&dt);
let _rslt = fasta_wrtr.flush();
let mut riblast_args = args.clone();
riblast_args.insert(0, String::from("ris"));
riblast_args.push(String::from("-i"));
riblast_args.push(String::from(tmp_otpt.to_str().expect("Parsing temporary file path failed. ")));
riblast_args.push(String::from("-o"));
riblast_args.push(String::from(otpt.to_str().expect("Parsing output dir. path failed. ")));
let mut riblast_arg_slcs = Vec::new();
for riblast_arg in &riblast_args {
riblast_arg_slcs.push(riblast_arg.as_str());
}
let otpt = Command::new(&riblast_pth).args(&riblast_arg_slcs).output().expect("RIblast failed. ");
println!("Status: {}", otpt.status);
println!("stdout: {}", String::from_utf8_lossy(&otpt.stdout));
println!("stderr: {}", String::from_utf8_lossy(&otpt.stderr));
assert!(otpt.status.success());
}
Command::new("rm").args(&["-rf", tmp.to_str().expect("Parsing temporary dir. path failed. ")]).output().expect("Removing temporary dir. failed. ");
}
#[cfg(test)]
mod tsts {
use super::*;
use time::precise_time_ns;
use prll_ri::rn_riblast_in_prll;
#[test]
fn tst_riblast_in_prll() {
let mut args = Vec::new();
args.push(String::from("prll-ri"));
args.push(String::from("-i"));
args.push(String::from("asts/fnc_ncrnas.fa"));
args.push(String::from("-o"));
args.push(String::from("asts/prll_ri"));
args.push(String::from("-d"));
args.push(String::from("asts/s_pmb_rna_db/s_pmb_rna_db"));
let bgn = precise_time_ns();
rn_riblast_in_prll(&args);
let elps_tm = precise_time_ns() - bgn;
let bgn = precise_time_ns();
rn_riblast_in_srl(&args);
let spd_rt = (precise_time_ns() - bgn) as f32 / elps_tm as f32;
println!("{} times faster than serial form. ", spd_rt);
}
}