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 + -
显示快捷键?