use crate::tsdef::Time;
use crate::TableCollection;
use tskit::{tsk_flags_t, tsk_id_t, TSK_NODE_IS_SAMPLE, TSK_NULL};
pub fn simple_time_reverser(x: Time) -> Box<dyn Fn(Time) -> f64> {
Box::new(move |t: Time| -1. * (t - x) as f64)
}
pub fn convert_to_tskit_minimal(
tables: &TableCollection,
is_sample: &[i32],
convert_time: impl Fn(Time) -> f64,
build_indexes: bool,
) -> tskit::TableCollection {
let mut tsk_tables = tskit::TableCollection::new(tables.genome_length() as f64).unwrap();
for e in tables.edges() {
tsk_tables
.add_edge(e.left as f64, e.right as f64, e.parent, e.child)
.unwrap();
}
let mut max_pop: tsk_id_t = -1;
for (i, n) in tables.enumerate_nodes() {
let flags: tsk_flags_t = if is_sample[i] > 0 {
TSK_NODE_IS_SAMPLE
} else {
0
};
tsk_tables
.add_node(flags, convert_time(n.time), n.deme, TSK_NULL)
.unwrap();
max_pop = std::cmp::max(n.deme, max_pop);
}
for _ in 0..(max_pop + 1) {
tsk_tables.add_population().unwrap();
}
if build_indexes {
tsk_tables.build_index().unwrap();
}
tsk_tables
}
fn swap_with_empty<T>(v: &mut Vec<T>) {
let mut temp = Vec::<T>::new();
std::mem::swap(v, &mut temp);
}
pub fn convert_to_tskit_and_drain_minimal(
is_sample: &[i32],
convert_time: impl Fn(Time) -> f64,
build_indexes: bool,
tables: &mut TableCollection,
) -> tskit::TableCollection {
let mut tsk_tables = tskit::TableCollection::new(tables.genome_length() as f64).unwrap();
let mut max_pop: tsk_id_t = -1;
for (i, n) in tables.enumerate_nodes() {
let flags: tsk_flags_t = if is_sample[i] > 0 {
TSK_NODE_IS_SAMPLE
} else {
0
};
tsk_tables
.add_node(flags, convert_time(n.time), n.deme, TSK_NULL)
.unwrap();
max_pop = std::cmp::max(n.deme, max_pop);
}
swap_with_empty(&mut tables.nodes_);
for e in tables.edges() {
tsk_tables
.add_edge(e.left as f64, e.right as f64, e.parent, e.child)
.unwrap();
}
swap_with_empty(&mut tables.edges_);
for _ in 0..(max_pop + 1) {
tsk_tables.add_population().unwrap();
}
if build_indexes {
tsk_tables.build_index().unwrap();
}
tsk_tables
}
#[cfg(test)]
mod tests {
use super::*;
use tskit::TableAccess;
#[test]
fn test_convert_to_tskit() {
let mut tables = TableCollection::new(100).unwrap();
tables.add_node(0, 0).unwrap(); tables.add_node(1, 0).unwrap(); tables.add_edge(0, 100, 0, 1).unwrap(); let is_sample = vec![0, 1]; let tsk_tables =
convert_to_tskit_minimal(&tables, &is_sample, simple_time_reverser(1), true);
assert_eq!(tsk_tables.nodes().num_rows(), 2);
assert_eq!(tsk_tables.edges().num_rows(), 1);
assert_eq!(tsk_tables.populations().num_rows(), 1);
assert_eq!(tables.num_edges(), 1);
assert_eq!(tables.num_nodes(), 2);
}
#[test]
fn test_convert_to_tskit_and_drain() {
let mut tables = TableCollection::new(100).unwrap();
tables.add_node(0, 0).unwrap(); tables.add_node(1, 0).unwrap(); tables.add_edge(0, 100, 0, 1).unwrap(); let is_sample = vec![0, 1]; let tsk_tables = convert_to_tskit_and_drain_minimal(
&is_sample,
simple_time_reverser(1),
true,
&mut tables,
);
assert_eq!(tsk_tables.nodes().num_rows(), 2);
assert_eq!(tsk_tables.edges().num_rows(), 1);
assert_eq!(tsk_tables.populations().num_rows(), 1);
assert_eq!(tables.edges_.capacity(), 0);
assert_eq!(tables.nodes_.capacity(), 0);
}
}