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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: seq_loc_cvt.cpp,v $
  4.  * PRODUCTION Revision 1000.5  2004/06/01 19:24:09  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.29
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: seq_loc_cvt.cpp,v 1000.5 2004/06/01 19:24:09 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: Eugene Vasilchenko
  35. *
  36. * File Description:
  37. *   Class for mapping Seq-loc petween sequences.
  38. *
  39. */
  40. #include <ncbi_pch.hpp>
  41. #include <objmgr/impl/seq_loc_cvt.hpp>
  42. #include <objmgr/impl/seq_align_mapper.hpp>
  43. #include <objmgr/seq_map_ci.hpp>
  44. #include <objmgr/impl/scope_impl.hpp>
  45. #include <objmgr/annot_types_ci.hpp>
  46. #include <objects/seqloc/Seq_loc.hpp>
  47. #include <objects/seqloc/Seq_interval.hpp>
  48. #include <objects/seqloc/Seq_point.hpp>
  49. #include <objects/seqloc/Seq_loc_equiv.hpp>
  50. #include <objects/seqloc/Seq_bond.hpp>
  51. #include <objects/seqfeat/Seq_feat.hpp>
  52. BEGIN_NCBI_SCOPE
  53. BEGIN_SCOPE(objects)
  54. /////////////////////////////////////////////////////////////////////////////
  55. // CSeq_loc_Conversion
  56. /////////////////////////////////////////////////////////////////////////////
  57. CSeq_loc_Conversion::CSeq_loc_Conversion(CSeq_loc& master_loc_empty,
  58.                                          const CSeq_id_Handle& dst_id,
  59.                                          const CSeqMap_CI& seg,
  60.                                          const CSeq_id_Handle& src_id,
  61.                                          CScope* scope)
  62.     : m_Src_id_Handle(src_id),
  63.       m_Src_from(0),
  64.       m_Src_to(0),
  65.       m_Shift(0),
  66.       m_Reverse(false),
  67.       m_Dst_id_Handle(dst_id),
  68.       m_Dst_loc_Empty(&master_loc_empty),
  69.       m_Partial(false),
  70.       m_LastType(eMappedObjType_not_set),
  71.       m_LastStrand(eNa_strand_unknown),
  72.       m_Scope(scope)
  73. {
  74.     SetConversion(seg);
  75.     Reset();
  76. }
  77. CSeq_loc_Conversion::CSeq_loc_Conversion(const CSeq_id_Handle& master_id,
  78.                                          CScope* scope)
  79.     : m_Src_id_Handle(master_id),
  80.       m_Src_from(0),
  81.       m_Src_to(kInvalidSeqPos - 1),
  82.       m_Shift(0),
  83.       m_Reverse(false),
  84.       m_Dst_id_Handle(master_id),
  85.       m_Dst_loc_Empty(0),
  86.       m_Partial(false),
  87.       m_LastType(eMappedObjType_not_set),
  88.       m_LastStrand(eNa_strand_unknown),
  89.       m_Scope(scope)
  90. {
  91.     m_Dst_loc_Empty.Reset(new CSeq_loc);
  92.     m_Dst_loc_Empty->SetEmpty().Assign(*master_id.GetSeqId());
  93.     Reset();
  94. }
  95. CSeq_loc_Conversion::~CSeq_loc_Conversion(void)
  96. {
  97.     _ASSERT(!IsSpecialLoc());
  98. }
  99. void CSeq_loc_Conversion::SetConversion(const CSeqMap_CI& seg)
  100. {
  101.     m_Src_from = seg.GetRefPosition();
  102.     m_Src_to = m_Src_from + seg.GetLength() - 1;
  103.     m_Reverse = seg.GetRefMinusStrand();
  104.     if ( !m_Reverse ) {
  105.         m_Shift = seg.GetPosition() - m_Src_from;
  106.     }
  107.     else {
  108.         m_Shift = seg.GetPosition() + m_Src_to;
  109.     }
  110. }
  111. bool CSeq_loc_Conversion::ConvertPoint(TSeqPos src_pos,
  112.                                        ENa_strand src_strand)
  113. {
  114.     _ASSERT(!IsSpecialLoc());
  115.     if ( src_pos < m_Src_from || src_pos > m_Src_to ) {
  116.         m_Partial = true;
  117.         return false;
  118.     }
  119.     TSeqPos dst_pos;
  120.     if ( !m_Reverse ) {
  121.         m_LastStrand = src_strand;
  122.         dst_pos = m_Shift + src_pos;
  123.     }
  124.     else {
  125.         m_LastStrand = Reverse(src_strand);
  126.         dst_pos = m_Shift - src_pos;
  127.     }
  128.     m_LastType = eMappedObjType_Seq_point;
  129.     m_TotalRange += m_LastRange.SetFrom(dst_pos).SetTo(dst_pos);
  130.     return true;
  131. }
  132. bool CSeq_loc_Conversion::ConvertInterval(TSeqPos src_from, TSeqPos src_to,
  133.                                           ENa_strand src_strand)
  134. {
  135.     _ASSERT(!IsSpecialLoc());
  136.     if ( src_from < m_Src_from ) {
  137.         m_Partial = true;
  138.         src_from = m_Src_from;
  139.     }
  140.     if ( src_to > m_Src_to ) {
  141.         m_Partial = true;
  142.         src_to = m_Src_to;
  143.     }
  144.     if ( src_from > src_to ) {
  145.         return false;
  146.     }
  147.     TSeqPos dst_from, dst_to;
  148.     if ( !m_Reverse ) {
  149.         m_LastStrand = src_strand;
  150.         dst_from = m_Shift + src_from;
  151.         dst_to = m_Shift + src_to;
  152.     }
  153.     else {
  154.         m_LastStrand = Reverse(src_strand);
  155.         dst_from = m_Shift - src_to;
  156.         dst_to = m_Shift - src_from;
  157.     }
  158.     m_LastType = eMappedObjType_Seq_interval;
  159.     m_TotalRange += m_LastRange.SetFrom(dst_from).SetTo(dst_to);
  160.     return true;
  161. }
  162. inline
  163. void CSeq_loc_Conversion::CheckDstInterval(void)
  164. {
  165.     if ( m_LastType != eMappedObjType_Seq_interval ) {
  166.         NCBI_THROW(CAnnotException, eBadLocation,
  167.                    "Wrong last location type");
  168.     }
  169.     m_LastType = eMappedObjType_not_set;
  170. }
  171. inline
  172. void CSeq_loc_Conversion::CheckDstPoint(void)
  173. {
  174.     if ( m_LastType != eMappedObjType_Seq_point ) {
  175.         NCBI_THROW(CAnnotException, eBadLocation,
  176.                    "Wrong last location type");
  177.     }
  178.     m_LastType = eMappedObjType_not_set;
  179. }
  180. CRef<CSeq_interval> CSeq_loc_Conversion::GetDstInterval(void)
  181. {
  182.     CheckDstInterval();
  183.     CRef<CSeq_interval> ret(new CSeq_interval);
  184.     CSeq_interval& interval = *ret;
  185.     interval.SetId(GetDstId());
  186.     interval.SetFrom(m_LastRange.GetFrom());
  187.     interval.SetTo(m_LastRange.GetTo());
  188.     if ( m_LastStrand != eNa_strand_unknown ) {
  189.         interval.SetStrand(m_LastStrand);
  190.     }
  191.     return ret;
  192. }
  193. CRef<CSeq_point> CSeq_loc_Conversion::GetDstPoint(void)
  194. {
  195.     CheckDstPoint();
  196.     _ASSERT(m_LastRange.GetLength() == 1);
  197.     CRef<CSeq_point> ret(new CSeq_point);
  198.     CSeq_point& point = *ret;
  199.     point.SetId(GetDstId());
  200.     point.SetPoint(m_LastRange.GetFrom());
  201.     if ( m_LastStrand != eNa_strand_unknown ) {
  202.         point.SetStrand(m_LastStrand);
  203.     }
  204.     return ret;
  205. }
  206. void CSeq_loc_Conversion::SetDstLoc(CRef<CSeq_loc>* dst)
  207. {
  208.     CSeq_loc* loc = 0;
  209.     if ( !(*dst) ) {
  210.         switch ( m_LastType ) {
  211.         case eMappedObjType_Seq_interval:
  212.             dst->Reset(loc = new CSeq_loc);
  213.             loc->SetInt(*GetDstInterval());
  214.             break;
  215.         case eMappedObjType_Seq_point:
  216.             dst->Reset(loc = new CSeq_loc);
  217.             loc->SetPnt(*GetDstPoint());
  218.             break;
  219.         default:
  220.             _ASSERT(0);
  221.             break;
  222.         }
  223.     }
  224.     else {
  225.         _ASSERT(!IsSpecialLoc());
  226.     }
  227. }
  228. bool CSeq_loc_Conversion::Convert(const CSeq_loc& src, CRef<CSeq_loc>* dst,
  229.                                   EConvertFlag flag)
  230. {
  231.     dst->Reset();
  232.     CSeq_loc* loc = 0;
  233.     _ASSERT(!IsSpecialLoc());
  234.     m_LastType = eMappedObjType_Seq_loc;
  235.     switch ( src.Which() ) {
  236.     case CSeq_loc::e_not_set:
  237.     case CSeq_loc::e_Feat:
  238.         // Nothing to do, although this should never happen --
  239.         // the seq_loc is intersecting with the conv. loc.
  240.         _ASSERT("this cannot happen" && 0);
  241.         break;
  242.     case CSeq_loc::e_Null:
  243.     {
  244.         dst->Reset(loc = new CSeq_loc);
  245.         loc->SetNull();
  246.         break;
  247.     }
  248.     case CSeq_loc::e_Empty:
  249.     {
  250.         if ( GoodSrcId(src.GetEmpty()) ) {
  251.             dst->Reset(loc = new CSeq_loc);
  252.             loc->SetEmpty(GetDstId());
  253.         }
  254.         break;
  255.     }
  256.     case CSeq_loc::e_Whole:
  257.     {
  258.         const CSeq_id& src_id = src.GetWhole();
  259.         // Convert to the allowed master seq interval
  260.         if ( GoodSrcId(src_id) ) {
  261.             CBioseq_Handle bh = m_Scope->GetBioseqHandle(src_id,
  262.                 CScope::eGetBioseq_All);
  263.             ConvertInterval(0, bh.GetBioseqLength()-1, eNa_strand_unknown);
  264.         }
  265.         break;
  266.     }
  267.     case CSeq_loc::e_Int:
  268.     {
  269.         ConvertInterval(src.GetInt());
  270.         break;
  271.     }
  272.     case CSeq_loc::e_Pnt:
  273.     {
  274.         ConvertPoint(src.GetPnt());
  275.         break;
  276.     }
  277.     case CSeq_loc::e_Packed_int:
  278.     {
  279.         const CPacked_seqint::Tdata& src_ints = src.GetPacked_int().Get();
  280.         CPacked_seqint::Tdata* dst_ints = 0;
  281.         ITERATE ( CPacked_seqint::Tdata, i, src_ints ) {
  282.             if ( ConvertInterval(**i) ) {
  283.                 if ( !dst_ints ) {
  284.                     dst->Reset(loc = new CSeq_loc);
  285.                     dst_ints = &loc->SetPacked_int().Set();
  286.                 }
  287.                 dst_ints->push_back(GetDstInterval());
  288.             }
  289.         }
  290.         break;
  291.     }
  292.     case CSeq_loc::e_Packed_pnt:
  293.     {
  294.         const CPacked_seqpnt& src_pack_pnts = src.GetPacked_pnt();
  295.         if ( !GoodSrcId(src_pack_pnts.GetId()) ) {
  296.             break;
  297.         }
  298.         const CPacked_seqpnt::TPoints& src_pnts = src_pack_pnts.GetPoints();
  299.         CPacked_seqpnt::TPoints* dst_pnts = 0;
  300.         ITERATE ( CPacked_seqpnt::TPoints, i, src_pnts ) {
  301.             TSeqPos dst_pos = ConvertPos(*i);
  302.             if ( dst_pos != kInvalidSeqPos ) {
  303.                 if ( !dst_pnts ) {
  304.                     dst->Reset(loc = new CSeq_loc);
  305.                     CPacked_seqpnt& pnts = loc->SetPacked_pnt();
  306.                     pnts.SetId(GetDstId());
  307.                     dst_pnts = &pnts.SetPoints();
  308.                     if ( src_pack_pnts.IsSetStrand() ) {
  309.                         pnts.SetStrand(ConvertStrand(src_pack_pnts.GetStrand()));
  310.                     }
  311.                 }
  312.                 dst_pnts->push_back(dst_pos);
  313.                 m_TotalRange += TRange(dst_pos, dst_pos);
  314.             }
  315.         }
  316.         break;
  317.     }
  318.     case CSeq_loc::e_Mix:
  319.     {
  320.         const CSeq_loc_mix::Tdata& src_mix = src.GetMix().Get();
  321.         CSeq_loc_mix::Tdata* dst_mix = 0;
  322.         CRef<CSeq_loc> dst_loc;
  323.         ITERATE ( CSeq_loc_mix::Tdata, i, src_mix ) {
  324.             if ( Convert(**i, &dst_loc, eCnvAlways) ) {
  325.                 if ( !dst_mix ) {
  326.                     dst->Reset(loc = new CSeq_loc);
  327.                     dst_mix = &loc->SetMix().Set();
  328.                 }
  329.                 _ASSERT(dst_loc);
  330.                 dst_mix->push_back(dst_loc);
  331.             }
  332.         }
  333.         break;
  334.     }
  335.     case CSeq_loc::e_Equiv:
  336.     {
  337.         const CSeq_loc_equiv::Tdata& src_equiv = src.GetEquiv().Get();
  338.         CSeq_loc_equiv::Tdata* dst_equiv = 0;
  339.         CRef<CSeq_loc> dst_loc;
  340.         ITERATE ( CSeq_loc_equiv::Tdata, i, src_equiv ) {
  341.             if ( Convert(**i, &dst_loc, eCnvAlways) ) {
  342.                 if ( !dst_equiv ) {
  343.                     dst->Reset(loc = new CSeq_loc);
  344.                     dst_equiv = &loc->SetEquiv().Set();
  345.                 }
  346.                 dst_equiv->push_back(dst_loc);
  347.             }
  348.         }
  349.         break;
  350.     }
  351.     case CSeq_loc::e_Bond:
  352.     {
  353.         const CSeq_bond& src_bond = src.GetBond();
  354.         CSeq_bond* dst_bond = 0;
  355.         if ( ConvertPoint(src_bond.GetA()) ) {
  356.             dst->Reset(loc = new CSeq_loc);
  357.             dst_bond = &loc->SetBond();
  358.             dst_bond->SetA(*GetDstPoint());
  359.             if ( src_bond.IsSetB() ) {
  360.                 dst_bond->SetB().Assign(src_bond.GetB());
  361.             }
  362.         }
  363.         if ( src_bond.IsSetB() ) {
  364.             if ( ConvertPoint(src_bond.GetB()) ) {
  365.                 if ( !dst_bond ) {
  366.                     dst->Reset(loc = new CSeq_loc);
  367.                     dst_bond = &loc->SetBond();
  368.                     dst_bond->SetA().Assign(src_bond.GetA());
  369.                 }
  370.                 dst_bond->SetB(*GetDstPoint());
  371.             }
  372.         }
  373.         break;
  374.     }
  375.     default:
  376.         NCBI_THROW(CAnnotException, eBadLocation,
  377.                    "Unsupported location type");
  378.     }
  379.     if ( flag == eCnvAlways && IsSpecialLoc() ) {
  380.         SetDstLoc(dst);
  381.     }
  382.     return *dst;
  383. }
  384. void CSeq_loc_Conversion::Convert(CAnnotObject_Ref& ref, ELocationType loctype)
  385. {
  386.     Reset();
  387.     const CAnnotObject_Info& obj = ref.GetAnnotObject_Info();
  388.     switch ( obj.Which() ) {
  389.     case CSeq_annot::C_Data::e_Ftable:
  390.     {
  391.         CRef<CSeq_loc> mapped_loc;
  392.         const CSeq_loc* src_loc;
  393.         if ( loctype != eProduct ) {
  394.             src_loc = &obj.GetFeatFast()->GetLocation();
  395.         }
  396.         else {
  397.             src_loc = &obj.GetFeatFast()->GetProduct();
  398.         }
  399.         Convert(*src_loc, &mapped_loc);
  400.         ref.SetMappedSeq_loc(mapped_loc.GetPointerOrNull());
  401.         break;
  402.     }
  403.     case CSeq_annot::C_Data::e_Graph:
  404.     {
  405.         CRef<CSeq_loc> mapped_loc;
  406.         Convert(obj.GetGraphFast()->GetLoc(), &mapped_loc);
  407.         ref.SetMappedSeq_loc(mapped_loc.GetPointerOrNull());
  408.         break;
  409.     }
  410.     default:
  411.         _ASSERT(0);
  412.         break;
  413.     }
  414.     SetMappedLocation(ref, loctype);
  415. }
  416. void CSeq_loc_Conversion::SetMappedLocation(CAnnotObject_Ref& ref,
  417.                                             ELocationType loctype)
  418. {
  419.     ref.SetProduct(loctype == eProduct);
  420.     ref.SetPartial(m_Partial || ref.IsPartial());
  421.     ref.SetTotalRange(m_TotalRange);
  422.     if ( IsSpecialLoc() ) {
  423.         // special interval or point
  424.         ref.SetMappedSeq_id(GetDstId(),
  425.                             m_LastType == eMappedObjType_Seq_point);
  426.         ref.SetMappedStrand(m_LastStrand);
  427.         m_LastType = eMappedObjType_not_set;
  428.     }
  429. }
  430. /////////////////////////////////////////////////////////////////////////////
  431. // CSeq_loc_Conversion_Set
  432. /////////////////////////////////////////////////////////////////////////////
  433. CSeq_loc_Conversion_Set::CSeq_loc_Conversion_Set(CHeapScope& scope)
  434.     : m_SingleConv(0),
  435.       m_SingleIndex(0),
  436.       m_Partial(false),
  437.       m_TotalRange(TRange::GetEmpty()),
  438.       m_Scope(scope)
  439. {
  440.     return;
  441. }
  442. void CSeq_loc_Conversion_Set::Add(CSeq_loc_Conversion& cvt,
  443.                                   unsigned int loc_index)
  444. {
  445.     if (!m_SingleConv) {
  446.         m_SingleConv.Reset(&cvt);
  447.         m_SingleIndex = loc_index;
  448.         return;
  449.     }
  450.     else {
  451.         TIdMap& id_map = m_CvtByIndex[m_SingleIndex];
  452.         TRangeMap& ranges = id_map[m_SingleConv->m_Src_id_Handle];
  453.         ranges.insert(TRangeMap::value_type
  454.                       (TRange(cvt.m_Src_from, cvt.m_Src_to),
  455.                        m_SingleConv));
  456.     }
  457.     TIdMap& id_map = m_CvtByIndex[loc_index];
  458.     TRangeMap& ranges = id_map[cvt.m_Src_id_Handle];
  459.     ranges.insert(TRangeMap::value_type(TRange(cvt.m_Src_from, cvt.m_Src_to),
  460.                                         Ref(&cvt)));
  461. }
  462. CSeq_loc_Conversion_Set::TRangeIterator
  463. CSeq_loc_Conversion_Set::BeginRanges(CSeq_id_Handle id,
  464.                                      TSeqPos from,
  465.                                      TSeqPos to,
  466.                                      unsigned int loc_index)
  467. {
  468.     TIdMap::iterator ranges = m_CvtByIndex[loc_index].find(id);
  469.     if (ranges == m_CvtByIndex[loc_index].end()) {
  470.         return TRangeIterator();
  471.     }
  472.     return ranges->second.begin(TRange(from, to));
  473. }
  474. void CSeq_loc_Conversion_Set::Convert(CAnnotObject_Ref& ref,
  475.                                       CSeq_loc_Conversion::ELocationType
  476.                                       loctype)
  477. {
  478.     _ASSERT(m_SingleConv);
  479.     if (m_CvtByIndex.size() == 0  &&
  480.         !ref.IsAlign()) {
  481.         // No multiple mappings
  482.         m_SingleConv->Convert(ref, loctype);
  483.         return;
  484.     }
  485.     const CAnnotObject_Info& obj = ref.GetAnnotObject_Info();
  486.     switch ( obj.Which() ) {
  487.     case CSeq_annot::C_Data::e_Ftable:
  488.     {
  489.         CRef<CSeq_loc> mapped_loc;
  490.         const CSeq_loc* src_loc;
  491.         unsigned int loc_index = 0;
  492.         if ( loctype != CSeq_loc_Conversion::eProduct ) {
  493.             src_loc = &obj.GetFeatFast()->GetLocation();
  494.         }
  495.         else {
  496.             src_loc = &obj.GetFeatFast()->GetProduct();
  497.             loc_index = 1;
  498.         }
  499.         Convert(*src_loc, &mapped_loc, loc_index);
  500.         ref.SetMappedSeq_loc(mapped_loc.GetPointerOrNull());
  501.         break;
  502.     }
  503.     case CSeq_annot::C_Data::e_Graph:
  504.     {
  505.         CRef<CSeq_loc> mapped_loc;
  506.         Convert(obj.GetGraphFast()->GetLoc(), &mapped_loc, 0);
  507.         ref.SetMappedSeq_loc(mapped_loc.GetPointerOrNull());
  508.         break;
  509.     }
  510.     case CSeq_annot::C_Data::e_Align:
  511.     {
  512.         ref.SetMappedSeq_align_Cvts(*this);
  513.         break;
  514.     }
  515.     default:
  516.         _ASSERT(0);
  517.         break;
  518.     }
  519.     ref.SetProduct(loctype == CSeq_loc_Conversion::eProduct);
  520.     ref.SetPartial(m_Partial);
  521.     ref.SetTotalRange(m_TotalRange);
  522. }
  523. bool CSeq_loc_Conversion_Set::ConvertPoint(const CSeq_point& src,
  524.                                            CRef<CSeq_loc>* dst,
  525.                                            unsigned int loc_index)
  526. {
  527.     _ASSERT(*dst);
  528.     bool res = false;
  529.     TRangeIterator mit = BeginRanges(CSeq_id_Handle::GetHandle(src.GetId()),
  530.         src.GetPoint(), src.GetPoint(), loc_index);
  531.     for ( ; mit; ++mit) {
  532.         CSeq_loc_Conversion& cvt = *mit->second;
  533.         cvt.Reset();
  534.         if (cvt.ConvertPoint(src)) {
  535.             (*dst)->SetPnt(*cvt.GetDstPoint());
  536.             m_TotalRange += cvt.GetTotalRange();
  537.             res = true;
  538.             break;
  539.         }
  540.     }
  541.     m_Partial |= !res;
  542.     return res;
  543. }
  544. bool CSeq_loc_Conversion_Set::ConvertInterval(const CSeq_interval& src,
  545.                                               CRef<CSeq_loc>* dst,
  546.                                               unsigned int loc_index)
  547. {
  548.     _ASSERT(*dst);
  549.     CRef<CSeq_loc> tmp(new CSeq_loc);
  550.     CPacked_seqint::Tdata& ints = tmp->SetPacked_int().Set();
  551.     TRange total_range(TRange::GetEmpty());
  552.     bool revert_order = (src.IsSetStrand()
  553.         && src.GetStrand() == eNa_strand_minus);
  554.     bool res = false;
  555.     TRangeIterator mit = BeginRanges(CSeq_id_Handle::GetHandle(src.GetId()),
  556.         src.GetFrom(), src.GetTo(), loc_index);
  557.     for ( ; mit; ++mit) {
  558.         CSeq_loc_Conversion& cvt = *mit->second;
  559.         cvt.Reset();
  560.         if (cvt.ConvertInterval(src)) {
  561.             if (revert_order) {
  562.                 ints.push_front(cvt.GetDstInterval());
  563.             }
  564.             else {
  565.                 ints.push_back(cvt.GetDstInterval());
  566.             }
  567.             total_range += cvt.GetTotalRange();
  568.             res = true;
  569.         }
  570.     }
  571.     if (ints.size() > 1) {
  572.         dst->Reset(tmp);
  573.     }
  574.     else if (ints.size() == 1) {
  575.         (*dst)->SetInt(**ints.begin());
  576.     }
  577.     m_TotalRange += total_range;
  578.     // does not guarantee the whole interval is mapped, but should work
  579.     // in normal situations
  580.     m_Partial |= (!res  || src.GetLength() > total_range.GetLength());
  581.     return res;
  582. }
  583. bool CSeq_loc_Conversion_Set::Convert(const CSeq_loc& src,
  584.                                       CRef<CSeq_loc>* dst,
  585.                                       unsigned int loc_index)
  586. {
  587.     dst->Reset(new CSeq_loc);
  588.     bool res = false;
  589.     switch ( src.Which() ) {
  590.     case CSeq_loc::e_not_set:
  591.     case CSeq_loc::e_Feat:
  592.         // Nothing to do, although this should never happen --
  593.         // the seq_loc is intersecting with the conv. loc.
  594.         _ASSERT("this cannot happen" && 0);
  595.         break;
  596.     case CSeq_loc::e_Null:
  597.     {
  598.         (*dst)->SetNull();
  599.         res = true;
  600.         break;
  601.     }
  602.     case CSeq_loc::e_Empty:
  603.     {
  604.         TRangeIterator mit = BeginRanges(CSeq_id_Handle::GetHandle(src.GetEmpty()),
  605.                                          TRange::GetWhole().GetFrom(),
  606.                                          TRange::GetWhole().GetTo(),
  607.                                          loc_index);
  608.         for ( ; mit; ++mit) {
  609.             CSeq_loc_Conversion& cvt = *mit->second;
  610.             cvt.Reset();
  611.             if ( cvt.GoodSrcId(src.GetEmpty()) ) {
  612.                 (*dst)->SetEmpty(cvt.GetDstId());
  613.                 res = true;
  614.                 break;
  615.             }
  616.         }
  617.         break;
  618.     }
  619.     case CSeq_loc::e_Whole:
  620.     {
  621.         const CSeq_id& src_id = src.GetWhole();
  622.         // Convert to the allowed master seq interval
  623.         CSeq_interval whole_int;
  624.         whole_int.SetId().Assign(src_id);
  625.         whole_int.SetFrom(0);
  626.         CBioseq_Handle bh = m_Scope->GetBioseqHandle(src_id,
  627.             CScope::eGetBioseq_All);
  628.         whole_int.SetTo(bh.GetBioseqLength());
  629.         res = ConvertInterval(whole_int, dst, loc_index);
  630.         break;
  631.     }
  632.     case CSeq_loc::e_Int:
  633.     {
  634.         res = ConvertInterval(src.GetInt(), dst, loc_index);
  635.         break;
  636.     }
  637.     case CSeq_loc::e_Pnt:
  638.     {
  639.         res = ConvertPoint(src.GetPnt(), dst, loc_index);
  640.         break;
  641.     }
  642.     case CSeq_loc::e_Packed_int:
  643.     {
  644.         const CPacked_seqint::Tdata& src_ints = src.GetPacked_int().Get();
  645.         CPacked_seqint::Tdata& dst_ints = (*dst)->SetPacked_int().Set();
  646.         ITERATE ( CPacked_seqint::Tdata, i, src_ints ) {
  647.             CRef<CSeq_loc> dst_int(new CSeq_loc);
  648.             bool mapped = ConvertInterval(**i, &dst_int, loc_index);
  649.             if (mapped) {
  650.                 if ( dst_int->IsInt() ) {
  651.                     dst_ints.push_back(CRef<CSeq_interval>(&dst_int->SetInt()));
  652.                 }
  653.                 else if ( dst_int->IsPacked_int() ) {
  654.                     CPacked_seqint::Tdata& splitted = dst_int->SetPacked_int().Set();
  655.                     dst_ints.merge(splitted);
  656.                 }
  657.                 else {
  658.                     _ASSERT("this cannot happen" && 0);
  659.                 }
  660.             }
  661.             m_Partial |= !mapped;
  662.             res |= mapped;
  663.         }
  664.         break;
  665.     }
  666.     case CSeq_loc::e_Packed_pnt:
  667.     {
  668.         const CPacked_seqpnt& src_pack_pnts = src.GetPacked_pnt();
  669.         const CPacked_seqpnt::TPoints& src_pnts = src_pack_pnts.GetPoints();
  670.         CRef<CSeq_loc> tmp(new CSeq_loc);
  671.         // using mix, not point, since mappings may have
  672.         // different strand, fuzz etc.
  673.         CSeq_loc_mix::Tdata& locs = tmp->SetMix().Set();
  674.         ITERATE ( CPacked_seqpnt::TPoints, i, src_pnts ) {
  675.             bool mapped = false;
  676.             TRangeIterator mit = BeginRanges(
  677.                 CSeq_id_Handle::GetHandle(src_pack_pnts.GetId()),
  678.                 *i, *i,
  679.                 loc_index);
  680.             for ( ; mit; ++mit) {
  681.                 CSeq_loc_Conversion& cvt = *mit->second;
  682.                 cvt.Reset();
  683.                 if ( !cvt.GoodSrcId(src_pack_pnts.GetId()) ) {
  684.                     continue;
  685.                 }
  686.                 TSeqPos dst_pos = cvt.ConvertPos(*i);
  687.                 if ( dst_pos != kInvalidSeqPos ) {
  688.                     CRef<CSeq_loc> pnt(new CSeq_loc);
  689.                     pnt->SetPnt(*cvt.GetDstPoint());
  690.                     _ASSERT(pnt);
  691.                     locs.push_back(pnt);
  692.                     m_TotalRange += cvt.GetTotalRange();
  693.                     mapped = true;
  694.                     break;
  695.                 }
  696.             }
  697.             m_Partial |= !mapped;
  698.             res |= mapped;
  699.         }
  700.         break;
  701.     }
  702.     case CSeq_loc::e_Mix:
  703.     {
  704.         const CSeq_loc_mix::Tdata& src_mix = src.GetMix().Get();
  705.         CRef<CSeq_loc> dst_loc;
  706.         CSeq_loc_mix::Tdata& dst_mix = (*dst)->SetMix().Set();
  707.         ITERATE ( CSeq_loc_mix::Tdata, i, src_mix ) {
  708.             dst_loc.Reset(new CSeq_loc);
  709.             if ( Convert(**i, &dst_loc, loc_index) ) {
  710.                 _ASSERT(dst_loc);
  711.                 dst_mix.push_back(dst_loc);
  712.                 res = true;
  713.             }
  714.         }
  715.         m_Partial |= !res;
  716.         break;
  717.     }
  718.     case CSeq_loc::e_Equiv:
  719.     {
  720.         const CSeq_loc_equiv::Tdata& src_equiv = src.GetEquiv().Get();
  721.         CRef<CSeq_loc> dst_loc;
  722.         CSeq_loc_equiv::Tdata& dst_equiv = (*dst)->SetEquiv().Set();
  723.         ITERATE ( CSeq_loc_equiv::Tdata, i, src_equiv ) {
  724.             if ( Convert(**i, &dst_loc, loc_index) ) {
  725.                 dst_equiv.push_back(dst_loc);
  726.                 res = true;
  727.             }
  728.         }
  729.         m_Partial |= !res;
  730.         break;
  731.     }
  732.     case CSeq_loc::e_Bond:
  733.     {
  734.         const CSeq_bond& src_bond = src.GetBond();
  735.         // using mix, not bond, since mappings may have
  736.         // different strand, fuzz etc.
  737.         (*dst)->SetBond();
  738.         CRef<CSeq_point> pntA;
  739.         CRef<CSeq_point> pntB;
  740.         {{
  741.             TRangeIterator mit = BeginRanges(
  742.                 CSeq_id_Handle::GetHandle(src_bond.GetA().GetId()),
  743.                 src_bond.GetA().GetPoint(), src_bond.GetA().GetPoint(),
  744.                 loc_index);
  745.             for ( ; mit  &&  !bool(pntA); ++mit) {
  746.                 CSeq_loc_Conversion& cvt = *mit->second;
  747.                 cvt.Reset();
  748.                 if (cvt.ConvertPoint(src_bond.GetA())) {
  749.                     pntA = cvt.GetDstPoint();
  750.                     m_TotalRange += cvt.GetTotalRange();
  751.                     res = true;
  752.                 }
  753.             }
  754.         }}
  755.         if ( src_bond.IsSetB() ) {
  756.             TRangeIterator mit = BeginRanges(
  757.                 CSeq_id_Handle::GetHandle(src_bond.GetB().GetId()),
  758.                 src_bond.GetB().GetPoint(), src_bond.GetB().GetPoint(),
  759.                 loc_index);
  760.             for ( ; mit  &&  !bool(pntB); ++mit) {
  761.                 CSeq_loc_Conversion& cvt = *mit->second;
  762.                 cvt.Reset();
  763.                 if (!bool(pntB)  &&  cvt.ConvertPoint(src_bond.GetB())) {
  764.                     pntB = cvt.GetDstPoint();
  765.                     m_TotalRange += cvt.GetTotalRange();
  766.                     res = true;
  767.                 }
  768.             }
  769.         }
  770.         CSeq_bond& dst_bond = (*dst)->SetBond();
  771.         if ( bool(pntA)  ||  bool(pntB) ) {
  772.             if ( bool(pntA) ) {
  773.                 dst_bond.SetA(*pntA);
  774.             }
  775.             else {
  776.                 dst_bond.SetA().Assign(src_bond.GetA());
  777.             }
  778.             if ( bool(pntB) ) {
  779.                 dst_bond.SetB(*pntB);
  780.             }
  781.             else if ( src_bond.IsSetB() ) {
  782.                 dst_bond.SetB().Assign(src_bond.GetB());
  783.             }
  784.         }
  785.         m_Partial |= (!bool(pntA)  ||  !bool(pntB));
  786.         break;
  787.     }
  788.     default:
  789.         NCBI_THROW(CAnnotException, eBadLocation,
  790.                    "Unsupported location type");
  791.     }
  792.     return res;
  793. }
  794. void CSeq_loc_Conversion_Set::Convert(const CSeq_align& src,
  795.                                       CRef<CSeq_align>* dst)
  796. {
  797.     CRef<CSeq_align_Mapper> mapper(new CSeq_align_Mapper(src));
  798.     mapper->Convert(*this);
  799.     *dst = mapper->GetDstAlign();
  800. }
  801. END_SCOPE(objects)
  802. END_NCBI_SCOPE
  803. /*
  804. * ---------------------------------------------------------------------------
  805. * $Log: seq_loc_cvt.cpp,v $
  806. * Revision 1000.5  2004/06/01 19:24:09  gouriano
  807. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.29
  808. *
  809. * Revision 1.29  2004/05/26 14:29:20  grichenk
  810. * Redesigned CSeq_align_Mapper: preserve non-mapping intervals,
  811. * fixed strands handling, improved performance.
  812. *
  813. * Revision 1.28  2004/05/21 21:42:13  gorelenk
  814. * Added PCH ncbi_pch.hpp
  815. *
  816. * Revision 1.27  2004/05/10 18:26:37  grichenk
  817. * Fixed 'not used' warnings
  818. *
  819. * Revision 1.26  2004/04/13 15:59:35  grichenk
  820. * Added CScope::GetBioseqHandle() with id resolving flag.
  821. *
  822. * Revision 1.25  2004/03/30 21:21:09  grichenk
  823. * Reduced number of includes.
  824. *
  825. * Revision 1.24  2004/03/30 15:42:33  grichenk
  826. * Moved alignment mapper to separate file, added alignment mapping
  827. * to CSeq_loc_Mapper.
  828. *
  829. * Revision 1.23  2004/03/16 15:47:28  vasilche
  830. * Added CBioseq_set_Handle and set of EditHandles
  831. *
  832. * Revision 1.22  2004/02/23 15:23:16  grichenk
  833. * Removed unused members
  834. *
  835. * Revision 1.21  2004/02/19 19:25:09  vasilche
  836. * Hidded implementation of CAnnotObject_Ref.
  837. * Added necessary access methods.
  838. *
  839. * Revision 1.20  2004/02/19 17:18:44  vasilche
  840. * Formatting + use CRef<> assignment directly.
  841. *
  842. * Revision 1.19  2004/02/06 16:07:27  grichenk
  843. * Added CBioseq_Handle::GetSeq_entry_Handle()
  844. * Fixed MapLocation()
  845. *
  846. * Revision 1.18  2004/02/05 22:49:19  grichenk
  847. * Added default cases in switches
  848. *
  849. * Revision 1.17  2004/02/05 20:18:37  grichenk
  850. * Fixed std-segs processing
  851. *
  852. * Revision 1.16  2004/02/02 14:44:54  vasilche
  853. * Removed several compilation warnings.
  854. *
  855. * Revision 1.15  2004/01/30 15:25:45  grichenk
  856. * Fixed alignments mapping and sorting
  857. *
  858. * Revision 1.14  2004/01/28 22:09:35  grichenk
  859. * Added CSeq_align_Mapper initialization for e_Disc
  860. *
  861. * Revision 1.13  2004/01/28 20:54:36  vasilche
  862. * Fixed mapping of annotations.
  863. *
  864. * Revision 1.12  2004/01/23 22:13:48  ucko
  865. * Fix variable shadowing that some compilers treated as an error.
  866. *
  867. * Revision 1.11  2004/01/23 16:14:48  grichenk
  868. * Implemented alignment mapping
  869. *
  870. * Revision 1.10  2004/01/02 16:06:53  grichenk
  871. * Skip location mapping for seq-aligns
  872. *
  873. * Revision 1.9  2003/12/04 20:04:24  grichenk
  874. * Fixed bugs in seq-loc converters.
  875. *
  876. * Revision 1.8  2003/11/10 18:11:04  grichenk
  877. * Moved CSeq_loc_Conversion_Set to seq_loc_cvt
  878. *
  879. * Revision 1.7  2003/11/04 16:21:37  grichenk
  880. * Updated CAnnotTypes_CI to map whole features instead of splitting
  881. * them by sequence segments.
  882. *
  883. * Revision 1.6  2003/10/29 19:55:47  vasilche
  884. * Avoid making 'whole' features on 'whole' segment partial (by Aleksey Grichenko)
  885. *
  886. * Revision 1.5  2003/09/30 16:22:03  vasilche
  887. * Updated internal object manager classes to be able to load ID2 data.
  888. * SNP blobs are loaded as ID2 split blobs - readers convert them automatically.
  889. * Scope caches results of requests for data to data loaders.
  890. * Optimized CSeq_id_Handle for gis.
  891. * Optimized bioseq lookup in scope.
  892. * Reduced object allocations in annotation iterators.
  893. * CScope is allowed to be destroyed before other objects using this scope are
  894. * deleted (feature iterators, bioseq handles etc).
  895. * Optimized lookup for matching Seq-ids in CSeq_id_Mapper.
  896. * Added 'adaptive' option to objmgr_demo application.
  897. *
  898. * Revision 1.4  2003/09/05 17:29:40  grichenk
  899. * Structurized Object Manager exceptions
  900. *
  901. * Revision 1.3  2003/08/27 14:29:52  vasilche
  902. * Reduce object allocations in feature iterator.
  903. *
  904. * Revision 1.2  2003/08/15 19:19:16  vasilche
  905. * Fixed memory leak in string packing hooks.
  906. * Fixed processing of 'partial' flag of features.
  907. * Allow table packing of non-point SNP.
  908. * Allow table packing of SNP with long alleles.
  909. *
  910. * Revision 1.1  2003/08/14 20:05:19  vasilche
  911. * Simple SNP features are stored as table internally.
  912. * They are recreated when needed using CFeat_CI.
  913. *
  914. * ===========================================================================
  915. */