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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: seq_vector.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 19:24:24  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.68
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: seq_vector.cpp,v 1000.3 2004/06/01 19:24:24 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: Aleksey Grichenko, Eugene Vasilchenko
  35. *
  36. * File Description:
  37. *   Sequence data container for object manager
  38. *
  39. */
  40. #include <ncbi_pch.hpp>
  41. #include <objmgr/seq_vector.hpp>
  42. #include <objmgr/seq_vector_ci.hpp>
  43. #include <corelib/ncbimtx.hpp>
  44. #include <objmgr/impl/data_source.hpp>
  45. #include <objects/seq/seqport_util.hpp>
  46. #include <objects/seqloc/Seq_loc.hpp>
  47. #include <objmgr/seq_map.hpp>
  48. #include <objmgr/objmgr_exception.hpp>
  49. #include <algorithm>
  50. #include <map>
  51. #include <vector>
  52. BEGIN_NCBI_SCOPE
  53. BEGIN_SCOPE(objects)
  54. ////////////////////////////////////////////////////////////////////
  55. //
  56. //  CSeqVector::
  57. //
  58. CSeqVector::CSeqVector(void)
  59.     : m_Size(0)
  60. {
  61.     m_Iterator.x_SetVector(*this);
  62. }
  63. CSeqVector::CSeqVector(const CSeqVector& vec)
  64.     : m_SeqMap(vec.m_SeqMap),
  65.       m_Scope(vec.m_Scope),
  66.       m_Size(vec.m_Size),
  67.       m_Mol(vec.m_Mol),
  68.       m_Strand(vec.m_Strand),
  69.       m_Coding(vec.m_Coding)
  70. {
  71.     m_Iterator.x_SetVector(*this);
  72. }
  73. CSeqVector::CSeqVector(CConstRef<CSeqMap> seqMap, CScope& scope,
  74.                        EVectorCoding coding, ENa_strand strand)
  75.     : m_SeqMap(seqMap),
  76.       m_Scope(&scope),
  77.       m_Size(seqMap->GetLength(&scope)),
  78.       m_Mol(seqMap->GetMol()),
  79.       m_Strand(strand),
  80.       m_Coding(CSeq_data::e_not_set)
  81. {
  82.     m_Iterator.x_SetVector(*this);
  83.     SetCoding(coding);
  84. }
  85. CSeqVector::CSeqVector(const CSeqMap& seqMap, CScope& scope,
  86.                        EVectorCoding coding, ENa_strand strand)
  87.     : m_SeqMap(&seqMap),
  88.       m_Scope(&scope),
  89.       m_Size(seqMap.GetLength(&scope)),
  90.       m_Mol(seqMap.GetMol()),
  91.       m_Strand(strand),
  92.       m_Coding(CSeq_data::e_not_set)
  93. {
  94.     m_Iterator.x_SetVector(*this);
  95.     SetCoding(coding);
  96. }
  97. CSeqVector::CSeqVector(const CSeq_loc& loc, CScope& scope,
  98.                        EVectorCoding coding, ENa_strand strand)
  99.     : m_SeqMap(CSeqMap::CreateSeqMapForSeq_loc(loc, &scope)),
  100.       m_Scope(&scope),
  101.       m_Size(m_SeqMap->GetLength(&scope)),
  102.       m_Mol(m_SeqMap->GetMol()),
  103.       m_Strand(strand),
  104.       m_Coding(CSeq_data::e_not_set)
  105. {
  106.     m_Iterator.x_SetVector(*this);
  107.     SetCoding(coding);
  108. }
  109. CSeqVector::~CSeqVector(void)
  110. {
  111. }
  112. CSeqVector& CSeqVector::operator= (const CSeqVector& vec)
  113. {
  114.     if ( &vec != this ) {
  115.         m_SeqMap = vec.m_SeqMap;
  116.         m_Scope  = vec.m_Scope;
  117.         m_Size   = vec.m_Size;
  118.         m_Mol    = vec.m_Mol;
  119.         m_Strand = vec.m_Strand;
  120.         m_Coding = vec.m_Coding;
  121.         m_Iterator.x_SetVector(*this);
  122.     }
  123.     return *this;
  124. }
  125. bool CSeqVector::CanGetRange(TSeqPos from, TSeqPos to) const
  126. {
  127.     return m_SeqMap->CanResolveRange(m_Scope.GetScopeOrNull(),
  128.                                      from, to, m_Strand);
  129. }
  130. CSeqVector::TResidue CSeqVector::x_GetGapChar(TCoding coding)
  131. {
  132.     switch (coding) {
  133.     case CSeq_data::e_Iupacna: // DNA - N
  134.         return 'N';
  135.     
  136.     case CSeq_data::e_Ncbi8na: // DNA - bit representation
  137.     case CSeq_data::e_Ncbi4na:
  138.         return 0x0f;  // all bits set == any base
  139.     case CSeq_data::e_Ncbieaa: // Proteins - X
  140.     case CSeq_data::e_Iupacaa:
  141.         return 'X';
  142.     
  143.     case CSeq_data::e_Ncbi8aa: // Protein - numeric representation
  144.     case CSeq_data::e_Ncbistdaa:
  145.         return 21;
  146.     case CSeq_data::e_not_set:
  147.         return 0;     // It's not good to throw an exception here
  148.     case CSeq_data::e_Ncbi2na: // Codings without gap symbols
  149.     case CSeq_data::e_Ncbipaa: //### Not sure about this
  150.     case CSeq_data::e_Ncbipna: //### Not sure about this
  151.     default:
  152.         NCBI_THROW(CSeqVectorException, eCodingError,
  153.                    "Can not indicate gap using the selected coding");
  154.     }
  155. }
  156. DEFINE_STATIC_FAST_MUTEX(s_ConvertTableMutex2);
  157. const char* CSeqVector::sx_GetConvertTable(TCoding src,
  158.                                            TCoding dst,
  159.                                            bool reverse)
  160. {
  161.     CFastMutexGuard guard(s_ConvertTableMutex2);
  162.     typedef pair<pair<TCoding, TCoding>, bool> TKey;
  163.     typedef map<TKey, vector<char> > TTables;
  164.     static TTables tables;
  165.     TKey key(pair<TCoding, TCoding>(src, dst), reverse);
  166.     TTables::iterator it = tables.find(key);
  167.     if ( it != tables.end() ) {
  168.         // already created
  169.         return it->second.empty()? 0: &it->second[0];
  170.     }
  171.     it = tables.insert(TTables::value_type(key, vector<char>())).first;
  172.     if ( !CSeqportUtil::IsCodeAvailable(src) ||
  173.          !CSeqportUtil::IsCodeAvailable(dst) ) {
  174.         // invalid types
  175.         return 0;
  176.     }
  177.     const size_t COUNT = kMax_UChar+1;
  178.     const unsigned kInvalidCode = kMax_UChar;
  179.     pair<unsigned, unsigned> srcIndex = CSeqportUtil::GetCodeIndexFromTo(src);
  180.     if ( srcIndex.second >= COUNT ) {
  181.         // too large range
  182.         return 0;
  183.     }
  184.     if ( reverse ) {
  185.         // check if src needs complement conversion
  186.         try {
  187.             CSeqportUtil::GetIndexComplement(src, srcIndex.first);
  188.         }
  189.         catch ( exception& /*noComplement*/ ) {
  190.             reverse = false;
  191.         }
  192.     }
  193.     if ( dst != src ) {
  194.         pair<unsigned, unsigned> dstIndex =
  195.             CSeqportUtil::GetCodeIndexFromTo(dst);
  196.         if ( dstIndex.second >= COUNT ) {
  197.             // too large range
  198.             return 0;
  199.         }
  200.         try {
  201.             // check for types compatibility
  202.             CSeqportUtil::GetMapToIndex(src, dst, srcIndex.first);
  203.         }
  204.         catch ( exception& /*badType*/ ) {
  205.             // incompatible types
  206.             return 0;
  207.         }
  208.     }
  209.     else if ( !reverse ) {
  210.         // no need to convert at all
  211.         return 0;
  212.     }
  213.     it->second.resize(COUNT, char(kInvalidCode));
  214.     for ( unsigned i = srcIndex.first; i <= srcIndex.second; ++i ) {
  215.         try {
  216.             unsigned code = i;
  217.             if ( reverse ) {
  218.                 code = CSeqportUtil::GetIndexComplement(src, code);
  219.             }
  220.             if ( dst != src ) {
  221.                 code = CSeqportUtil::GetMapToIndex(src, dst, code);
  222.             }
  223.             code = min(kInvalidCode, code);
  224.             it->second[i] = char(code);
  225.         }
  226.         catch ( exception& /*noConversion or noComplement*/ ) {
  227.         }
  228.     }
  229.     return &it->second[0];
  230. }
  231. void CSeqVector::SetCoding(TCoding coding)
  232. {
  233.     if (m_Coding != coding) {
  234.         m_Coding = coding;
  235.     }
  236.     m_Iterator.SetCoding(coding);
  237. }
  238. void CSeqVector::SetIupacCoding(void)
  239. {
  240.     SetCoding(IsProtein()? CSeq_data::e_Iupacaa: CSeq_data::e_Iupacna);
  241. }
  242. void CSeqVector::SetNcbiCoding(void)
  243. {
  244.     SetCoding(IsProtein()? CSeq_data::e_Ncbistdaa: CSeq_data::e_Ncbi4na);
  245. }
  246. void CSeqVector::SetCoding(EVectorCoding coding)
  247. {
  248.     switch ( coding ) {
  249.     case CBioseq_Handle::eCoding_Iupac:
  250.         SetIupacCoding();
  251.         break;
  252.     case CBioseq_Handle::eCoding_Ncbi:
  253.         SetNcbiCoding();
  254.         break;
  255.     default:
  256.         SetCoding(CSeq_data::e_not_set);
  257.         break;
  258.     }
  259. }
  260. END_SCOPE(objects)
  261. END_NCBI_SCOPE
  262. /*
  263. * ---------------------------------------------------------------------------
  264. * $Log: seq_vector.cpp,v $
  265. * Revision 1000.3  2004/06/01 19:24:24  gouriano
  266. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.68
  267. *
  268. * Revision 1.68  2004/05/21 21:42:13  gorelenk
  269. * Added PCH ncbi_pch.hpp
  270. *
  271. * Revision 1.67  2004/04/12 16:49:16  vasilche
  272. * Allow null scope in CSeqMap_CI and CSeqVector.
  273. *
  274. * Revision 1.66  2004/02/25 18:58:47  shomrat
  275. * Added a new construtor based on Seq-loc in scope
  276. *
  277. * Revision 1.65  2003/11/19 22:18:04  grichenk
  278. * All exceptions are now CException-derived. Catch "exception" rather
  279. * than "runtime_error".
  280. *
  281. * Revision 1.64  2003/10/08 14:16:55  vasilche
  282. * Removed circular reference CSeqVector <-> CSeqVector_CI.
  283. *
  284. * Revision 1.63  2003/09/30 16:22:04  vasilche
  285. * Updated internal object manager classes to be able to load ID2 data.
  286. * SNP blobs are loaded as ID2 split blobs - readers convert them automatically.
  287. * Scope caches results of requests for data to data loaders.
  288. * Optimized CSeq_id_Handle for gis.
  289. * Optimized bioseq lookup in scope.
  290. * Reduced object allocations in annotation iterators.
  291. * CScope is allowed to be destroyed before other objects using this scope are
  292. * deleted (feature iterators, bioseq handles etc).
  293. * Optimized lookup for matching Seq-ids in CSeq_id_Mapper.
  294. * Added 'adaptive' option to objmgr_demo application.
  295. *
  296. * Revision 1.62  2003/09/05 17:29:40  grichenk
  297. * Structurized Object Manager exceptions
  298. *
  299. * Revision 1.61  2003/08/29 13:34:47  vasilche
  300. * Rewrote CSeqVector/CSeqVector_CI code to allow better inlining.
  301. * CSeqVector::operator[] made significantly faster.
  302. * Added possibility to have platform dependent byte unpacking functions.
  303. *
  304. * Revision 1.60  2003/08/21 18:43:29  vasilche
  305. * Added CSeqVector::IsProtein() and CSeqVector::IsNucleotide() methods.
  306. *
  307. * Revision 1.59  2003/08/21 17:04:10  vasilche
  308. * Fixed bug in making conversion tables.
  309. *
  310. * Revision 1.58  2003/08/21 13:32:04  vasilche
  311. * Optimized CSeqVector iteration.
  312. * Set some CSeqVector values (mol type, coding) in constructor instead of detecting them while iteration.
  313. * Remove unsafe bit manipulations with coding.
  314. *
  315. * Revision 1.57  2003/06/24 19:46:43  grichenk
  316. * Changed cache from vector<char> to char*. Made
  317. * CSeqVector::operator[] inline.
  318. *
  319. * Revision 1.56  2003/06/17 20:35:39  grichenk
  320. * CSeqVector_CI-related improvements
  321. *
  322. * Revision 1.55  2003/06/13 17:22:28  grichenk
  323. * Check if seq-map is not null before using it
  324. *
  325. * Revision 1.54  2003/06/12 18:39:21  vasilche
  326. * Added default constructor of CSeqVector.
  327. * Cleared cache iterator on CSeqVector assignment.
  328. *
  329. * Revision 1.53  2003/06/11 19:32:55  grichenk
  330. * Added molecule type caching to CSeqMap, simplified
  331. * coding and sequence type calculations in CSeqVector.
  332. *
  333. * Revision 1.52  2003/06/04 13:48:56  grichenk
  334. * Improved double-caching, fixed problem with strands.
  335. *
  336. * Revision 1.51  2003/06/02 16:06:38  dicuccio
  337. * Rearranged src/objects/ subtree.  This includes the following shifts:
  338. *     - src/objects/asn2asn --> arc/app/asn2asn
  339. *     - src/objects/testmedline --> src/objects/ncbimime/test
  340. *     - src/objects/objmgr --> src/objmgr
  341. *     - src/objects/util --> src/objmgr/util
  342. *     - src/objects/alnmgr --> src/objtools/alnmgr
  343. *     - src/objects/flat --> src/objtools/flat
  344. *     - src/objects/validator --> src/objtools/validator
  345. *     - src/objects/cddalignview --> src/objtools/cddalignview
  346. * In addition, libseq now includes six of the objects/seq... libs, and libmmdb
  347. * replaces the three libmmdb? libs.
  348. *
  349. * Revision 1.50  2003/05/27 19:44:06  grichenk
  350. * Added CSeqVector_CI class
  351. *
  352. * Revision 1.49  2003/05/20 15:44:38  vasilche
  353. * Fixed interaction of CDataSource and CDataLoader in multithreaded app.
  354. * Fixed some warnings on WorkShop.
  355. * Added workaround for memory leak on WorkShop.
  356. *
  357. * Revision 1.48  2003/05/05 21:00:26  vasilche
  358. * Fix assignment of empty CSeqVector.
  359. *
  360. * Revision 1.47  2003/04/29 19:51:13  vasilche
  361. * Fixed interaction of Data Loader garbage collector and TSE locking mechanism.
  362. * Made some typedefs more consistent.
  363. *
  364. * Revision 1.46  2003/04/24 16:12:38  vasilche
  365. * Object manager internal structures are splitted more straightforward.
  366. * Removed excessive header dependencies.
  367. *
  368. * Revision 1.45  2003/02/07 16:28:05  vasilche
  369. * Fixed delayed seq vector coding setting.
  370. *
  371. * Revision 1.44  2003/02/06 19:05:28  vasilche
  372. * Fixed old cache data copying.
  373. * Delayed sequence type (protein/dna) resolution.
  374. *
  375. * Revision 1.43  2003/02/05 17:59:17  dicuccio
  376. * Moved formerly private headers into include/objects/objmgr/impl
  377. *
  378. * Revision 1.42  2003/02/05 15:05:28  vasilche
  379. * Added string::reserve()
  380. *
  381. * Revision 1.41  2003/01/28 17:17:06  vasilche
  382. * Fixed bug processing minus strands.
  383. * Used CSeqMap::ResolvedRangeIterator with strand coordinate translation.
  384. *
  385. * Revision 1.40  2003/01/23 19:33:57  vasilche
  386. * Commented out obsolete methods.
  387. * Use strand argument of CSeqVector instead of creation reversed seqmap.
  388. * Fixed ordering operators of CBioseqHandle to be consistent.
  389. *
  390. * Revision 1.39  2003/01/23 18:26:02  ucko
  391. * Explicitly #include <algorithm>
  392. *
  393. * Revision 1.38  2003/01/22 20:11:54  vasilche
  394. * Merged functionality of CSeqMapResolved_CI to CSeqMap_CI.
  395. * CSeqMap_CI now supports resolution and iteration over sequence range.
  396. * Added several caches to CScope.
  397. * Optimized CSeqVector().
  398. * Added serveral variants of CBioseqHandle::GetSeqVector().
  399. * Tried to optimize annotations iterator (not much success).
  400. * Rewritten CHandleRange and CHandleRangeMap classes to avoid sorting of list.
  401. *
  402. * Revision 1.37  2003/01/03 19:45:12  dicuccio
  403. * Replaced kPosUnknwon with kInvalidSeqPos (non-static variable; worka-round for
  404. * MSVC)
  405. *
  406. * Revision 1.36  2002/12/26 16:39:24  vasilche
  407. * Object manager class CSeqMap rewritten.
  408. *
  409. * Revision 1.35  2002/12/06 15:36:00  grichenk
  410. * Added overlap type for annot-iterators
  411. *
  412. * Revision 1.34  2002/10/03 13:45:39  grichenk
  413. * CSeqVector::size() made const
  414. *
  415. * Revision 1.33  2002/09/26 20:15:11  grichenk
  416. * Fixed cache lengths checks
  417. *
  418. * Revision 1.32  2002/09/16 20:13:01  grichenk
  419. * Fixed Iupac coding setter
  420. *
  421. * Revision 1.31  2002/09/16 13:52:49  dicuccio
  422. * Fixed bug in calculating total range of cached interval to retrieve -
  423. * must clamp the cached range to the desired range.
  424. *
  425. * Revision 1.30  2002/09/12 19:59:25  grichenk
  426. * Fixed bugs in calculating cached intervals
  427. *
  428. * Revision 1.29  2002/09/10 19:55:52  grichenk
  429. * Fixed reverse-complement position
  430. *
  431. * Revision 1.28  2002/09/09 21:38:37  grichenk
  432. * Fixed problem with GetSeqData() for minus strand
  433. *
  434. * Revision 1.27  2002/09/03 21:27:01  grichenk
  435. * Replaced bool arguments in CSeqVector constructor and getters
  436. * with enums.
  437. *
  438. * Revision 1.26  2002/07/08 20:51:02  grichenk
  439. * Moved log to the end of file
  440. * Replaced static mutex (in CScope, CDataSource) with the mutex
  441. * pool. Redesigned CDataSource data locking.
  442. *
  443. * Revision 1.25  2002/05/31 20:58:19  grichenk
  444. * Fixed GetSeqData() bug
  445. *
  446. * Revision 1.24  2002/05/31 17:53:00  grichenk
  447. * Optimized for better performance (CTSE_Info uses atomic counter,
  448. * delayed annotations indexing, no location convertions in
  449. * CAnnot_Types_CI if no references resolution is required etc.)
  450. *
  451. * Revision 1.23  2002/05/17 17:14:53  grichenk
  452. * +GetSeqData() for getting a range of characters from a seq-vector
  453. *
  454. * Revision 1.22  2002/05/09 14:16:31  grichenk
  455. * sm_SizeUnknown -> kPosUnknown, minor fixes for unsigned positions
  456. *
  457. * Revision 1.21  2002/05/06 03:28:47  vakatov
  458. * OM/OM1 renaming
  459. *
  460. * Revision 1.20  2002/05/03 21:28:10  ucko
  461. * Introduce T(Signed)SeqPos.
  462. *
  463. * Revision 1.19  2002/05/03 18:36:19  grichenk
  464. * Fixed members initialization
  465. *
  466. * Revision 1.18  2002/05/02 20:42:38  grichenk
  467. * throw -> THROW1_TRACE
  468. *
  469. * Revision 1.17  2002/04/29 16:23:28  grichenk
  470. * GetSequenceView() reimplemented in CSeqVector.
  471. * CSeqVector optimized for better performance.
  472. *
  473. * Revision 1.16  2002/04/26 14:37:21  grichenk
  474. * Limited CSeqVector cache size
  475. *
  476. * Revision 1.15  2002/04/25 18:14:47  grichenk
  477. * e_not_set coding gap symbol set to 0
  478. *
  479. * Revision 1.14  2002/04/25 16:37:21  grichenk
  480. * Fixed gap coding, added GetGapChar() function
  481. *
  482. * Revision 1.13  2002/04/23 19:01:07  grichenk
  483. * Added optional flag to GetSeqVector() and GetSequenceView()
  484. * for switching to IUPAC encoding.
  485. *
  486. * Revision 1.12  2002/04/22 20:03:08  grichenk
  487. * Updated comments
  488. *
  489. * Revision 1.11  2002/04/17 21:07:59  grichenk
  490. * String pre-allocation added
  491. *
  492. * Revision 1.10  2002/04/03 18:06:48  grichenk
  493. * Fixed segmented sequence bugs (invalid positioning of literals
  494. * and gaps). Improved CSeqVector performance.
  495. *
  496. * Revision 1.8  2002/03/28 18:34:58  grichenk
  497. * Fixed convertions bug
  498. *
  499. * Revision 1.7  2002/03/08 21:24:35  gouriano
  500. * fixed errors with unresolvable references
  501. *
  502. * Revision 1.6  2002/02/21 19:27:06  grichenk
  503. * Rearranged includes. Added scope history. Added searching for the
  504. * best seq-id match in data sources and scopes. Updated tests.
  505. *
  506. * Revision 1.5  2002/02/15 20:35:38  gouriano
  507. * changed implementation of HandleRangeMap
  508. *
  509. * Revision 1.4  2002/01/30 22:09:28  gouriano
  510. * changed CSeqMap interface
  511. *
  512. * Revision 1.3  2002/01/23 21:59:32  grichenk
  513. * Redesigned seq-id handles and mapper
  514. *
  515. * Revision 1.2  2002/01/16 16:25:58  gouriano
  516. * restructured objmgr
  517. *
  518. * Revision 1.1  2002/01/11 19:06:24  gouriano
  519. * restructured objmgr
  520. *
  521. *
  522. * ===========================================================================
  523. */