alnmix.cpp
来自「ncbi源码」· C++ 代码 · 共 1,672 行 · 第 1/5 页
CPP
1,672 行
if ( !first_refseq ) { if ( !seq2->m_MatchList.empty() ) { seq2->m_MatchList.erase(match_list_iter2); } } } start_i = starts.end(); lo_start_i = starts.end(); hi_start_i = starts.end(); if (!starts.size()) { // no starts exist yet if ( !m_IndependentDSs ) { // TEMPORARY, for the single refseq version of mix, // clear all MatchLists and exit if ( !(m_SingleRefseq || first_refseq) ) { ITERATE (TSeqs, it, m_Seqs){ if ( !((*it)->m_MatchList.empty()) ) { (*it)->m_MatchList.clear(); } } break; } } // this seq has not yet been used, set the strand seq1->m_PositiveStrand = ! (m_MergeFlags & fNegativeStrand); //create the first one seg = new CAlnMixSegment; seg->m_Len = len; seg->m_DSIndex = match->m_DSIndex; starts[start1] = seg; seg->m_StartIts[seq1] = lo_start_i = hi_start_i = starts.begin(); second_row_fits = eSecondRowFitsOk; // DONE! } else { // some starts exist already if (seq2) { // check if the second row fits // this will truncate the match if // there's an inconsistent overlap // and truncation was requested second_row_fits = x_SecondRowFits(match); {{ // reset the ones below, // since match may have been modified seq1 = match->m_AlnSeq1; start1 = match->m_Start1; match_list_iter1 = match->m_MatchIter1; seq2 = match->m_AlnSeq2; start2 = match->m_Start2; match_list_iter2 = match->m_MatchIter2; curr_len = len = match->m_Len; }} if (second_row_fits == eIgnoreMatch) { continue; } } // look ahead if ((lo_start_i = start_i = starts.lower_bound(start1)) == starts.end() || start1 < start_i->first) { // the start position does not exist if (lo_start_i != starts.begin()) { --lo_start_i; } } // look back if (hi_start_i == starts.end() && start_i != lo_start_i) { CAlnMixSegment * prev_seg = lo_start_i->second; if (lo_start_i->first + prev_seg->m_Len * width1 > start1) { // x----.. becomes x-x--.. // x--.. TSeqPos len1 = (start1 - lo_start_i->first) / width1; TSeqPos len2 = prev_seg->m_Len - len1; // create the second seg seg = new CAlnMixSegment; seg->m_Len = len2; seg->m_DSIndex = match->m_DSIndex; starts[start1] = seg; // create rows info ITERATE (CAlnMixSegment::TStartIterators, it, prev_seg->m_StartIts) { CAlnMixSeq * seq = it->first; tmp_start_i = it->second; if (seq->m_PositiveStrand == seq1->m_PositiveStrand) { seq->m_Starts [tmp_start_i->first + len1 * seq->m_Width] = seg; seg->m_StartIts[seq] = ++tmp_start_i; } else { seq->m_Starts [tmp_start_i->first + len2 * seq->m_Width] = prev_seg; seq->m_Starts[tmp_start_i->first] = seg; seg->m_StartIts[seq] = tmp_start_i; prev_seg->m_StartIts[seq] = ++tmp_start_i; } } // truncate the first seg prev_seg->m_Len = len1; if (start_i != starts.begin()) { start_i--; // point to the newly created start } } if (lo_start_i != starts.end()) { lo_start_i++; } } } // loop through overlapping segments start = start1; while (hi_start_i == starts.end()) { if (start_i != starts.end() && start_i->first == start) { CAlnMixSegment * prev_seg = start_i->second; if (prev_seg->m_Len > curr_len) { // x-------) becomes x----)x--) // x----) // create the second seg seg = new CAlnMixSegment; TSeqPos len1 = seg->m_Len = prev_seg->m_Len - curr_len; start += curr_len * width1; // truncate the first seg prev_seg->m_Len = curr_len; // create rows info ITERATE (CAlnMixSegment::TStartIterators, it, prev_seg->m_StartIts) { CAlnMixSeq * seq = it->first; tmp_start_i = it->second; if (seq->m_PositiveStrand == seq1->m_PositiveStrand) { seq->m_Starts[tmp_start_i->first + curr_len * seq->m_Width] = seg; seg->m_StartIts[seq] = ++tmp_start_i; } else{ seq->m_Starts[tmp_start_i->first + len1 * seq->m_Width] = prev_seg; seq->m_Starts[tmp_start_i->first] = seg; seg->m_StartIts[seq] = tmp_start_i; prev_seg->m_StartIts[seq] = ++tmp_start_i; } } hi_start_i = start_i; // DONE! } else if (curr_len == prev_seg->m_Len) { // x----) // x----) hi_start_i = start_i; // DONE! } else { // x----) becomes x----)x--) // x-------) start += prev_seg->m_Len * width1; curr_len -= prev_seg->m_Len; if (start_i != starts.end()) { start_i++; } } } else { seg = new CAlnMixSegment; starts[start] = seg; tmp_start_i = start_i; if (tmp_start_i != starts.begin()) { tmp_start_i--; } seg->m_StartIts[seq1] = tmp_start_i; if (start_i != starts.end() && start + curr_len * width1 > start_i->first) { // x--.. // x--------.. seg->m_Len = (start_i->first - start) / width1; seg->m_DSIndex = match->m_DSIndex; } else { // x-----) // x---) seg->m_Len = curr_len; seg->m_DSIndex = match->m_DSIndex; hi_start_i = start_i; if (hi_start_i != starts.begin()) { hi_start_i--; // DONE! } } start += seg->m_Len * width1; curr_len -= seg->m_Len; if (lo_start_i == start_i) { if (lo_start_i != starts.begin()) { lo_start_i--; } } } } // try to resolve the second row if (seq2) { // set the frame if not initialized if (width2 == 3 && seq2->m_Starts.empty()) { seq2->m_Frame = start2 % 3; } // create a copy of the match, // which we could work with temporarily // without modifying the original CAlnMixMatch tmp_match = *match; match = &tmp_match; // point to the new tmp_match while (second_row_fits != eSecondRowFitsOk && second_row_fits != eIgnoreMatch) { if (!seq2->m_ExtraRow) { // create an extra row CRef<CAlnMixSeq> row (new CAlnMixSeq); row->m_BioseqHandle = seq2->m_BioseqHandle; row->m_SeqId = seq2->m_SeqId; row->m_Width = seq2->m_Width; row->m_Frame = start2 % 3; row->m_SeqIndex = seq2->m_SeqIndex; if (m_MergeFlags & fQuerySeqMergeOnly) { row->m_DSIndex = match->m_DSIndex; } m_ExtraRows.push_back(row); seq2->m_ExtraRow = row; seq2 = match->m_AlnSeq2 = seq2->m_ExtraRow; break; } seq2 = match->m_AlnSeq2 = seq2->m_ExtraRow; second_row_fits = x_SecondRowFits(match); {{ // reset the ones below, // since match may have been modified seq1 = match->m_AlnSeq1; start1 = match->m_Start1; match_list_iter1 = match->m_MatchIter1; seq2 = match->m_AlnSeq2; start2 = match->m_Start2; match_list_iter2 = match->m_MatchIter2; curr_len = len = match->m_Len; }} } if (second_row_fits == eIgnoreMatch) { continue; } if (m_MergeFlags & fTruncateOverlaps) { // we need to reset these shtorcuts // in case the match was truncated start1 = match->m_Start1; start2 = match->m_Start2; len = match->m_Len; } // set the strand if first time if (seq2->m_Starts.empty()) { seq2->m_PositiveStrand = (seq1->m_PositiveStrand ? !match->m_StrandsDiffer : match->m_StrandsDiffer); } // create row info CAlnMixSeq::TStarts& starts2 = match->m_AlnSeq2->m_Starts; start = start2; CAlnMixSeq::TStarts::iterator start2_i = starts2.lower_bound(start2); start_i = match->m_StrandsDiffer ? hi_start_i : lo_start_i; while(start < start2 + len * width2) { if (start2_i != starts2.end() && start2_i->first == start) { // this position already exists if (start2_i->second != start_i->second) { // merge the two segments // store the seg in a CRef to delay its deletion // until after the iteration on it is finished CRef<CAlnMixSegment> tmp_seg = start2_i->second; ITERATE (CAlnMixSegment::TStartIterators, it, tmp_seg->m_StartIts) { CAlnMixSeq * tmp_seq = it->first; tmp_start_i = it->second; tmp_start_i->second = start_i->second; start_i->second->m_StartIts[tmp_seq] = tmp_start_i; } } } else { // this position does not exist, create it seq2->m_Starts[start] = start_i->second; // start2_i != starts.begin() because we just // made an insertion, so decrement is ok start2_i--; // point this segment's row start iterator start_i->second->m_StartIts[seq2] = start2_i; } // increment values start += start_i->second->m_Len * width2; if (start2_i != starts2.end()) { start2_i++; } if (match->m_StrandsDiffer) { if (start_i != starts.begin()) { start_i--; } } else { if (start_i != starts.end()) { start_i++; } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?