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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: seq_map.cpp,v $
  4.  * PRODUCTION Revision 1000.4  2004/06/01 19:24:15  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.53
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: seq_map.cpp,v 1000.4 2004/06/01 19:24:15 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. * Authors: Aleksey Grichenko, Michael Kimelman, Eugene Vasilchenko,
  35. *          Andrei Gourianov
  36. *
  37. * File Description:
  38. *   Sequence map for the Object Manager. Describes sequence as a set of
  39. *   segments of different types (data, reference, gap or end).
  40. *
  41. */
  42. #include <ncbi_pch.hpp>
  43. #include <objmgr/seq_map.hpp>
  44. #include <objmgr/seq_map_ci.hpp>
  45. #include <objmgr/seq_map_ext.hpp>
  46. #include <objmgr/seq_id_mapper.hpp>
  47. #include <objmgr/scope.hpp>
  48. #include <objmgr/bioseq_handle.hpp>
  49. #include <objects/seq/Bioseq.hpp>
  50. #include <objects/seq/Seq_data.hpp>
  51. #include <objects/seq/Seq_inst.hpp>
  52. #include <objects/seq/Delta_ext.hpp>
  53. #include <objects/seq/Delta_seq.hpp>
  54. #include <objects/seq/Seq_literal.hpp>
  55. #include <objects/seq/Seq_ext.hpp>
  56. #include <objects/seq/Seg_ext.hpp>
  57. #include <objects/seq/Ref_ext.hpp>
  58. #include <objects/seqloc/Seq_loc.hpp>
  59. #include <objects/seqloc/Seq_point.hpp>
  60. #include <objects/seqloc/Seq_loc_mix.hpp>
  61. #include <objects/seqloc/Seq_loc_equiv.hpp>
  62. #include <objects/seqloc/Seq_interval.hpp>
  63. #include <objects/seqloc/Packed_seqint.hpp>
  64. #include <objects/seqloc/Packed_seqpnt.hpp>
  65. #include <algorithm>
  66. BEGIN_NCBI_SCOPE
  67. BEGIN_SCOPE(objects)
  68. ////////////////////////////////////////////////////////////////////
  69. //  CSeqMap::CSegment
  70. inline
  71. CSeqMap::CSegment::CSegment(ESegmentType seg_type,
  72.                             TSeqPos length)
  73.     : m_Position(kInvalidSeqPos),
  74.       m_Length(length),
  75.       m_SegType(seg_type),
  76.       m_RefMinusStrand(false),
  77.       m_RefPosition(0)
  78. {
  79. }
  80. ////////////////////////////////////////////////////////////////////
  81. //  CSeqMap
  82. CSeqMap::CSeqMap(void)
  83.     : m_Resolved(0),
  84.       m_Mol(CSeq_inst::eMol_not_set),
  85.       m_SeqLength(kInvalidSeqPos)
  86. {
  87. }
  88. CSeqMap::CSeqMap(CSeqMap* /*parent*/, size_t /*index*/)
  89.     : m_Resolved(0),
  90.       m_Mol(CSeq_inst::eMol_not_set),
  91.       m_SeqLength(kInvalidSeqPos)
  92. {
  93. }
  94. CSeqMap::CSeqMap(const CSeq_loc& ref)
  95.     : m_Resolved(0),
  96.       m_Mol(CSeq_inst::eMol_not_set),
  97.       m_SeqLength(kInvalidSeqPos)
  98. {
  99.     x_AddEnd();
  100.     x_Add(ref);
  101.     x_AddEnd();
  102. }
  103. CSeqMap::CSeqMap(const CSeq_data& data, TSeqPos length)
  104.     : m_Resolved(0),
  105.       m_Mol(CSeq_inst::eMol_not_set),
  106.       m_SeqLength(kInvalidSeqPos)
  107. {
  108.     x_AddEnd();
  109.     x_Add(data, length);
  110.     x_AddEnd();
  111. }
  112. CSeqMap::CSeqMap(TSeqPos length)
  113.     : m_Resolved(0),
  114.       m_Mol(CSeq_inst::eMol_not_set),
  115.       m_SeqLength(length)
  116. {
  117.     x_AddEnd();
  118.     x_AddGap(length);
  119.     x_AddEnd();
  120. }
  121. CSeqMap::~CSeqMap(void)
  122. {
  123.     m_Resolved = 0;
  124.     m_Segments.clear();
  125. }
  126. void CSeqMap::x_GetSegmentException(size_t /*index*/) const
  127. {
  128.     NCBI_THROW(CSeqMapException, eInvalidIndex,
  129.                "Invalid segment index");
  130. }
  131. CSeqMap::CSegment& CSeqMap::x_SetSegment(size_t index)
  132. {
  133.     if ( index >= x_GetSegmentsCount() ) {
  134.         NCBI_THROW(CSeqMapException, eInvalidIndex,
  135.                    "Invalid segment index");
  136.     }
  137.     return m_Segments[index];
  138. }
  139. CBioseq_Handle CSeqMap::x_GetBioseqHandle(const CSegment& seg, CScope* scope) const
  140. {
  141.     if ( !scope ) {
  142.         NCBI_THROW(CSeqMapException, eNullPointer,
  143.                    "Null scope pointer");
  144.     }
  145.     CBioseq_Handle bh = scope->GetBioseqHandle(x_GetRefSeqid(seg));
  146.     if ( !bh ) {
  147.         NCBI_THROW(CSeqMapException, eFail,
  148.                    "Cannot resolve reference");
  149.     }
  150.     return bh;
  151. }
  152. TSeqPos CSeqMap::x_ResolveSegmentLength(size_t index, CScope* scope) const
  153. {
  154.     const CSegment& seg = x_GetSegment(index);
  155.     TSeqPos length = seg.m_Length;
  156.     if ( length == kInvalidSeqPos ) {
  157.         if ( seg.m_SegType == eSeqSubMap ) {
  158.             length = x_GetSubSeqMap(seg, scope)->GetLength(scope);
  159.         }
  160.         else if ( seg.m_SegType == eSeqRef ) {
  161.             length = x_GetBioseqHandle(seg, scope).GetBioseqLength();
  162.         }
  163.         _ASSERT(length != kInvalidSeqPos);
  164.         seg.m_Length = length;
  165.     }
  166.     return length;
  167. }
  168. TSeqPos CSeqMap::x_ResolveSegmentPosition(size_t index, CScope* scope) const
  169. {
  170.     if ( index > x_GetSegmentsCount() ) {
  171.         NCBI_THROW(CSeqMapException, eInvalidIndex,
  172.                    "Invalid segment index");
  173.     }
  174.     size_t resolved = m_Resolved;
  175.     if ( index <= resolved )
  176.         return x_GetSegment(index).m_Position;
  177.     TSeqPos resolved_pos = x_GetSegment(resolved).m_Position;
  178.     do {
  179.         resolved_pos += x_GetSegmentLength(resolved, scope);
  180.         m_Segments[++resolved].m_Position = resolved_pos;
  181.     } while ( resolved < index );
  182.     {{
  183.         CFastMutexGuard guard(m_SeqMap_Mtx);
  184.         if ( m_Resolved < resolved )
  185.             m_Resolved = resolved;
  186.     }}
  187.     return resolved_pos;
  188. }
  189. size_t CSeqMap::x_FindSegment(TSeqPos pos, CScope* scope) const
  190. {
  191.     size_t resolved = m_Resolved;
  192.     TSeqPos resolved_pos = x_GetSegment(resolved).m_Position;
  193.     if ( resolved_pos <= pos ) {
  194.         do {
  195.             if ( resolved >= x_GetSegmentsCount() ) {
  196.                 // end of segments
  197.                 m_Resolved = resolved;
  198.                 return size_t(-1);
  199.             }
  200.             resolved_pos += x_GetSegmentLength(resolved, scope);
  201.             m_Segments[++resolved].m_Position = resolved_pos;
  202.         } while ( resolved_pos <= pos );
  203.         {{
  204.             CFastMutexGuard guard(m_SeqMap_Mtx);
  205.             if ( m_Resolved < resolved )
  206.                 m_Resolved = resolved;
  207.         }}
  208.         return resolved - 1;
  209.     }
  210.     else {
  211.         TSegments::const_iterator end = m_Segments.begin()+resolved;
  212.         TSegments::const_iterator it = 
  213.             upper_bound(m_Segments.begin(), end,
  214.                         pos, SPosLessSegment());
  215.         if ( it == end ) {
  216.             return size_t(-1);
  217.         }
  218.         return it - m_Segments.begin();
  219.     }
  220. }
  221. void CSeqMap::x_LoadObject(const CSegment& seg) const
  222. {
  223.     _ASSERT(seg.m_Position != kInvalidSeqPos);
  224.     if ( !seg.m_RefObject ) {
  225.         NCBI_THROW(CSeqMapException, eFail, "Cannot load part of seqmap");
  226.     }
  227. }
  228. CConstRef<CSeqMap> CSeqMap::x_GetSubSeqMap(const CSegment& seg, CScope* scope,
  229.                                            bool resolveExternal) const
  230. {
  231.     CConstRef<CSeqMap> ret;
  232.     if ( seg.m_SegType == eSeqSubMap ) {
  233.         if ( !seg.m_RefObject ) {
  234.             x_LoadObject(seg);
  235.         }
  236.         if ( !seg.m_RefObject ) {
  237.         NCBI_THROW(CSeqMapException, eNullPointer, "Null CSeqMap pointer");
  238.         }
  239.         ret.Reset(static_cast<const CSeqMap*>(seg.m_RefObject.GetPointer()));
  240.     }
  241.     else if ( resolveExternal && seg.m_SegType == eSeqRef ) {
  242.         ret.Reset(&x_GetBioseqHandle(seg, scope).GetSeqMap());
  243.     }
  244.     return ret;
  245. }
  246. void CSeqMap::x_SetSubSeqMap(size_t /*index*/, CSeqMap_Delta_seqs* /*subMap*/)
  247. {
  248.     // not valid in generic seq map -> incompatible objects
  249.     NCBI_THROW(CSeqMapException, eDataError, "Invalid parent map");
  250. }
  251. const CSeq_data& CSeqMap::x_GetSeq_data(const CSegment& seg) const
  252. {
  253.     if ( seg.m_SegType == eSeqData ) {
  254.         if ( !seg.m_RefObject ) {
  255.             x_LoadObject(seg);
  256.         }
  257.         if ( !seg.m_RefObject ) {
  258.             NCBI_THROW(CSeqMapException, eNullPointer,
  259.                        "Null CSeq_data pointer");
  260.         }
  261.         return *static_cast<const CSeq_data*>(seg.m_RefObject.GetPointer());
  262.     }
  263.     NCBI_THROW(CSeqMapException, eSegmentTypeError,
  264.                "Invalid segment type");
  265. }
  266. void CSeqMap::x_SetSeq_data(size_t index, CSeq_data& data)
  267. {
  268.     // check segment type
  269.     CSegment& seg = x_SetSegment(index);
  270.     if ( seg.m_SegType != eSeqData ) {
  271.         NCBI_THROW(CSeqMapException, eSegmentTypeError,
  272.                    "Invalid segment type");
  273.     }
  274.     // lock for object modification
  275.     CFastMutexGuard guard(m_SeqMap_Mtx);
  276.     // check for object
  277.     if ( seg.m_RefObject ) {
  278.         NCBI_THROW(CSeqMapException, eDataError, "CSeq_data already set");
  279.     }
  280.     // set object
  281.     seg.m_RefObject.Reset(&data);
  282. }
  283. const CSeq_id& CSeqMap::x_GetRefSeqid(const CSegment& seg) const
  284. {
  285.     if ( seg.m_SegType == eSeqRef ) {
  286.         if ( !seg.m_RefObject ) {
  287.             NCBI_THROW(CSeqMapException, eNullPointer, "Null CSeq_id pointer");
  288.         }
  289.         return static_cast<const CSeq_id&>(*seg.m_RefObject);
  290.     }
  291.     NCBI_THROW(CSeqMapException, eSegmentTypeError,
  292.                "Invalid segment type");
  293. }
  294. TSeqPos CSeqMap::x_GetRefPosition(const CSegment& seg) const
  295. {
  296.     return seg.m_RefPosition;
  297. }
  298. bool CSeqMap::x_GetRefMinusStrand(const CSegment& seg) const
  299. {
  300.     return seg.m_RefMinusStrand;
  301. }
  302. CSeqMap::TSegment_CI CSeqMap::Begin(CScope* scope) const
  303. {
  304.     return TSegment_CI(CConstRef<CSeqMap>(this), scope, 0);
  305. }
  306. CSeqMap::TSegment_CI CSeqMap::End(CScope* scope) const
  307. {
  308.     return TSegment_CI(CConstRef<CSeqMap>(this), scope, GetLength(scope));
  309. }
  310. CSeqMap::TSegment_CI CSeqMap::FindSegment(TSeqPos pos, CScope* scope) const
  311. {
  312.     return TSegment_CI(CConstRef<CSeqMap>(this), scope, pos);
  313. }
  314. CSeqMap::const_iterator CSeqMap::begin(CScope* scope) const
  315. {
  316.     return Begin(scope);
  317. }
  318. CSeqMap::const_iterator CSeqMap::end(CScope* scope) const
  319. {
  320.     return End(scope);
  321. }
  322. CSeqMap::const_iterator CSeqMap::find(TSeqPos pos, CScope* scope) const
  323. {
  324.     return FindSegment(pos, scope);
  325. }
  326. CSeqMap::TSegment_CI CSeqMap::BeginResolved(CScope* scope, size_t maxResolveCount,
  327.                                             TFlags flags) const
  328. {
  329.     return begin_resolved(scope, maxResolveCount, flags);
  330. }
  331. CSeqMap::TSegment_CI CSeqMap::EndResolved(CScope* scope, size_t maxResolveCount,
  332.                                           TFlags flags) const
  333. {
  334.     return end_resolved(scope, maxResolveCount, flags);
  335. }
  336. CSeqMap::TSegment_CI CSeqMap::FindResolved(TSeqPos pos, CScope* scope,
  337.                                            size_t maxResolveCount,
  338.                                            TFlags flags) const
  339. {
  340.     return find_resolved(pos, scope, maxResolveCount, flags);
  341. }
  342. CSeqMap::TSegment_CI CSeqMap::FindResolved(TSeqPos pos, CScope* scope,
  343.                                            ENa_strand strand,
  344.                                            size_t maxResolveCount,
  345.                                            TFlags flags) const
  346. {
  347.     return find_resolved(pos, scope, strand, maxResolveCount, flags);
  348. }
  349. CSeqMap::const_iterator CSeqMap::begin_resolved(CScope* scope,
  350.                                                 size_t maxResolveCount,
  351.                                                 TFlags flags) const
  352. {
  353.     return TSegment_CI(CConstRef<CSeqMap>(this), scope, 0,
  354.                        maxResolveCount, flags);
  355. }
  356. CSeqMap::const_iterator CSeqMap::end_resolved(CScope* scope,
  357.                                               size_t maxResolveCount,
  358.                                               TFlags flags) const
  359. {
  360.     return TSegment_CI(CConstRef<CSeqMap>(this), scope,
  361.                        GetLength(scope),
  362.                        maxResolveCount, flags);
  363. }
  364. CSeqMap::const_iterator CSeqMap::find_resolved(TSeqPos pos, CScope* scope,
  365.                                                size_t maxResolveCount,
  366.                                                TFlags flags) const
  367. {
  368.     return TSegment_CI(CConstRef<CSeqMap>(this), scope, pos,
  369.                        maxResolveCount, flags);
  370. }
  371. CSeqMap::const_iterator CSeqMap::find_resolved(TSeqPos pos, CScope* scope,
  372.                                                ENa_strand strand,
  373.                                                size_t maxResolveCount,
  374.                                                TFlags flags) const
  375. {
  376.     return TSegment_CI(CConstRef<CSeqMap>(this), scope,
  377.                        pos, strand,
  378.                        maxResolveCount, flags);
  379. }
  380. CSeqMap::TSegment_CI
  381. CSeqMap::ResolvedRangeIterator(CScope* scope,
  382.                                ENa_strand strand,
  383.                                TSeqPos from,
  384.                                TSeqPos length,
  385.                                size_t maxResolveCount,
  386.                                TFlags flags) const
  387. {
  388.     if ( IsReverse(strand) ) {
  389.         from = GetLength(scope) - from - length;
  390.     }
  391.     return TSegment_CI(CConstRef<CSeqMap>(this), scope,
  392.                        SSeqMapSelector()
  393.                        .SetRange(from, length)
  394.                        .SetResolveCount(maxResolveCount)
  395.                        .SetFlags(flags),
  396.                        strand);
  397. }
  398. CSeqMap::TSegment_CI
  399. CSeqMap::ResolvedRangeIterator(CScope* scope,
  400.                                TSeqPos from,
  401.                                TSeqPos length,
  402.                                ENa_strand strand,
  403.                                size_t maxResolveCount,
  404.                                TFlags flags) const
  405. {
  406.     return TSegment_CI(CConstRef<CSeqMap>(this), scope,
  407.                        SSeqMapSelector()
  408.                        .SetRange(from, length)
  409.                        .SetResolveCount(maxResolveCount)
  410.                        .SetFlags(flags),
  411.                        strand);
  412. }
  413. bool CSeqMap::CanResolveRange(CScope* scope,
  414.                               TSeqPos from,
  415.                               TSeqPos length,
  416.                               ENa_strand strand) const
  417. {
  418.     try {
  419.         TSegment_CI seg(CConstRef<CSeqMap>(this), scope,
  420.                         SSeqMapSelector()
  421.                         .SetRange(from, length)
  422.                         .SetResolveCount(size_t(-1))
  423.                         .SetFlags(fDefaultFlags),
  424.                         strand);
  425.         for ( ; seg; ++seg);
  426.     }
  427.     catch (exception) {
  428.         return false;
  429.     }
  430.     return true;
  431. }
  432. void CSeqMap::DebugDump(CDebugDumpContext /*ddc*/,
  433.                         unsigned int /*depth*/) const
  434. {
  435. #if 0
  436.     ddc.SetFrame("CSeqMap");
  437.     CObject::DebugDump( ddc, depth);
  438.     DebugDumpValue(ddc, "m_FirstUnresolvedPos", m_FirstUnresolvedPos);
  439.     if (depth == 0) {
  440.         DebugDumpValue(ddc, "m_Data.size()", m_Data.size());
  441.     } else {
  442.         DebugDumpValue(ddc, "m_Data.type",
  443.             "vector<CRef<CSegment>>");
  444.         DebugDumpRangeCRef(ddc, "m_Data",
  445.             m_Data.begin(), m_Data.end(), depth);
  446.     }
  447. #endif
  448. }
  449. CConstRef<CSeqMap> CSeqMap::CreateSeqMapForBioseq(const CBioseq& seq)
  450. {
  451.     CConstRef<CSeqMap> ret;
  452.     const CSeq_inst& inst = seq.GetInst();
  453.     if ( inst.IsSetSeq_data() ) {
  454.         ret.Reset(new CSeqMap(inst.GetSeq_data(),
  455.                               inst.GetLength()));
  456.     }
  457.     else if ( inst.IsSetExt() ) {
  458.         const CSeq_ext& ext = inst.GetExt();
  459.         switch (ext.Which()) {
  460.         case CSeq_ext::e_Seg:
  461.             ret.Reset(new CSeqMap_Seq_locs(ext.GetSeg(),
  462.                                            ext.GetSeg().Get()));
  463.             break;
  464.         case CSeq_ext::e_Ref:
  465.             ret.Reset(new CSeqMap(ext.GetRef()));
  466.             break;
  467.         case CSeq_ext::e_Delta:
  468.             ret.Reset(new CSeqMap_Delta_seqs(ext.GetDelta()));
  469.             break;
  470.         case CSeq_ext::e_Map:
  471.             //### Not implemented
  472.             NCBI_THROW(CSeqMapException, eUnimplemented,
  473.                        "CSeq_ext::e_Map -- not implemented");
  474.         default:
  475.             //### Not implemented
  476.             NCBI_THROW(CSeqMapException, eUnimplemented,
  477.                        "CSeq_ext::??? -- not implemented");
  478.         }
  479.     }
  480.     else if ( inst.GetRepr() == CSeq_inst::eRepr_virtual ) {
  481.         // Virtual sequence -- no data, no segments
  482.         // The total sequence is gap
  483.         ret.Reset(new CSeqMap(inst.GetLength()));
  484.     }
  485.     else {
  486.         if ( inst.GetRepr() != CSeq_inst::eRepr_not_set ) {
  487.             NCBI_THROW(CSeqMapException, eDataError,
  488.                        "CSeq_inst.repr of sequence without data "
  489.                        "should be not_set");
  490.         }
  491.         if ( inst.IsSetLength() && inst.GetLength() != 0 ) {
  492.             NCBI_THROW(CSeqMapException, eDataError,
  493.                        "CSeq_inst.length of sequence without data "
  494.                        "should be 0");
  495.         }
  496.         ret.Reset(new CSeqMap(TSeqPos(0)));
  497.     }
  498.     const_cast<CSeqMap&>(*ret).m_Mol = inst.GetMol();
  499.     if ( inst.IsSetLength() ) {
  500.         const_cast<CSeqMap&>(*ret).m_SeqLength = inst.GetLength();
  501.     }
  502.     return ret;
  503. }
  504. CConstRef<CSeqMap> CSeqMap::CreateSeqMapForSeq_loc(const CSeq_loc& loc,
  505.                                                    CScope* scope)
  506. {
  507.     CConstRef<CSeqMap> ret(new CSeqMap(loc));
  508.     if ( scope ) {
  509.         CSeqMap::const_iterator i(
  510.             ret->BeginResolved(scope, size_t(-1), fFindData));
  511.         for ( ; i; ++i ) {
  512.             _ASSERT(i.GetType() == eSeqData);
  513.             switch ( i.GetRefData().Which() ) {
  514.             case CSeq_data::e_Ncbi2na:
  515.             case CSeq_data::e_Ncbi4na:
  516.             case CSeq_data::e_Ncbi8na:
  517.             case CSeq_data::e_Ncbipna:
  518.             case CSeq_data::e_Iupacna:
  519.                 const_cast<CSeqMap&>(*ret).m_Mol = CSeq_inst::eMol_na;
  520.                 break;
  521.             case CSeq_data::e_Ncbi8aa:
  522.             case CSeq_data::e_Ncbieaa:
  523.             case CSeq_data::e_Ncbipaa:
  524.             case CSeq_data::e_Ncbistdaa:
  525.             case CSeq_data::e_Iupacaa:
  526.                 const_cast<CSeqMap&>(*ret).m_Mol = CSeq_inst::eMol_aa;
  527.                 break;
  528.             default:
  529.                 const_cast<CSeqMap&>(*ret).m_Mol = CSeq_inst::eMol_not_set;
  530.             }
  531.         }
  532.     }
  533.     return ret;
  534. }
  535. CConstRef<CSeqMap> CSeqMap::CreateSeqMapForStrand(CConstRef<CSeqMap> seqMap,
  536.                                                   ENa_strand strand)
  537. {
  538.     if ( IsReverse(strand) ) {
  539.         CRef<CSeqMap> ret(new CSeqMap());
  540.         ret->x_AddEnd();
  541.         ret->x_AddSegment(eSeqSubMap,
  542.                           const_cast<CSeqMap*>(seqMap.GetPointer()),
  543.                           0, kInvalidSeqPos, strand);
  544.         ret->x_AddEnd();
  545.         ret->m_Mol = seqMap->m_Mol;
  546.         ret->m_SeqLength = seqMap->m_SeqLength;
  547.         seqMap = ret;
  548.     }
  549.     return seqMap;
  550. }
  551. CSeqMap::CSegment& CSeqMap::x_AddSegment(ESegmentType type, TSeqPos len)
  552. {
  553.     m_Segments.push_back(CSegment(type, len));
  554.     return m_Segments.back();
  555. }
  556. CSeqMap::CSegment& CSeqMap::x_AddSegment(ESegmentType type, TSeqPos len,
  557.                                          const CObject* object)
  558. {
  559.     CSegment& ret = x_AddSegment(type, len);
  560.     ret.m_RefObject.Reset(object);
  561.     return ret;
  562. }
  563. CSeqMap::CSegment& CSeqMap::x_AddSegment(ESegmentType type,
  564.                                          const CObject* object,
  565.                                          TSeqPos refPos,
  566.                                          TSeqPos len,
  567.                                          ENa_strand strand)
  568. {
  569.     CSegment& ret = x_AddSegment(type, len, object);
  570.     ret.m_RefPosition = refPos;
  571.     ret.m_RefMinusStrand = IsReverse(strand);
  572.     return ret;
  573. }
  574. void CSeqMap::x_AddEnd(void)
  575. {
  576.     TSeqPos pos = m_Segments.empty()? 0: kInvalidSeqPos;
  577.     x_AddSegment(eSeqEnd, 0).m_Position = pos;
  578. }
  579. CSeqMap::CSegment& CSeqMap::x_AddGap(TSeqPos len)
  580. {
  581.     return x_AddSegment(eSeqGap, len);
  582. }
  583. CSeqMap::CSegment& CSeqMap::x_AddUnloadedSubMap(TSeqPos len)
  584. {
  585.     return x_AddSegment(eSeqSubMap, len);
  586. }
  587. CSeqMap::CSegment& CSeqMap::x_AddUnloadedSeq_data(TSeqPos len)
  588. {
  589.     return x_AddSegment(eSeqData, len);
  590. }
  591. CSeqMap::CSegment& CSeqMap::x_Add(const CSeq_data& data, TSeqPos len)
  592. {
  593.     return x_AddSegment(eSeqData, len, &data);
  594. }
  595. CSeqMap::CSegment& CSeqMap::x_Add(const CSeq_point& ref)
  596. {
  597.     return x_AddSegment(eSeqRef, &ref.GetId(),
  598.                         ref.GetPoint(), 1,
  599.                         ref.IsSetStrand()? ref.GetStrand(): eNa_strand_unknown);
  600. }
  601. CSeqMap::CSegment& CSeqMap::x_Add(const CSeq_interval& ref)
  602. {
  603.     return x_AddSegment(eSeqRef, &ref.GetId(),
  604.                         ref.GetFrom(), ref.GetLength(),
  605.                         ref.IsSetStrand()? ref.GetStrand(): eNa_strand_unknown);
  606. }
  607. CSeqMap::CSegment& CSeqMap::x_Add(const CSeq_id& ref)
  608. {
  609.     return x_AddSegment(eSeqRef, &ref, 0, kInvalidSeqPos);
  610. }
  611. CSeqMap::CSegment& CSeqMap::x_Add(CSeqMap* submap)
  612. {
  613.     return x_AddSegment(eSeqSubMap, kInvalidSeqPos, submap);
  614. }
  615. CSeqMap::CSegment& CSeqMap::x_Add(const CPacked_seqint& seq)
  616. {
  617.     return x_Add(new CSeqMap_Seq_intervals(seq));
  618. }
  619. CSeqMap::CSegment& CSeqMap::x_Add(const CPacked_seqpnt& seq)
  620. {
  621.     return x_Add(new CSeqMap_SeqPoss(seq));
  622. }
  623. CSeqMap::CSegment& CSeqMap::x_Add(const CSeq_loc_mix& seq)
  624. {
  625.     return x_Add(new CSeqMap_Seq_locs(seq, seq.Get()));
  626. }
  627. CSeqMap::CSegment& CSeqMap::x_Add(const CSeq_loc_equiv& seq)
  628. {
  629.     return x_Add(new CSeqMap_Seq_locs(seq, seq.Get()));
  630. }
  631. CSeqMap::CSegment& CSeqMap::x_Add(const CSeq_literal& seq)
  632. {
  633.     if ( seq.IsSetSeq_data() ) {
  634.         return x_Add(seq.GetSeq_data(), seq.GetLength());
  635.     }
  636.     else {
  637.         // No data exist - treat it like a gap
  638.         return x_AddGap(seq.GetLength()); //???
  639.     }
  640. }
  641. CSeqMap::CSegment& CSeqMap::x_Add(const CSeq_loc& loc)
  642. {
  643.     switch ( loc.Which() ) {
  644.     case CSeq_loc::e_not_set:
  645.     case CSeq_loc::e_Null:
  646.     case CSeq_loc::e_Empty:
  647.         return x_AddGap(0); // Add gap ???
  648.     case CSeq_loc::e_Whole:
  649.         return x_Add(loc.GetWhole());
  650.     case CSeq_loc::e_Int:
  651.         return x_Add(loc.GetInt());
  652.     case CSeq_loc::e_Pnt:
  653.         return x_Add(loc.GetPnt());
  654.     case CSeq_loc::e_Packed_int:
  655.         return x_Add(loc.GetPacked_int());
  656.     case CSeq_loc::e_Packed_pnt:
  657.         return x_Add(loc.GetPacked_pnt());
  658.     case CSeq_loc::e_Mix:
  659.         return x_Add(loc.GetMix());
  660.     case CSeq_loc::e_Equiv:
  661.         return x_Add(loc.GetEquiv());
  662.     case CSeq_loc::e_Bond:
  663.         NCBI_THROW(CSeqMapException, eDataError,
  664.                    "e_Bond is not allowed as a reference type");
  665.     case CSeq_loc::e_Feat:
  666.         NCBI_THROW(CSeqMapException, eDataError,
  667.                    "e_Feat is not allowed as a reference type");
  668.     default:
  669.         NCBI_THROW(CSeqMapException, eDataError,
  670.                    "invalid reference type");
  671.     }
  672. }
  673. CSeqMap::CSegment& CSeqMap::x_Add(const CDelta_seq& seq)
  674. {
  675.     switch ( seq.Which() ) {
  676.     case CDelta_seq::e_Loc:
  677.         return x_Add(seq.GetLoc());
  678.     case CDelta_seq::e_Literal:
  679.         return x_Add(seq.GetLiteral());
  680.     default:
  681.         NCBI_THROW(CSeqMapException, eDataError,
  682.                    "Can not add empty Delta-seq");
  683.     }
  684. }
  685. END_SCOPE(objects)
  686. END_NCBI_SCOPE
  687. /*
  688. * ---------------------------------------------------------------------------
  689. * $Log: seq_map.cpp,v $
  690. * Revision 1000.4  2004/06/01 19:24:15  gouriano
  691. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.53
  692. *
  693. * Revision 1.53  2004/05/21 21:42:13  gorelenk
  694. * Added PCH ncbi_pch.hpp
  695. *
  696. * Revision 1.52  2004/03/16 15:47:28  vasilche
  697. * Added CBioseq_set_Handle and set of EditHandles
  698. *
  699. * Revision 1.51  2004/02/19 17:19:10  vasilche
  700. * Removed 'unused argument' warning.
  701. *
  702. * Revision 1.50  2003/11/19 22:18:04  grichenk
  703. * All exceptions are now CException-derived. Catch "exception" rather
  704. * than "runtime_error".
  705. *
  706. * Revision 1.49  2003/11/12 16:53:17  grichenk
  707. * Modified CSeqMap to work with const objects (CBioseq, CSeq_loc etc.)
  708. *
  709. * Revision 1.48  2003/09/30 16:22:04  vasilche
  710. * Updated internal object manager classes to be able to load ID2 data.
  711. * SNP blobs are loaded as ID2 split blobs - readers convert them automatically.
  712. * Scope caches results of requests for data to data loaders.
  713. * Optimized CSeq_id_Handle for gis.
  714. * Optimized bioseq lookup in scope.
  715. * Reduced object allocations in annotation iterators.
  716. * CScope is allowed to be destroyed before other objects using this scope are
  717. * deleted (feature iterators, bioseq handles etc).
  718. * Optimized lookup for matching Seq-ids in CSeq_id_Mapper.
  719. * Added 'adaptive' option to objmgr_demo application.
  720. *
  721. * Revision 1.47  2003/09/05 17:29:40  grichenk
  722. * Structurized Object Manager exceptions
  723. *
  724. * Revision 1.46  2003/08/27 14:27:19  vasilche
  725. * Use Reverse(ENa_strand) function.
  726. *
  727. * Revision 1.45  2003/07/17 19:10:28  grichenk
  728. * Added methods for seq-map and seq-vector validation,
  729. * updated demo.
  730. *
  731. * Revision 1.44  2003/07/14 21:13:26  grichenk
  732. * Added possibility to resolve seq-map iterator withing a single TSE
  733. * and to skip intermediate references during this resolving.
  734. *
  735. * Revision 1.43  2003/06/30 18:39:18  vasilche
  736. * Fixed access to uninitialized member.
  737. *
  738. * Revision 1.42  2003/06/27 19:09:02  grichenk
  739. * Fixed problem with unset sequence length.
  740. *
  741. * Revision 1.41  2003/06/26 19:47:27  grichenk
  742. * Added sequence length cache
  743. *
  744. * Revision 1.40  2003/06/24 14:22:46  vasilche
  745. * Fixed CSeqMap constructor from CSeq_loc.
  746. *
  747. * Revision 1.39  2003/06/12 17:04:55  vasilche
  748. * Fixed creation of CSeqMap for sequences with repr == not_set.
  749. *
  750. * Revision 1.38  2003/06/11 19:32:55  grichenk
  751. * Added molecule type caching to CSeqMap, simplified
  752. * coding and sequence type calculations in CSeqVector.
  753. *
  754. * Revision 1.37  2003/06/02 16:06:38  dicuccio
  755. * Rearranged src/objects/ subtree.  This includes the following shifts:
  756. *     - src/objects/asn2asn --> arc/app/asn2asn
  757. *     - src/objects/testmedline --> src/objects/ncbimime/test
  758. *     - src/objects/objmgr --> src/objmgr
  759. *     - src/objects/util --> src/objmgr/util
  760. *     - src/objects/alnmgr --> src/objtools/alnmgr
  761. *     - src/objects/flat --> src/objtools/flat
  762. *     - src/objects/validator --> src/objtools/validator
  763. *     - src/objects/cddalignview --> src/objtools/cddalignview
  764. * In addition, libseq now includes six of the objects/seq... libs, and libmmdb
  765. * replaces the three libmmdb? libs.
  766. *
  767. * Revision 1.36  2003/05/21 16:03:08  vasilche
  768. * Fixed access to uninitialized optional members.
  769. * Added initialization of mandatory members.
  770. *
  771. * Revision 1.35  2003/05/20 20:36:14  vasilche
  772. * Added FindResolved() with strand argument.
  773. *
  774. * Revision 1.34  2003/05/20 15:44:38  vasilche
  775. * Fixed interaction of CDataSource and CDataLoader in multithreaded app.
  776. * Fixed some warnings on WorkShop.
  777. * Added workaround for memory leak on WorkShop.
  778. *
  779. * Revision 1.33  2003/04/24 16:12:38  vasilche
  780. * Object manager internal structures are splitted more straightforward.
  781. * Removed excessive header dependencies.
  782. *
  783. * Revision 1.32  2003/02/24 18:57:22  vasilche
  784. * Make feature gathering in one linear pass using CSeqMap iterator.
  785. * Do not use feture index by sub locations.
  786. * Sort features at the end of gathering in one vector.
  787. * Extracted some internal structures and classes in separate header.
  788. * Delay creation of mapped features.
  789. *
  790. * Revision 1.31  2003/02/05 17:59:17  dicuccio
  791. * Moved formerly private headers into include/objects/objmgr/impl
  792. *
  793. * Revision 1.30  2003/02/05 15:55:26  vasilche
  794. * Added eSeqEnd segment at the beginning of seq map.
  795. * Added flags to CSeqMap_CI to stop on data, gap, or references.
  796. *
  797. * Revision 1.29  2003/01/28 17:16:06  vasilche
  798. * Added CSeqMap::ResolvedRangeIterator with strand coordinate translation.
  799. *
  800. * Revision 1.28  2003/01/22 20:11:54  vasilche
  801. * Merged functionality of CSeqMapResolved_CI to CSeqMap_CI.
  802. * CSeqMap_CI now supports resolution and iteration over sequence range.
  803. * Added several caches to CScope.
  804. * Optimized CSeqVector().
  805. * Added serveral variants of CBioseqHandle::GetSeqVector().
  806. * Tried to optimize annotations iterator (not much success).
  807. * Rewritten CHandleRange and CHandleRangeMap classes to avoid sorting of list.
  808. *
  809. * Revision 1.27  2002/12/26 20:55:18  dicuccio
  810. * Moved seq_id_mapper.hpp, tse_info.hpp, and bioseq_info.hpp -> include/ tree
  811. *
  812. * Revision 1.26  2002/12/26 20:35:14  ucko
  813. * #include <algorithm> for upper_bound<>
  814. *
  815. * Revision 1.25  2002/12/26 16:39:24  vasilche
  816. * Object manager class CSeqMap rewritten.
  817. *
  818. * Revision 1.24  2002/11/04 21:29:12  grichenk
  819. * Fixed usage of const CRef<> and CRef<> constructor
  820. *
  821. * Revision 1.23  2002/10/18 19:12:40  grichenk
  822. * Removed mutex pools, converted most static mutexes to non-static.
  823. * Protected CSeqMap::x_Resolve() with mutex. Modified code to prevent
  824. * dead-locks.
  825. *
  826. * Revision 1.22  2002/07/08 20:51:02  grichenk
  827. * Moved log to the end of file
  828. * Replaced static mutex (in CScope, CDataSource) with the mutex
  829. * pool. Redesigned CDataSource data locking.
  830. *
  831. * Revision 1.21  2002/05/29 21:21:13  gouriano
  832. * added debug dump
  833. *
  834. * Revision 1.20  2002/05/06 17:43:06  ivanov
  835. * ssize_t changed to long
  836. *
  837. * Revision 1.19  2002/05/06 17:03:49  ivanov
  838. * Sorry. Rollback to R1.17
  839. *
  840. * Revision 1.18  2002/05/06 16:56:23  ivanov
  841. * Fixed typo ssize_t -> size_t
  842. *
  843. * Revision 1.17  2002/05/06 03:28:47  vakatov
  844. * OM/OM1 renaming
  845. *
  846. * Revision 1.16  2002/05/03 21:28:10  ucko
  847. * Introduce T(Signed)SeqPos.
  848. *
  849. * Revision 1.15  2002/05/02 20:42:38  grichenk
  850. * throw -> THROW1_TRACE
  851. *
  852. * Revision 1.14  2002/04/30 18:55:41  gouriano
  853. * added GetRefSeqid function
  854. *
  855. * Revision 1.13  2002/04/11 12:07:30  grichenk
  856. * Redesigned CAnnotTypes_CI to resolve segmented sequences correctly.
  857. *
  858. * Revision 1.12  2002/04/04 21:33:55  grichenk
  859. * Fixed x_FindSegment() for sequences with unresolved segments
  860. *
  861. * Revision 1.11  2002/04/03 18:06:48  grichenk
  862. * Fixed segmented sequence bugs (invalid positioning of literals
  863. * and gaps). Improved CSeqVector performance.
  864. *
  865. * Revision 1.9  2002/03/08 21:36:21  gouriano
  866. * *** empty log message ***
  867. *
  868. * Revision 1.8  2002/03/08 21:24:35  gouriano
  869. * fixed errors with unresolvable references
  870. *
  871. * Revision 1.7  2002/02/25 21:05:29  grichenk
  872. * Removed seq-data references caching. Increased MT-safety. Fixed typos.
  873. *
  874. * Revision 1.6  2002/02/21 19:27:06  grichenk
  875. * Rearranged includes. Added scope history. Added searching for the
  876. * best seq-id match in data sources and scopes. Updated tests.
  877. *
  878. * Revision 1.5  2002/02/01 21:49:38  gouriano
  879. * minor changes to make it compilable and run on Solaris Workshop
  880. *
  881. * Revision 1.4  2002/01/30 22:09:28  gouriano
  882. * changed CSeqMap interface
  883. *
  884. * Revision 1.3  2002/01/23 21:59:32  grichenk
  885. * Redesigned seq-id handles and mapper
  886. *
  887. * Revision 1.2  2002/01/16 16:25:56  gouriano
  888. * restructured objmgr
  889. *
  890. * Revision 1.1  2002/01/11 19:06:24  gouriano
  891. * restructured objmgr
  892. *
  893. *
  894. * ===========================================================================
  895. */