pub mod infinite_sites_neutral_variation;
pub mod single_cell_bulk;
pub mod tumor_normal;
pub mod flat;
pub mod normal;
use bio::stats::LogProb;
use model::{AlleleFreq, AlleleFreqs, Variant};
pub use priors::infinite_sites_neutral_variation::InfiniteSitesNeutralVariationModel;
pub use priors::single_cell_bulk::SingleCellBulkModel;
pub use priors::tumor_normal::TumorNormalModel;
pub use model::PairPileup;
pub use priors::flat::FlatNormalNormalModel;
pub use priors::flat::FlatTumorNormalModel;
pub trait Model<A: AlleleFreqs> {
fn prior_prob(&self, af: AlleleFreq, variant: &Variant) -> LogProb;
fn allele_freqs(&self) -> &A;
fn marginal_prob<L>(&self, likelihood: &L, variant: &Variant, n_obs: usize) -> LogProb
where
L: Fn(AlleleFreq) -> LogProb;
fn joint_prob<L>(&self, af: &A, likelihood: &L, variant: &Variant, n_obs: usize) -> LogProb
where
L: Fn(AlleleFreq) -> LogProb;
fn map<L>(&self, likelihood: &L, variant: &Variant, n_obs: usize) -> AlleleFreq
where
L: Fn(AlleleFreq) -> LogProb;
}
pub trait PairModel<A: AlleleFreqs, B: AlleleFreqs> {
fn prior_prob(&self, af1: AlleleFreq, af2: AlleleFreq, variant: &Variant) -> LogProb;
fn joint_prob(&self, af1: &A, af2: &B, pileup: &mut PairPileup<A, B, Self>) -> LogProb;
fn marginal_prob(&self, pileup: &mut PairPileup<A, B, Self>) -> LogProb;
fn map(&self, pileup: &mut PairPileup<A, B, Self>) -> (AlleleFreq, AlleleFreq);
fn allele_freqs(&self) -> (&A, &B);
}
pub trait TrioModel<A: AlleleFreqs, B: AlleleFreqs, C: AlleleFreqs> {
fn prior_prob(
&self,
af1: AlleleFreq,
af2: AlleleFreq,
af3: AlleleFreq,
variant: &Variant,
) -> LogProb;
fn joint_prob<L, O, Q>(
&self,
af1: &A,
af2: &B,
af3: &C,
likelihood1: &L,
likelihood2: &O,
likelihood3: &Q,
variant: &Variant,
n_obs1: usize,
n_obs2: usize,
n_obs3: usize,
) -> LogProb
where
L: Fn(AlleleFreq, Option<AlleleFreq>) -> LogProb,
O: Fn(AlleleFreq, Option<AlleleFreq>) -> LogProb,
Q: Fn(AlleleFreq, Option<AlleleFreq>) -> LogProb;
fn marginal_prob<L, O, Q>(
&self,
likelihood1: &L,
likelihood2: &O,
likelihood3: &Q,
variant: &Variant,
n_obs1: usize,
n_obs2: usize,
n_obs3: usize,
) -> LogProb
where
L: Fn(AlleleFreq, Option<AlleleFreq>) -> LogProb,
O: Fn(AlleleFreq, Option<AlleleFreq>) -> LogProb,
Q: Fn(AlleleFreq, Option<AlleleFreq>) -> LogProb;
fn map<L, O, Q>(
&self,
likelihood1: &L,
likelihood2: &O,
likelihood3: &Q,
variant: &Variant,
n_obs1: usize,
n_obs2: usize,
n_obs3: usize,
) -> (AlleleFreq, AlleleFreq, AlleleFreq)
where
L: Fn(AlleleFreq, Option<AlleleFreq>) -> LogProb,
O: Fn(AlleleFreq, Option<AlleleFreq>) -> LogProb,
Q: Fn(AlleleFreq, Option<AlleleFreq>) -> LogProb;
fn allele_freqs(&self) -> (&A, &B, &C);
}
#[cfg(test)]
mod tests {
use super::*;
use bio::stats::Prob;
use itertools_num::linspace;
use model::evidence::observation::Observation;
use model::tests::observation;
use model::AlleleFreq;
use model::Variant;
pub fn create_obs_vector(n_obs_ref: usize, n_obs_alt: usize) -> Vec<Observation> {
let obs_ref_abs = observation(LogProb::ln_one(), LogProb::ln_zero(), LogProb::ln_one());
let obs_alt_abs = observation(LogProb::ln_one(), LogProb::ln_one(), LogProb::ln_zero());
let mut obs = Vec::new();
for _ in 0..n_obs_ref {
obs.push(obs_ref_abs.clone());
}
for _ in 0..n_obs_alt {
obs.push(obs_alt_abs.clone());
}
obs
}
#[test]
fn test_infinite_sites_neutral_variation() {
let ploidy = 2;
let het = Prob(0.001);
let model = InfiniteSitesNeutralVariationModel::new(1, ploidy, het);
assert_relative_eq!(model.prior_prob(1).exp(), 0.001);
assert_relative_eq!(model.prior_prob(2).exp(), 0.0005);
assert_relative_eq!(model.prior_prob(0).exp(), 0.9985, epsilon = 0.00001);
}
#[test]
fn test_tumor() {
let variant = Variant::Deletion(3);
let model = TumorNormalModel::new(2, 300.0, 1.0, 1.0, 3e9 as u64, Prob(0.001));
println!(
"af=0.0,0.0 -> {}",
*model.prior_prob(AlleleFreq(0.0), AlleleFreq(0.0), &variant)
);
println!(
"af=0.5,0.5 -> {}",
*model.prior_prob(AlleleFreq(0.5), AlleleFreq(0.5), &variant)
);
for af in linspace(0.0, 1.0, 20) {
println!(
"normal={} af={} p={}",
0.0,
af,
*model.prior_prob(AlleleFreq(af), AlleleFreq(0.0), &variant)
);
println!(
"normal={} af={} p={}",
0.5,
af,
*model.prior_prob(AlleleFreq(af), AlleleFreq(0.5), &variant)
);
println!(
"normal={} af={} p={}",
1.0,
af,
*model.prior_prob(AlleleFreq(af), AlleleFreq(1.0), &variant)
);
}
}
}