@@ -749,7 +749,7 @@ pub fn align_paired_read(
749749 combined_seeds. extend ( m2_seeds) ;
750750 // mate_id: positions 0..len1 → mate1(0); positions len1+1.. → RC(mate2)(1).
751751 for s in & mut combined_seeds {
752- s. mate_id = if s. read_pos < len1 { 0 } else { 1 } ;
752+ s. mate_id = u8 :: from ( s. read_pos >= len1) ;
753753 }
754754
755755 // Cluster combined seeds using the combined read length
@@ -831,135 +831,132 @@ pub fn align_paired_read(
831831 for wt in & wts {
832832 let split_result =
833833 split_combined_wt ( wt, len1, len2, stitch_is_reverse, scorer. align_intron_min ) ;
834- match split_result {
835- Some ( ( m1_wt, m2_wt) ) => {
836- let ( m1_read_slice, m1_orig_rev, m2_read_slice, m2_orig_rev) =
837- if stitch_is_reverse {
838- // stitch_read = [mate2(0..len2) | SPACER | RC(mate1)(len2+1..)]
839- (
840- & stitch_read[ len2 + 1 ..] , // RC(mate1_seq)
841- true , // mate1 5' at right in RC
842- & stitch_read[ ..len2] , // mate2_seq
843- false , // mate2 5' at left
844- )
845- } else {
846- // stitch_read = [mate1(0..len1) | SPACER | RC(mate2)(len1+1..)]
847- (
848- & stitch_read[ ..len1] , // mate1_seq
849- false , // mate1 5' at left
850- & stitch_read[ len1 + 1 ..] , // RC(mate2_seq)
851- true , // mate2 5' at right in RC
852- )
853- } ;
854-
855- // Suppress inner-side extensions for each mate.
856- // Inner = 3' end: right for forward (orig_is_rev=false), left for reverse.
857- let Some ( mut t1) = finalize_transcript (
858- & m1_wt,
859- m1_read_slice,
834+ if let Some ( ( m1_wt, m2_wt) ) = split_result {
835+ let ( m1_read_slice, m1_orig_rev, m2_read_slice, m2_orig_rev) = if stitch_is_reverse
836+ {
837+ // stitch_read = [mate2(0..len2) | SPACER | RC(mate1)(len2+1..)]
838+ (
839+ & stitch_read[ len2 + 1 ..] , // RC(mate1_seq)
840+ true , // mate1 5' at right in RC
841+ & stitch_read[ ..len2] , // mate2_seq
842+ false , // mate2 5' at left
843+ )
844+ } else {
845+ // stitch_read = [mate1(0..len1) | SPACER | RC(mate2)(len1+1..)]
846+ (
847+ & stitch_read[ ..len1] , // mate1_seq
848+ false , // mate1 5' at left
849+ & stitch_read[ len1 + 1 ..] , // RC(mate2_seq)
850+ true , // mate2 5' at right in RC
851+ )
852+ } ;
853+
854+ // Suppress inner-side extensions for each mate.
855+ // Inner = 3' end: right for forward (orig_is_rev=false), left for reverse.
856+ let Some ( mut t1) = finalize_transcript (
857+ & m1_wt,
858+ m1_read_slice,
859+ index,
860+ & scorer,
861+ & stitch_cluster,
862+ m1_orig_rev,
863+ m1_orig_rev, // no_left_ext = inner for reverse (orig_is_rev=true)
864+ !m1_orig_rev, // no_right_ext = inner for forward (orig_is_rev=false)
865+ ) else {
866+ continue ;
867+ } ;
868+ let Some ( mut t2) = finalize_transcript (
869+ & m2_wt,
870+ m2_read_slice,
871+ index,
872+ & scorer,
873+ & stitch_cluster,
874+ m2_orig_rev,
875+ m2_orig_rev, // no_left_ext = inner for reverse (orig_is_rev=true)
876+ !m2_orig_rev, // no_right_ext = inner for forward (orig_is_rev=false)
877+ ) else {
878+ continue ;
879+ } ;
880+
881+ if stitch_is_reverse {
882+ t1. is_reverse = true ;
883+ t2. is_reverse = false ;
884+ } else {
885+ t1. is_reverse = false ;
886+ t2. is_reverse = true ;
887+ }
888+ t1. read_seq = mate1_seq. to_vec ( ) ;
889+ t2. read_seq = mate2_seq. to_vec ( ) ;
890+
891+ if params. chim_segment_min > 0 {
892+ all_m1_transcripts. push ( t1. clone ( ) ) ;
893+ all_m2_transcripts. push ( t2. clone ( ) ) ;
894+ }
895+
896+ let combined_span =
897+ t1. genome_end . max ( t2. genome_end ) - t1. genome_start . min ( t2. genome_start ) ;
898+ let combined_wt_score = wt. score + scorer. genomic_length_penalty ( combined_span) ;
899+
900+ if let Some ( pair) = try_pair_transcripts (
901+ & t1,
902+ & t2,
903+ len1,
904+ len2,
905+ params,
906+ combined_score_threshold,
907+ combined_wt_score,
908+ ) {
909+ joint_pairs. push ( pair) ;
910+ }
911+ } else {
912+ // Single-mate WT: save for half-mapped fallback
913+ let all_m1 = wt. exons . iter ( ) . all ( |e| e. mate_id == 0 ) ;
914+ let all_m2 = wt. exons . iter ( ) . all ( |e| e. mate_id == 1 ) ;
915+ if all_m1 {
916+ let ( read_slice, orig_rev) = if stitch_is_reverse {
917+ ( & stitch_read[ len2 + 1 ..] , true )
918+ } else {
919+ ( & stitch_read[ ..len1] , false )
920+ } ;
921+ if let Some ( mut t) = finalize_transcript (
922+ wt,
923+ read_slice,
860924 index,
861925 & scorer,
862926 & stitch_cluster,
863- m1_orig_rev,
864- m1_orig_rev, // no_left_ext = inner for reverse (orig_is_rev=true)
865- !m1_orig_rev, // no_right_ext = inner for forward (orig_is_rev=false)
866- ) else {
867- continue ;
927+ orig_rev,
928+ false ,
929+ false ,
930+ ) {
931+ t. is_reverse = stitch_is_reverse;
932+ t. read_seq = mate1_seq. to_vec ( ) ;
933+ if params. chim_segment_min > 0 {
934+ all_m1_transcripts. push ( t. clone ( ) ) ;
935+ }
936+ single_mate1_transcripts. push ( t) ;
937+ }
938+ } else if all_m2 {
939+ let ( read_slice, orig_rev) = if stitch_is_reverse {
940+ ( & stitch_read[ ..len2] , false )
941+ } else {
942+ ( & stitch_read[ len1 + 1 ..] , true )
868943 } ;
869- let Some ( mut t2 ) = finalize_transcript (
870- & m2_wt ,
871- m2_read_slice ,
944+ if let Some ( mut t ) = finalize_transcript (
945+ wt ,
946+ read_slice ,
872947 index,
873948 & scorer,
874949 & stitch_cluster,
875- m2_orig_rev,
876- m2_orig_rev, // no_left_ext = inner for reverse (orig_is_rev=true)
877- !m2_orig_rev, // no_right_ext = inner for forward (orig_is_rev=false)
878- ) else {
879- continue ;
880- } ;
881-
882- if stitch_is_reverse {
883- t1. is_reverse = true ;
884- t2. is_reverse = false ;
885- } else {
886- t1. is_reverse = false ;
887- t2. is_reverse = true ;
888- }
889- t1. read_seq = mate1_seq. to_vec ( ) ;
890- t2. read_seq = mate2_seq. to_vec ( ) ;
891-
892- if params. chim_segment_min > 0 {
893- all_m1_transcripts. push ( t1. clone ( ) ) ;
894- all_m2_transcripts. push ( t2. clone ( ) ) ;
895- }
896-
897- let combined_span =
898- t1. genome_end . max ( t2. genome_end ) - t1. genome_start . min ( t2. genome_start ) ;
899- let combined_wt_score = wt. score + scorer. genomic_length_penalty ( combined_span) ;
900-
901- if let Some ( pair) = try_pair_transcripts (
902- & t1,
903- & t2,
904- len1,
905- len2,
906- params,
907- combined_score_threshold,
908- combined_wt_score,
950+ orig_rev,
951+ false ,
952+ false ,
909953 ) {
910- joint_pairs. push ( pair) ;
911- }
912- }
913- None => {
914- // Single-mate WT: save for half-mapped fallback
915- let all_m1 = wt. exons . iter ( ) . all ( |e| e. mate_id == 0 ) ;
916- let all_m2 = wt. exons . iter ( ) . all ( |e| e. mate_id == 1 ) ;
917- if all_m1 {
918- let ( read_slice, orig_rev) = if stitch_is_reverse {
919- ( & stitch_read[ len2 + 1 ..] , true )
920- } else {
921- ( & stitch_read[ ..len1] , false )
922- } ;
923- if let Some ( mut t) = finalize_transcript (
924- wt,
925- read_slice,
926- index,
927- & scorer,
928- & stitch_cluster,
929- orig_rev,
930- false ,
931- false ,
932- ) {
933- t. is_reverse = stitch_is_reverse;
934- t. read_seq = mate1_seq. to_vec ( ) ;
935- if params. chim_segment_min > 0 {
936- all_m1_transcripts. push ( t. clone ( ) ) ;
937- }
938- single_mate1_transcripts. push ( t) ;
939- }
940- } else if all_m2 {
941- let ( read_slice, orig_rev) = if stitch_is_reverse {
942- ( & stitch_read[ ..len2] , false )
943- } else {
944- ( & stitch_read[ len1 + 1 ..] , true )
945- } ;
946- if let Some ( mut t) = finalize_transcript (
947- wt,
948- read_slice,
949- index,
950- & scorer,
951- & stitch_cluster,
952- orig_rev,
953- false ,
954- false ,
955- ) {
956- t. is_reverse = !stitch_is_reverse;
957- t. read_seq = mate2_seq. to_vec ( ) ;
958- if params. chim_segment_min > 0 {
959- all_m2_transcripts. push ( t. clone ( ) ) ;
960- }
961- single_mate2_transcripts. push ( t) ;
954+ t. is_reverse = !stitch_is_reverse;
955+ t. read_seq = mate2_seq. to_vec ( ) ;
956+ if params. chim_segment_min > 0 {
957+ all_m2_transcripts. push ( t. clone ( ) ) ;
962958 }
959+ single_mate2_transcripts. push ( t) ;
963960 }
964961 }
965962 }
@@ -2144,7 +2141,7 @@ mod tests {
21442141 assert_eq ! ( items[ 4 ] , ( 40 , 4 ) ) ;
21452142 // Tied prefix contains the original three items in some order.
21462143 let mut top: Vec < u32 > = items[ ..3 ] . iter ( ) . map ( |t| t. 1 ) . collect ( ) ;
2147- top. sort ( ) ;
2144+ top. sort_unstable ( ) ;
21482145 assert_eq ! ( top, vec![ 0 , 1 , 2 ] ) ;
21492146 }
21502147
0 commit comments