alnmap.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:40k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: alnmap.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 19:40:42  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.48
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: alnmap.cpp,v 1000.3 2004/06/01 19:40:42 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Author:  Kamen Todorov, NCBI
  35. *
  36. * File Description:
  37. *   Interface for examining alignments (of type Dense-seg)
  38. *
  39. * ===========================================================================
  40. */
  41. #include <ncbi_pch.hpp>
  42. #include <objtools/alnmgr/alnmap.hpp>
  43. BEGIN_NCBI_SCOPE
  44. BEGIN_objects_SCOPE // namespace ncbi::objects::
  45. void CAlnMap::x_Init(void)
  46. {
  47.     m_SeqLeftSegs.resize(GetNumRows(), -1);
  48.     m_SeqRightSegs.resize(GetNumRows(), -1);
  49. }
  50. void CAlnMap::x_CreateAlnStarts(void)
  51. {
  52.     m_AlnStarts.clear();
  53.     m_AlnStarts.reserve(GetNumSegs());
  54.     
  55.     int start = 0, len = 0;
  56.     for (int i = 0;  i < GetNumSegs();  ++i) {
  57.         start += len;
  58.         m_AlnStarts.push_back(start);
  59.         len = m_Lens[i];
  60.     }
  61. }
  62. void CAlnMap::UnsetAnchor(void)
  63. {
  64.     m_AlnSegIdx.clear();
  65.     m_NumSegWithOffsets.clear();
  66.     if (m_RawSegTypes) {
  67.         delete m_RawSegTypes;
  68.         m_RawSegTypes = 0;
  69.     }
  70.     m_Anchor = -1;
  71.     // we must call this last, as it uses some internal shenanigans that
  72.     // are affected by the reset above
  73.     x_CreateAlnStarts();
  74. }
  75. void CAlnMap::SetAnchor(TNumrow anchor)
  76. {
  77.     if (anchor == -1) {
  78.         UnsetAnchor();
  79.         return;
  80.     }
  81.     if (anchor < 0  ||  anchor >= m_NumRows) {
  82.         NCBI_THROW(CAlnException, eInvalidRow,
  83.                    "CAlnVec::SetAnchor(): "
  84.                    "Invalid row");
  85.     }
  86.     m_AlnSegIdx.clear();
  87.     m_AlnStarts.clear();
  88.     m_NumSegWithOffsets.clear();
  89.     if (m_RawSegTypes) {
  90.         delete m_RawSegTypes;
  91.         m_RawSegTypes = 0;
  92.     }
  93.     int start = 0, len = 0, aln_seg = -1, offset = 0;
  94.     
  95.     m_Anchor = anchor;
  96.     for (int i = 0, pos = m_Anchor;  i < m_NumSegs;
  97.          ++i, pos += m_NumRows) {
  98.         if (m_Starts[pos] != -1) {
  99.             ++aln_seg;
  100.             offset = 0;
  101.             m_AlnSegIdx.push_back(i);
  102.             m_NumSegWithOffsets.push_back(CNumSegWithOffset(aln_seg));
  103.             start += len;
  104.             m_AlnStarts.push_back(start);
  105.             len = m_Lens[i];
  106.         } else {
  107.             ++offset;
  108.             m_NumSegWithOffsets.push_back(CNumSegWithOffset(aln_seg, offset));
  109.         }
  110.     }
  111.     if (!m_AlnSegIdx.size()) {
  112.         NCBI_THROW(CAlnException, eInvalidDenseg,
  113.                    "CAlnVec::SetAnchor(): "
  114.                    "Invalid Dense-seg: No sequence on the anchor row");
  115.     }
  116. }
  117. CAlnMap::TSegTypeFlags 
  118. CAlnMap::x_SetRawSegType(TNumrow row, TNumseg seg) const
  119. {
  120.     TSegTypeFlags flags = 0;
  121.     TNumseg       l_seg, r_seg, l_index, r_index, index;
  122.     TSeqPos       cont_next_start, cont_prev_stop;
  123.     l_seg = r_seg = seg;
  124.     l_index = r_index = index = seg * m_NumRows + row;
  125.     TSignedSeqPos start = m_Starts[index];
  126.     // is it seq or gap?
  127.     if (start >= 0) {
  128.         flags |= fSeq;
  129.         cont_next_start = start + x_GetLen(row, seg);
  130.         cont_prev_stop  = start;
  131.     }
  132.     // is it aligned to sequence on the anchor?
  133.     if (IsSetAnchor()) {
  134.         flags |= fNotAlignedToSeqOnAnchor;
  135.         if (m_Starts[seg * m_NumRows + m_Anchor] >= 0) {
  136.             flags &= ~(flags & fNotAlignedToSeqOnAnchor);
  137.         }
  138.     }
  139.     // what's on the right?
  140.     if (r_seg < m_NumSegs - 1) {
  141.         flags |= fEndOnRight;
  142.     }
  143.     flags |= fNoSeqOnRight;
  144.     while (++r_seg < m_NumSegs) {
  145.         flags &= ~(flags & fEndOnRight);
  146.         r_index += m_NumRows;
  147.         if ((start = m_Starts[r_index]) >= 0) {
  148.             if ((flags & fSeq) && 
  149.                 (IsPositiveStrand(row) ?
  150.                  start != (TSignedSeqPos)cont_next_start :
  151.                  start + x_GetLen(row, r_seg) != cont_prev_stop)) {
  152.                 flags |= fUnalignedOnRight;
  153.             }
  154.             flags &= ~(flags & fNoSeqOnRight);
  155.             break;
  156.         }
  157.     }
  158.     // what's on the left?
  159.     if (l_seg > 0) {
  160.         flags |= fEndOnLeft;
  161.     }
  162.     flags |= fNoSeqOnLeft;
  163.     while (--l_seg >= 0) {
  164.         flags &= ~(flags & fEndOnLeft);
  165.         l_index -= m_NumRows;
  166.         if ((start = m_Starts[l_index]) >= 0) {
  167.             if ((flags & fSeq) && 
  168.                 (IsPositiveStrand(row) ?
  169.                  start + x_GetLen(row, l_seg) != cont_prev_stop :
  170.                  start != (TSignedSeqPos)cont_next_start)) {
  171.                 flags |= fUnalignedOnLeft;
  172.             }
  173.             flags &= ~(flags & fNoSeqOnLeft);
  174.             break;
  175.         }
  176.     }
  177.         
  178.     // add to cache
  179.     if ( !m_RawSegTypes ) {
  180.         // Using kZero for 0 works around a bug in Compaq's C++ compiler.
  181.         static const TSegTypeFlags kZero = 0;
  182.         m_RawSegTypes = new vector<TSegTypeFlags>
  183.             (m_NumRows * m_NumSegs, kZero);
  184.     }
  185.     (*m_RawSegTypes)[row + m_NumRows * seg] = flags | fTypeIsSet;
  186.     return flags;
  187. }
  188. CAlnMap::TNumseg CAlnMap::GetSeg(TSeqPos aln_pos) const
  189. {
  190.     TNumseg btm, top, mid;
  191.     btm = 0;
  192.     top = m_AlnStarts.size() - 1;
  193.     if (aln_pos > m_AlnStarts[top] +
  194.         m_Lens[x_GetRawSegFromSeg(top)] - 1) 
  195.         return -1; // out of range
  196.     while (btm < top) {
  197.         mid = (top + btm) / 2;
  198.         if (m_AlnStarts[mid] == (TSignedSeqPos)aln_pos) {
  199.             return mid;
  200.         }
  201.         if (m_AlnStarts[mid + 1] <= (TSignedSeqPos)aln_pos) {
  202.             btm = mid + 1; 
  203.         } else {
  204.             top = mid;
  205.         }
  206.     } 
  207.     return top;
  208. }
  209. CAlnMap::TNumseg
  210. CAlnMap::GetRawSeg(TNumrow row, TSeqPos seq_pos,
  211.                    ESearchDirection dir, bool try_reverse_dir) const
  212. {
  213.     TSignedSeqPos start = -1, sseq_pos = seq_pos;
  214.     TNumseg       btm, top, mid, cur, last, cur_top, cur_btm;
  215.     btm = cur_btm = 0; cur = top = last = cur_top = m_NumSegs - 1;
  216.     bool plus = IsPositiveStrand(row);
  217.     // if out-of-range, return either -1 or the closest seg in dir direction
  218.     if (sseq_pos < GetSeqStart(row)) {
  219.         if (dir == eNone) {
  220.             return -1;
  221.         } else if (dir == eForward  || 
  222.                    dir == (plus ? eRight : eLeft)  ||
  223.                    try_reverse_dir) {
  224.             TNumseg seg;
  225.             if (plus) {
  226.                 seg = -1;
  227.                 while (++seg < m_NumSegs) {
  228.                     if (m_Starts[seg * m_NumRows + row] >= 0) {
  229.                         return seg;
  230.                     }
  231.                 }
  232.             } else {
  233.                 seg = m_NumSegs;
  234.                 while (seg--) {
  235.                     if (m_Starts[seg * m_NumRows + row] >= 0) {
  236.                         return seg;
  237.                     }
  238.                 }
  239.             }
  240.         }
  241.     } else if (sseq_pos > GetSeqStop(row)) {
  242.         if (dir == eNone) {
  243.             return -1;
  244.         } else if (dir == eBackwards  ||
  245.                    dir == (plus ? eLeft : eRight)  ||
  246.                    try_reverse_dir) {
  247.             TNumseg seg;
  248.             if (plus) {
  249.                 seg = m_NumSegs;
  250.                 while (seg--) {
  251.                     if (m_Starts[seg * m_NumRows + row] >= 0) {
  252.                         return seg;
  253.                     }
  254.                 }
  255.             } else {
  256.                 seg = -1;
  257.                 while (++seg < m_NumSegs) {
  258.                     if (m_Starts[seg * m_NumRows + row] >= 0) {
  259.                         return seg;
  260.                     }
  261.                 }
  262.             }
  263.         }
  264.     }
  265.     // main loop
  266.     while (btm <= top) {
  267.         cur = mid = (top + btm) / 2;
  268.         while (cur <= top
  269.                &&  (start = m_Starts[(plus ? cur : last - cur) 
  270.                                              * m_NumRows + row]) < 0) {
  271.             ++cur;
  272.         }
  273.         if (cur <= top && start >= 0) {
  274.             if (sseq_pos >= start &&
  275.                 seq_pos < start + x_GetLen(row, plus ? cur : last - cur)) {
  276.                 return (plus ? cur : last - cur); // found
  277.             }
  278.             if (sseq_pos > start) {
  279.                 btm = cur + 1;
  280.                 cur_btm = cur;
  281.             } else {
  282.                 top = mid - 1;
  283.                 cur_top = cur;
  284.             }
  285.             continue;
  286.         }
  287.         cur = mid-1;
  288.         while (cur >= btm &&
  289.                (start = m_Starts[(plus ? cur : last - cur)
  290.                                          * m_NumRows + row]) < 0) {
  291.             --cur;
  292.         }
  293.         if (cur >= btm && start >= 0) {
  294.             if (sseq_pos >= start
  295.                 &&  seq_pos < start + x_GetLen(row, plus ? cur : last - cur)) {
  296.                 return (plus ? cur : last - cur); // found
  297.             }
  298.             if (sseq_pos > start) {
  299.                 btm = mid + 1;
  300.                 cur_btm = cur;
  301.             } else {
  302.                 top = cur - 1;
  303.                 cur_top = cur;
  304.             }
  305.             continue;
  306.         }
  307.         // if we get here, seq_pos falls into an unaligned region
  308.         // return either -1 or the closest segment in dir direction
  309.         if (dir == eNone) {
  310.             return -1;
  311.         } else if (dir == eBackwards  ||  dir == (plus ? eLeft : eRight)) {
  312.             return (plus ? cur_btm : last - cur_btm);
  313.         } else if (dir == eForward  ||  dir == (plus ? eRight : eLeft)) {
  314.             return (plus ? cur_top : last - cur_top);
  315.         }
  316.     }        
  317.     return -1; /* No match found */
  318. }
  319.     
  320. TSignedSeqPos CAlnMap::GetAlnPosFromSeqPos(TNumrow row, TSeqPos seq_pos,
  321.                                            ESearchDirection dir,
  322.                                            bool try_reverse_dir) const
  323. {
  324.     TNumseg raw_seg = GetRawSeg(row, seq_pos, dir, try_reverse_dir);
  325.     if (raw_seg < 0) { // out of seq range
  326.         return -1;
  327.     }
  328.     TSeqPos start = m_Starts[raw_seg * m_NumRows + row];
  329.     TSeqPos len   = x_GetLen(row, raw_seg);
  330.     TSeqPos stop  = start + len -1;
  331.     bool    plus  = IsPositiveStrand(row);
  332.     CNumSegWithOffset seg = x_GetSegFromRawSeg(raw_seg);
  333.     if (dir == eNone) {
  334.         if (seg.GetOffset()) {
  335.             // seq_pos is within an insert
  336.             return -1;
  337.         } 
  338.     } else {
  339.         // check if within unaligned region
  340.         // if seq_pos outside the segment returned by GetRawSeg
  341.         // then return the edge alnpos
  342.         if ((plus ? seq_pos < start : seq_pos > stop)) {
  343.             return GetAlnStart(seg.GetAlnSeg());
  344.         }
  345.         if ((plus ? seq_pos > stop : seq_pos < start)) {
  346.             return GetAlnStop(seg.GetAlnSeg());
  347.         }
  348.         // check if within an insert
  349.         if (seg.GetOffset()  &&  
  350.             (dir == eRight  ||
  351.              dir == (plus ? eForward : eBackwards))) {
  352.             // seek the nearest alnpos on the right
  353.             if (seg.GetAlnSeg() < GetNumSegs() - 1) {
  354.                 return GetAlnStart(seg.GetAlnSeg() + 1);
  355.             } else if (try_reverse_dir) {
  356.                 return GetAlnStop(seg.GetAlnSeg());
  357.             } else {
  358.                 return -1;
  359.             }
  360.         }
  361.         if (seg.GetOffset()  &&
  362.             (dir == eLeft  ||
  363.              dir == (plus ? eBackwards : eForward))) {
  364.             
  365.             // seek the nearest alnpos on left
  366.             if (seg.GetAlnSeg() >= 0) {
  367.                 return GetAlnStop(seg.GetAlnSeg());
  368.             } else if (try_reverse_dir) {
  369.                 return GetAlnStart(seg.GetAlnSeg() + 1);
  370.             } else {
  371.                 return -1;
  372.             }
  373.         }
  374.     } 
  375.     // main case: seq_pos is within an alnseg
  376.     //assert(seq_pos >= start  &&  seq_pos <= stop);
  377.     TSeqPos delta = (seq_pos - start) / GetWidth(row);
  378.     return m_AlnStarts[seg.GetAlnSeg()]
  379.         + (plus ? delta : m_Lens[raw_seg] - 1 - delta);
  380. }
  381. TSignedSeqPos CAlnMap::GetSeqPosFromAlnPos(TNumrow for_row,
  382.                                            TSeqPos aln_pos,
  383.                                            ESearchDirection dir,
  384.                                            bool try_reverse_dir) const
  385. {
  386.     if (aln_pos > GetAlnStop()) {
  387.         aln_pos = GetAlnStop(); // out-of-range adjustment
  388.     }
  389.     TNumseg seg = GetSeg(aln_pos);
  390.     TSignedSeqPos pos = GetStart(for_row, seg);
  391.     if (pos >= 0) {
  392.         TSeqPos delta = (aln_pos - GetAlnStart(seg)) * GetWidth(for_row);
  393.         if (IsPositiveStrand(for_row)) {
  394.             pos += delta;
  395.         } else {
  396.             pos += x_GetLen(for_row, x_GetRawSegFromSeg(seg)) - 1 - delta;
  397.         }
  398.     } else if (dir != eNone) {
  399.         // it is a gap, search in the neighbouring segments
  400.         // according to search direction (dir) and strand
  401.         bool reverse_pass = false;
  402.         TNumseg orig_seg = seg = x_GetRawSegFromSeg(seg);
  403.             
  404.         while (true) {
  405.             if (IsPositiveStrand(for_row)) {
  406.                 if (dir == eBackwards  ||  dir == eLeft) {
  407.                     while (--seg >=0  &&  pos == -1) {
  408.                         pos = x_GetRawStop(for_row, seg);
  409.                     }
  410.                 } else {
  411.                     while (++seg < m_NumSegs  &&  pos == -1) {
  412.                         pos = x_GetRawStart(for_row, seg);
  413.                     }
  414.                 }
  415.             } else {
  416.                 if (dir == eForward  ||  dir == eLeft) {
  417.                     while (--seg >=0  &&  pos == -1) {
  418.                         pos = x_GetRawStart(for_row, seg);
  419.                     }
  420.                 } else {
  421.                     while (++seg < m_NumSegs  &&  pos == -1) {
  422.                         pos = x_GetRawStop(for_row, seg);
  423.                     } 
  424.                 }
  425.             }
  426.             if (!try_reverse_dir) {
  427.                 break;
  428.             }
  429.             if (pos >= 0) {
  430.                 break; // found
  431.             } else if (reverse_pass) {
  432.                 string msg = "CAlnVec::GetSeqPosFromAlnPos(): "
  433.                     "Invalid Dense-seg: Row " +
  434.                     NStr::IntToString(for_row) +
  435.                     " contains gaps only.";
  436.                 NCBI_THROW(CAlnException, eInvalidDenseg, msg);
  437.             }
  438.             // not found, try reverse direction
  439.             reverse_pass = true;
  440.             seg = orig_seg;
  441.             switch (dir) {
  442.             case eLeft:
  443.                 dir = eRight; break;
  444.             case eRight:
  445.                 dir = eLeft; break;
  446.             case eForward:
  447.                 dir = eBackwards; break;
  448.             case eBackwards:
  449.                 dir = eForward; break;
  450.             }
  451.         }
  452.     }
  453.     return pos;
  454. }
  455. TSignedSeqPos CAlnMap::GetSeqPosFromSeqPos(TNumrow for_row,
  456.                                            TNumrow row, TSeqPos seq_pos) const
  457. {
  458.     TNumseg raw_seg = GetRawSeg(row, seq_pos);
  459.     if (raw_seg < 0) {
  460.         return -1;
  461.     }
  462.     unsigned offset = raw_seg * m_NumRows;
  463.     TSignedSeqPos start = m_Starts[offset + for_row];
  464.     if (start >= 0) {
  465.         TSeqPos delta
  466.             = seq_pos - m_Starts[offset + row];
  467.         if (GetWidth(for_row) != GetWidth(row)) {
  468.             delta = delta / GetWidth(row) * GetWidth(for_row);
  469.         }
  470.         return start
  471.             + (StrandSign(row) == StrandSign(for_row) ? delta
  472.                : x_GetLen(for_row, raw_seg) - 1 - delta);
  473.     } else {
  474.         return -1;
  475.     }
  476. }
  477. const CAlnMap::TNumseg& CAlnMap::x_GetSeqLeftSeg(TNumrow row) const
  478. {
  479.     TNumseg& seg = m_SeqLeftSegs[row];
  480.     if (seg < 0) {
  481.         while (++seg < m_NumSegs) {
  482.             if (m_Starts[seg * m_NumRows + row] >= 0) {
  483.                 return seg;
  484.             }
  485.         }
  486.     } else {
  487.         return seg;
  488.     }
  489.     seg = -1;
  490.     string err_msg = "CAlnVec::x_GetSeqLeftSeg(): "
  491.         "Invalid Dense-seg: Row " + NStr::IntToString(row) +
  492.         " contains gaps only.";
  493.     NCBI_THROW(CAlnException, eInvalidDenseg, err_msg);
  494. }
  495.     
  496. const CAlnMap::TNumseg& CAlnMap::x_GetSeqRightSeg(TNumrow row) const
  497. {
  498.     TNumseg& seg = m_SeqRightSegs[row];
  499.     if (seg < 0) {
  500.         seg = m_NumSegs;
  501.         while (seg--) {
  502.             if (m_Starts[seg * m_NumRows + row] >= 0) {
  503.                 return seg;
  504.             }
  505.         }
  506.     } else {
  507.         return seg;
  508.     }
  509.     seg = -1;
  510.     string err_msg = "CAlnVec::x_GetSeqRightSeg(): "
  511.         "Invalid Dense-seg: Row " + NStr::IntToString(row) +
  512.         " contains gaps only.";
  513.     NCBI_THROW(CAlnException, eInvalidDenseg, err_msg);
  514. }
  515.     
  516. void CAlnMap::GetResidueIndexMap(TNumrow row0,
  517.                                  TNumrow row1,
  518.                                  TRange aln_rng,
  519.                                  vector<TSignedSeqPos>& result,
  520.                                  TRange& rng0,
  521.                                  TRange& rng1) const
  522. {
  523.     _ASSERT( ! IsSetAnchor() );
  524.     TNumseg l_seg, r_seg;
  525.     TSeqPos aln_start = aln_rng.GetFrom();
  526.     TSeqPos aln_stop = aln_rng.GetTo();
  527.     int l_idx0 = row0;
  528.     int l_idx1 = row1;
  529.     TSeqPos aln_pos = 0, next_aln_pos, l_len, r_len, l_delta, r_delta;
  530.     bool plus0 = IsPositiveStrand(row0);
  531.     bool plus1 = IsPositiveStrand(row1);
  532.     TSeqPos l_pos0, r_pos0, l_pos1, r_pos1;
  533.     l_seg = 0;
  534.     while (l_seg < m_NumSegs) {
  535.         l_len = m_Lens[l_seg];
  536.         next_aln_pos = aln_pos + l_len;
  537.         if (m_Starts[l_idx0] >= 0  &&  m_Starts[l_idx1] >= 0  &&
  538.             aln_start >= aln_pos  &&  aln_start < next_aln_pos) {
  539.             // found the left seg
  540.             break;
  541.         }
  542.         aln_pos = next_aln_pos;
  543.         l_idx0 += m_NumRows; l_idx1 += m_NumRows;
  544.         l_seg++;
  545.     }
  546.     _ASSERT(l_seg < m_NumSegs);
  547.     // determine left seq positions
  548.     l_pos0 = m_Starts[l_idx0];
  549.     l_pos1 = m_Starts[l_idx1];
  550.     l_delta = aln_start - aln_pos;
  551.     l_len -= l_delta;
  552.     _ASSERT(l_delta >= 0);
  553.     if (plus0) {
  554.         l_pos0 += l_delta;
  555.     } else {
  556.         l_pos0 += l_len - 1;
  557.     }
  558.     if (plus1) {
  559.         l_pos1 += l_delta;
  560.     } else {
  561.         l_pos1 += l_len - 1;
  562.     }
  563.         
  564.     r_seg = m_NumSegs - 1;
  565.     int r_idx0 = r_seg * m_NumRows + row0;
  566.     int r_idx1 = r_seg * m_NumRows + row1;
  567.     aln_pos = GetAlnStop();
  568.     if (aln_stop > aln_pos) {
  569.         aln_stop = aln_pos;
  570.     }
  571.     while (r_seg >= 0) {
  572.         r_len = m_Lens[r_seg];
  573.         next_aln_pos = aln_pos - r_len;
  574.         if (m_Starts[l_idx0] >= 0  &&  m_Starts[l_idx1] >= 0  &&
  575.             aln_stop > next_aln_pos  &&  aln_stop <= aln_pos) {
  576.             // found the right seg
  577.             break;
  578.         }
  579.         aln_pos = next_aln_pos;
  580.         r_idx0 -= m_NumRows; r_idx1 -= m_NumRows;
  581.         r_seg--;
  582.     }
  583.     
  584.     // determine right seq positions
  585.     r_pos0 = m_Starts[r_idx0];
  586.     r_pos1 = m_Starts[r_idx1];
  587.     r_delta = aln_pos - aln_stop;
  588.     r_len -= r_delta;
  589.     _ASSERT(r_delta >= 0);
  590.     if (plus0) {
  591.         r_pos0 += r_len - 1;
  592.     } else {
  593.         r_pos0 += r_delta;
  594.     }
  595.     if (plus1) {
  596.         r_pos1 += r_len - 1;
  597.     } else {
  598.         r_pos1 += r_delta;
  599.     }
  600.         
  601.     // We now know the size of the resulting vector
  602.     TSeqPos size = (plus0 ? r_pos0 - l_pos0 : l_pos0 - r_pos0) + 1;
  603.     result.resize(size, -1);
  604.     // Initialize index positions (from left to right)
  605.     TSeqPos pos0 = plus0 ? 0 : l_pos0 - r_pos0;
  606.     TSeqPos pos1 = plus1 ? 0 : l_pos1 - r_pos1;
  607.     // Initialize 'next' positions
  608.     // -- to determine if there are unaligned pieces
  609.     TSeqPos next_l_pos0 = plus0 ? l_pos0 + l_len : l_pos0 - l_len;
  610.     TSeqPos next_l_pos1 = plus1 ? l_pos1 + l_len : l_pos1 - l_len;
  611.     l_idx0 = row0;
  612.     l_idx1 = row1;
  613.     TNumseg seg = l_seg;
  614.     TSeqPos delta;
  615.     while (true) {
  616.         if (m_Starts[l_idx0] >= 0) { // if row0 is not gapped
  617.             if (seg > l_seg) {
  618.                 // check for unaligned region / validate
  619.                 if (plus0) {
  620.                     delta = m_Starts[l_idx0] - next_l_pos0;
  621.                     next_l_pos0 = m_Starts[l_idx0] + l_len;
  622.                 } else {
  623.                     delta = next_l_pos0 - m_Starts[l_idx0] - l_len + 1;
  624.                     next_l_pos0 = m_Starts[l_idx0] - 1;
  625.                 }
  626.                 if (delta > 0) {
  627.                     // unaligned region
  628.                     if (plus0) {
  629.                         pos0 += delta;
  630.                     } else {
  631.                         pos0 -= delta;
  632.                     }
  633.                 } else if (delta < 0) {
  634.                     // invalid segment
  635.                     string errstr = string("CAlnMap::GetResidueIndexMap():")
  636.                         + " Starts are not consistent!"
  637.                         + " Row=" + NStr::IntToString(row0) +
  638.                         " Seg=" + NStr::IntToString(seg);
  639.                     NCBI_THROW(CAlnException, eInvalidDenseg, errstr);
  640.                 }
  641.             }
  642.             if (m_Starts[l_idx1] >= 0) { // if row1 is not gapped
  643.                 
  644.                 if (seg > l_seg) {
  645.                     // check for unaligned region / validate
  646.                     if (plus1) {
  647.                         delta = m_Starts[l_idx1] - next_l_pos1;
  648.                         next_l_pos1 = m_Starts[l_idx1] + l_len;
  649.                     } else {
  650.                         delta = next_l_pos1 - m_Starts[l_idx1] - l_len + 1;
  651.                         next_l_pos1 = m_Starts[l_idx1] - 1;
  652.                     }
  653.                     if (delta > 0) {
  654.                         // unaligned region
  655.                         if (plus1) {
  656.                             pos1 += delta;
  657.                         } else {
  658.                             pos1 -= delta;
  659.                         }
  660.                     } else if (delta < 0) {
  661.                         // invalid segment
  662.                         string errstr = string("CAlnMap::GetResidueIndexMap():")
  663.                             + " Starts are not consistent!"
  664.                             + " Row=" + NStr::IntToString(row1) +
  665.                             " Seg=" + NStr::IntToString(seg);
  666.                         NCBI_THROW(CAlnException, eInvalidDenseg, errstr);
  667.                     }
  668.                 }
  669.                 if (plus0) {
  670.                     if (plus1) { // if row1 on +
  671.                         while (l_len--) {
  672.                             result[pos0++] = pos1++;
  673.                         }
  674.                     } else { // if row1 on -
  675.                         while (l_len--) {
  676.                             result[pos0++] = pos1--;
  677.                         }
  678.                     }
  679.                 } else { // if row0 on -
  680.                     if (plus1) { // if row1 on +
  681.                         while (l_len--) {
  682.                             result[pos0--] = pos1++;
  683.                         }
  684.                     } else { // if row1 on -
  685.                         while (l_len--) {
  686.                             result[pos0--] = pos1--;
  687.                         }
  688.                     }
  689.                 }                    
  690.             } else {
  691.                 if (plus0) {
  692.                     pos0 += l_len;
  693.                 } else {
  694.                     pos0 -= l_len;
  695.                 }
  696.             }
  697.         }
  698.         // iterate to next segment
  699.         seg++;
  700.         l_idx0 += m_NumRows;
  701.         l_idx1 += m_NumRows;
  702.         if (seg < r_seg) {
  703.             l_len = m_Lens[seg];
  704.         } else if (seg == r_seg) {
  705.             l_len = r_len;
  706.         } else {
  707.             break;
  708.         }
  709.     }
  710.     // finally, set the ranges for the two sequences
  711.     rng0.SetFrom(plus0 ? l_pos0 : r_pos0);
  712.     rng0.SetTo(plus0 ? r_pos0 : l_pos0);
  713.     rng1.SetFrom(plus1 ? l_pos1 : r_pos1);
  714.     rng1.SetTo(plus1 ? r_pos1 : l_pos1);
  715. }
  716. TSignedSeqPos CAlnMap::GetSeqAlnStart(TNumrow row) const
  717. {
  718.     if (IsSetAnchor()) {
  719.         TNumseg seg = -1;
  720.         while (++seg < m_AlnSegIdx.size()) {
  721.             if (m_Starts[m_AlnSegIdx[seg] * m_NumRows + row] >= 0) {
  722.                 return GetAlnStart(seg);
  723.             }
  724.         }
  725.         return -1;
  726.     } else {
  727.         return GetAlnStart(x_GetSeqLeftSeg(row));
  728.     }
  729. }
  730. TSignedSeqPos CAlnMap::GetSeqAlnStop(TNumrow row) const
  731. {
  732.     if (IsSetAnchor()) {
  733.         TNumseg seg = m_AlnSegIdx.size();
  734.         while (seg--) {
  735.             if (m_Starts[m_AlnSegIdx[seg] * m_NumRows + row] >= 0) {
  736.                 return GetAlnStop(seg);
  737.             }
  738.         }
  739.         return -1;
  740.     } else {
  741.         return GetAlnStop(x_GetSeqRightSeg(row));
  742.     }
  743. }
  744. CRef<CAlnMap::CAlnChunkVec>
  745. CAlnMap::GetAlnChunks(TNumrow row, const TSignedRange& range,
  746.                       TGetChunkFlags flags) const
  747. {
  748.     CRef<CAlnChunkVec> vec(new CAlnChunkVec(*this, row));
  749.     // boundaries check
  750.     if (range.GetTo() < 0
  751.         ||  range.GetFrom() > (TSignedSeqPos) GetAlnStop(GetNumSegs() - 1)) {
  752.         return vec;
  753.     }
  754.     // determine the participating segments range
  755.     TNumseg first_seg, last_seg, aln_seg;
  756.     if (range.GetFrom() < 0) {
  757.         first_seg = 0;
  758.     } else {        
  759.         first_seg = x_GetRawSegFromSeg(aln_seg = GetSeg(range.GetFrom()));
  760.         if ( !(flags & fDoNotTruncateSegs) ) {
  761.             vec->m_LeftDelta = range.GetFrom() - GetAlnStart(aln_seg);
  762.         }
  763.     }
  764.     if ((TSeqPos)range.GetTo() > GetAlnStop(GetNumSegs()-1)) {
  765.         last_seg = m_NumSegs-1;
  766.     } else {
  767.         last_seg = x_GetRawSegFromSeg(aln_seg = GetSeg(range.GetTo()));
  768.         if ( !(flags & fDoNotTruncateSegs) ) {
  769.             vec->m_RightDelta = GetAlnStop(aln_seg) - range.GetTo();
  770.         }
  771.     }
  772.     
  773.     x_GetChunks(vec, row, first_seg, last_seg, flags);
  774.     return vec;
  775. }
  776. CRef<CAlnMap::CAlnChunkVec>
  777. CAlnMap::GetSeqChunks(TNumrow row, const TSignedRange& range,
  778.                       TGetChunkFlags flags) const
  779. {
  780.     CRef<CAlnChunkVec> vec(new CAlnChunkVec(*this, row));
  781.     // boundaries check
  782.     if (range.GetTo() < GetSeqStart(row)  ||
  783.         range.GetFrom() > GetSeqStop(row)) {
  784.         return vec;
  785.     }
  786.     // determine the participating segments range
  787.     TNumseg first_seg, last_seg;
  788.     if (range.GetFrom() < GetSeqStart(row)) {
  789.         if (IsPositiveStrand(row)) {
  790.             first_seg = 0;
  791.         } else {
  792.             last_seg = m_NumSegs - 1;
  793.         }
  794.     } else {        
  795.         if (IsPositiveStrand(row)) {
  796.             first_seg = GetRawSeg(row, range.GetFrom());
  797.             vec->m_LeftDelta = range.GetFrom() - x_GetRawStart(row, first_seg);
  798.         } else {
  799.             last_seg = GetRawSeg(row, range.GetFrom());
  800.             vec->m_RightDelta = range.GetFrom() - x_GetRawStart(row, last_seg);
  801.         }
  802.     }
  803.     if (range.GetTo() > GetSeqStop(row)) {
  804.         if (IsPositiveStrand(row)) {
  805.             last_seg = m_NumSegs - 1;
  806.         } else {
  807.             first_seg = 0;
  808.         }
  809.     } else {
  810.         if (IsPositiveStrand(row)) {
  811.             last_seg = GetRawSeg(row, range.GetTo());
  812.             if ( !(flags & fDoNotTruncateSegs) ) {
  813.                 vec->m_RightDelta = x_GetRawStop(row, last_seg) - range.GetTo();
  814.             }
  815.         } else {
  816.             first_seg = GetRawSeg(row, range.GetTo());
  817.             if ( !(flags & fDoNotTruncateSegs) ) {
  818.                 vec->m_LeftDelta = x_GetRawStop(row, last_seg) - range.GetTo();
  819.             }
  820.         }
  821.     }
  822.     x_GetChunks(vec, row, first_seg, last_seg, flags);
  823.     return vec;
  824. }
  825. inline
  826. bool CAlnMap::x_SkipType(TSegTypeFlags type, TGetChunkFlags flags) const
  827. {
  828.     bool skip = false;
  829.     if (type & fSeq) {
  830.         if (type & fNotAlignedToSeqOnAnchor) {
  831.             if (flags & fSkipInserts) {
  832.                 skip = true;
  833.             }
  834.         } else {
  835.             if (flags & fSkipAlnSeq) {
  836.                 skip = true;
  837.             }
  838.         }
  839.     } else {
  840.         if (type & fNotAlignedToSeqOnAnchor) {
  841.             if (flags & fSkipUnalignedGaps) {
  842.                 skip = true;
  843.             }
  844.         } else {
  845.             if (flags & fSkipDeletions) {
  846.                 skip = true;
  847.             }
  848.         }
  849.     }        
  850.     return skip;
  851. }
  852. inline
  853. bool
  854. CAlnMap::x_CompareAdjacentSegTypes(TSegTypeFlags left_type, 
  855.                                    TSegTypeFlags right_type,
  856.                                    TGetChunkFlags flags) const
  857.     // returns true if types are the same (as specified by flags)
  858. {
  859.     if (flags & fChunkSameAsSeg) {
  860.         return false;
  861.     }
  862.         
  863.     if ((left_type & fSeq) != (right_type & fSeq)) {
  864.         return false;
  865.     }
  866.     if (!(flags & fIgnoreUnaligned)  &&
  867.         (left_type & fUnalignedOnRight || right_type & fUnalignedOnLeft)) {
  868.         return false;
  869.     }
  870.     if ((left_type & fNotAlignedToSeqOnAnchor) ==
  871.         (right_type & fNotAlignedToSeqOnAnchor)) {
  872.         return true;
  873.     }
  874.     if (left_type & fSeq) {
  875.         if (!(flags & fInsertSameAsSeq)) {
  876.             return false;
  877.         }
  878.     } else {
  879.         if (!(flags & fDeletionSameAsGap)) {
  880.             return false;
  881.         }
  882.     }
  883.     return true;
  884. }
  885. void CAlnMap::x_GetChunks(CAlnChunkVec * vec,
  886.                           TNumrow row,
  887.                           TNumseg first_seg, TNumseg last_seg,
  888.                           TGetChunkFlags flags) const
  889. {
  890.     TSegTypeFlags type, test_type;
  891.     // add the participating segments to the vector
  892.     for (TNumseg seg = first_seg;  seg <= last_seg;  seg++) {
  893.         type = x_GetRawSegType(row, seg);
  894.         // see if the segment needs to be skipped
  895.         if (x_SkipType(type, flags)) {
  896.             if (seg == first_seg) {
  897.                 vec->m_LeftDelta = 0;
  898.             } else if (seg == last_seg) {
  899.                 vec->m_RightDelta = 0;
  900.             }
  901.             continue;
  902.         }
  903.         vec->m_StartSegs.push_back(seg); // start seg
  904.         // find the stop seg
  905.         TNumseg test_seg = seg;
  906.         while (test_seg < last_seg) {
  907.             test_seg++;
  908.             test_type = x_GetRawSegType(row, test_seg);
  909.             if (x_CompareAdjacentSegTypes(type, test_type, flags)) {
  910.                 seg = test_seg;
  911.                 continue;
  912.             }
  913.             // include included gaps if desired
  914.             if (flags & fIgnoreGaps  &&  !(test_type & fSeq)  &&
  915.                 x_CompareAdjacentSegTypes(type & ~fSeq, test_type, flags)) {
  916.                 continue;
  917.             }
  918.             break;
  919.         }
  920.         vec->m_StopSegs.push_back(seg);
  921.     }
  922. }
  923. CConstRef<CAlnMap::CAlnChunk>
  924. CAlnMap::CAlnChunkVec::operator[](CAlnMap::TNumchunk i) const
  925. {
  926.     CAlnMap::TNumseg start_seg = m_StartSegs[i];
  927.     CAlnMap::TNumseg stop_seg  = m_StopSegs[i];
  928.     CRef<CAlnChunk>  chunk(new CAlnChunk());
  929.     TSignedSeqPos from, to;
  930.     from = m_AlnMap.m_Starts[start_seg * m_AlnMap.m_NumRows
  931.                                      + m_Row];
  932.     if (from >= 0) {
  933.         to = from + m_AlnMap.x_GetLen(m_Row, start_seg) - 1;
  934.     } else {
  935.         from = -1;
  936.         to = -1;
  937.     }
  938.     chunk->SetRange().Set(from, to);
  939.     chunk->SetType(m_AlnMap.x_GetRawSegType(m_Row, start_seg));
  940.     TSegTypeFlags type;
  941.     for (CAlnMap::TNumseg seg = start_seg + 1;  seg <= stop_seg;  seg++) {
  942.         type = m_AlnMap.x_GetRawSegType(m_Row, seg);
  943.         if (type & fSeq) {
  944.             // extend the range
  945.             if (m_AlnMap.IsPositiveStrand(m_Row)) {
  946.                 chunk->SetRange().Set(chunk->GetRange().GetFrom(),
  947.                                       chunk->GetRange().GetTo()
  948.                                       + m_AlnMap.x_GetLen(m_Row, seg));
  949.             } else {
  950.                 chunk->SetRange().Set(chunk->GetRange().GetFrom()
  951.                                       - m_AlnMap.x_GetLen(m_Row, seg),
  952.                                       chunk->GetRange().GetTo());
  953.             }
  954.         }
  955.         // extend the type
  956.         chunk->SetType(chunk->GetType() | type);
  957.     }
  958.     //determine the aln range
  959.     {{
  960.         // from position
  961.         CNumSegWithOffset seg = m_AlnMap.x_GetSegFromRawSeg(start_seg);
  962.         if (seg.GetAlnSeg() < 0) {
  963.             // before the aln start
  964.             from = -1;
  965.         } else {
  966.             if (seg.GetOffset() > 0) {
  967.                 // between aln segs
  968.                 from = m_AlnMap.GetAlnStop(seg.GetAlnSeg()) + 1;
  969.             } else {
  970.                 // at an aln seg
  971.                 from = m_AlnMap.GetAlnStart(seg.GetAlnSeg()) +
  972.                     (i == 0  &&  m_LeftDelta ? m_LeftDelta : 0);
  973.             }
  974.         }
  975.         // to position
  976.         seg = m_AlnMap.x_GetSegFromRawSeg(stop_seg);
  977.         if (seg.GetAlnSeg() < 0) {
  978.             // before the aln start
  979.             to = 0;
  980.         } else {
  981.             if (seg.GetOffset() > 0) {
  982.                 // between aln segs
  983.                 to = m_AlnMap.GetAlnStop(seg.GetAlnSeg());
  984.             } else {
  985.                 // at an aln seg
  986.                 to = m_AlnMap.GetAlnStop(seg.GetAlnSeg()) -
  987.                     (i == size() - 1  &&  m_RightDelta ? m_RightDelta : 0);
  988.             }
  989.         }
  990.         chunk->SetAlnRange().Set(from, to);
  991.     }}
  992.     // fix if extreme end
  993.     if (i == 0 && m_LeftDelta) {
  994.         if (!chunk->IsGap()) {
  995.             if (m_AlnMap.IsPositiveStrand(m_Row)) {
  996.                 chunk->SetRange().Set
  997.                     (chunk->GetRange().GetFrom()
  998.                      + m_LeftDelta * m_AlnMap.GetWidth(m_Row),
  999.                      chunk->GetRange().GetTo());
  1000.             } else {
  1001.                 chunk->SetRange().Set(chunk->GetRange().GetFrom(),
  1002.                                       chunk->GetRange().GetTo()
  1003.                                       - m_LeftDelta
  1004.                                       * m_AlnMap.GetWidth(m_Row));
  1005.             }
  1006.             chunk->SetType(chunk->GetType() & ~fNoSeqOnLeft);
  1007.         }            
  1008.         chunk->SetType(chunk->GetType() & ~(fUnalignedOnLeft | fEndOnLeft));
  1009.     }
  1010.     if (i == size() - 1 && m_RightDelta) {
  1011.         if (!chunk->IsGap()) {
  1012.             if (m_AlnMap.IsPositiveStrand(m_Row)) {
  1013.                 chunk->SetRange().Set
  1014.                     (chunk->GetRange().GetFrom(),
  1015.                      chunk->GetRange().GetTo()
  1016.                      - m_RightDelta * m_AlnMap.GetWidth(m_Row));
  1017.             } else {
  1018.                 chunk->SetRange().Set
  1019.                     (chunk->GetRange().GetFrom()
  1020.                      + m_RightDelta * m_AlnMap.GetWidth(m_Row),
  1021.                      chunk->GetRange().GetTo());
  1022.             }
  1023.             chunk->SetType(chunk->GetType() & ~fNoSeqOnRight);
  1024.         }
  1025.         chunk->SetType(chunk->GetType() & ~(fUnalignedOnRight | fEndOnRight));
  1026.     }
  1027.     return chunk;
  1028. }
  1029. END_objects_SCOPE // namespace ncbi::objects::
  1030. END_NCBI_SCOPE
  1031. /*
  1032. * ===========================================================================
  1033. *
  1034. * $Log: alnmap.cpp,v $
  1035. * Revision 1000.3  2004/06/01 19:40:42  gouriano
  1036. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.48
  1037. *
  1038. * Revision 1.48  2004/05/21 21:42:51  gorelenk
  1039. * Added PCH ncbi_pch.hpp
  1040. *
  1041. * Revision 1.47  2004/03/03 19:39:22  todorov
  1042. * +GetResidueIndexMap
  1043. *
  1044. * Revision 1.46  2004/01/21 21:15:59  ucko
  1045. * Fix typos in last revision.
  1046. *
  1047. * Revision 1.45  2004/01/21 20:59:42  todorov
  1048. * fDoNotTruncate -> fDoNotTruncateSegs; +comments
  1049. *
  1050. * Revision 1.44  2004/01/21 20:53:35  todorov
  1051. * EGetChunkFlags += fDoNotTruncate
  1052. *
  1053. * Revision 1.43  2004/01/14 22:32:16  todorov
  1054. * Check for out of range seq_pos in GetSeqPosFromSeqPos
  1055. *
  1056. * Revision 1.42  2004/01/14 21:32:40  todorov
  1057. * Swapped aln range coords for insert chunks to insure proper range arithmetics
  1058. *
  1059. * Revision 1.41  2003/11/04 19:37:38  todorov
  1060. * Fixed GetRawSeg and GetAlnPosFromSeqPos in case of unaligned region
  1061. *
  1062. * Revision 1.40  2003/09/18 23:05:18  todorov
  1063. * Optimized GetSeqAln{Start,Stop}
  1064. *
  1065. * Revision 1.39  2003/09/17 16:26:35  todorov
  1066. * Fixed GetSeqPosFromSeqPos
  1067. *
  1068. * Revision 1.38  2003/09/10 22:53:37  todorov
  1069. * Use raw seg in GetSeqPosFromAlnPos
  1070. *
  1071. * Revision 1.37  2003/08/25 16:34:59  todorov
  1072. * exposed GetWidth
  1073. *
  1074. * Revision 1.36  2003/08/20 14:34:58  todorov
  1075. * Support for NA2AA Densegs
  1076. *
  1077. * Revision 1.35  2003/07/17 22:47:13  todorov
  1078. * name change
  1079. *
  1080. * Revision 1.34  2003/07/08 20:26:34  todorov
  1081. * Created seq end segments cache
  1082. *
  1083. * Revision 1.33  2003/06/09 17:47:26  todorov
  1084. * local var start type fixed in GetSeqStart,GetSeqStop
  1085. *
  1086. * Revision 1.32  2003/06/05 21:14:15  todorov
  1087. * Type fixed
  1088. *
  1089. * Revision 1.31  2003/06/05 19:59:33  todorov
  1090. * Fixed a few inefficiencies
  1091. *
  1092. * Revision 1.30  2003/06/05 19:03:12  todorov
  1093. * Added const refs to Dense-seg members as a speed optimization
  1094. *
  1095. * Revision 1.29  2003/06/02 16:06:40  dicuccio
  1096. * Rearranged src/objects/ subtree.  This includes the following shifts:
  1097. *     - src/objects/asn2asn --> arc/app/asn2asn
  1098. *     - src/objects/testmedline --> src/objects/ncbimime/test
  1099. *     - src/objects/objmgr --> src/objmgr
  1100. *     - src/objects/util --> src/objmgr/util
  1101. *     - src/objects/alnmgr --> src/objtools/alnmgr
  1102. *     - src/objects/flat --> src/objtools/flat
  1103. *     - src/objects/validator --> src/objtools/validator
  1104. *     - src/objects/cddalignview --> src/objtools/cddalignview
  1105. * In addition, libseq now includes six of the objects/seq... libs, and libmmdb
  1106. * replaces the three libmmdb? libs.
  1107. *
  1108. * Revision 1.28  2003/05/23 18:10:47  todorov
  1109. * +fChunkSameAsSeg
  1110. *
  1111. * Revision 1.27  2003/03/20 16:38:21  todorov
  1112. * +fIgnoreGaps for GetXXXChunks
  1113. *
  1114. * Revision 1.26  2003/03/07 17:30:26  todorov
  1115. * + ESearchDirection dir, bool try_reverse_dir for GetAlnPosFromSeqPos
  1116. *
  1117. * Revision 1.25  2003/03/04 16:19:05  todorov
  1118. * Added advance search options for GetRawSeg
  1119. *
  1120. * Revision 1.24  2003/01/31 17:22:14  todorov
  1121. * Fixed a typo
  1122. *
  1123. * Revision 1.23  2003/01/15 18:48:30  todorov
  1124. * Added GetSeqChunks to be used with native seq range
  1125. *
  1126. * Revision 1.22  2003/01/08 23:04:47  todorov
  1127. * Fixed a bug in x_CompareAdjacentSegTypes
  1128. *
  1129. * Revision 1.21  2003/01/03 17:00:41  todorov
  1130. * Fixed negative strand handling in GetRawSeg
  1131. *
  1132. * Revision 1.20  2002/12/20 21:25:14  todorov
  1133. * ... and another small fix
  1134. *
  1135. * Revision 1.19  2002/12/20 20:30:42  todorov
  1136. * Fixed a bug introduced in the previous revision
  1137. *
  1138. * Revision 1.18  2002/12/19 20:24:53  grichenk
  1139. * Updated usage of CRange<>
  1140. *
  1141. * Revision 1.17  2002/11/13 16:40:56  todorov
  1142. * out of range check for GetAlnPosFromSeqPos
  1143. *
  1144. * Revision 1.16  2002/11/04 21:29:08  grichenk
  1145. * Fixed usage of const CRef<> and CRef<> constructor
  1146. *
  1147. * Revision 1.15  2002/10/24 21:27:29  todorov
  1148. * out-of-range adjustment instead of return -1 for the GetSeqPosFromAlnPos
  1149. *
  1150. * Revision 1.14  2002/10/21 19:14:27  todorov
  1151. * reworked aln chunks: now supporting more types; added chunk aln coords
  1152. *
  1153. * Revision 1.13  2002/10/10 17:23:43  todorov
  1154. * switched back to one (but this time enhanced) GetSeqPosFromAlnPos method
  1155. *
  1156. * Revision 1.12  2002/10/04 16:38:06  todorov
  1157. * new method GetBestSeqPosFromAlnPos
  1158. *
  1159. * Revision 1.11  2002/09/27 16:57:46  todorov
  1160. * changed order of params for GetSeqPosFrom{Seq,Aln}Pos
  1161. *
  1162. * Revision 1.10  2002/09/26 18:24:50  todorov
  1163. * fixed a just introduced bug
  1164. *
  1165. * Revision 1.9  2002/09/26 17:43:17  todorov
  1166. * 1) Changed flag fAlignedToSeqOnAnchor to fNotAlignedToSeqOnAnchor. This proved
  1167. * more convenient.
  1168. * 2) Introduced some exceptions
  1169. * 3) Fixed a strand bug in CAlnMap::CAlnChunkVec::operator[]
  1170. *
  1171. * Revision 1.8  2002/09/25 18:16:29  dicuccio
  1172. * Reworked computation of consensus sequence - this is now stored directly
  1173. * in the underlying CDense_seg
  1174. * Added exception class; currently used only on access of non-existent
  1175. * consensus.
  1176. *
  1177. * Revision 1.7  2002/09/19 22:16:48  todorov
  1178. * fix the range on the extreme end only if not a gap
  1179. *
  1180. * Revision 1.6  2002/09/19 22:09:07  todorov
  1181. * fixed a problem due to switching of lines during code cleanup
  1182. *
  1183. * Revision 1.5  2002/09/18 19:24:54  todorov
  1184. * fixing the flags on the extreme end only if delta
  1185. *
  1186. * Revision 1.4  2002/09/05 19:30:39  dicuccio
  1187. * - added ability to reference a consensus sequence for a given alignment
  1188. * - added caching for CSeqVector objects (big performance gain)
  1189. * - many small bugs fixed
  1190. *
  1191. * Revision 1.3  2002/08/23 20:34:17  ucko
  1192. * Work around a Compaq C++ compiler bug.
  1193. *
  1194. * Revision 1.2  2002/08/23 20:31:17  todorov
  1195. * fixed neg strand deltas
  1196. *
  1197. * Revision 1.1  2002/08/23 14:43:52  ucko
  1198. * Add the new C++ alignment manager to the public tree (thanks, Kamen!)
  1199. *
  1200. *
  1201. * ===========================================================================
  1202. */