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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: multiseq_src.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 18:06:13  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.16
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: multiseq_src.cpp,v 1000.1 2004/06/01 18:06:13 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:  Ilya Dondoshansky
  35. *
  36. */
  37. /// @file multiseq_src.cpp
  38. /// Implementation of the BlastSeqSrc interface for a vector of sequence 
  39. /// locations.
  40. #include <ncbi_pch.hpp>
  41. #include <objects/seqloc/Seq_id.hpp>
  42. #include <objmgr/util/sequence.hpp>
  43. #include <algo/blast/api/multiseq_src.hpp>
  44. #include <algo/blast/core/blast_def.h>
  45. #include "blast_setup.hpp"
  46. #include <algo/blast/api/blast_exception.hpp>
  47. /** @addtogroup AlgoBlast
  48.  *
  49.  * @{
  50.  */
  51. BEGIN_NCBI_SCOPE
  52. USING_SCOPE(objects);
  53. BEGIN_SCOPE(blast)
  54. CMultiSeqInfo::CMultiSeqInfo(const TSeqLocVector& seq_vector, EProgram program)
  55.     : m_vSeqVector(seq_vector)
  56. {
  57.     m_ibIsProt = (program == eBlastp || program == eBlastx);
  58.     
  59.     try {
  60.         SetupSubjects(seq_vector, program, &m_ivSeqBlkVec, &m_iMaxLength);
  61.     } catch (const CBlastException& exptn) {
  62.         Blast_MessageWrite(&m_icErrMsg, BLAST_SEV_ERROR, exptn.GetErrCode(),
  63.                            1, exptn.GetErrCodeString());
  64.     }
  65.     // Do not set right away
  66.     m_iAvgLength = 0;
  67. }
  68. CMultiSeqInfo::~CMultiSeqInfo()
  69. {
  70.     NON_CONST_ITERATE(vector<BLAST_SequenceBlk*>, itr, m_ivSeqBlkVec) {
  71.         *itr = BlastSequenceBlkFree(*itr);
  72.     }
  73.     m_ivSeqBlkVec.clear();
  74. }
  75. void* CMultiSeqInfo::GetSeqId(int index)
  76. {
  77.     CSeq_id* seqid = 
  78.         const_cast<CSeq_id*>(&sequence::GetId(*m_vSeqVector[index].seqloc,
  79.                                               m_vSeqVector[index].scope));
  80.     return (void*) seqid;
  81. }
  82. void* CMultiSeqInfo::GetSeqLoc(int index)
  83. {
  84.     return (void*) &m_vSeqVector[index];
  85. }
  86. /** Retrieves the length of the longest sequence in the BlastSeqSrc.
  87.  * @param multiseq_handle Pointer to the structure containing sequences [in]
  88.  */
  89. extern "C" {
  90. static Int4 MultiSeqGetMaxLength(void* multiseq_handle, void*)
  91. {
  92.     Int4 retval = 0;
  93.     Uint4 index;
  94.     CMultiSeqInfo* seq_info = (CMultiSeqInfo*) multiseq_handle;
  95.     ASSERT(seq_info);
  96.     
  97.     if ((retval = seq_info->GetMaxLength()) > 0)
  98.         return retval;
  99.     for (index=0; index<seq_info->GetNumSeqs(); ++index)
  100.         retval = MAX(retval, seq_info->GetSeqBlk(index)->length);
  101.     seq_info->SetMaxLength(retval);
  102.     return retval;
  103. }
  104. /** Retrieves the length of the longest sequence in the BlastSeqSrc.
  105.  * @param multiseq_handle Pointer to the structure containing sequences [in]
  106.  */
  107. static Int4 MultiSeqGetAvgLength(void* multiseq_handle, void*)
  108. {
  109.     Int8 total_length = 0;
  110.     Uint4 num_seqs = 0;
  111.     Uint4 avg_length;
  112.     Uint4 index;
  113.     CMultiSeqInfo* seq_info = (CMultiSeqInfo*) multiseq_handle;
  114.     ASSERT(seq_info);
  115.     if ((avg_length = seq_info->GetAvgLength()) > 0)
  116.         return avg_length;
  117.     if ((num_seqs = seq_info->GetNumSeqs()) == 0)
  118.         return 0;
  119.     for (index = 0; index < num_seqs; ++index) 
  120.         total_length += (Int8) seq_info->GetSeqBlk(index)->length;
  121.     avg_length = (Uint4) (total_length / num_seqs);
  122.     seq_info->SetAvgLength(avg_length);
  123.     return avg_length;
  124. }
  125. /** Retrieves the number of sequences in the BlastSeqSrc.
  126.  * @param multiseq_handle Pointer to the structure containing sequences [in]
  127.  */
  128. static Int4 MultiSeqGetNumSeqs(void* multiseq_handle, void*)
  129. {
  130.     CMultiSeqInfo* seq_info = (CMultiSeqInfo*) multiseq_handle;
  131.     ASSERT(seq_info);
  132.     return seq_info->GetNumSeqs();
  133. }
  134. /** Returns 0 as total length, indicating that this is NOT a database!
  135.  */
  136. static Int8 MultiSeqGetTotLen(void* /*multiseq_handle*/, void*)
  137. {
  138.     return 0;
  139. }
  140. /** Needed for completeness only.
  141.  */
  142. static char* MultiSeqGetName(void* /*multiseq_handle*/, void*)
  143. {
  144.     return NULL;
  145. }
  146. /** Needed for completeness only
  147.  */
  148. static char* MultiSeqGetDefinition(void* /*multiseq_handle*/, void*)
  149. {
  150.     return NULL;
  151. }
  152. /** Needed for completeness only.
  153.  */
  154. static char* MultiSeqGetDate(void* /*multiseq_handle*/, void*)
  155. {
  156.     return NULL;
  157. }
  158. /** Retrieves the date of the BLAST database.
  159.  * @param multiseq_handle Pointer to the structure containing sequences [in]
  160.  */
  161. static Boolean MultiSeqGetIsProt(void* multiseq_handle, void*)
  162. {
  163.     CMultiSeqInfo* seq_info = (CMultiSeqInfo*) multiseq_handle;
  164.     ASSERT(seq_info);
  165.     return (Boolean) seq_info->GetIsProtein();
  166. }
  167. /** Retrieves the sequence meeting the criteria defined by its second argument.
  168.  * @param multiseq_handle Pointer to the structure containing sequences [in]
  169.  * @param args Pointer to GetSeqArg structure [in]
  170.  * @return return codes defined in blast_seqsrc.h
  171.  */
  172. static Int2 MultiSeqGetSequence(void* multiseq_handle, void* args)
  173. {
  174.     CMultiSeqInfo* seq_info = (CMultiSeqInfo*) multiseq_handle;
  175.     GetSeqArg* seq_args = (GetSeqArg*) args;
  176.     Int4 index;
  177.     ASSERT(seq_info);
  178.     ASSERT(args);
  179.     if (seq_info->GetNumSeqs() == 0 || !seq_args)
  180.         return BLAST_SEQSRC_ERROR;
  181.     index = seq_args->oid;
  182.     if (index >= (Int4) seq_info->GetNumSeqs())
  183.         return BLAST_SEQSRC_EOF;
  184.     BlastSequenceBlkCopy(&seq_args->seq, seq_info->GetSeqBlk(index));
  185.     /* If this is a nucleotide sequence, and it is the traceback stage, 
  186.        we need the uncompressed buffer, stored in the 'sequence_start' 
  187.        pointer. That buffer has an extra sentinel byte for blastn, but
  188.        no sentinel byte for translated programs. */
  189.     if (seq_args->encoding == BLASTNA_ENCODING) {
  190.         seq_args->seq->sequence = seq_args->seq->sequence_start + 1;
  191.     } else if (seq_args->encoding == NCBI4NA_ENCODING) {
  192.         seq_args->seq->sequence = seq_args->seq->sequence_start;
  193.     }
  194.     seq_args->seq->oid = index;
  195.     return BLAST_SEQSRC_SUCCESS;
  196. }
  197. /** Deallocates the uncompressed sequence buffer if necessary.
  198.  * @param multiseq_handle Pointer to the structure containing sequences [in]
  199.  * @param args Pointer to GetSeqArg structure [in]
  200.  * @return return codes defined in blast_seqsrc.h
  201.  */
  202. static Int2 MultiSeqRetSequence(void* /*multiseq_handle*/, void* args)
  203. {
  204.     GetSeqArg* seq_args = (GetSeqArg*) args;
  205.     ASSERT(seq_args);
  206.     if (seq_args->seq->sequence_start_allocated)
  207.         sfree(seq_args->seq->sequence_start);
  208.     return 0;
  209. }
  210. /** Retrieves the sequence identifier given its index into the sequence vector.
  211.  * Client code is responsible for deallocating the return value. 
  212.  * @param multiseq_handle Pointer to the structure containing sequences [in]
  213.  * @param args Pointer to integer indicating ordinal id [in]
  214.  * @return Sequence id structure generated from ASN.1 spec, 
  215.  *         cast to a void pointer.
  216.  */
  217. static ListNode* MultiSeqGetSeqId(void* multiseq_handle, void* args)
  218. {
  219.     CMultiSeqInfo* seq_info = (CMultiSeqInfo*) multiseq_handle;
  220.     Int4 index;
  221.     ListNode* seqid_wrap;
  222.     ASSERT(seq_info);
  223.     ASSERT(args);
  224.     index = *((Int4*) args);
  225.     seqid_wrap = ListNodeAddPointer(NULL, BLAST_SEQSRC_CPP_SEQID, 
  226.                                     seq_info->GetSeqId(index));
  227.     return seqid_wrap;
  228. }
  229. /** Retrieves the sequence identifier in character string form.
  230.  * Client code is responsible for deallocating the return value. 
  231.  * @param multiseq_handle Pointer to the structure containing sequences [in]
  232.  * @param args Pointer to integer indicating index into the vector [in]
  233.  */
  234. static char* MultiSeqGetSeqIdStr(void* multiseq_handle, void* args)
  235. {
  236.     CSeq_id* seqid;
  237.     char *seqid_str = NULL;
  238.     ListNode* seqid_wrap;
  239.     ASSERT(args);
  240.     seqid_wrap = MultiSeqGetSeqId(multiseq_handle, args);
  241.     if (seqid_wrap->choice != BLAST_SEQSRC_CPP_SEQID)
  242.         return NULL;
  243.     seqid = (CSeq_id*) seqid_wrap->ptr;
  244.     ListNodeFree(seqid_wrap);
  245.     if (seqid)
  246.         seqid_str = strdup(seqid->GetSeqIdString().c_str());
  247.     return seqid_str;
  248. }
  249. /** Retrieves the sequence identifier given its index into the sequence vector.
  250.  * Client code is responsible for deallocating the return value. 
  251.  * @param multiseq_handle Pointer to the structure containing sequences [in]
  252.  * @param args Pointer to integer indicating ordinal id [in]
  253.  * @return Sequence id structure generated from ASN.1 spec, 
  254.  *         cast to a void pointer.
  255.  */
  256. static ListNode* MultiSeqGetSeqLoc(void* multiseq_handle, void* args)
  257. {
  258.     CMultiSeqInfo* seq_info = (CMultiSeqInfo*) multiseq_handle;
  259.     Int4 index;
  260.     ListNode* seqloc_wrap;
  261.     ASSERT(seq_info);
  262.     ASSERT(args);
  263.     index = *((Int4*) args);
  264.     seqloc_wrap = ListNodeAddPointer(NULL, BLAST_SEQSRC_CPP_SEQLOC, 
  265.                                      seq_info->GetSeqLoc(index));
  266.     return seqloc_wrap;
  267. }
  268. /** Retrieve length of a given sequence.
  269.  * @param multiseq_handle Pointer to the structure containing sequences [in]
  270.  * @param args Pointer to integer indicating index into the sequences 
  271.  *             vector [in]
  272.  * @return Length of the sequence or BLAST_SEQSRC_ERROR.
  273.  */
  274. static Int4 MultiSeqGetSeqLen(void* multiseq_handle, void* args)
  275. {
  276.     CMultiSeqInfo* seq_info = (CMultiSeqInfo*)multiseq_handle;
  277.     Int4 index;
  278.     ASSERT(seq_info);
  279.     ASSERT(args);
  280.     index = *((Int4*) args);
  281.     return seq_info->GetSeqBlk(index)->length;
  282. }
  283. /** Gets the next sequence index, given a BlastSeqSrc pointer. */
  284. static Int4 MultiSeqIteratorNext(void* seqsrc, BlastSeqSrcIterator* itr)
  285. {
  286.     BlastSeqSrc* seq_src = (BlastSeqSrc*) seqsrc;
  287.     Int4 retval = BLAST_SEQSRC_EOF;
  288.     Int2 status = 0;
  289.     ASSERT(seq_src);
  290.     ASSERT(itr);
  291.     if ((status = BLASTSeqSrcGetNextChunk(seq_src, itr))
  292.         == BLAST_SEQSRC_EOF) {
  293.         return status;
  294.     }
  295.     retval = itr->current_pos++;
  296.     return retval;
  297. }
  298. /** Gets the next sequence index, given a MultiSeqInfo pointer. */
  299. static Int2 MultiSeqGetNextChunk(void* multiseq_handle, 
  300.                                  BlastSeqSrcIterator* itr)
  301. {
  302.     CMultiSeqInfo* seq_info = (CMultiSeqInfo*) multiseq_handle;
  303.     ASSERT(itr);
  304.     if (itr->current_pos == UINT4_MAX) {
  305.         itr->current_pos = 0;
  306.     }
  307.     if (itr->current_pos >= seq_info->GetNumSeqs())
  308.         return BLAST_SEQSRC_EOF;
  309.     return BLAST_SEQSRC_SUCCESS;
  310. }
  311. ListNode* MultiSeqGetErrorMessage(void* multiseq_handle, void*)
  312. {
  313.     CMultiSeqInfo* seq_info = (CMultiSeqInfo*) multiseq_handle;
  314.     Blast_Message* error_msg = seq_info->GetErrorMessage();
  315.     ListNode* retval = NULL;
  316.     if (error_msg) {
  317.         retval = 
  318.             ListNodeAddPointer(NULL, BLAST_SEQSRC_MESSAGE, (void*) error_msg);
  319.     }
  320.     return retval;
  321. }
  322. BlastSeqSrc* MultiSeqSrcNew(BlastSeqSrc* retval, void* args)
  323. {
  324.     SMultiSeqSrcNewArgs* seqsrc_args = (SMultiSeqSrcNewArgs*) args;
  325.     if (!retval)
  326.         return NULL;
  327.     
  328.     CMultiSeqInfo* seq_info = 
  329.         new CMultiSeqInfo(seqsrc_args->seq_vector, seqsrc_args->program);
  330.     /* Initialize the BlastSeqSrc structure fields with user-defined function
  331.      * pointers and seq_info */
  332.     SetDeleteFnPtr(retval, &MultiSeqSrcFree);
  333.     SetDataStructure(retval, (void*) seq_info);
  334.     SetGetNumSeqs(retval, &MultiSeqGetNumSeqs);
  335.     SetGetMaxSeqLen(retval, &MultiSeqGetMaxLength);
  336.     SetGetAvgSeqLen(retval, &MultiSeqGetAvgLength);
  337.     SetGetTotLen(retval, &MultiSeqGetTotLen);
  338.     SetGetName(retval, &MultiSeqGetName);
  339.     SetGetDefinition(retval, &MultiSeqGetDefinition);
  340.     SetGetDate(retval, &MultiSeqGetDate);
  341.     SetGetIsProt(retval, &MultiSeqGetIsProt);
  342.     SetGetSequence(retval, &MultiSeqGetSequence);
  343.     SetGetSeqIdStr(retval, &MultiSeqGetSeqIdStr);
  344.     SetGetSeqId(retval, &MultiSeqGetSeqId);
  345.     SetGetSeqLoc(retval, &MultiSeqGetSeqLoc);
  346.     SetGetSeqLen(retval, &MultiSeqGetSeqLen);
  347.     SetGetNextChunk(retval, &MultiSeqGetNextChunk);
  348.     SetIterNext(retval, &MultiSeqIteratorNext);
  349.     SetGetError(retval, &MultiSeqGetErrorMessage);
  350.     SetRetSequence(retval, &MultiSeqRetSequence);
  351.     return retval;
  352. }
  353. } // extern "C"
  354. BlastSeqSrc* MultiSeqSrcFree(BlastSeqSrc* seq_src)
  355. {
  356.     if (!seq_src) 
  357.         return NULL;
  358.     CMultiSeqInfo* seq_info = static_cast<CMultiSeqInfo*>
  359.                                 (GetDataStructure(seq_src));
  360.     delete seq_info;
  361.     sfree(seq_src);
  362.     return NULL;
  363. }
  364. BlastSeqSrc*
  365. MultiSeqSrcInit(const TSeqLocVector& seq_vector, EProgram program)
  366. {
  367.     BlastSeqSrc* seq_src = NULL;
  368.     BlastSeqSrcNewInfo bssn_info;
  369.     auto_ptr<SMultiSeqSrcNewArgs> args(new SMultiSeqSrcNewArgs);
  370.     args->seq_vector = (TSeqLocVector) seq_vector;
  371.     args->program = program;
  372.     bssn_info.constructor = &MultiSeqSrcNew;
  373.     bssn_info.ctor_argument = (void*) args.get();
  374.     seq_src = BlastSeqSrcNew(&bssn_info);
  375.     ListNode* error_wrap = BLASTSeqSrcGetError(seq_src);
  376.     Blast_Message* error_msg = NULL;
  377.     if (error_wrap && error_wrap->choice == BLAST_SEQSRC_MESSAGE) {
  378.         error_msg = (Blast_Message*) error_wrap->ptr;
  379.         ListNodeFree(error_wrap);
  380.     }
  381.     if (error_msg && error_msg->code < CBlastException::eMaxErrCode) {
  382.         seq_src = BlastSeqSrcFree(seq_src);
  383.         CBlastException::EErrCode code = (CBlastException::EErrCode) error_msg->code;
  384.         string message(error_msg->message);
  385.         Blast_MessageFree(error_msg);
  386.         throw CBlastException(__FILE__, __LINE__, 0, code, message.c_str());
  387.     }
  388.     Blast_MessageFree(error_msg);
  389.     return seq_src;
  390. }
  391. END_SCOPE(blast)
  392. END_NCBI_SCOPE
  393. /* @} */
  394. /*
  395.  * ===========================================================================
  396.  *
  397.  * $Log: multiseq_src.cpp,v $
  398.  * Revision 1000.1  2004/06/01 18:06:13  gouriano
  399.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.16
  400.  *
  401.  * Revision 1.16  2004/05/21 21:41:02  gorelenk
  402.  * Added PCH ncbi_pch.hpp
  403.  *
  404.  * Revision 1.15  2004/04/28 20:09:43  dondosha
  405.  * Commented out unused argument name
  406.  *
  407.  * Revision 1.14  2004/04/28 19:38:20  dondosha
  408.  * Added implementation of BLASTSeqSrcRetSequence function
  409.  *
  410.  * Revision 1.13  2004/03/26 19:18:40  dondosha
  411.  * Minor correction in assigning sequence pointer in returned sequence block
  412.  *
  413.  * Revision 1.12  2004/03/24 22:12:46  dondosha
  414.  * Fixed memory leaks
  415.  *
  416.  * Revision 1.11  2004/03/24 19:14:48  dondosha
  417.  * Fixed memory leaks
  418.  *
  419.  * Revision 1.10  2004/03/23 21:48:34  camacho
  420.  * Avoid memory leak in exceptional conditions
  421.  *
  422.  * Revision 1.9  2004/03/23 18:25:33  dondosha
  423.  * Use auto_ptr and operator new to make sure SMultiSeqSrcNewArgs structure is deleted when no longer needed
  424.  *
  425.  * Revision 1.8  2004/03/23 14:13:52  camacho
  426.  * Moved doxygen comment to header
  427.  *
  428.  * Revision 1.7  2004/03/22 16:15:21  camacho
  429.  * doxygen fix
  430.  *
  431.  * Revision 1.6  2004/03/19 19:22:55  camacho
  432.  * Move to doxygen group AlgoBlast, add missing CVS logs at EOF
  433.  *
  434.  *
  435.  * ===========================================================================
  436.  */