@@ -286,13 +286,14 @@ impl<CX: ColorsManager> IndirectSequencesJoiner<CX> {
286286 } else {
287287 ( extra. counters . first , extra. counters . last )
288288 } ;
289+ let overlapping_kmers = ( overlapping_characters >= self . k ) as u64 ;
289290
290291 self . counters . first = if self . sequence . bases_count == 0 {
291292 other_first
292293 } else {
293294 self . counters . first
294295 } ;
295- self . counters . sum += extra. counters . sum - other_first;
296+ self . counters . sum += extra. counters . sum - ( other_first * overlapping_kmers ) ;
296297 self . counters . last = other_last;
297298 }
298299
@@ -473,21 +474,29 @@ mod tests {
473474 } ;
474475
475476 use super :: IndirectSequencesJoiner ;
477+ #[ cfg( feature = "support_kmer_counters" ) ]
478+ use io:: partial_unitigs_extra_data:: SequenceAbundance ;
476479 use io:: partial_unitigs_extra_data:: { PartialUnitigExtraData , PartialUnitigMode } ;
477480
478- fn inline_extra ( ) -> PartialUnitigExtraData < NonColoredManager > {
481+ fn inline_extra_with_multiplicity (
482+ multiplicity : u64 ,
483+ ) -> PartialUnitigExtraData < NonColoredManager > {
479484 PartialUnitigExtraData {
480485 colors : NonColoredManager ,
481486 mode : PartialUnitigMode :: Inline ,
482487 #[ cfg( feature = "support_kmer_counters" ) ]
483- counters : sequence_output :: structured_sequences :: SequenceAbundance {
484- first : 1 ,
485- sum : 1 ,
486- last : 1 ,
488+ counters : SequenceAbundance {
489+ first : multiplicity ,
490+ sum : multiplicity ,
491+ last : multiplicity ,
487492 } ,
488493 }
489494 }
490495
496+ fn inline_extra ( ) -> PartialUnitigExtraData < NonColoredManager > {
497+ inline_extra_with_multiplicity ( 1 )
498+ }
499+
491500 fn new_temp_path ( prefix : & str ) -> PathBuf {
492501 let now = SystemTime :: now ( )
493502 . duration_since ( UNIX_EPOCH )
@@ -516,6 +525,29 @@ mod tests {
516525 ) ;
517526 }
518527
528+ #[ cfg( feature = "support_kmer_counters" ) ]
529+ fn append_plain_with_multiplicity (
530+ joiner : & mut IndirectSequencesJoiner < NonColoredManager > ,
531+ seq : & str ,
532+ overlap : usize ,
533+ is_rc : bool ,
534+ multiplicity : u64 ,
535+ ) {
536+ let mut storage = Vec :: new ( ) ;
537+ let read = CompressedReadIndipendent :: from_plain ( seq. as_bytes ( ) , & mut storage) ;
538+ let mut extra = inline_extra_with_multiplicity ( multiplicity) ;
539+ extra. counters . sum = multiplicity * ( seq. len ( ) - joiner. k + 1 ) as u64 ;
540+ let extra_buffer = <PartialUnitigExtraData < NonColoredManager > >:: new_temp_buffer ( ) ;
541+ joiner. append_sequence (
542+ read. as_reference ( & storage) ,
543+ & extra,
544+ overlap,
545+ is_rc,
546+ & extra_buffer,
547+ None ,
548+ ) ;
549+ }
550+
519551 #[ test]
520552 fn inline_join_various_lengths_forward ( ) {
521553 let k = 5 ;
@@ -564,4 +596,46 @@ mod tests {
564596
565597 fs:: remove_file ( & temp_path) . unwrap ( ) ;
566598 }
599+
600+ #[ cfg( feature = "support_kmer_counters" ) ]
601+ #[ test]
602+ fn abundance_keeps_all_kmers_for_k_minus_one_overlap ( ) {
603+ let k = 5 ;
604+ let temp_path = new_temp_path ( "joiner_abundance_k_minus_one_overlap" ) ;
605+ let writer = ConcurrentFileWriter :: create ( & temp_path) . unwrap ( ) ;
606+ let mut joiner = IndirectSequencesJoiner :: < NonColoredManager > :: new ( k, writer. clone ( ) ) ;
607+
608+ append_plain_with_multiplicity ( & mut joiner, "AACCTGGA" , 0 , false , 2 ) ;
609+ append_plain_with_multiplicity ( & mut joiner, "TGGAACCC" , k - 1 , false , 5 ) ;
610+
611+ let joined = joiner. get_sequence ( ) ;
612+
613+ assert_eq ! ( joined. sequence. to_string( ) , "AACCTGGAACCC" ) ;
614+ assert_eq ! ( joined. extra. counters. first, 2 ) ;
615+ assert_eq ! ( joined. extra. counters. last, 5 ) ;
616+ assert_eq ! ( joined. extra. counters. sum, 28 ) ;
617+
618+ fs:: remove_file ( & temp_path) . unwrap ( ) ;
619+ }
620+
621+ #[ cfg( feature = "support_kmer_counters" ) ]
622+ #[ test]
623+ fn abundance_drops_one_kmer_for_exact_k_overlap ( ) {
624+ let k = 5 ;
625+ let temp_path = new_temp_path ( "joiner_abundance_k_overlap" ) ;
626+ let writer = ConcurrentFileWriter :: create ( & temp_path) . unwrap ( ) ;
627+ let mut joiner = IndirectSequencesJoiner :: < NonColoredManager > :: new ( k, writer. clone ( ) ) ;
628+
629+ append_plain_with_multiplicity ( & mut joiner, "AAACCCCTA" , 0 , false , 2 ) ;
630+ append_plain_with_multiplicity ( & mut joiner, "CCCTAT" , k, false , 5 ) ;
631+
632+ let joined = joiner. get_sequence ( ) ;
633+
634+ assert_eq ! ( joined. sequence. to_string( ) , "AAACCCCTAT" ) ;
635+ assert_eq ! ( joined. extra. counters. first, 2 ) ;
636+ assert_eq ! ( joined. extra. counters. last, 5 ) ;
637+ assert_eq ! ( joined. extra. counters. sum, 15 ) ;
638+
639+ fs:: remove_file ( & temp_path) . unwrap ( ) ;
640+ }
567641}
0 commit comments