use std::error::Error;
use std::io;
use bio::stats::{LogProb, PHREDProb, bayesian};
use itertools::Itertools;
use rust_htslib::bcf;
use csv;
use Event;
use estimation::fdr::{Record, ALPHAS};
use model;
use utils;
pub fn control_fdr<E: Event, W: io::Write>(
calls: &mut bcf::Reader,
writer: &mut W,
event: &E,
vartype: &model::VariantType) -> Result<(), Box<Error>> {
let mut writer = csv::Writer::from_writer(writer).delimiter(b'\t');
try!(writer.write(["FDR", "max-prob"].into_iter()));
let prob_dist = utils::collect_prob_dist(calls, event, vartype)?;
if prob_dist.is_empty() {
for &alpha in &ALPHAS {
writer.write([&format!("{}", alpha), ""].iter())?;
}
return Ok(());
}
let pep_dist = prob_dist.into_iter().rev().map(|p| LogProb(*p).ln_one_minus_exp()).collect_vec();
let fdrs = bayesian::expected_fdr(&pep_dist);
for &alpha in &ALPHAS {
let ln_alpha = LogProb(alpha.ln());
for i in (0..fdrs.len()).rev() {
if fdrs[i] <= ln_alpha && (i == 0 || pep_dist[i] != pep_dist[i - 1]) {
let pep = pep_dist[i];
writer.encode(&Record {
alpha: alpha,
gamma: PHREDProb::from(pep.ln_one_minus_exp())
})?;
break;
}
}
}
writer.flush()?;
Ok(())
}