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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: test_seqvector_ci.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:42:39  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: test_seqvector_ci.cpp,v 1000.1 2004/06/01 19:42:39 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
  35. *
  36. * File Description:
  37. *   Test for CSeqVector_CI
  38. *
  39. * ===========================================================================
  40. */
  41. #include <ncbi_pch.hpp>
  42. #include <corelib/ncbistd.hpp>
  43. #include <corelib/ncbiapp.hpp>
  44. #include <corelib/ncbienv.hpp>
  45. #include <corelib/ncbiargs.hpp>
  46. #include <corelib/ncbi_system.hpp>
  47. #include <corelib/ncbi_limits.hpp>
  48. #include <util/random_gen.hpp>
  49. // Objects includes
  50. #include <objects/seqloc/Seq_id.hpp>
  51. // Object manager includes
  52. #include <objmgr/object_manager.hpp>
  53. #include <objmgr/scope.hpp>
  54. #include <objmgr/seq_vector.hpp>
  55. #include <objmgr/seq_vector_ci.hpp>
  56. #include <objtools/data_loaders/genbank/gbloader.hpp>
  57. #include <objmgr/bioseq_handle.hpp>
  58. BEGIN_NCBI_SCOPE
  59. using namespace objects;
  60. class CTestApp : public CNcbiApplication
  61. {
  62. public:
  63.     virtual void Init(void);
  64.     virtual int  Run (void);
  65. private:
  66.     void x_TestIterate(CSeqVector_CI& vit,
  67.                        TSeqPos start,
  68.                        TSeqPos stop);
  69.     void x_TestGetData(CSeqVector_CI& vit,
  70.                        TSeqPos start,
  71.                        TSeqPos stop);
  72.     void x_TestVector(TSeqPos start,
  73.                       TSeqPos stop);
  74.     bool x_CheckBuf(const string& buf, size_t pos, size_t len) const;
  75.     CRef<CObjectManager> m_OM;
  76.     CSeqVector m_Vect;
  77.     string m_RefBuf;
  78. };
  79. void CTestApp::Init(void)
  80. {
  81.     // Prepare command line descriptions
  82.     //
  83.     // Create
  84.     auto_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
  85.     // GI to fetch
  86.     arg_desc->AddDefaultKey("gi", "SeqEntryID",
  87.                             "GI id of the Seq-Entry to fetch",
  88.                             CArgDescriptions::eInteger,
  89.                             "29791621");
  90.     arg_desc->AddDefaultKey("cycles", "RandomCycles",
  91.                             "repeat random test 'cycles' times",
  92.                             CArgDescriptions::eInteger, "100");
  93.     arg_desc->AddDefaultKey("seed", "RandomSeed",
  94.                             "Force random seed",
  95.                             CArgDescriptions::eInteger, "0");
  96.     // Program description
  97.     string prog_description = "Test for CSeqVector_CIn";
  98.     arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),
  99.                               prog_description, false);
  100.     // Pass argument descriptions to the application
  101.     //
  102.     SetupArgDescriptions(arg_desc.release());
  103. }
  104. bool CTestApp::x_CheckBuf(const string& buf, size_t pos, size_t len) const
  105. {
  106.     if ( pos > m_RefBuf.size() || pos + len > m_RefBuf.size() ||
  107.          buf.size() != len ) {
  108.         return false;
  109.     }
  110.     return memcmp(buf.data(), m_RefBuf.data()+pos, len) == 0;
  111. }
  112. void CTestApp::x_TestIterate(CSeqVector_CI& vit,
  113.                              TSeqPos start,
  114.                              TSeqPos stop)
  115. {
  116.     if (stop > m_Vect.size()) {
  117.         stop = m_Vect.size();
  118.     }
  119.     if (start != kInvalidSeqPos) {
  120.         if (start > m_Vect.size())
  121.             start = m_Vect.size();
  122.         vit.SetPos(start);
  123.     }
  124.     else {
  125.         start = vit.GetPos();
  126.     }
  127.     // cout << "Testing iterator, " << start << " - " << stop << "... ";
  128.     if (start > stop) {
  129.         // Moving down
  130.         const char* data = m_RefBuf.data();
  131.         for ( TSeqPos pos = start; pos > stop;  ) {
  132.             --vit; --pos;
  133.             if ( vit.GetPos() != pos ) {
  134.                 cout << endl << "ERROR: GetPos failed at position " << pos << endl;
  135.                 throw runtime_error("Test failed");
  136.             }
  137.             if (*vit != data[pos]) {
  138.                 cout << endl << "ERROR: Test failed at position " << pos << endl;
  139.                 throw runtime_error("Test failed");
  140.             }
  141.         }
  142.     }
  143.     else {
  144.         // Moving up
  145.         const char* data = m_RefBuf.data();
  146.         for ( TSeqPos pos = start; pos < stop; ++vit, ++pos ) {
  147.             if ( vit.GetPos() != pos ) {
  148.                 cout << endl << "ERROR: GetPos failed at position " << pos << endl;
  149.                 throw runtime_error("Test failed");
  150.             }
  151.             if (*vit != data[pos]) {
  152.                 cout << endl << "ERROR: Test failed at position " << pos << endl;
  153.                 throw runtime_error("Test failed");
  154.             }
  155.         }
  156.     }
  157.     // cout << "OK" << endl;
  158. }
  159. void CTestApp::x_TestGetData(CSeqVector_CI& vit,
  160.                              TSeqPos start,
  161.                              TSeqPos stop)
  162. {
  163.     if (start == kInvalidSeqPos) {
  164.         start = vit.GetPos();
  165.     }
  166.     if (start > stop)
  167.         swap(start, stop);
  168.     // cout << "Testing GetSeqData(" << start << ", " << stop << ")... " << endl;
  169.     string buf;
  170.     vit.GetSeqData(start, stop, buf);
  171.     if (start >= stop  &&  buf.size() > 0) {
  172.         cout << endl << "ERROR: Test failed -- invalid data length" << endl;
  173.         throw runtime_error("Test failed");
  174.     }
  175.     if (stop > m_Vect.size())
  176.         stop = m_Vect.size();
  177.     if ( !x_CheckBuf(buf, start, stop - start) ) {
  178.         cout << endl << "ERROR: Test failed -- invalid data" << endl;
  179.         throw runtime_error("Test failed");
  180.     }
  181.     // cout << "OK" << endl;
  182. }
  183. void CTestApp::x_TestVector(TSeqPos start,
  184.                             TSeqPos stop)
  185. {
  186.     if (start > m_Vect.size()) {
  187.         start = m_Vect.size();
  188.     }
  189.     if (stop > m_Vect.size()) {
  190.         stop = m_Vect.size();
  191.     }
  192.     // cout << "Testing vector[], " << start << " - " << stop << "... ";
  193.     if (start > stop) {
  194.         // Moving down
  195.         const char* data = m_RefBuf.data();
  196.         for (TSeqPos i = start; i > stop; ) {
  197.             --i;
  198.             if (m_Vect[i] != data[i]) {
  199.                 cout << endl << "ERROR: Test failed at position " << i << endl;
  200.                 throw runtime_error("Test failed");
  201.             }
  202.         }
  203.     }
  204.     else {
  205.         // Moving up
  206.         const char* data = m_RefBuf.data();
  207.         for (TSeqPos i = start; i < stop; ++i) {
  208.             if (m_Vect[i] != data[i]) {
  209.                 cout << endl << "ERROR: Test failed at position " << i << endl;
  210.                 throw runtime_error("Test failed");
  211.             }
  212.         }
  213.     }
  214.     // cout << "OK" << endl;
  215. }
  216. int CTestApp::Run(void)
  217. {
  218.     // Process command line args: get GI to load
  219.     const CArgs& args = GetArgs();
  220.     // GI with many segments of different sizes.
  221.     int gi = args["gi"].AsInteger(); // 29791621;
  222.     m_OM.Reset(new CObjectManager);
  223.     m_OM->RegisterDataLoader(*new CGBDataLoader("ID", 0, 2),
  224.                              CObjectManager::eDefault);
  225.     CScope scope(*m_OM);
  226.     scope.AddDefaults();
  227.     CSeq_id id;
  228.     id.SetGi(gi);
  229.     CBioseq_Handle handle = scope.GetBioseqHandle(id);
  230.     // Check if the handle is valid
  231.     if ( !handle ) {
  232.         cout << "Can not find gi " << gi << endl;
  233.         return 0;
  234.     }
  235.     // Create seq-vector
  236.     m_Vect = handle.GetSeqVector(CBioseq_Handle::eCoding_Iupac);
  237.     // Prepare reference data
  238.     m_Vect.GetSeqData(0, m_Vect.size(), m_RefBuf);
  239.     CSeqVector_CI vit = CSeqVector_CI(m_Vect);
  240.     string buf;
  241.     // start > stop test
  242.     cout << "Testing empty range (start > stop)... ";
  243.     vit.GetSeqData(m_Vect.size(), 0, buf);
  244.     if (buf.size() != 0) {
  245.         cout << endl << "ERROR: Test failed -- got non-empty data" << endl;
  246.         throw runtime_error("Empty range test failed");
  247.     }
  248.     cout << "OK" << endl;
  249.     // stop > length test
  250.     cout << "Testing past-end read (stop > size)... ";
  251.     vit.GetSeqData(
  252.         max<TSeqPos>(m_Vect.size(), 100) - 100, m_Vect.size() + 1, buf);
  253.     if ( !x_CheckBuf(buf, max<TSeqPos>(m_Vect.size(), 100) - 100, 100) ) {
  254.         cout << "ERROR: GetSeqData() failed -- invalid data" << endl;
  255.         throw runtime_error("Past-end read test failed");
  256.     }
  257.     cout << "OK" << endl;
  258.     buf = ""; // .erase();
  259.     // Compare iterator with GetSeqData()
  260.     // Not using x_TestIterate() to also check operator bool()
  261.     cout << "Testing basic iterator... ";
  262.     const char* data = m_RefBuf.data();
  263.     const char* c = data;
  264.     const char* data_end = data + m_RefBuf.size();
  265.     for (vit.SetPos(0); vit; ++vit, ++c) {
  266.         if (c == data_end ||  *vit != *c) {
  267.             cout << "ERROR: Invalid data at " << vit.GetPos() << endl;
  268.             throw runtime_error("Basic iterator test failed");
  269.         }
  270.     }
  271.     if (c != data_end) {
  272.         cout << "ERROR: Invalid data length" << endl;
  273.         throw runtime_error("Basic iterator test failed");
  274.     }
  275.     cout << "OK" << endl;
  276.     // Partial retrieval with GetSeqData() test, limit to 2000 bases
  277.     cout << "Testing partial retrieval... ";
  278.     for (unsigned i = max<int>(1, m_Vect.size() / 2 - 2000);
  279.          i <= m_Vect.size() / 2; ++i) {
  280.         x_TestGetData(vit, i, m_Vect.size() - i);
  281.     }
  282.     cout << "OK" << endl;
  283.     // Butterfly test
  284.     cout << "Testing butterfly reading... ";
  285.     for (unsigned i = 1; i < m_Vect.size() / 2; ++i) {
  286.         if (m_Vect[i] != data[i]) {
  287.             cout << "ERROR: Butterfly test failed at position " << i << endl;
  288.             throw runtime_error("Butterfly read test failed");
  289.         }
  290.     }
  291.     cout << "OK" << endl;
  292.     TSeqPos pos1 = 0;
  293.     TSeqPos pos2 = 0;
  294.     TSeqPos pos3 = 0;
  295.     TSeqPos pos4 = 0;
  296.     {{
  297.         const CSeqMap& smap = handle.GetSeqMap();
  298.         CSeqMap_CI map_it = smap.begin_resolved(&scope);
  299.         if ( map_it ) {
  300.             // Should happen for any non-empty sequence
  301.             pos2 = map_it.GetEndPosition();
  302.             ++map_it;
  303.             if ( map_it ) {
  304.                 // Should happen for most segmented sequences
  305.                 pos3 = map_it.GetEndPosition();
  306.                 ++map_it;
  307.                 if ( map_it ) {
  308.                     // May happen for some segmented sequences
  309.                     pos4 = map_it.GetEndPosition();
  310.                 }
  311.             }
  312.         }
  313.     }}
  314.     // ========= Iterator tests ==========
  315.     cout << "Testing iterator - single segment... ";
  316.     // Single segment test, start from the middle of the first segment
  317.     vit = CSeqVector_CI(m_Vect, (pos1 + pos2) / 2);
  318.     // Back to the first segment start
  319.     x_TestIterate(vit, kInvalidSeqPos, pos1);
  320.     // Forward to the first segment end
  321.     x_TestIterate(vit, kInvalidSeqPos, pos2);
  322.     // Back to the first segment start again
  323.     x_TestIterate(vit, kInvalidSeqPos, pos1);
  324.     cout << "OK" << endl;
  325.     // Try to run multi-segment tests
  326.     if ( pos3 ) {
  327.         cout << "Testing iterator - multiple segments... ";
  328.         // Start from the middle of the second segment
  329.         vit = CSeqVector_CI(m_Vect, (pos2 + pos3) / 2);
  330.         // Back to the first segment start
  331.         x_TestIterate(vit, kInvalidSeqPos, pos1);
  332.         // Forward to the second or third segment end
  333.         x_TestIterate(vit, kInvalidSeqPos, pos4 ? pos4 : pos3);
  334.         // Back to the first segment start again
  335.         x_TestIterate(vit, kInvalidSeqPos, pos1);
  336.         cout << "OK" << endl;
  337.     }
  338.     // ========= GetSeqData() tests ==========
  339.     cout << "Testing GetSeqData() - single segment... ";
  340.     // Single segment test, start from the middle of the first segment
  341.     vit = CSeqVector_CI(m_Vect, (pos1 + pos2) / 2);
  342.     // Back to the first segment start
  343.     x_TestGetData(vit, kInvalidSeqPos, pos1);
  344.     // Forward to the first segment end
  345.     x_TestGetData(vit, kInvalidSeqPos, pos2);
  346.     // Back to the first segment start again
  347.     x_TestGetData(vit, kInvalidSeqPos, pos1);
  348.     cout << "OK" << endl;
  349.     // Try to run multi-segment tests
  350.     if ( pos3 ) {
  351.         cout << "Testing GetSeqData() - multiple segments... ";
  352.         // Start from the middle of the second segment
  353.         vit = CSeqVector_CI(m_Vect, (pos2 + pos3) / 2);
  354.         // Back to the first segment start
  355.         x_TestGetData(vit, kInvalidSeqPos, pos1);
  356.         // Forward to the second or third segment end
  357.         x_TestGetData(vit, kInvalidSeqPos, pos4 ? pos4 : pos3);
  358.         // Back to the first segment start again
  359.         x_TestGetData(vit, kInvalidSeqPos, pos1);
  360.         cout << "OK" << endl;
  361.     }
  362.     // ========= CSeqVector[] tests ==========
  363.     cout << "Testing operator[] - single segment... ";
  364.     // Single segment test, start from the middle of the first segment
  365.     // Back to the first segment start
  366.     x_TestVector((pos1 + pos2) / 2, pos1);
  367.     // Forward to the first segment end
  368.     x_TestVector(pos1, pos2);
  369.     // Back to the first segment start again
  370.     x_TestVector(pos2, pos1);
  371.     cout << "OK" << endl;
  372.     // Try to run multi-segment tests
  373.     if ( pos3 ) {
  374.         cout << "Testing operator[] - multiple segments... ";
  375.         // Start from the middle of the second segment
  376.         // Back to the first segment start
  377.         x_TestVector((pos2 + pos3) / 2, pos1);
  378.         // Forward to the second or third segment end
  379.         x_TestVector(pos1, pos4 ? pos4 : pos3);
  380.         // Back to the first segment start again
  381.         x_TestVector(pos4 ? pos4 : pos3, pos1);
  382.         cout << "OK" << endl;
  383.     }
  384.     // Random access tests
  385.     cout << "Testing random access" << endl;
  386.     unsigned int rseed = args["seed"].AsInteger();
  387.     int cycles = args["cycles"].AsInteger();
  388.     if (rseed == 0) {
  389.         rseed = (unsigned)time( NULL );
  390.     }
  391.     cout << "Testing random reading (seed: " << rseed
  392.          << ", cycles: " << cycles << ")... " << endl;
  393.     CRandom random(rseed);
  394.     vit = CSeqVector_CI(m_Vect);
  395.     for (int i = 0; i < cycles; ++i) {
  396.         TSeqPos start = random.GetRand(0, m_Vect.size());
  397.         TSeqPos stop = random.GetRand(0, m_Vect.size());
  398.         switch (i % 3) {
  399.         case 0:
  400.             x_TestIterate(vit, start, stop);
  401.             break;
  402.         case 1:
  403.             x_TestGetData(vit, start, stop);
  404.             break;
  405.         case 2:
  406.             x_TestVector(start, stop);
  407.             break;
  408.         }
  409.     }
  410.     cout << "OK" << endl;
  411.     NcbiCout << "All tests passed" << NcbiEndl;
  412.     return 0;
  413. }
  414. END_NCBI_SCOPE
  415. /////////////////////////////////////////////////////////////////////////////
  416. //  MAIN
  417. USING_NCBI_SCOPE;
  418. int main(int argc, const char* argv[])
  419. {
  420.     return CTestApp().AppMain(argc, argv);
  421. }
  422. /*
  423. * ---------------------------------------------------------------------------
  424. * $Log: test_seqvector_ci.cpp,v $
  425. * Revision 1000.1  2004/06/01 19:42:39  gouriano
  426. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.2
  427. *
  428. * Revision 1.2  2004/05/21 21:42:52  gorelenk
  429. * Added PCH ncbi_pch.hpp
  430. *
  431. * Revision 1.1  2003/12/16 17:51:23  kuznets
  432. * Code reorganization
  433. *
  434. * Revision 1.6  2003/11/12 20:16:15  vasilche
  435. * Fixed error: Attempt to delete Object Manager with open scopes.
  436. *
  437. * Revision 1.5  2003/08/29 13:34:48  vasilche
  438. * Rewrote CSeqVector/CSeqVector_CI code to allow better inlining.
  439. * CSeqVector::operator[] made significantly faster.
  440. * Added possibility to have platform dependent byte unpacking functions.
  441. *
  442. * Revision 1.4  2003/08/06 20:51:54  grichenk
  443. * Use CRandom class
  444. *
  445. * Revision 1.3  2003/07/09 18:49:33  grichenk
  446. * Added arguments (seed and cycles), default random cycles set to 20.
  447. *
  448. * Revision 1.2  2003/06/26 17:02:52  grichenk
  449. * Simplified output, decreased number of cycles.
  450. *
  451. * Revision 1.1  2003/06/24 19:50:02  grichenk
  452. * Added test for CSeqVector_CI
  453. *
  454. *
  455. * ===========================================================================
  456. */