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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: queue_poll.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 18:06:48  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: queue_poll.cpp,v 1000.2 2004/06/01 18:06:48 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:  Kevin Bealer
  35.  *
  36.  */
  37. /** @file queue_poll.cpp
  38.  * Queueing and Polling code for remote_blast.
  39.  */
  40. static char const rcsid[] = 
  41.     "$Id: queue_poll.cpp,v 1000.2 2004/06/01 18:06:48 gouriano Exp $";
  42. #include <ncbi_pch.hpp>
  43. #include <sys/time.h>
  44. #include <unistd.h>
  45. // CRemoteBlast
  46. #include <algo/blast/api/remote_blast.hpp>
  47. // Local
  48. #include "queue_poll.hpp"
  49. // Corelib
  50. #include <corelib/ncbi_system.hpp>
  51. // Objects
  52. #include <objects/blast/Blast4_subject.hpp>
  53. #include <objects/blast/Blast4_queue_search_reques.hpp>
  54. #include <objects/blast/Blast4_parameter.hpp>
  55. #include <objects/blast/Blast4_parameters.hpp>
  56. #include <objects/blast/Blast4_value.hpp>
  57. #include <objects/blast/blastclient.hpp>
  58. #include <objects/blast/Blast4_queue_search_reply.hpp>
  59. #include <objects/blast/Blas_get_searc_resul_reque.hpp>
  60. #include <objects/blast/Blas_get_searc_resul_reply.hpp>
  61. #include <objects/blast/Blast4_error.hpp>
  62. #include <objects/blast/Blast4_error_code.hpp>
  63. #include <objects/seqalign/Seq_align_set.hpp>
  64. // Object Manager
  65. #include <objmgr/object_manager.hpp>
  66. #include <objmgr/scope.hpp>
  67. #include <objtools/data_loaders/genbank/gbloader.hpp>
  68. // Objtools
  69. #include <objtools/readers/fasta.hpp>
  70. // Use _exit() if available.
  71. #if defined(NCBI_OS_UNIX)
  72. #include <unistd.h>
  73. #endif
  74. USING_NCBI_SCOPE;
  75. USING_SCOPE(blast);
  76. USING_SCOPE(objects);
  77. typedef list< CRef<CBlast4_error> > TErrorList;
  78. //--------------------------------------------------------------------
  79. //  Helper Functions
  80. //--------------------------------------------------------------------
  81. #define BLAST4_POLL_DELAY_SEC 15
  82. #define BLAST4_IGNORE_ERRS    5
  83. static inline bool
  84. s_QueryIsAmino(const string & program)
  85. {
  86.     // Should the FASTA be NUC or PROT data?
  87.         
  88.     return (program == "blastp")  ||  (program == "tblastn");
  89. }
  90. void
  91. s_Setp(list<CRef<CBlast4_parameter> >& l, string n, CRef<CBlast4_cutoff> x)
  92. {
  93.     CRef<CBlast4_value> v(new CBlast4_value);
  94.     v->SetCutoff(*x);
  95.     CRef<CBlast4_parameter> p(new CBlast4_parameter);
  96.     p->SetName(n);
  97.     p->SetValue(*v);
  98.     l.push_back(p);
  99. }
  100. void
  101. s_Setp(list<CRef<CBlast4_parameter> >& l, string n, const string x)
  102. {
  103.     CRef<CBlast4_value> v(new CBlast4_value);
  104.     v->SetString(x);
  105.     CRef<CBlast4_parameter> p(new CBlast4_parameter);
  106.     p->SetName(n);
  107.     p->SetValue(*v);
  108.     l.push_back(p);
  109. }
  110. void
  111. s_Setp(list<CRef<CBlast4_parameter> >& l, string n, const int & x)
  112. {
  113.     CRef<CBlast4_value> v(new CBlast4_value);
  114.     v->SetInteger(x);
  115.     
  116.     CRef<CBlast4_parameter> p(new CBlast4_parameter);
  117.     p->SetName(n);
  118.     p->SetValue(*v);
  119.     
  120.     l.push_back(p);
  121. }
  122. void
  123. s_Setp(list<CRef<CBlast4_parameter> >& l, string n, const bool & x)
  124. {
  125.     CRef<CBlast4_value> v(new CBlast4_value);
  126.     v->SetBoolean(x);
  127.     
  128.     CRef<CBlast4_parameter> p(new CBlast4_parameter);
  129.     p->SetName(n);
  130.     p->SetValue(*v);
  131.     
  132.     l.push_back(p);
  133. }
  134. void
  135. s_Setp(list<CRef<CBlast4_parameter> >& l, string n, const double & x)
  136. {
  137.     CRef<CBlast4_value> v(new CBlast4_value);
  138.     v->SetReal(x);
  139.     
  140.     CRef<CBlast4_parameter> p(new CBlast4_parameter);
  141.     p->SetName(n);
  142.     p->SetValue(*v);
  143.     
  144.     l.push_back(p);
  145. }
  146. template <class T1, class T2, class T3>
  147. void
  148. s_SetpOpt(T1 & params, T2 & name, T3 & object)
  149. {
  150.     if (object.Exists()) {
  151.         s_Setp(params, name, object.GetValue());
  152.     }
  153. }
  154. template <class T>
  155. void
  156. s_Output(CNcbiOstream & os, CRef<T> t)
  157. {
  158.     auto_ptr<CObjectOStream> x(CObjectOStream::Open(eSerial_AsnText, os));
  159.     *x << *t;
  160.     os.flush();
  161. }
  162. //--------------------------------------------------------------------
  163. //  Queueing and Polling
  164. //--------------------------------------------------------------------
  165. static CRef<CBioseq_set>
  166. s_SetupQuery(CNcbiIstream    & query_in,
  167.              CRef<CScope>      scope,
  168.              TReadFastaFlags   fasta_flags)
  169. {
  170.     CRef<CSeq_entry> seqentry = ReadFasta(query_in, fasta_flags, 0, 0);
  171.     
  172.     scope->AddTopLevelSeqEntry(*seqentry);
  173.     
  174.     CRef<CBioseq_set> seqset(new CBioseq_set);
  175.     seqset->SetSeq_set().push_back(seqentry);
  176.     
  177.     return seqset;
  178. }
  179. class CSearchParamBuilder : public COptionWalker
  180. {
  181. public:
  182.     template <class T>
  183.     void Local(T &,
  184.                CUserOpt,
  185.                CArgKey,
  186.                COptDesc)
  187.     { }
  188.     
  189.     template <class ValueT, class MethodT, class OptsT>
  190.     void Same(ValueT   & valobj,
  191.                CUserOpt,
  192.                MethodT    param,
  193.                CArgKey,
  194.                COptDesc,
  195.                OptsT    & cboh)
  196.     {
  197.         if (valobj.Exists()) {
  198.             param.Set(cboh, valobj.GetValue());
  199.         }
  200.     }
  201.     
  202.     template <class ValueT, class MethodT, class OptsT>
  203.     void Remote(ValueT & valobj,
  204.                 MethodT param,
  205.                 OptsT & cboh)
  206.     {
  207.         if (valobj.Exists()) {
  208.             param.Set(cboh, valobj.GetValue());
  209.         }
  210.     }
  211.     
  212.     bool NeedRemote(void) { return true; }
  213. };
  214. template<class T> void
  215. s_SetSearchParams(CRef<CRemoteBlast>  & cb4o,
  216.                   CNetblastSearchOpts & opts)
  217. {
  218.     CRef<T> cboh;
  219.     
  220.     cboh.Reset(new T(CBlastOptions::eRemote));
  221.     cb4o.Reset(new CRemoteBlast(cboh));
  222.     
  223.     CSearchParamBuilder spb;
  224.     
  225.     opts.Apply(spb, cboh, cb4o);
  226. }
  227. static CRef<CRemoteBlast>
  228. s_SetBlast4Params(string              & program,
  229.                   string              & service,
  230.                   string              & database,
  231.                   CNetblastSearchOpts & opts,
  232.                   CRef<CBioseq_set>     query,
  233.                   string              & err)
  234. {
  235.     CRef<CRemoteBlast> cb4o;
  236.     
  237.     // NOTE: If adding new types here, add them also to the code in
  238.     // search_opts.hpp that handles argument setting, i.e. the
  239.     // OPT_HANDLER_SUPPORT_ALL() macro.
  240.     
  241.     if (program == "blastp" && service == "plain") {
  242.         s_SetSearchParams<CBlastProteinOptionsHandle>(cb4o, opts);
  243.     }
  244.     else if (program  == "blastn" &&
  245.              (service == "plain"  || service == "megablast")) {
  246.         s_SetSearchParams<CBlastNucleotideOptionsHandle>(cb4o, opts);
  247.     }
  248.     else if (program == "tblastn" && service == "plain") {
  249.         s_SetSearchParams<CTBlastnOptionsHandle>(cb4o, opts);
  250.     }
  251.     else if (program == "tblastx" && service == "plain") {
  252.         s_SetSearchParams<CTBlastxOptionsHandle>(cb4o, opts);
  253.     }
  254.     else if (program == "blastx" && service == "plain") {
  255.         s_SetSearchParams<CBlastxOptionsHandle>(cb4o, opts);
  256.     }
  257.     else if (program == "blastx" && service == "plain") {
  258.         s_SetSearchParams<CBlastxOptionsHandle>(cb4o, opts);
  259.     }
  260.     
  261.     if (cb4o.Empty()) {
  262.         err +="Combination of program [";
  263.         err += program;
  264.         err += "] and service [";
  265.         err += service;
  266.         err += " is not supported.n";
  267.     } else {
  268.         cb4o->SetDatabase(database);
  269.         
  270.         // Should the following adjustment / workaround be in...
  271.         // ... CRemoteBlast ?
  272.         // ... blast4 server?
  273.         // ... right here?
  274.         
  275.         if (query->GetSeq_set().front()->IsSeq()) {
  276.             cb4o->SetQueries(query);
  277.         } else {
  278.             const CBioseq_set * myset = & query->GetSeq_set().front()->GetSet();
  279.             CBioseq_set * myset2 = (CBioseq_set *) myset;
  280.             
  281.             cb4o->SetQueries(CRef<CBioseq_set>(myset2));
  282.         }
  283.         
  284.         cb4o->SetQueries (query);
  285.     }
  286.     
  287.     return cb4o;
  288. }
  289. static CRef<CRemoteBlast>
  290. s_QueueSearch(string              & program,
  291.               string              & service,
  292.               string              & database,
  293.               CNetblastSearchOpts & opts,
  294.               CRef<CBioseq_set>     query,
  295.               string              & err)
  296. {
  297.     CRef<CRemoteBlast> cb4o
  298.         = s_SetBlast4Params(program,
  299.                             service,
  300.                             database,
  301.                             opts,
  302.                             query,
  303.                             err);
  304.     
  305.     if (cb4o.NotEmpty()) {
  306.         string cb4err(cb4o->GetErrors());
  307.         
  308.         if (cb4err.size()) {
  309.             err += cb4err + "n";
  310.         }
  311.     }
  312.     
  313.     return cb4o;
  314. }
  315. inline double dbl_time(void)
  316. {
  317.     struct timeval tv;
  318.     gettimeofday(& tv, 0);
  319.     
  320.     return tv.tv_sec + double(tv.tv_usec) / 1000000.0;
  321. }
  322. static void
  323. s_ShowAlign(CNcbiOstream         & os,
  324.             CRef<CRemoteBlast>   cb4o,
  325.             CRef<CScope>           scope,
  326.             CAlignParms          & alparms,
  327.             bool                   /*gapped*/)
  328. {
  329.     CRef<CSeq_align_set> alignments = cb4o->GetAlignments();
  330.     
  331.     if (alignments.Empty()) {
  332.         os << "This search did not find any matches.n";
  333.         return;
  334.     }
  335.     
  336.     list <CDisplaySeqalign::SeqlocInfo*>  none1;
  337.     list <CDisplaySeqalign::FeatureInfo*> none2;
  338.     
  339.     AutoPtr<CDisplaySeqalign> dsa_ptr;
  340.     
  341.     // if (async_mode || (! gapped)) {
  342.     
  343.     // 1. The "prepare" function needs to be called in ungapped mode.
  344.     // 2. It's safe to call this even if it is not needed (i.e. gapped mode).
  345.     // 3. If not needed, it takes almost no time compared to the actual display,
  346.     //    the ratio seems to be about 80,000 to 1.
  347.     // 4. We can't tell if we are in gapped mode in the async case.
  348.     // 5. So, we always call the prepare function.
  349.     
  350.     CRef<CSeq_align_set> newalign =
  351.         CDisplaySeqalign::PrepareBlastUngappedSeqalign(*alignments);
  352.     
  353.     dsa_ptr = new CDisplaySeqalign(*newalign, none1, none2, 0, * scope);
  354.     
  355.     // } else {
  356.     //     dsa_ptr = new CDisplaySeqalign(*alignments, none1, none2, 0, * scope);
  357.     // }
  358.     
  359.     alparms.AdjustDisplay(*dsa_ptr);
  360.     
  361.     dsa_ptr->DisplaySeqalign(os);
  362. }
  363. void ShowResults(CRef<CRemoteBlast>  cb4o,
  364.                  CRef<CScope>          scope,
  365.                  CAlignParms         & alparms,
  366.                  bool                  async_mode,
  367.                  bool                  raw_asn)
  368. {
  369.     bool display = false;
  370.     
  371.     if (async_mode) {
  372.         // Note that in ASYNC mode, we ONLY report status.  The user
  373.         // can rerun without -async_mode to get results.  This is to
  374.         // facilitate script writers (...is this a good decision?)
  375.         
  376.         bool   rid_done  = cb4o->CheckDone();
  377.         string err       = cb4o->GetErrors();
  378.         
  379.         if (! err.empty()) {
  380.             cout << "STATUS [error:" << err << "] RID [" << cb4o->GetRID() << "]" << endl;
  381.         } else {
  382.             string status = (rid_done ? "done" : "pending");
  383.             cout << "STATUS [" << status << "] RID [" << cb4o->GetRID() << "]" << endl;
  384.         }
  385.     } else {
  386.         cb4o->SubmitSync();
  387.         string err = cb4o->GetErrors();
  388.         
  389.         if (! err.empty()) {
  390.             cout << "STATUS [error:" << err << "] RID [" << cb4o->GetRID() << "]" << endl;
  391.         } else {
  392.             display = true;
  393.         }
  394.     }
  395.     
  396.     if (display) {
  397.         bool gapped = true;
  398.         
  399.         // if (opts.Gapped().Exists()) {
  400.         //     gapped = opts.Gapped().GetValue();
  401.         // }
  402.         
  403.         if (raw_asn) {
  404.             s_Output(NcbiCout, cb4o->GetAlignments());
  405.         } else {
  406.             s_ShowAlign(NcbiCout, cb4o, scope, alparms, gapped);
  407.         }
  408.     }
  409. }
  410. // Int4
  411. // QueueAndPoll(string                program,
  412. //              string                service,
  413. //              string                database,
  414. //              CNetblastSearchOpts & opts,
  415. //              CNcbiIstream        & query_in,
  416. //              bool                  verbose,
  417. //              bool                  trust_defline,
  418. //              bool                  raw_asn,
  419. //              CAlignParms         & alparms,
  420. //              bool                  async_mode,
  421. //              string                get_RID)
  422. // {
  423. //     // no dice
  424. //     return 123;
  425. // }
  426. Int4
  427. QueueAndPoll(string                program,
  428.              string                service,
  429.              string                database,
  430.              CNetblastSearchOpts & opts,
  431.              CNcbiIstream        & query_in,
  432.              bool                  verbose,
  433.              bool                  trust_defline,
  434.              bool                  raw_asn,
  435.              CAlignParms         & alparms,
  436.              bool                  async_mode,
  437.              string                get_RID)
  438. {
  439.     Int4 err_ret = 0;
  440.         
  441.     // Read the FASTA input data
  442.     string fasta_line1;
  443.     string fasta_block;
  444.         
  445.     // Queue and poll
  446.     CRef<CObjectManager> objmgr(new CObjectManager);
  447.     CRef<CScope>         scope (new CScope(*objmgr));
  448.         
  449.     objmgr->RegisterDataLoader(*new CGBDataLoader("ID", 0, 2),
  450.                                CObjectManager::eDefault);
  451.     
  452.     scope->AddDefaults();
  453.         
  454.     string err;
  455.     
  456.     CRef<CRemoteBlast> cb4o;
  457.     
  458.     CRef<CBioseq_set> cbss;
  459.     
  460.     bool amino = s_QueryIsAmino(program);
  461.     
  462.     int flags = fReadFasta_AllSeqIds; // | fReadFasta_OneSeq;
  463.     
  464.     if (amino) {
  465.         flags |= fReadFasta_AssumeProt;
  466.     } else {
  467.         flags |= fReadFasta_AssumeNuc;
  468.     }
  469.     
  470.     if (! trust_defline) {
  471.         flags |= fReadFasta_NoParseID;
  472.     }
  473.     
  474.     cbss = s_SetupQuery(query_in, scope, flags);
  475.     
  476.     if (get_RID.empty()) {
  477.         cb4o = s_QueueSearch(program,
  478.                              service,
  479.                              database,
  480.                              opts,
  481.                              cbss,
  482.                              err);
  483.     
  484.         if (cb4o.Empty() && err.empty()) {
  485.             err = "Internal: Did not get search object from s_QueueSearch()n";
  486.         }
  487.         
  488.         if (err.empty() && verbose) {
  489.             cb4o->SetVerbose(CRemoteBlast::eDebug);
  490.         }
  491.         
  492.         if (err.empty()) {
  493.             if (async_mode) {
  494.                 cb4o->Submit();
  495.             } else {
  496.                 cb4o->SubmitSync();
  497.             }
  498.         } else {
  499.             err_ret = 1;
  500.         }
  501.     } else {
  502.         cb4o.Reset( new CRemoteBlast(get_RID) );
  503.     }
  504.     
  505.     if (! err.empty()) {
  506.         cerr << err << endl;
  507.     } else {
  508.         ShowResults(cb4o, scope, alparms, async_mode, raw_asn);
  509.     }
  510.     
  511.     return err_ret;
  512. }
  513. /*
  514.  * ===========================================================================
  515.  *
  516.  * $Log: queue_poll.cpp,v $
  517.  * Revision 1000.2  2004/06/01 18:06:48  gouriano
  518.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.6
  519.  *
  520.  * Revision 1.6  2004/05/21 21:41:03  gorelenk
  521.  * Added PCH ncbi_pch.hpp
  522.  *
  523.  * Revision 1.5  2004/05/19 14:52:02  camacho
  524.  * 1. Added doxygen tags to enable doxygen processing of algo/blast/core
  525.  * 2. Standardized copyright, CVS $Id string, $Log and rcsid formatting and i
  526.  *    location
  527.  * 3. Added use of @todo doxygen keyword
  528.  *
  529.  * Revision 1.4  2004/04/19 14:37:52  bealer
  530.  * - Fix compiler warnings.
  531.  *
  532.  * Revision 1.3  2004/03/22 20:46:21  bealer
  533.  * - Fix non-literate comments to look less like doxygen comments.
  534.  *
  535.  * Revision 1.2  2004/02/18 20:28:18  bealer
  536.  * - Always call prepare function.
  537.  * - Set verbosity flag earlier.
  538.  *
  539.  * Revision 1.1  2004/02/18 17:04:41  bealer
  540.  * - Adapt blast_client code for Remote Blast API, merging code into the
  541.  *   remote_blast demo application.
  542.  *
  543.  * ===========================================================================
  544.  */