Skip to content
Snippets Groups Projects
Commit fb8eee06 authored by Martin Larralde's avatar Martin Larralde
Browse files

Rename `DnaSymbol` to `Nucleotide` and `DnaAlphabet` to `Dna`

parent 19516f82
No related branches found
No related tags found
No related merge requests found
......@@ -45,7 +45,7 @@ let pwm = pbm.to_weight(Background::uniform());
// Encode the target sequence into a striped matrix
let seq = "ATGTCCCAACAACGATACCCCGAGCCCATCGCCGTCATCGGCTCGGCATGCAGATTCCCAGGCG";
let encoded = EncodedSequence::<DnaAlphabet>::encode(seq).unwrap();
let encoded = EncodedSequence::<Dna>::encode(seq).unwrap();
let mut striped = encoded.to_striped::<32>();
// Create a pipeline and compute scores for every position of the matrix
......
......@@ -14,7 +14,7 @@ use std::str::FromStr;
use lightmotif::Alphabet;
use lightmotif::Background;
use lightmotif::CountMatrix;
use lightmotif::DnaAlphabet;
use lightmotif::Dna;
use lightmotif::EncodedSequence;
use lightmotif::Pipeline;
use lightmotif::StripedScores;
......@@ -24,11 +24,11 @@ const SEQUENCE: &'static str = include_str!("../lightmotif/benches/ecoli.txt");
#[bench]
fn bench_generic(bencher: &mut test::Bencher) {
let seq = &SEQUENCE[..10000];
let encoded = EncodedSequence::<DnaAlphabet>::from_str(seq).unwrap();
let encoded = EncodedSequence::<Dna>::from_str(seq).unwrap();
let mut striped = encoded.to_striped::<32>();
let bg = Background::<DnaAlphabet, { DnaAlphabet::K }>::uniform();
let cm = CountMatrix::<DnaAlphabet, { DnaAlphabet::K }>::from_sequences(&[
let bg = Background::<Dna, { Dna::K }>::uniform();
let cm = CountMatrix::<Dna, { Dna::K }>::from_sequences(&[
EncodedSequence::from_str("GTTGACCTTATCAAC").unwrap(),
EncodedSequence::from_str("GTTGATCCAGTCAAC").unwrap(),
])
......@@ -50,11 +50,11 @@ fn bench_generic(bencher: &mut test::Bencher) {
#[bench]
fn bench_sse2(bencher: &mut test::Bencher) {
let seq = &SEQUENCE[..10000];
let encoded = EncodedSequence::<DnaAlphabet>::from_str(seq).unwrap();
let encoded = EncodedSequence::<Dna>::from_str(seq).unwrap();
let mut striped = encoded.to_striped();
let bg = Background::<DnaAlphabet, { DnaAlphabet::K }>::uniform();
let cm = CountMatrix::<DnaAlphabet, { DnaAlphabet::K }>::from_sequences(&[
let bg = Background::<Dna, { Dna::K }>::uniform();
let cm = CountMatrix::<Dna, { Dna::K }>::from_sequences(&[
EncodedSequence::from_str("GTTGACCTTATCAAC").unwrap(),
EncodedSequence::from_str("GTTGATCCAGTCAAC").unwrap(),
])
......@@ -77,11 +77,11 @@ fn bench_sse2(bencher: &mut test::Bencher) {
#[bench]
fn bench_avx2(bencher: &mut test::Bencher) {
let seq = &SEQUENCE[..10000];
let encoded = EncodedSequence::<DnaAlphabet>::from_str(seq).unwrap();
let encoded = EncodedSequence::<Dna>::from_str(seq).unwrap();
let mut striped = encoded.to_striped();
let bg = Background::<DnaAlphabet, { DnaAlphabet::K }>::uniform();
let cm = CountMatrix::<DnaAlphabet, { DnaAlphabet::K }>::from_sequences(&[
let bg = Background::<Dna, { Dna::K }>::uniform();
let cm = CountMatrix::<Dna, { Dna::K }>::from_sequences(&[
EncodedSequence::from_str("GTTGACCTTATCAAC").unwrap(),
EncodedSequence::from_str("GTTGATCCAGTCAAC").unwrap(),
])
......
......@@ -121,8 +121,8 @@ pub fn parse_matrices<A: Alphabet, const K: usize>(
mod test {
use lightmotif::Alphabet;
use lightmotif::DnaAlphabet;
use lightmotif::DnaSymbol;
use lightmotif::Dna;
use lightmotif::Nucleotide;
use lightmotif::Symbol;
#[test]
......@@ -144,20 +144,20 @@ mod test {
#[test]
fn test_parse_alphabet() {
let line = "P0 A T G C\n";
let res = super::parse_alphabet::<DnaSymbol>(line).unwrap();
let res = super::parse_alphabet::<Nucleotide>(line).unwrap();
assert_eq!(res.0, "");
assert_eq!(
res.1,
vec![DnaSymbol::A, DnaSymbol::T, DnaSymbol::G, DnaSymbol::C]
vec![Nucleotide::A, Nucleotide::T, Nucleotide::G, Nucleotide::C]
);
let line = "P0 A T\n";
let res = super::parse_alphabet::<DnaSymbol>(line).unwrap();
let res = super::parse_alphabet::<Nucleotide>(line).unwrap();
assert_eq!(res.0, "");
assert_eq!(res.1, vec![DnaSymbol::A, DnaSymbol::T]);
assert_eq!(res.1, vec![Nucleotide::A, Nucleotide::T]);
let line = "P0 X Y Z\n";
let res = super::parse_alphabet::<DnaSymbol>(line);
let res = super::parse_alphabet::<Nucleotide>(line);
assert!(res.is_err());
}
......@@ -185,21 +185,21 @@ mod test {
"XX\n",
"//\n",
);
let res = super::parse_matrix::<DnaAlphabet, { DnaAlphabet::K }>(text).unwrap();
let res = super::parse_matrix::<Dna, { Dna::K }>(text).unwrap();
assert_eq!(res.0, "");
let matrix = res.1;
// assert_eq!(matrix.name, "prodoric_MX000001");
assert_eq!(matrix.data.rows(), 7);
assert_eq!(matrix.data[0][DnaSymbol::A.as_index()], 0);
assert_eq!(matrix.data[0][DnaSymbol::T.as_index()], 0);
assert_eq!(matrix.data[0][DnaSymbol::G.as_index()], 2);
assert_eq!(matrix.data[0][DnaSymbol::C.as_index()], 0);
assert_eq!(matrix.data[0][DnaSymbol::N.as_index()], 0);
assert_eq!(matrix.data[5][DnaSymbol::A.as_index()], 0);
assert_eq!(matrix.data[5][DnaSymbol::T.as_index()], 1);
assert_eq!(matrix.data[5][DnaSymbol::G.as_index()], 0);
assert_eq!(matrix.data[5][DnaSymbol::C.as_index()], 1);
assert_eq!(matrix.data[5][DnaSymbol::N.as_index()], 0);
assert_eq!(matrix.counts().rows(), 7);
assert_eq!(matrix.counts()[0][Nucleotide::A.as_index()], 0);
assert_eq!(matrix.counts()[0][Nucleotide::T.as_index()], 0);
assert_eq!(matrix.counts()[0][Nucleotide::G.as_index()], 2);
assert_eq!(matrix.counts()[0][Nucleotide::C.as_index()], 0);
assert_eq!(matrix.counts()[0][Nucleotide::N.as_index()], 0);
assert_eq!(matrix.counts()[5][Nucleotide::A.as_index()], 0);
assert_eq!(matrix.counts()[5][Nucleotide::T.as_index()], 1);
assert_eq!(matrix.counts()[5][Nucleotide::G.as_index()], 0);
assert_eq!(matrix.counts()[5][Nucleotide::C.as_index()], 1);
assert_eq!(matrix.counts()[5][Nucleotide::N.as_index()], 0);
}
}
......@@ -12,7 +12,7 @@ use std::str::FromStr;
use lightmotif::Alphabet;
use lightmotif::Background;
use lightmotif::CountMatrix;
use lightmotif::DnaAlphabet;
use lightmotif::Dna;
use lightmotif::EncodedSequence;
use lightmotif::Pipeline;
use lightmotif::StripedScores;
......@@ -21,11 +21,11 @@ const SEQUENCE: &'static str = include_str!("ecoli.txt");
#[bench]
fn bench_generic(bencher: &mut test::Bencher) {
let encoded = EncodedSequence::<DnaAlphabet>::from_str(SEQUENCE).unwrap();
let encoded = EncodedSequence::<Dna>::from_str(SEQUENCE).unwrap();
let mut striped = encoded.to_striped::<32>();
let bg = Background::<DnaAlphabet, { DnaAlphabet::K }>::uniform();
let cm = CountMatrix::<DnaAlphabet, { DnaAlphabet::K }>::from_sequences(&[
let bg = Background::<Dna, { Dna::K }>::uniform();
let cm = CountMatrix::<Dna, { Dna::K }>::from_sequences(&[
EncodedSequence::from_str("GTTGACCTTATCAAC").unwrap(),
EncodedSequence::from_str("GTTGATCCAGTCAAC").unwrap(),
])
......@@ -43,7 +43,7 @@ fn bench_generic(bencher: &mut test::Bencher) {
#[cfg(target_feature = "ssse3")]
#[bench]
fn bench_ssse3(bencher: &mut test::Bencher) {
let encoded = EncodedSequence::<DnaAlphabet>::from_str(SEQUENCE).unwrap();
let encoded = EncodedSequence::<Dna>::from_str(SEQUENCE).unwrap();
let mut striped = encoded.to_striped();
let bg = Background::uniform();
......@@ -66,7 +66,7 @@ fn bench_ssse3(bencher: &mut test::Bencher) {
#[cfg(target_feature = "avx2")]
#[bench]
fn bench_avx2(bencher: &mut test::Bencher) {
let encoded = EncodedSequence::<DnaAlphabet>::from_str(SEQUENCE).unwrap();
let encoded = EncodedSequence::<Dna>::from_str(SEQUENCE).unwrap();
let mut striped = encoded.to_striped();
let bg = Background::uniform();
......
......@@ -20,46 +20,53 @@ pub trait Alphabet: Debug + Copy + Default + 'static {
}
}
/// A nucleobase
#[derive(Clone, Copy, PartialEq, Debug)]
#[repr(u8)]
pub enum DnaSymbol {
pub enum Nucleotide {
/// Adenine.
A = 0,
/// Cytosine.
C = 1,
/// Thymine.
T = 2,
/// Guanine.
G = 3,
/// Unknown base.
N = 4,
}
impl Symbol for DnaSymbol {
impl Symbol for Nucleotide {
fn as_index(&self) -> usize {
*self as usize
}
}
impl TryFrom<char> for DnaSymbol {
impl TryFrom<char> for Nucleotide {
type Error = InvalidSymbol;
fn try_from(c: char) -> Result<Self, Self::Error> {
match c {
'A' => Ok(DnaSymbol::A),
'C' => Ok(DnaSymbol::C),
'T' => Ok(DnaSymbol::T),
'G' => Ok(DnaSymbol::G),
'N' => Ok(DnaSymbol::N),
'A' => Ok(Nucleotide::A),
'C' => Ok(Nucleotide::C),
'T' => Ok(Nucleotide::T),
'G' => Ok(Nucleotide::G),
'N' => Ok(Nucleotide::N),
_ => Err(InvalidSymbol(c)),
}
}
}
impl Default for DnaSymbol {
fn default() -> DnaSymbol {
DnaSymbol::N
impl Default for Nucleotide {
fn default() -> Nucleotide {
Nucleotide::N
}
}
/// The standard DNA alphabet composed of 4 nucleobases and a wildcard.
#[derive(Default, Debug, Clone, Copy)]
pub struct DnaAlphabet;
pub struct Dna;
impl Alphabet for DnaAlphabet {
type Symbol = DnaSymbol;
impl Alphabet for Dna {
type Symbol = Nucleotide;
const K: usize = 5;
}
......@@ -7,8 +7,8 @@ mod pwm;
mod seq;
pub use abc::Alphabet;
pub use abc::DnaAlphabet;
pub use abc::DnaSymbol;
pub use abc::Dna;
pub use abc::Nucleotide;
pub use abc::Symbol;
pub use dense::DenseMatrix;
pub use pli::Pipeline;
......
......@@ -3,7 +3,7 @@ use std::arch::x86_64::*;
use self::seal::Vector;
use super::abc::Alphabet;
use super::abc::DnaAlphabet;
use super::abc::Dna;
use super::abc::Symbol;
use super::dense::DenseMatrix;
use super::pwm::WeightMatrix;
......@@ -35,15 +35,15 @@ impl<A: Alphabet, V: Vector> Pipeline<A, V> {
}
}
impl Pipeline<DnaAlphabet, f32> {
impl Pipeline<Dna, f32> {
pub fn score_into<S, M, const C: usize>(
&self,
seq: S,
pwm: M,
scores: &mut StripedScores<f32, C>,
) where
S: AsRef<StripedSequence<DnaAlphabet, C>>,
M: AsRef<WeightMatrix<DnaAlphabet, { DnaAlphabet::K }>>,
S: AsRef<StripedSequence<Dna, C>>,
M: AsRef<WeightMatrix<Dna, { Dna::K }>>,
{
let seq = seq.as_ref();
let pwm = pwm.as_ref();
......@@ -60,7 +60,7 @@ impl Pipeline<DnaAlphabet, f32> {
let offset = i + j;
let col = offset / seq_rows;
let row = offset % seq_rows;
score += pwm.data[j][seq.data[row][col].as_index()];
score += pwm.weights()[j][seq.data[row][col].as_index()];
}
let col = i / result.rows();
let row = i % result.rows();
......@@ -70,8 +70,8 @@ impl Pipeline<DnaAlphabet, f32> {
pub fn score<S, M, const C: usize>(&self, seq: S, pwm: M) -> StripedScores<f32, C>
where
S: AsRef<StripedSequence<DnaAlphabet, C>>,
M: AsRef<WeightMatrix<DnaAlphabet, { DnaAlphabet::K }>>,
S: AsRef<StripedSequence<Dna, C>>,
M: AsRef<WeightMatrix<Dna, { Dna::K }>>,
{
let mut scores = StripedScores::new_for(&seq, &pwm);
self.score_into(seq, pwm, &mut scores);
......@@ -80,15 +80,15 @@ impl Pipeline<DnaAlphabet, f32> {
}
#[cfg(target_feature = "ssse3")]
impl Pipeline<DnaAlphabet, __m128> {
impl Pipeline<Dna, __m128> {
pub fn score_into<S, M>(
&self,
seq: S,
pwm: M,
scores: &mut StripedScores<__m128, { std::mem::size_of::<__m128i>() }>,
) where
S: AsRef<StripedSequence<DnaAlphabet, { std::mem::size_of::<__m128i>() }>>,
M: AsRef<WeightMatrix<DnaAlphabet, { DnaAlphabet::K }>>,
S: AsRef<StripedSequence<Dna, { std::mem::size_of::<__m128i>() }>>,
M: AsRef<WeightMatrix<Dna, { Dna::K }>>,
{
let seq = seq.as_ref();
let pwm = pwm.as_ref();
......@@ -145,9 +145,9 @@ impl Pipeline<DnaAlphabet, __m128> {
let x3 = _mm_shuffle_epi8(x, m3);
let x4 = _mm_shuffle_epi8(x, m4);
// load row for current weight matrix position
let row = pwm.data[j].as_ptr();
let row = pwm.weights()[j].as_ptr();
// index lookup table with each bases incrementally
for i in 0..DnaAlphabet::K {
for i in 0..Dna::K {
let sym = _mm_set1_epi32(i as i32);
let lut = _mm_set1_ps(*row.add(i as usize));
let p1 = _mm_castsi128_ps(_mm_cmpeq_epi32(x1, sym));
......@@ -176,8 +176,8 @@ impl Pipeline<DnaAlphabet, __m128> {
pwm: M,
) -> StripedScores<__m128, { std::mem::size_of::<__m128i>() }>
where
S: AsRef<StripedSequence<DnaAlphabet, { std::mem::size_of::<__m128i>() }>>,
M: AsRef<WeightMatrix<DnaAlphabet, { DnaAlphabet::K }>>,
S: AsRef<StripedSequence<Dna, { std::mem::size_of::<__m128i>() }>>,
M: AsRef<WeightMatrix<Dna, { Dna::K }>>,
{
let mut scores = StripedScores::new_for(&seq, &pwm);
self.score_into(seq, pwm, &mut scores);
......@@ -186,15 +186,15 @@ impl Pipeline<DnaAlphabet, __m128> {
}
#[cfg(target_feature = "avx2")]
impl Pipeline<DnaAlphabet, __m256> {
impl Pipeline<Dna, __m256> {
pub fn score_into<S, M>(
&self,
seq: S,
pwm: M,
scores: &mut StripedScores<__m256, { std::mem::size_of::<__m256i>() }>,
) where
S: AsRef<StripedSequence<DnaAlphabet, { std::mem::size_of::<__m256i>() }>>,
M: AsRef<WeightMatrix<DnaAlphabet, { DnaAlphabet::K }>>,
S: AsRef<StripedSequence<Dna, { std::mem::size_of::<__m256i>() }>>,
M: AsRef<WeightMatrix<Dna, { Dna::K }>>,
{
let seq = seq.as_ref();
let pwm = pwm.as_ref();
......@@ -210,7 +210,7 @@ impl Pipeline<DnaAlphabet, __m256> {
scores.length = seq.length - pwm.len() + 1;
unsafe {
// constant vector for comparing unknown bases
let n = _mm256_set1_epi8(super::abc::DnaSymbol::N as i8);
let n = _mm256_set1_epi8(super::Nucleotide::N as i8);
// mask vectors for broadcasting uint8x32_t to uint32x8_t to floatx8_t
let m1 = _mm256_set_epi32(
0xFFFFFF03u32 as i32,
......@@ -268,10 +268,10 @@ impl Pipeline<DnaAlphabet, __m256> {
let x3 = _mm256_shuffle_epi8(x, m3);
let x4 = _mm256_shuffle_epi8(x, m4);
// load row for current weight matrix position
let row = pwm.data[j].as_ptr();
let row = pwm.weights()[j].as_ptr();
let c = _mm_load_ps(row);
let t = _mm256_set_m128(c, c);
let u = _mm256_set1_ps(*row.add(crate::abc::DnaSymbol::N.as_index()));
let u = _mm256_set1_ps(*row.add(crate::abc::Nucleotide::N.as_index()));
// check which bases from the sequence are unknown
let mask = _mm256_cmpeq_epi8(x, n);
let unk1 = _mm256_castsi256_ps(_mm256_shuffle_epi8(mask, m1));
......@@ -310,8 +310,8 @@ impl Pipeline<DnaAlphabet, __m256> {
pwm: M,
) -> StripedScores<__m256, { std::mem::size_of::<__m256i>() }>
where
S: AsRef<StripedSequence<DnaAlphabet, { std::mem::size_of::<__m256i>() }>>,
M: AsRef<WeightMatrix<DnaAlphabet, { DnaAlphabet::K }>>,
S: AsRef<StripedSequence<Dna, { std::mem::size_of::<__m256i>() }>>,
M: AsRef<WeightMatrix<Dna, { Dna::K }>>,
{
let mut scores = StripedScores::new_for(&seq, &pwm);
self.score_into(seq, pwm, &mut scores);
......
......@@ -7,7 +7,13 @@ use super::seq::EncodedSequence;
#[derive(Clone, Debug)]
pub struct Pseudocount<A: Alphabet, const K: usize> {
alphabet: std::marker::PhantomData<A>,
pub counts: [f32; K],
counts: [f32; K],
}
impl<A: Alphabet, const K: usize> Default for Pseudocount<A, K> {
fn default() -> Self {
Self::from([0.0; K])
}
}
impl<A: Alphabet, const K: usize> From<[f32; K]> for Pseudocount<A, K> {
......@@ -34,13 +40,27 @@ impl<A: Alphabet, const K: usize> From<f32> for Pseudocount<A, K> {
}
}
impl<A: Alphabet, const K: usize> AsRef<[f32; K]> for Pseudocount<A, K> {
fn as_ref(&self) -> &[f32; K] {
&self.counts
}
}
impl<A: Alphabet, const K: usize> AsMut<[f32; K]> for Pseudocount<A, K> {
fn as_mut(&mut self) -> &mut [f32; K] {
&mut self.counts
}
}
/// A matrix storing symbol occurences at each position.
#[derive(Clone, Debug)]
pub struct CountMatrix<A: Alphabet, const K: usize> {
alphabet: std::marker::PhantomData<A>,
pub data: DenseMatrix<u32, K>,
data: DenseMatrix<u32, K>,
}
impl<A: Alphabet, const K: usize> CountMatrix<A, K> {
/// Create a new count matrix from the given data.
pub fn new(data: DenseMatrix<u32, K>) -> Result<Self, ()> {
Ok(Self {
data,
......@@ -48,6 +68,7 @@ impl<A: Alphabet, const K: usize> CountMatrix<A, K> {
})
}
/// Create a new count matrix from the given sequences.
pub fn from_sequences<'seq, I>(sequences: I) -> Result<Self, ()>
where
I: IntoIterator,
......@@ -100,27 +121,29 @@ impl<A: Alphabet, const K: usize> CountMatrix<A, K> {
data: probas,
}
}
}
impl<A: Alphabet, const K: usize> AsRef<DenseMatrix<u32, K>> for CountMatrix<A, K> {
fn as_ref(&self) -> &DenseMatrix<u32, K> {
/// The raw counts from the count matrix.
#[inline]
pub fn counts(&self) -> &DenseMatrix<u32, K> {
&self.data
}
}
impl<A: Alphabet, const K: usize> AsMut<DenseMatrix<u32, K>> for CountMatrix<A, K> {
fn as_mut(&mut self) -> &mut DenseMatrix<u32, K> {
&mut self.data
impl<A: Alphabet, const K: usize> AsRef<DenseMatrix<u32, K>> for CountMatrix<A, K> {
fn as_ref(&self) -> &DenseMatrix<u32, K> {
&self.data
}
}
/// A matrix storing symbol probabilities at each position.
#[derive(Clone, Debug)]
pub struct ProbabilityMatrix<A: Alphabet, const K: usize> {
alphabet: std::marker::PhantomData<A>,
pub data: DenseMatrix<f32, K>,
data: DenseMatrix<f32, K>,
}
impl<A: Alphabet, const K: usize> ProbabilityMatrix<A, K> {
/// Convert to a weight matrix using the given background frequencies.
pub fn to_weight<B>(&self, background: B) -> WeightMatrix<A, K>
where
B: Into<Background<A, K>>,
......@@ -148,19 +171,19 @@ impl<A: Alphabet, const K: usize> AsRef<DenseMatrix<f32, K>> for ProbabilityMatr
}
}
impl<A: Alphabet, const K: usize> AsMut<DenseMatrix<f32, K>> for ProbabilityMatrix<A, K> {
fn as_mut(&mut self) -> &mut DenseMatrix<f32, K> {
&mut self.data
}
}
/// A structure for storing background frequencies.
#[derive(Clone, Debug)]
pub struct Background<A: Alphabet, const K: usize> {
pub frequencies: [f32; K],
frequencies: [f32; K],
alphabet: std::marker::PhantomData<A>,
}
impl<A: Alphabet, const K: usize> Background<A, K> {
// Create a new background with uniform frequencies.
//
// The non-default symbols from the alphabet `A` will be initialized
// with a frequency of `1/(K-1)`, while the default symbol will remain
// with a zero frequency.
pub fn uniform() -> Self {
let mut frequencies = [0.0; K];
for i in 0..K {
......@@ -168,7 +191,6 @@ impl<A: Alphabet, const K: usize> Background<A, K> {
frequencies[i] = 1.0 / ((K - 1) as f32);
}
}
Self {
frequencies,
alphabet: std::marker::PhantomData,
......@@ -176,6 +198,12 @@ impl<A: Alphabet, const K: usize> Background<A, K> {
}
}
impl<A: Alphabet, const K: usize> AsRef<[f32; K]> for Background<A, K> {
fn as_ref(&self) -> &[f32; K] {
&self.frequencies
}
}
impl<A: Alphabet, const K: usize> From<[f32; K]> for Background<A, K> {
fn from(frequencies: [f32; K]) -> Self {
Self {
......@@ -185,18 +213,32 @@ impl<A: Alphabet, const K: usize> From<[f32; K]> for Background<A, K> {
}
}
/// A matrix storing log-likelihood of symbol probabilities at each position.
#[derive(Clone, Debug)]
pub struct WeightMatrix<A: Alphabet, const K: usize> {
alphabet: std::marker::PhantomData<A>,
pub background: Background<A, K>,
pub data: DenseMatrix<f32, K>,
background: Background<A, K>,
data: DenseMatrix<f32, K>,
}
impl<A: Alphabet, const K: usize> WeightMatrix<A, K> {
/// The length of the motif encoded in this weight matrix.
#[inline]
pub fn len(&self) -> usize {
self.data.rows()
}
/// The log-likelihoods of the position weight matrix.
#[inline]
pub fn weights(&self) -> &DenseMatrix<f32, K> {
&self.data
}
/// The background frequencies of the position weight matrix.
#[inline]
pub fn background(&self) -> &Background<A, K> {
&self.background
}
}
impl<A: Alphabet, const K: usize> AsRef<WeightMatrix<A, K>> for WeightMatrix<A, K> {
......@@ -210,9 +252,3 @@ impl<A: Alphabet, const K: usize> AsRef<DenseMatrix<f32, K>> for WeightMatrix<A,
&self.data
}
}
impl<A: Alphabet, const K: usize> AsMut<DenseMatrix<f32, K>> for WeightMatrix<A, K> {
fn as_mut(&mut self) -> &mut DenseMatrix<f32, K> {
&mut self.data
}
}
......@@ -118,12 +118,12 @@ impl<A: Alphabet, const C: usize> From<EncodedSequence<A>> for StripedSequence<A
#[cfg(test)]
mod test {
use super::*;
use crate::DnaAlphabet;
use crate::DnaSymbol::*;
use crate::Dna;
use crate::Nucleotide::*;
#[test]
fn test_stripe() {
let seq = EncodedSequence::<DnaAlphabet>::from_str("ATGCA").unwrap();
let seq = EncodedSequence::<Dna>::from_str("ATGCA").unwrap();
let striped = seq.to_striped::<4>();
assert_eq!(striped.data.rows(), 2);
assert_eq!(&striped.data[0], &[A, G, A, N]);
......@@ -138,7 +138,7 @@ mod test {
#[test]
fn test_configure_wrap() {
let seq = EncodedSequence::<DnaAlphabet>::from_str("ATGCA").unwrap();
let seq = EncodedSequence::<Dna>::from_str("ATGCA").unwrap();
let mut striped = seq.to_striped::<4>();
striped.configure_wrap(2);
......
......@@ -8,7 +8,7 @@ use std::str::FromStr;
use lightmotif::Alphabet;
use lightmotif::CountMatrix;
use lightmotif::DnaAlphabet;
use lightmotif::Dna;
use lightmotif::EncodedSequence;
use lightmotif::Pipeline;
......@@ -35,10 +35,10 @@ const EXPECTED: &[f32] = &[
#[test]
fn test_score_generic() {
let encoded = EncodedSequence::<DnaAlphabet>::from_str(SEQUENCE).unwrap();
let encoded = EncodedSequence::<Dna>::from_str(SEQUENCE).unwrap();
let mut striped = encoded.to_striped::<2>();
let cm = CountMatrix::<DnaAlphabet, { DnaAlphabet::K }>::from_sequences(
let cm = CountMatrix::<Dna, { Dna::K }>::from_sequences(
PATTERNS
.iter()
.map(|x| EncodedSequence::from_str(x).unwrap()),
......@@ -68,7 +68,7 @@ fn test_score_generic() {
#[cfg(target_feature = "ssse3")]
#[test]
fn test_score_ssse3() {
let encoded = EncodedSequence::<DnaAlphabet>::from_str(SEQUENCE).unwrap();
let encoded = EncodedSequence::<Dna>::from_str(SEQUENCE).unwrap();
let mut striped = encoded.to_striped();
let cm = CountMatrix::from_sequences(
......@@ -104,10 +104,10 @@ fn test_score_ssse3() {
#[cfg(target_feature = "avx2")]
#[test]
fn test_score_avx2() {
let encoded = EncodedSequence::<DnaAlphabet>::from_str(SEQUENCE).unwrap();
let encoded = EncodedSequence::<Dna>::from_str(SEQUENCE).unwrap();
let mut striped = encoded.to_striped::<{ std::mem::size_of::<__m256>() }>();
let cm = CountMatrix::<DnaAlphabet, { DnaAlphabet::K }>::from_sequences(
let cm = CountMatrix::<Dna, { Dna::K }>::from_sequences(
PATTERNS
.iter()
.map(|x| EncodedSequence::from_str(x).unwrap()),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment