1use std::collections::HashMap;
2use std::mem::take;
3use std::ops::Range;
4use bimap::BiMap;
5use itertools::Itertools;
6use serde::de::DeserializeOwned;
7use serde_derive::{Deserialize, Serialize};
8use std::fmt::{Debug, Display};
9use std::hash::Hash;
10use std::{mem, str};
11use crate::dna_string::DnaString;
12use crate::summarizer::{IDTag, Tag, ID};
13use crate::{BaseQuality, Exts, Kmer, QualityBins, QualityVec, Vmer, base_to_bits, base_to_bits_checked};
14
15#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Copy)]
16pub enum Strandedness {
17 Forward,
18 Reverse,
19 Unstranded
20}
21
22#[derive(Debug, PartialEq, )]
24pub struct Read<D> {
25 seq: DnaString,
26 exts: Exts,
27 data: D,
28 strand: Strandedness,
29 quality: Option<QualityVec>
30}
31
32impl<D: Clone + Copy> Read<D> {
33 pub fn new(seq: DnaString, exts: Exts, data: D, strand: Strandedness, quality: Option<QualityVec>) -> Read<D> {
35 Read { seq, exts, data, strand, quality }
36 }
37
38 pub fn seq(&self) -> &DnaString {
40 &self.seq
41 }
42
43 pub fn exts(&self) -> Exts {
45 self.exts
46 }
47
48 pub fn data(&self) -> D {
50 self.data
51 }
52
53 pub fn stranded(&self) -> Strandedness {
55 self.strand
56 }
57
58 pub fn iter_kmer_exts_quality<'a, K: Kmer + 'a>(&'a self) -> Box<dyn Iterator<Item = (K, Exts, Option<BaseQuality>)> + 'a> {
59 if let Some(quality) = self.quality.as_ref() {
60 Box::new(self.seq()
61 .iter_kmer_exts::<K>(self.exts)
62 .zip(quality
63 .iter_k_lowest_q::<K>()
64 .map(Some)
65 )
66 .map(|((kmer, exts), quality)| (kmer, exts, quality))
67 )
68 } else {
69 Box::new(self.seq()
70 .iter_kmer_exts::<K>(self.exts)
71 .map(|(kmer, exts)| (kmer, exts, None)))
72 }
73 }
74}
75
76pub struct PairedRead<D> {
78 read1: Read<D>,
79 read2: Read<D>
80}
81
82impl<D> PairedRead<D> {
83 pub fn new(read1: Read<D>, read2: Read<D>) -> PairedRead<D> {
85 PairedRead {
86 read1,
87 read2
88 }
89 }
90
91 pub fn reads(&self) -> (&Read<D>, &Read<D>) {
93 (&self.read1, &self.read2)
94 }
95}
96
97#[derive(Ord, PartialOrd, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Debug)]
108pub struct Reads<D> {
109 storage: Vec<u64>,
110 ends: Vec<usize>,
111 exts: Option<Vec<Exts>>,
112 quality: Option<Vec<u64>>,
113 data: Vec<D>,
114 len: usize,
115 stranded: Strandedness,
116 quality_bins: QualityBins
117
118}
119
120impl<D: Clone + Copy> Reads<D> {
121
122 pub fn new(stranded: Strandedness) -> Self {
124 Reads {
125 storage: Vec::new(),
126 ends: Vec::new(),
127 exts: None,
128 data: Vec::new(),
129 quality: None,
130 len: 0,
131 stranded,
132 quality_bins: QualityBins::default(),
133 }
134 }
135
136 pub fn new_with_quality(stranded: Strandedness) -> Self {
137 Reads {
138 storage: Vec::new(),
139 ends: Vec::new(),
140 exts: None,
141 data: Vec::new(),
142 quality: Some(Vec::new()),
143 len: 0,
144 stranded,
145 quality_bins: QualityBins::default(),
146 }
147 }
148
149 #[inline(always)]
150 pub fn stranded(&self) -> Strandedness {
151 self.stranded
152 }
153
154 #[inline(always)]
155 pub fn n_reads(&self) -> usize {
157 self.ends.len()
158 }
159
160 pub fn mem(&self) -> usize {
162 let exts_size = if let Some(e_vec) = self.exts.as_ref() { size_of_val(&**e_vec) } else { 0 };
163 let quality_size_inner = if let Some(q) = self.quality.as_ref() {
164 size_of_val(&*q)
165 } else {
166 0
167 };
168 mem::size_of_val(self) + size_of_val(&*self.storage) + size_of_val(&*self.data) + size_of_val(&*self.ends) + exts_size + quality_size_inner
169 }
170
171 pub fn set_stranded(&mut self, stranded: Strandedness) {
173 self.stranded = stranded
174 }
175
176 pub fn set_custom_quality_bins(&mut self, quality_bins: QualityBins) {
178 self.quality_bins = quality_bins
179 }
180
181 fn add_exts(&mut self, exts: Option<Exts>) {
183 match exts {
184 Some(e) => {
185 match self.exts.as_mut() {
187 Some(e_vec) => e_vec.push(e),
189 None => {
191 if e != Exts::empty() {
193 self.exts = Some(vec![Exts::empty(); self.n_reads() - 1]);
195 self.exts.as_mut().unwrap().push(e);
196 } }
198 }
199 }
200 None => {
201 if let Some(e_vec) = self.exts.as_mut() {
202 e_vec.push(Exts::empty())
204 } }
206 }
207
208 }
209
210 pub fn add_read<V: Vmer>(&mut self, seq: V, exts: Option<Exts>, data: D, quality_scores: Option<&[u8]>) {
213 if let (Some(q), true) = (quality_scores, self.quality.is_some()) {
215 assert_eq!(seq.len(), q.len(), "mismatch in read and quality score length");
217 for (base, &score) in seq.iter().zip(q) {
218 self.push_base_and_quality(base, score)
219 }
220 } else if self.quality.is_none() {
221 for base in seq.iter() {
223 self.push_base(base);
224 }
225 } else {
226 panic!("Error: quality scores have to be added to all reads or none")
228 }
229
230 self.ends.push(self.len);
231 self.add_exts(exts);
232 self.data.push(data);
233 }
234
235 pub fn from_vmer_vec<V: Vmer, S: IntoIterator<Item=(V, Exts, D)>>(vec_iter: S, stranded: Strandedness) -> Self {
238 let mut reads = Reads::new(stranded);
239 for (vmer, exts, data) in vec_iter {
240 for base in vmer.iter() {
241 reads.push_base(base);
242 }
243 reads.ends.push(reads.len);
244 reads.add_exts(Some(exts));
245 reads.data.push(data);
246 }
247
248 reads.shrink_to_fit();
249
250 reads
251 }
252
253
254 pub fn add_from_bytes(&mut self, bytes: &[u8], exts: Option<Exts>, data: D) {
261
262 let missing = 32 - (self.len % 32);
264 if missing != 0 {
265 if missing > bytes.len() {
266 let fill = bytes.iter().map(|c| base_to_bits(*c));
267 self.extend(fill);
268 self.ends.push(self.len);
269 self.add_exts(exts);
270 self.data.push(data);
271 return;
272 } else {
273 let fill = bytes[0..missing].iter().map(|c| base_to_bits(*c));
274 self.extend(fill);
275 }
276 }
277
278 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
280 {
281 if is_x86_feature_detected!("avx2") {
282 for chunk in bytes[missing..bytes.len()].chunks(32) {
283 if chunk.len() == 32 {
284 let (conv_chunk, _) = unsafe { crate::bitops_avx2::convert_bases(chunk) };
285 let packed = unsafe { crate::bitops_avx2::pack_32_bases(conv_chunk) };
286 self.storage.push(packed);
287 self.len += 32;
288 } else {
289 let b = chunk.iter().map(|c| base_to_bits(*c));
290 self.extend(b);
291 }
292 }
293 self.ends.push(self.len);
294 self.add_exts(exts);
295 self.data.push(data);
296
297 return;
298 }
299 }
300
301 let b = bytes.iter().map(|c| base_to_bits(*c));
302 self.extend(b);
303 self.ends.push(self.len);
304 self.add_exts(exts);
305 self.data.push(data);
306
307
308 }
309
310 pub fn add_from_bytes_checked(&mut self, bytes: &[u8], exts: Option<Exts>, data: D) -> bool {
315
316 let (_, corrects): (Vec<u8>, Vec<bool>) = bytes.iter().map(|c| base_to_bits_checked(*c)).collect();
317 if corrects.iter().contains(&false) { return false }
318
319
320 let missing = 32 - (self.len % 32);
322 if missing != 0 {
323 if missing > bytes.len() {
324 let fill = bytes.iter().map(|c| base_to_bits(*c));
325 self.extend(fill);
326 self.add_exts(exts);
327 self.data.push(data);
328 self.ends.push(self.len);
329 return true;
330 } else {
331 let fill = bytes[0..missing].iter().map(|c| base_to_bits(*c));
332 self.extend(fill);
333 }
334 }
335
336 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
338 {
339 if is_x86_feature_detected!("avx2") {
340 for chunk in bytes[missing..bytes.len()].chunks(32) {
341 if chunk.len() == 32 {
342 let (conv_chunk, _) = unsafe { crate::bitops_avx2::convert_bases(chunk) };
343 let packed = unsafe { crate::bitops_avx2::pack_32_bases(conv_chunk) };
344 self.storage.push(packed);
345 self.len += 32;
346 } else {
347 let b = chunk.iter().map(|c| base_to_bits(*c));
348 self.extend(b);
349 }
350 }
351
352 self.ends.push(self.len);
353 self.add_exts(exts);
354 self.data.push(data);
355
356 return true;
357 }
358 }
359
360 let b = bytes.iter().map(|c| base_to_bits(*c));
361 self.extend(b);
362 self.ends.push(self.len);
363 self.add_exts(exts);
364 self.data.push(data);
365
366 true
367 }
368
369
370 fn push_base(&mut self, base: u8) {
372 let bit = (self.len % 32) * 2;
373 if bit != 0 {
374 match self.storage.pop() {
375 Some(last) => {
376 let last = last + ((base as u64) << (64 - bit - 2));
377 self.storage.push(last);
378 },
379 None => panic!("tried to push base to empty vector (?)")
380 }
381 } else {
382 self.storage.push((base as u64) << 62);
383 }
384 self.len += 1;
385 }
386
387 fn push_base_and_quality(&mut self, base: u8, score: u8) {
389 let Some(quality) = self.quality.as_mut() else { return; };
390 let base_quality = self.quality_bins.base_quality_from_ascii_bytes(score);
391
392 let bit = (self.len % 32) * 2;
393 if bit != 0 {
394 match self.storage.pop() {
395 Some(last) => {
396 let last = last + ((base as u64) << (64 - bit - 2));
397 self.storage.push(last);
398 },
399 None => panic!("tried to push base to empty vector (?)")
400 }
401
402 match quality.pop() {
403 Some(last) => {
404 let last = last + ((base_quality as u64) << (64 - bit - 2));
405 quality.push(last);
406 },
407 None => panic!("tried to push quality to empty vector (?)")
408 }
409 } else {
410 self.storage.push((base as u64) << 62);
411 quality.push((base_quality as u64) << 62);
412 }
413 self.len += 1;
414 }
415
416 fn extend(&mut self, mut bytes: impl Iterator<Item = u8>) {
418 while self.len % 32 != 0 {
420 match bytes.next() {
421 Some(b) => self.push_base(b),
422 None => return,
423 }
424 }
425
426 let mut bytes = bytes.peekable();
427
428 while bytes.peek().is_some() {
430 let mut val: u64 = 0;
431 let mut offset = 62;
432 let mut n_added = 0;
433
434 for _ in 0..32 {
435 if let Some(b) = bytes.next() {
436 assert!(b < 4);
437 val |= (b as u64) << offset;
438 offset -= 2;
439 n_added += 1;
440 } else {
441 break;
442 }
443 }
444
445 self.storage.push(val);
446 self.len += n_added;
447 }
448 }
449
450 #[inline(always)]
451 fn addr(&self, i: &usize) -> (usize, usize) {
452 (i / 32, (i % 32 ) * 2)
453 }
454
455 pub fn get_read(&self, i: usize) -> Option<Read<D>> {
457 if i >= self.n_reads() { return None }
458
459 let mut sequence = DnaString::new();
461 let end = self.ends[i];
462 let start = match i {
464 0 => 0,
465 1.. => self.ends[i-1]
466 };
467
468 for b in start..end {
469 let (block, bit) = self.addr(&b);
470 let base = ((self.storage[block] >> (62 - bit)) & 3u64) as u8;
471 sequence.push(base);
472 }
473
474 let quality = if let Some(quality) = self.quality.as_ref() {
476 let mut base_qualities = Vec::new();
477 for q in start..end {
478 let (block, bit) = self.addr(&q);
479 let base_quality = BaseQuality::from_u64((quality[block] >> (62 - bit)) & 3u64);
480 base_qualities.push(base_quality);
481 }
482
483 Some(QualityVec::from_vec(base_qualities))
484 } else {
485 None
486 };
487
488 let exts = match self.exts {
489 Some(ref e_vec) => e_vec[i],
490 None => Exts::empty()
491 };
492
493 Some(Read::new(sequence, exts, self.data[i], self.stranded, quality))
494 }
495
496
497 pub fn shrink_to_fit(&mut self) {
501 self.storage.shrink_to_fit();
502 self.data.shrink_to_fit();
503 if let Some(e_vec) = self.exts.as_mut() { e_vec.shrink_to_fit(); }
504 self.ends.shrink_to_fit();
505 }
506
507 pub fn iter(&self) -> ReadsIter<'_, D> {
509 ReadsIter {
510 reads: self,
511 i: 0,
512 end: self.n_reads(),
513 length: self.n_reads(),
514 }
515 }
516
517 pub fn partial_iter(&self, range: Range<usize>) -> ReadsIter<'_, D> {
519 assert!(range.end <= self.n_reads());
520 assert!(range.start < self.n_reads());
521 assert!(range.start < range.end);
522 ReadsIter {
523 reads: self,
524 i: range.start,
525 end: range.end,
526 length: (range.end - range.start)
527 }
528 }
529
530 pub fn info(&self) -> String {
531 format!("Reads {{ n reads: {}, stranded: {:?} }}", self.n_reads(), self.stranded)
532 }
533}
534
535impl<D: ReadData> Reads<D> {
536 pub fn tag_kmers(&self, k: usize) -> HashMap<Tag, usize> {
538 let mut hm = HashMap::new();
539
540 self.iter().for_each(|read| {
541 let kmers = read.seq.len().saturating_sub(k - 1);
542 if let Some(tag) = read.data.get_tag() {
543 if let Some(count) = hm.get_mut(&tag) {
544 *count += kmers;
545 } else {
546 hm.insert(tag, kmers);
547 }
548 }
549
550 });
551
552 hm
553 }
554}
555
556impl<D: Clone + Copy> Default for Reads<D> {
557 fn default() -> Self {
558 Self::new(Strandedness::Unstranded)
559 }
560}
561
562pub struct ReadsIter<'a, D> {
564 reads: &'a Reads<D>,
565 i: usize,
566 end: usize,
567 length: usize,
568}
569
570impl<D: Clone + Copy> Iterator for ReadsIter<'_, D> {
571 type Item = Read<D>;
572
573 fn next(&mut self) -> Option<Self::Item> {
574 if (self.i < self.reads.n_reads()) && (self.i < self.end) {
575 let value = self.reads.get_read(self.i);
576 self.i += 1;
577 value
578 } else {
579 None
580 }
581 }
582}
583
584impl<D: Copy> ExactSizeIterator for ReadsIter<'_, D> {
585 fn len(&self) -> usize {
586 self.length
587 }
588}
589
590impl<D: Clone + Copy + Debug> Display for Reads<D> {
591 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
592 let vec: Vec<_> = self.iter().collect();
593 write!(f, "{:?}", vec)
594 }
595}
596
597#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
598pub enum ReadsPaired<D> {
599 Empty,
600 Unpaired { reads: Reads<D> },
601 Paired { paired1: Reads<D>, paired2: Reads<D> },
602 Combined {paired1: Reads<D>, paired2: Reads<D>, unpaired: Reads<D>}
603}
604
605impl<D: Clone + Copy> ReadsPaired<D> {
606 pub fn iterable(&self) -> Vec<&Reads<D>> {
608 match self {
609 Self::Empty => vec![],
610 Self::Unpaired { reads } => vec![reads],
611 Self::Paired { paired1, paired2 } => vec![paired1, paired2],
612 Self::Combined { paired1, paired2, unpaired } => vec![paired1, paired2, unpaired],
613 }
614 }
615
616 pub fn n_reads(&self) -> usize {
618 match self {
619 Self::Empty => 0,
620 Self::Unpaired { reads } => reads.n_reads(),
621 Self::Paired { paired1, paired2 } => paired1.n_reads() + paired2.n_reads(),
622 Self::Combined { paired1, paired2, unpaired } => paired1.n_reads() + paired2.n_reads() + unpaired.n_reads(),
623 }
624 }
625
626 pub fn n_read_pairs(&self) -> usize {
628 match self {
629 Self::Empty => 0,
630 Self::Unpaired { reads: _ } => 0,
631 Self::Paired { paired1, paired2 } => {
632 assert_eq!(paired1.n_reads(), paired2.n_reads());
633 paired1.n_reads()
634 },
635 Self::Combined { paired1, paired2, unpaired: _ } => {
636 assert_eq!(paired1.n_reads(), paired2.n_reads());
637 paired1.n_reads()
638 }
639 }
640 }
641
642 pub fn n_unpaired_reads(&self) -> usize {
644 match self {
645 Self::Empty => 0,
646 Self::Unpaired { reads } => reads.n_reads(),
647 Self::Paired { paired1: _, paired2: _ } => 0,
648 Self::Combined { paired1: _, paired2: _, unpaired } => {
649 unpaired.n_reads()
650 }
651 }
652 }
653
654 pub fn get_read(&self, i: usize) -> Option<Read<D>> {
657 match self {
658 ReadsPaired::Empty => None,
659 ReadsPaired::Unpaired { reads } => reads.get_read(i),
660 ReadsPaired::Paired { paired1, paired2 } => {
661 if i < paired1.n_reads() {
662 paired1.get_read(i)
663 } else if (i - paired1.n_reads()) < paired2.n_reads() {
664 paired2.get_read(i - paired1.n_reads())
665 } else {
666 None
667 }
668 },
669 ReadsPaired::Combined { paired1, paired2, unpaired } => {
670 if i < paired1.n_reads() {
671 paired1.get_read(i)
672 } else if (i - paired1.n_reads()) < paired2.n_reads() {
673 paired2.get_read(i - paired1.n_reads())
674 } else if (i - (paired1.n_reads() + paired2.n_reads())) < unpaired.n_reads() {
675 unpaired.get_read(i - (paired1.n_reads() + paired2.n_reads()))
676 } else {
677 None
678 }
679 },
680 }
681 }
682
683 pub fn get_paired_read(&self, i: usize) -> Option<PairedRead<D>> {
684 match self {
685 ReadsPaired::Empty => None,
686 ReadsPaired::Unpaired { reads: _ } => None,
687 ReadsPaired::Paired { paired1, paired2 } => {
688 if let (Some(read1), Some(read2)) = (paired1.get_read(i), paired2.get_read(i)) {
689 Some(PairedRead::new(read1, read2))
690 } else {
691 None
692 }
693 }
694 ReadsPaired::Combined { paired1, paired2, unpaired: _ } => {
695 if let (Some(read1), Some(read2)) = (paired1.get_read(i), paired2.get_read(i)) {
696 Some(PairedRead::new(read1, read2))
697 } else {
698 None
699 }
700 },
701 }
702 }
703
704 pub fn mem(&self) -> usize {
705 match self {
706 Self::Empty => 0,
707 Self::Unpaired { reads } => reads.mem(),
708 Self::Paired { paired1, paired2 } => paired1.mem() + paired2.mem(),
709 Self::Combined { paired1, paired2, unpaired } => paired1.mem() + paired2.mem() + unpaired.mem(),
710 }
711 }
712
713 pub fn from_reads((paired1, paired2, unpaired): (Reads<D>, Reads<D>, Reads<D>)) -> Self {
716 assert_eq!(paired1.n_reads(), paired2.n_reads(), "Error: R1 read and R2 read counts have to match");
718
719 if (paired1.n_reads() + paired2.n_reads() + unpaired.n_reads()) == 0 {
720 ReadsPaired::Empty
722 } else if paired1.n_reads() == 0 && unpaired.n_reads() > 0 {
723 ReadsPaired::Unpaired { reads: unpaired }
725 } else if paired1.n_reads() > 0 && unpaired.n_reads() == 0 {
726 ReadsPaired::Paired { paired1, paired2 }
728 } else if paired1.n_reads() > 0 && unpaired.n_reads() > 0 {
729 ReadsPaired::Combined { paired1, paired2, unpaired }
731 } else {
732 panic!("error in transforming Reads into ReadsPaired")
733 }
734 }
735
736 pub fn iter(&self) -> Box<dyn Iterator<Item = Read<D>> + '_> {
737 match self {
738 ReadsPaired::Empty => panic!("Error: no reads to process"),
739 ReadsPaired::Unpaired { reads } => Box::new(reads.iter()),
740 ReadsPaired::Paired { paired1, paired2 } => Box::new(paired1.iter().chain(paired2.iter())),
741 ReadsPaired::Combined { paired1, paired2, unpaired } => Box::new(paired1.iter().chain(paired2.iter()).chain(unpaired.iter())),
742 }
743 }
744
745 pub fn iter_partial(&self, range: Range<usize>) -> Box<dyn Iterator<Item = Read<D>> + '_> {
746 match self {
747 Self::Empty => panic!("Error: no reads to process"),
748 Self::Unpaired { reads } => Box::new(reads.partial_iter(range)),
749 Self::Paired { paired1, paired2 } => {
750 let n_p1 = paired1.n_reads();
751 if range.start >= n_p1 {
752 Box::new(paired2.partial_iter((range.start - n_p1)..(range.end - n_p1)))
754 } else if range.end <= n_p1 {
755 Box::new(paired1.partial_iter(range))
757 } else {
758 Box::new(paired1.partial_iter(range.start..n_p1).chain(paired2.partial_iter(0..(range.end - n_p1))))
760 }
761 },
762 Self::Combined { paired1, paired2, unpaired } => {
763 let n_p1 = paired1.n_reads();
764 let n_p2 = paired2.n_reads();
765 let n_p12 = n_p1 + paired2.n_reads();
766 if range.end <= n_p1 {
767 Box::new(paired1.partial_iter(range))
769 } else if range.end >= n_p1 && range.end <= n_p12 && range.start >= n_p1 && range.start <= n_p12 {
770 Box::new(paired2.partial_iter((range.start - n_p1)..(range.end - n_p1)))
772 } else if range.start >= n_p12 {
773 Box::new(unpaired.partial_iter((range.start - n_p12)..(range.end - n_p12)))
775 } else if range.start <= n_p1 && range.end >= n_p1 && range.end <= n_p12 {
776 Box::new(paired1.partial_iter(range.start..n_p1).chain(paired2.partial_iter(0..(range.end - n_p1))))
778 } else if range.start >= n_p1 && range.start <= n_p12 && range.end >= n_p12 {
779 Box::new(paired2.partial_iter((range.start - n_p1)..n_p2).chain(unpaired.partial_iter(0..(range.end - n_p12))))
781 } else {
782 Box::new(paired1.partial_iter(range.start..n_p1).chain(paired2.partial_iter(0..n_p2)).chain(unpaired.partial_iter(0..(range.end - n_p12))))
784 }
785 }
786 }
787 }
788
789 pub fn decombine(&mut self) -> usize {
792 if let Self::Combined { paired1, paired2, unpaired } = self {
793 let rm_reads = unpaired.n_reads();
794 *self = ReadsPaired::Paired { paired1: take(paired1), paired2: take(paired2) };
795 rm_reads
796 } else {
797 0
798 }
799 }
800}
801
802impl<DI: ReadData> ReadsPaired<DI> {
803 pub fn tag_kmers(&self, k: usize) -> HashMap<Tag, usize> {
805 match self {
806 Self::Empty => HashMap::new(),
807 Self::Unpaired { reads } => reads.tag_kmers(k),
808 Self::Paired { paired1, paired2 } => {
809 let mut hm_p1 = paired1.tag_kmers(k);
810 let hm_p2 = paired2.tag_kmers(k);
811
812 hm_p2.into_iter().for_each(|(data, kmers)| {
814 if let Some(count) = hm_p1.get_mut(&data) {
815 *count += kmers;
816 } else {
817 hm_p1.insert(data, kmers);
818 }
819 });
820
821 hm_p1
822 },
823 Self::Combined { paired1, paired2, unpaired } => {
824 let mut hm_p1: HashMap<u8, usize> = paired1.tag_kmers(k);
825 let hm_p2 = paired2.tag_kmers(k);
826 let hm_up = unpaired.tag_kmers(k);
827
828 hm_p2.into_iter().for_each(|(data, kmers)| {
830 if let Some(count) = hm_p1.get_mut(&data) {
831 *count += kmers;
832 } else {
833 hm_p1.insert(data, kmers);
834 }
835 });
836
837 hm_up.into_iter().for_each(|(data, kmers)| {
838 if let Some(count) = hm_p1.get_mut(&data) {
839 *count += kmers;
840 } else {
841 hm_p1.insert(data, kmers);
842 }
843 });
844
845 hm_p1
846 }
847 }
848 }
849
850 pub fn tag_kmers_vec(&self, k: usize, n_samples: usize) -> Vec<u64> {
855 let hashed_kmer_counts = self.tag_kmers(k);
856
857 let mut kmer_counts = vec![0; n_samples];
858
859 for (tag, kmer_count) in hashed_kmer_counts {
860 kmer_counts[tag as usize] += kmer_count as u64;
861 }
862
863 kmer_counts
864 }
865}
866
867impl<D: Clone + Copy> Display for ReadsPaired<D> {
868 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
869 match self {
870 Self::Empty => write!(f, "empty ReadsPaired"),
871 Self::Unpaired { reads } => write!(f, "unpaired ReadsPaired: \n{}", reads.info()),
872 Self::Paired { paired1, paired2 } => write!(f, "paired ReadsPaired: \n{}\n{}", paired1.info(), paired2.info()),
873 Self::Combined { paired1, paired2, unpaired } => write!(f, "combined ReadsPaired: \n{}\n{}\n{}", paired1.info(), paired2.info(), unpaired.info()),
874 }
875 }
876}
877
878pub trait ReadData: PartialEq + Hash + serde::Serialize + DeserializeOwned + Debug + Clone + Copy + Eq + Send + Sync + Ord {
880 fn new(id: ID, tag: Tag) -> Self;
882 fn read_data(gene_ids: &mut BiMap<String, ID>, read_name: &[u8], tag: Tag) -> Self;
884 fn get_tag(&self) -> Option<Tag>;
886 fn read_datas() -> ReadDatas;
888}
889
890impl ReadData for Tag {
891 fn new(_id: ID, tag: Tag) -> Self {
892 tag
893 }
894
895 fn read_data(_: &mut BiMap<String, ID>, _: &[u8], tag: Tag) -> Self {
896 tag
897 }
898
899 fn get_tag(&self) -> Option<Tag> {
900 Some(*self)
901 }
902
903 fn read_datas() -> ReadDatas {
904 ReadDatas::Tag
905 }
906}
907
908impl ReadData for ID {
909 fn new(id: ID, _tag: Tag) -> Self {
910 id
911 }
912
913 fn read_data(gene_ids: &mut BiMap<String, ID>, read_name: &[u8], _: Tag) -> Self {
914
915 let read_name_sting = str::from_utf8(read_name).expect("error reading read name").to_string();
918 let mut split_iter = read_name_sting.split('_');
919 let mut gene = String::new();
920
921 let Some(gene1) = split_iter.next() else {
922 panic!("no gene names found in reads - only use id summarizers with marbel data - read name: {}", read_name_sting)
923 };
924 gene.push_str(gene1);
925
926 gene.push('_');
927
928 let Some(gene2) = split_iter.next() else {
929 panic!("no gene names found in reads - only use id summarizers with marbel data - read name: {}", read_name_sting)
930 };
931 gene.push_str(gene2);
932
933 let new_id = gene_ids.len() as ID;
935 if new_id == ID::MAX { panic!("number of genes has surpassed 65.5k limit of u16") }
936 match gene_ids.get_by_left(&gene) {
937 Some(id) => *id,
938 None => {
939 gene_ids.insert(gene, new_id);
940 new_id
941 },
942 }
943 }
944
945 fn get_tag(&self) -> Option<Tag> {
946 None
947 }
948
949 fn read_datas() -> ReadDatas {
950 ReadDatas::ID
951 }
952}
953
954impl ReadData for IDTag {
955 fn new(id: ID, tag: Tag) -> Self {
956 Self::new(id, tag)
957 }
958
959 fn read_data(gene_ids: &mut BiMap<String, ID>, read_name: &[u8], tag: Tag) -> Self {
960 let id = ID::read_data(gene_ids, read_name, tag);
961 IDTag::new(id, tag)
962 }
963
964 fn get_tag(&self) -> Option<Tag> {
965 Some(self.tag())
966 }
967
968 fn read_datas() -> ReadDatas {
969 ReadDatas::IDTag
970 }
971}
972
973#[derive(PartialEq, Eq, Debug, Clone, Copy, Serialize, Deserialize)]
974pub enum ReadDatas {
975 ID,
976 Tag,
977 IDTag
978}
979
980#[cfg(test)]
981mod tests {
982 use std::{collections::HashMap, time};
983
984 use bimap::BiMap;
985 use itertools::enumerate;
986 use rand::random;
987
988 use crate::{Exts, QualityVec, dna_string::DnaString, reads::{Read, Strandedness}, summarizer::{ID, IDTag, Tag}, test::random_dna};
989 use crate::reads::ReadData;
990 use super::{Reads, ReadsPaired};
991
992 #[test]
993 fn test_add() {
994
995 let fastq = vec![
996 (DnaString::from_acgt_bytes(str::as_bytes("ACGATCGT")), Exts::empty(), 6u8, str::as_bytes("CCC-CC;#")),
997 (DnaString::from_acgt_bytes(str::as_bytes("GGGGGG")), Exts::empty(), 5u8, str::as_bytes("CCCCCC")),
998 (DnaString::from_acgt_bytes(str::as_bytes("TTGGTT")), Exts::empty(), 7u8, str::as_bytes("CCC-CC")),
999 (DnaString::from_acgt_bytes(str::as_bytes("ACCAC")), Exts::empty(), 8u8, str::as_bytes("-CC;#")),
1000 (DnaString::from_acgt_bytes(str::as_bytes("TCCCT")), Exts::empty(), 9u8, str::as_bytes("CCCC;")),
1001 (DnaString::from_acgt_bytes(str::as_bytes("ACCAC")), Exts::empty(), 8u8, str::as_bytes("C-C;C")),
1002 (DnaString::from_acgt_bytes(str::as_bytes("TCCCT")), Exts::empty(), 9u8, str::as_bytes("CCC-C")),
1003 ];
1004
1005
1006 let mut reads = Reads::new_with_quality(Strandedness::Unstranded);
1007 for (read, _, data, quality) in fastq.clone() {
1008 reads.add_read(read, None, data, Some(quality));
1009 }
1010
1011 println!("reads: {:#?}", reads);
1012
1013
1014 assert_eq!(reads.storage, vec![1791212948343256433, 5140577499666710528]);
1019
1020 for (i, _) in fastq.iter().enumerate() {
1021 assert_eq!(
1023 Read::new(
1024 fastq[i].0.clone(),
1025 fastq[i].1,
1026 fastq[i].2,
1027 Strandedness::Unstranded,
1028 Some(QualityVec::from_ascii_bytes(fastq[i].3, reads.quality_bins))
1029 ),
1030 reads.get_read(i).unwrap())
1031 }
1032
1033 for read in reads.iter() {
1034 let seq = read.seq;
1035 println!("{:?}, {}", seq, seq.len())
1036 }
1037 println!();
1038
1039 for read in reads.partial_iter(5..7) {
1040 println!("{:?}", read)
1041 }
1042
1043 println!("memory usage: {}", reads.mem())
1044 }
1045
1046 #[test]
1047 fn test_get_read() {
1048 let mut reads = Reads::new(Strandedness::Unstranded);
1049 reads.add_from_bytes("ACGATCGNATGCTAGCTGATCGGCGACGATCGATGCTAGCTGATCGTAGCTGACTGATCGATCG".as_bytes(), None, 67u8);
1051 let read = reads.get_read(0);
1052 println!("{:?}", read);
1053 println!("{:#066b}", reads.storage[0]);
1054 println!("{:?}", reads)
1055 }
1056
1057 #[test]
1058 fn test_add_from_bytes() {
1059 let dna = [
1060 "AAGCGGAGATTATTCACGAGCATCGCGTAC".as_bytes(),
1061 "GATCGATGCATGCTAGA".as_bytes(),
1062 "ACGTAAAAAAAAAATTATATAACGTACGTAAAAAAAAAATTATATAACGTAACGTAAAAAAAAAAATTATAATAACGT".as_bytes(),
1063 "AGCTAGCTAGCTGACTGAGCGACTGA".as_bytes(),
1064 "AGCTAGCTAGCTGACTGAGCGACTGACGGATC".as_bytes(),
1065 "TTTTTTTTTTTTTTTTTTTTTTTT".as_bytes(),
1066 "ACGATCGAATGCTAGCTGATCGGCGACGATCGATGCTAGCTGATCGTAGCTGACTGATCGATCG".as_bytes(),
1067 "ACGATCGATGCTAGCTGATCGGCGACGATCGATGCTAGCTGATCGTAGCTGACTGATCGATCGAAGGGCAGTTAGGCCGTAAGCGCGAT".as_bytes(),
1068 ];
1069
1070 let mut reads: Reads<u8> = Reads::new(Strandedness::Unstranded);
1071 for seq in dna {
1072 reads.add_from_bytes(seq, None, random());
1073
1074 }
1075
1076 for (i, read) in enumerate(reads.iter()) {
1077 let sequence = DnaString::from_acgt_bytes(dna[i]);
1078 assert_eq!(read.seq, sequence);
1079 }
1080 }
1081
1082 #[test]
1083 fn test_add_from_bytes_checked() {
1084 let dna = [
1085 "AAGCGGAGATTATTCACGAGCATCGCGTAC".as_bytes(),
1086 "GATCGATGCATGCTAGA".as_bytes(),
1087 "ACGTAAAAAAAAAATTATATAACGTACGTAAAAAAAAAANTTATATAACGTAACGTAAAAAAAAAAATTATAATAACGT".as_bytes(),
1088 "AGCTAGCTAGCTGACNGAGCGACTGA".as_bytes(),
1089 "AGCTAGCTAGCTGACTGAGCGACTGACGGATC".as_bytes(),
1090 "TTTTTTTTTTTTTTTTTTTTTTTT".as_bytes(),
1091 "ACGATCGAATGCTAGCTGATCGGCGACGATCGATGCTAGCTGATCGTAGCTGACNNNTGATCGATCG".as_bytes(),
1092 "ACGATCGATGCTAGCTGATCGGCGACGATCGATGCTAGCTGATCGTAGCTGACTGATCGATCGAAGGGCAGTTAGGCCGTAAGCGCGAT".as_bytes(),
1093 "A".as_bytes(),
1094 "AAAAN".as_bytes(),
1095 "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN".as_bytes(),
1096 ];
1097
1098 let mut reads: Reads<u8> = Reads::new(Strandedness::Unstranded);
1099 let mut corrects = Vec::new();
1100 for seq in dna {
1101 corrects.push(reads.add_from_bytes_checked(seq, None, random()));
1102 }
1103
1104 let mut read_counter = 0;
1105
1106 for (i, correct) in enumerate(corrects) {
1107 let sequence = DnaString::from_acgt_bytes_checked(dna[i]);
1108 match correct {
1109 true => {
1110 let read = reads.get_read(read_counter).unwrap();
1111 assert_eq!(sequence.unwrap(), read.seq);
1112 read_counter += 1;
1113
1114 },
1115 false => assert!(sequence.is_err()),
1116 }
1117 }
1118 }
1119
1120 #[test]
1121 fn test_speed_from_bytes() {
1122 let dnas = [
1123 "AAGCGGAGATTATTCACGAGCATCGCGTAC".as_bytes(),
1124 "GATCGATGCATGCTAGA".as_bytes(),
1125 "ACGTAAAAAAAAAATTATATAACGTACGTAAAAAAAAAANTTATATAACGTAACGTAAAAAAAAAAATTATAATAACGT".as_bytes(),
1126 "AGCTAGCTAGCTGACNGAGCGACTGA".as_bytes(),
1127 "AGCTAGCTAGCTGACTGAGCGACTGACGGATC".as_bytes(),
1128 "TTTTTTTTTTTTTTTTTTTTTTTT".as_bytes(),
1129 "ACGATCGAATGCTAGCTGATCGGCGACGATCGATGCTAGCTGATCGTAGCTGACNNNTGATCGATCG".as_bytes(),
1130 "ACGATCGATGCTAGCTGATCGGCGACGATCGATGCTAGCTGATCGTAGCTGACTGATCGATCGAAGGGCAGTTAGGCCGTAAGCGCGAT".as_bytes(),
1131 "A".as_bytes(),
1132 "AAAAN".as_bytes(),
1133 "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN".as_bytes(),
1134 ];
1135
1136 const REPS: usize = 500000;
1137 let ds_start= time::Instant::now();
1145 let mut reads: Reads<u8> = Reads::new(Strandedness::Unstranded);
1146 for _i in 0..REPS {
1147 for dna in dnas {
1148 reads.add_read(DnaString::from_acgt_bytes(dna), None, random(), None);
1149 }
1150 }
1151 let ds_finish = ds_start.elapsed();
1152
1153 let r_start= time::Instant::now();
1154 let mut reads: Reads<u8> = Reads::new(Strandedness::Unstranded);
1155 for _i in 0..REPS {
1156 for dna in dnas {
1157 reads.add_from_bytes(dna, None, random());
1158 }
1159 }
1160 let r_finish = r_start.elapsed();
1161
1162 println!("through DnaString: {} s \n direct to Read: {} s", ds_finish.as_secs_f32(), r_finish.as_secs_f32())
1163
1164
1165 }
1166
1167
1168 #[test]
1169 fn test_reads_stranded() {
1170 let mut reads: Reads<u8> = Reads::new(Strandedness::Forward);
1171 assert_eq!(reads.stranded(), Strandedness::Forward);
1172 reads.set_stranded(Strandedness::Reverse);
1173 assert_eq!(reads.stranded(), Strandedness::Reverse);
1174
1175 }
1176
1177 #[test]
1178 fn test_reads_data_kmers() {
1179 let mut reads = Reads::new(Strandedness::Unstranded);
1180 let seqs = [
1181 ("ACGATCGTACGTACGTAGCTAGCTGCTAGCTAGCTGACTGACTGA", 0),
1182 ("CGATGCTATCAGCGAGCGATCGTACGTAGCTACG", 1),
1183 ("CGATCGACGAGCAGCGTATGCTACGAGCTGACGATCTACGA", 2),
1184 ("CACACACGGCATCGATCGAGCAGCATCGACTACGTA", 3),
1185 ];
1186
1187 seqs.iter().for_each(|(read, tag)| reads.add_from_bytes(read.as_bytes(), None, *tag as u8));
1188 let data_kmers = reads.tag_kmers(16);
1189
1190 let comp_hm: HashMap<u8, usize> = [(0, 30), (1, 19), (2, 26), (3, 21)].into_iter().collect();
1191
1192 assert_eq!(comp_hm, data_kmers);
1193 }
1194
1195 #[test]
1196 fn test_reads_add_exts() {
1197 let mut raw_reads = Vec::new();
1198 for _i in 0..10 {
1199 raw_reads.push((DnaString::from_bytes(&random_dna(100)), Exts::new(rand::random::<u8>()), rand::random::<u8>()));
1200 }
1201 let reads = Reads::from_vmer_vec(raw_reads.clone(), Strandedness::Unstranded);
1202 let new_raw_reads = reads.iter().map(|read| (read.seq, read.exts, read.data)).collect::<Vec<_>>();
1203
1204 assert_eq!(raw_reads, new_raw_reads)
1205 }
1206
1207 #[test]
1208 fn test_reads_info() {
1209 let mut reads = Reads::new(Strandedness::Unstranded);
1210 let seqs = [
1211 ("ACGATCGTACGTACGTAGCTAGCTGCTAGCTAGCTGACTGACTGA", 0),
1212 ("CGATGCTATCAGCGAGCGATCGTACGTAGCTACG", 1),
1213 ("CGATCGACGAGCAGCGTATGCTACGAGCTGACGATCTACGA", 2),
1214 ("CACACACGGCATCGATCGAGCAGCATCGACTACGTA", 3),
1215 ];
1216
1217 seqs.iter().for_each(|(read, tag)| reads.add_from_bytes(read.as_bytes(), None, *tag as u8));
1218
1219 assert_eq!(reads.info(), "Reads { n reads: 4, stranded: Unstranded }".to_string());
1220 }
1221
1222 #[test]
1223 fn test_reads_paired() {
1224 let mut p1 = Reads::new(Strandedness::Unstranded);
1225 let mut p2 = Reads::new(Strandedness::Unstranded);
1226 let mut up = Reads::new(Strandedness::Unstranded);
1227
1228 let reads_p1 = [
1229 "ACGATCGTACGTACGTAGCTAGCTGCTAGCTAGCTGACTGACTGA",
1230 "CGATGCTATCAGCGAGCGATCGTACGTAGCTACG",
1231 "CGATCGACGAGCAGCGTATGCTACGAGCTGACGATCTACGA",
1232 "CACACACGGCATCGATCGAGCAGCATCGACTACGTA",
1233 ];
1234
1235 let reads_p2 = [
1236 "AGCTAGCTAGCTACTGATCGTAGCTAGCTGATCGA",
1237 "AGCGATCGTACGTAGCTAGCTA",
1238 "CGATCGATCGACTAGCGTAGCTGACTGAC",
1239 "CAGATGCTCTGCTGACTGACTGATCGTACTGACTAGCATCTAGC",
1240 ];
1241
1242 let reads_up = [
1243 "CGTACTAGCTGACGTAC",
1244 "CGATGCTAGCTAGCTAGCGATCG",
1245 ];
1246
1247 let tags = (0..4).collect::<Vec<u8>>();
1248
1249 reads_p1.iter().enumerate().for_each(|(i, read)| p1.add_from_bytes(read.as_bytes(), None, tags[i]));
1250 reads_p2.iter().enumerate().for_each(|(i, read)| p2.add_from_bytes(read.as_bytes(), None, tags[i]));
1251 reads_up.iter().enumerate().for_each(|(i, read)| up.add_from_bytes(read.as_bytes(), Some(Exts::new(i as u8)), tags[i]));
1252
1253 let empty: ReadsPaired<u8> = ReadsPaired::from_reads((Reads::new(Strandedness::Unstranded), Reads::new(Strandedness::Unstranded), Reads::new(Strandedness::Unstranded)));
1254 assert_eq!(empty, ReadsPaired::Empty);
1255 assert_eq!(empty.mem(), 0);
1256 assert_eq!(empty.n_reads(), 0);
1257 assert_eq!(empty.iterable(), Vec::<&Reads<u8>>::new());
1258
1259 let unpaired = ReadsPaired::from_reads((Reads::new(Strandedness::Unstranded), Reads::new(Strandedness::Unstranded), up.clone()));
1260 assert_eq!(ReadsPaired::Unpaired { reads: up.clone() }, unpaired);
1261 println!("exts up {:?}", unpaired);
1262 assert_eq!(unpaired.mem(), 172);
1263 assert_eq!(unpaired.n_reads(), 2);
1264 assert_eq!(unpaired.iterable(), vec![&up]);
1265
1266 let paired = ReadsPaired::from_reads((p1.clone(), p2.clone(), Reads::new(Strandedness::Unstranded)));
1267 assert_eq!(ReadsPaired::Paired { paired1: p1.clone(), paired2: p2.clone() }, paired);
1268 assert_eq!(paired.mem(), 424);
1269 assert_eq!(paired.n_reads(), 8);
1270 assert_eq!(paired.iterable(), vec![&p1, &p2]);
1271
1272 let combined = ReadsPaired::from_reads((p1.clone(), p2.clone(), up.clone()));
1273 assert_eq!(ReadsPaired::Combined { paired1: p1.clone(), paired2: p2.clone(), unpaired: up.clone() }, combined);
1274 assert_eq!(combined.mem(), 596);
1275 assert_eq!(combined.n_reads(), 10);
1276 assert_eq!(combined.iterable(), vec![&p1, &p2, &up]);
1277
1278
1279 assert_eq!(unpaired.iter().collect::<Vec<_>>(), up.iter().collect::<Vec<_>>());
1282 assert_eq!(paired.iter().collect::<Vec<_>>(), p1.iter().chain(p2.iter()).collect::<Vec<_>>());
1283 assert_eq!(combined.iter().collect::<Vec<_>>(), p1.iter().chain(p2.iter()).chain(up.iter()).collect::<Vec<_>>());
1284
1285 assert_eq!(unpaired.iter_partial(0..1).collect::<Vec<_>>(), up.partial_iter(0..1).collect::<Vec<_>>());
1288
1289 assert_eq!(paired.iter_partial(0..1).collect::<Vec<_>>(), p1.partial_iter(0..1).collect::<Vec<_>>());
1290 assert_eq!(paired.iter_partial(5..7).collect::<Vec<_>>(), p2.partial_iter(1..3).collect::<Vec<_>>());
1291 assert_eq!(paired.iter_partial(1..8).collect::<Vec<_>>(), p1.partial_iter(1..4).chain(p2.partial_iter(0..4)).collect::<Vec<_>>());
1292
1293 assert_eq!(combined.iter_partial(0..1).collect::<Vec<_>>(), p1.partial_iter(0..1).collect::<Vec<_>>());
1294 assert_eq!(combined.iter_partial(5..7).collect::<Vec<_>>(), p2.partial_iter(1..3).collect::<Vec<_>>());
1295 assert_eq!(combined.iter_partial(8..10).collect::<Vec<_>>(), up.partial_iter(0..2).collect::<Vec<_>>());
1296 assert_eq!(combined.iter_partial(1..8).collect::<Vec<_>>(), p1.partial_iter(1..4).chain(p2.partial_iter(0..4)).collect::<Vec<_>>());
1297 assert_eq!(combined.iter_partial(6..9).collect::<Vec<_>>(), p2.partial_iter(2..4).chain(up.partial_iter(0..1)).collect::<Vec<_>>());
1298 assert_eq!(combined.iter_partial(1..9).collect::<Vec<_>>(), p1.partial_iter(1..4).chain(p2.partial_iter(0..4)).chain(up.partial_iter(0..1)).collect::<Vec<_>>());
1299
1300 assert_eq!(unpaired.tag_kmers_vec(16, 2), vec![2, 8]);
1302 assert_eq!(paired.tag_kmers_vec(16, 4), vec![50, 26, 40, 50]);
1303 assert_eq!(combined.tag_kmers_vec(16, 4), vec![52, 34, 40, 50]);
1304 assert_eq!(empty.tag_kmers_vec(16, 0), Vec::<u64>::new());
1305
1306 let mut paired_dc = paired.clone();
1308 let rm_reads_p = paired_dc.decombine();
1309 let mut combined_dc = combined.clone();
1310 let rm_reads_up = combined_dc.decombine();
1311 assert_eq!(paired_dc, paired);
1312 assert_eq!(rm_reads_p, 0);
1313 assert_eq!(combined_dc, paired);
1314 assert_eq!(rm_reads_up, 2);
1315
1316 assert_eq!(format!("{}", empty), "empty ReadsPaired".to_string());
1318 assert_eq!(format!("{}", unpaired), "unpaired ReadsPaired:
1319Reads { n reads: 2, stranded: Unstranded }".to_string());
1320 assert_eq!(format!("{}", paired), "paired ReadsPaired:
1321Reads { n reads: 4, stranded: Unstranded }
1322Reads { n reads: 4, stranded: Unstranded }".to_string());
1323 assert_eq!(format!("{}", combined), "combined ReadsPaired:
1324Reads { n reads: 4, stranded: Unstranded }
1325Reads { n reads: 4, stranded: Unstranded }
1326Reads { n reads: 2, stranded: Unstranded }".to_string());
1327
1328 }
1329
1330 #[test]
1331 #[should_panic]
1332 fn test_reads_paired_panic() {
1333 let mut p1 = Reads::new(Strandedness::Unstranded);
1334
1335 let reads_p1 = [
1336 "ACGATCGTACGTACGTAGCTAGCTGCTAGCTAGCTGACTGACTGA",
1337 "CGATGCTATCAGCGAGCGATCGTACGTAGCTACG",
1338 "CGATCGACGAGCAGCGTATGCTACGAGCTGACGATCTACGA",
1339 "CACACACGGCATCGATCGAGCAGCATCGACTACGTA",
1340 ];
1341
1342 reads_p1.iter().for_each(|read| p1.add_from_bytes(read.as_bytes(), None, 0u8));
1343
1344 let _ = ReadsPaired::from_reads((p1, Reads::new(Strandedness::Unstranded), Reads::new(Strandedness::Unstranded)));
1345 }
1346
1347 #[test]
1348 fn test_read_data() {
1349 let read_name_1 = "B7R87_RS28825_2_0/1".as_bytes(); let read_name_2 = "B7R87_RS21825_2_0/1".as_bytes(); let tag = 0 as Tag;
1353
1354 let mut ids = BiMap::new();
1355
1356 let id = ID::read_data(&mut ids, read_name_1, tag);
1357 assert_eq!(id, 0);
1358
1359 let id_tag = IDTag::read_data(&mut ids, read_name_1, tag);
1360 assert_eq!(id_tag, IDTag::new(id, tag));
1361 assert_eq!(id_tag.get_tag(), Some(tag));
1362
1363 let id = ID::read_data(&mut ids, read_name_2, tag);
1364 assert_eq!(id, 1);
1365 assert_eq!(id.get_tag(), None);
1366
1367 assert_eq!(Tag::read_data(&mut ids, read_name_1, tag), tag);
1368 assert_eq!(tag.get_tag(), Some(tag));
1369 }
1370
1371 #[test]
1372 #[should_panic]
1373 fn test_read_data_panic() {
1374 let mut ids = BiMap::new();
1375
1376 let read_name_1 = "B7R87_RS28825_2_0/1".as_bytes(); let read_name_2 = "B7R87_RS21825_2_0/1".as_bytes(); let _ = ID::read_data(&mut ids, read_name_1, 0);
1380 let _ = ID::read_data(&mut ids, read_name_2, 0);
1381
1382 let _ = ID::read_data(&mut ids, "AAAAAA".as_bytes(), 0);
1384 }
1385}