mod builder;
mod kmers;
mod mapper;
use serde::Deserialize;
use serde::Serialize;
use crate::matrix::CsrMatrix;
use crate::matrix::MatrixDimensions;
use crate::primer::Primer;
use crate::utils::OrderedSet;
use crate::utils::Paired;
use crate::utils::Rc;
pub use self::builder::Builder;
pub use self::kmers::Kmers;
pub use self::mapper::Mapper;
pub use self::mapper::MapperResult;
#[derive(Debug, Clone, Serialize, Deserialize)]
struct UnindexedRegion {
primer: Paired<Primer>,
unique_pairs: OrderedSet<Paired<usize>>,
unique_kmers: Paired<OrderedSet<Rc<str>>>,
matrix: CsrMatrix<f32>,
}
impl From<UnindexedRegion> for Region {
fn from(region: UnindexedRegion) -> Self {
let _k = region
.unique_kmers
.forward
.iter()
.next()
.map(|kmer| kmer.len())
.unwrap_or_default();
let block = region
.unique_kmers
.map(|kmers| Kmers::new(kmers.iter().map(|r| r.as_bytes())).unwrap());
Self {
primer: region.primer,
unique_pairs: region.unique_pairs,
matrix: region.matrix,
block,
}
}
}
impl From<Region> for UnindexedRegion {
fn from(region: Region) -> Self {
let unique_kmers = region.block.map(|kmers| {
let mut unique_kmers = Vec::with_capacity(kmers.columns());
let mut s = String::with_capacity(kmers.rows());
for j in 0..kmers.columns() {
s.clear();
for i in 0..kmers.rows() {
s.push(kmers[i][j] as char);
}
unique_kmers.push(Rc::from(s.as_str()));
}
unique_kmers.into()
});
Self {
primer: region.primer,
unique_pairs: region.unique_pairs,
unique_kmers,
matrix: region.matrix,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(from = "UnindexedRegion", into = "UnindexedRegion")]
pub struct Region {
primer: Paired<Primer>,
unique_pairs: OrderedSet<Paired<usize>>,
block: Paired<Kmers>,
matrix: CsrMatrix<f32>,
}
impl Region {
#[inline]
pub fn primer(&self) -> &Paired<Primer> {
&self.primer
}
#[inline]
pub fn matrix(&self) -> &CsrMatrix<f32> {
&self.matrix
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Database {
k: usize,
regions: Vec<Region>,
names: OrderedSet<Rc<str>>,
amplified: Vec<u8>,
}
impl Database {
#[inline]
pub fn k(&self) -> usize {
self.k
}
#[inline]
pub fn names(&self) -> &[Rc<str>] {
self.names.as_slice()
}
#[inline]
pub fn regions(&self) -> &[Region] {
self.regions.as_slice()
}
}
impl AsRef<Database> for &Database {
#[inline]
fn as_ref(&self) -> &Database {
*self
}
}
impl AsRef<[Region]> for &Database {
#[inline]
fn as_ref(&self) -> &[Region] {
self.regions()
}
}