@@ -706,22 +706,74 @@ std::vector<Seed> generate_raw_seeds(const std::string& query_seq, const FMIndex
706706 return current_seeds;
707707}
708708
709- ChainedSeed find_best_seed_chain (std::vector<Seed>& seeds_vec, int min_diag_gap_val = 0 , int max_diag_gap_val = 50000 , int max_offset_dev_val = 50 ) {
710- if (seeds_vec.empty ()) { return {}; }
709+ ChainedSeed find_best_seed_chain (
710+ std::vector<Seed> &seeds_vec,
711+ int min_diag_gap_val = 0 ,
712+ int max_diag_gap_val = 50000 ,
713+ int max_offset_dev_val = 50
714+ ) {
715+ if (seeds_vec.empty ()) return {};
716+
717+ // 1) sort by query_pos, then target_pos
711718 std::sort (seeds_vec.begin (), seeds_vec.end ());
712- int n_s_val = seeds_vec.size ();
713- std::vector<double > dp_scores (n_s_val); std::vector<int > prev_indices (n_s_val, -1 ); double max_chain_score = 0 ; int best_chain_end_idx = -1 ;
714- for (int i_s = 0 ; i_s < n_s_val; ++i_s) { dp_scores[i_s] = seeds_vec[i_s].len ;
715- for (int j_s = 0 ; j_s < i_s; ++j_s) {
716- if (seeds_vec[j_s].query_end () + min_diag_gap_val < seeds_vec[i_s].query_pos && seeds_vec[j_s].target_end () + min_diag_gap_val < seeds_vec[i_s].target_pos ) {
717- if (std::abs (((long long )seeds_vec[i_s].query_pos - seeds_vec[i_s].target_pos ) - ((long long )seeds_vec[j_s].query_pos - seeds_vec[j_s].target_pos )) > max_offset_dev_val) continue ;
718- if ((seeds_vec[i_s].query_pos - seeds_vec[j_s].query_end () > max_diag_gap_val) || (seeds_vec[i_s].target_pos - seeds_vec[j_s].target_end () > max_diag_gap_val)) continue ;
719- if (dp_scores[j_s] + seeds_vec[i_s].len > dp_scores[i_s]) { dp_scores[i_s] = dp_scores[j_s] + seeds_vec[i_s].len ; prev_indices[i_s] = j_s; }
719+
720+ int n = seeds_vec.size ();
721+ std::vector<double > dp (n, 0.0 );
722+ std::vector<int > prev (n, -1 );
723+
724+ double best_score = 0.0 ;
725+ int best_idx = -1 ;
726+
727+ for (int i = 0 ; i < n; ++i) {
728+ // start chain with just this seed’s own score (len × match_score=1)
729+ double seed_score = static_cast <double >(seeds_vec[i].len );
730+ dp[i] = seed_score;
731+
732+ // try extending every earlier seed j → i
733+ for (int j = i - 1 ; j >= 0 ; --j) {
734+ // no‐overlap
735+ if (seeds_vec[j].query_end () + min_diag_gap_val >= seeds_vec[i].query_pos ) continue ;
736+ if (seeds_vec[j].target_end () + min_diag_gap_val >= seeds_vec[i].target_pos ) continue ;
737+
738+ // compute gaps
739+ int dq = seeds_vec[i].query_pos - seeds_vec[j].query_end () - 1 ;
740+ int dt = seeds_vec[i].target_pos - seeds_vec[j].target_end () - 1 ;
741+ if (dq < 0 || dt < 0 ) continue ;
742+ if (dq > max_diag_gap_val || dt > max_diag_gap_val) continue ;
743+
744+ // diagonal consistency
745+ int diag_j = seeds_vec[j].query_pos - seeds_vec[j].target_pos ;
746+ int diag_i = seeds_vec[i].query_pos - seeds_vec[i].target_pos ;
747+ if (std::abs (diag_i - diag_j) > max_offset_dev_val) continue ;
748+
749+ // affine‐gap cost on each side
750+ double cost_q = dq > 0 ? (GAP_OPEN + (dq - 1 ) * GAP_EXTEND ) : 0.0 ;
751+ double cost_t = dt > 0 ? (GAP_OPEN + (dt - 1 ) * GAP_EXTEND ) : 0.0 ;
752+ double gap_cost = cost_q + cost_t ;
753+
754+ // DP recurrence: extend j→i
755+ double cand = dp[j] + seed_score - gap_cost;
756+ if (cand > dp[i]) {
757+ dp[i] = cand;
758+ prev[i] = j;
720759 }
721- } if (dp_scores[i_s] > max_chain_score) { max_chain_score = dp_scores[i_s]; best_chain_end_idx = i_s; }
722- } ChainedSeed result_chain; result_chain.chain_score = 0 ;
723- if (best_chain_end_idx != -1 ) { result_chain.chain_score = max_chain_score; int current_s_idx = best_chain_end_idx; while (current_s_idx != -1 ) { result_chain.seeds .push_back (seeds_vec[current_s_idx]); current_s_idx = prev_indices[current_s_idx]; } std::reverse (result_chain.seeds .begin (), result_chain.seeds .end ()); }
724- return result_chain;
760+ }
761+
762+ // track global best
763+ if (dp[i] > best_score) {
764+ best_score = dp[i];
765+ best_idx = i;
766+ }
767+ }
768+
769+ // reconstruct chain
770+ ChainedSeed chain;
771+ chain.chain_score = best_score;
772+ for (int cur = best_idx; cur != -1 ; cur = prev[cur]) {
773+ chain.seeds .push_back (seeds_vec[cur]);
774+ }
775+ std::reverse (chain.seeds .begin (), chain.seeds .end ());
776+ return chain;
725777}
726778
727779// -------- Segment/Window Alignment Helpers & Structs (Full Code) --------
0 commit comments