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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: seq_loader.cpp,v $
  4.  * PRODUCTION Revision 1000.6  2004/06/01 18:05:20  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: seq_loader.cpp,v 1000.6 2004/06/01 18:05:20 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:  Yuri Kapustin
  35. *
  36. * File Description:
  37. *   CSeqLoader class
  38. *
  39. */
  40. #include <ncbi_pch.hpp>
  41. #include "seq_loader.hpp"
  42. #include "splign_app_exception.hpp"
  43. #include <objtools/readers/fasta.hpp>
  44. #include <objects/seqset/Seq_entry.hpp>
  45. #include <objects/seq/Bioseq.hpp>
  46. #include <objects/seqloc/Seq_id.hpp>
  47. #include <objects/seq/Seq_inst.hpp>
  48. #include <objects/seq/Seq_data.hpp>
  49. #include <objects/seq/IUPACna.hpp>
  50. #include <objects/seq/NCBI2na.hpp>
  51. #include <objects/seq/NCBI4na.hpp>
  52. #include <objmgr/object_manager.hpp>
  53. #include <objmgr/scope.hpp>
  54. #include <objmgr/seq_vector.hpp>
  55. #include <string>
  56. #include <algorithm>
  57. #include <memory>
  58. BEGIN_NCBI_SCOPE
  59. USING_SCOPE(objects);
  60. void CSeqLoader::Open(const string& filename_index)
  61. {
  62.   CNcbiIfstream idxstream (filename_index.c_str());
  63.   if(idxstream) {
  64.     // first read file names
  65.     char buf [1024];
  66.     bool found_start = false;
  67.     while(idxstream.good()) {
  68.       buf[0] = 0;
  69.       idxstream.getline(buf, sizeof buf, 'n');
  70.       if(buf[0] == '#') continue;
  71.       if(idxstream.fail()) {
  72. goto throw_file_corrupt;
  73.       }
  74.       if(strcmp(buf,"$$$FI") == 0) {
  75. found_start = true;
  76. break;
  77.       }
  78.     }
  79.     if(!found_start) {
  80. goto throw_file_corrupt;
  81.     }
  82.     vector<string> filenames;
  83.     vector<size_t> indices;
  84.     found_start = false;
  85.     m_min_idx = kMax_UInt;
  86.     while(idxstream.good()) {
  87.       buf[0] = 0;
  88.       idxstream.getline(buf, sizeof buf, 'n');
  89.       if(strcmp("$$$SI", buf) == 0) {
  90. found_start = true;
  91. break;
  92.       }
  93.       if(buf[0] == '#' || buf[0] == 0) {
  94. continue;
  95.       }
  96.       CNcbiIstrstream iss (buf);
  97.       size_t idx = kMax_UInt;
  98.       string name;
  99.       iss >> name >> idx;
  100.       if(idx == kMax_UInt) {
  101. goto throw_file_corrupt;
  102.       }
  103.       filenames.push_back(name);
  104.       indices.push_back(idx);
  105.       if(idx < m_min_idx) {
  106. m_min_idx = idx;
  107.       }
  108.     }
  109.     if(!found_start) goto throw_file_corrupt;
  110.     const size_t fndim = filenames.size();
  111.     m_filenames.resize(fndim);
  112.     for(size_t i = 0; i < fndim; ++i) {
  113.       m_filenames[indices[i] - m_min_idx] = filenames[i];
  114.     }
  115.     m_idx.clear();
  116.     while(idxstream.good()) {
  117.       buf[0] = 0;
  118.       idxstream.getline(buf, sizeof buf, 'n');
  119.       if(buf[0] == '#') continue; // skip comments
  120.       if(idxstream.eof()) break;
  121.       if(idxstream.fail()) {
  122. goto throw_file_corrupt;
  123.       }
  124.       CNcbiIstrstream iss (buf);
  125.       string id;
  126.       SIdxTarget s;
  127.       iss >> id >> s.m_filename_idx >> s.m_offset;
  128.       if(s.m_offset == kMax_UInt) {
  129. goto throw_file_corrupt;
  130.       }
  131.       m_idx[id] = s;
  132.     }
  133.     return;
  134.   }
  135.   else {      
  136.     NCBI_THROW(
  137.        CSplignAppException,
  138.        eCannotOpenFile,
  139.        filename_index.c_str());
  140.   }
  141.  throw_file_corrupt: {
  142.     NCBI_THROW(
  143.        CSplignAppException,
  144.        eErrorReadingIndexFile,
  145.        "File is corrupt");
  146.   }
  147. }
  148. void CSeqLoader::Load(const string& id, vector<char>* seq,
  149.       size_t from, size_t to)
  150. {
  151.   if(seq == 0) {
  152.     NCBI_THROW(
  153.                CSplignAppException,
  154.                eInternal,
  155.                "Null pointer passed to CSeqLoader::Load()");
  156.     
  157.   }
  158.   
  159.   auto_ptr<istream> input (0);
  160.   map<string, SIdxTarget>::const_iterator im = m_idx.find(id);
  161.   if(im == m_idx.end()) {
  162.     string msg ("Unable to locate ");
  163.     msg += id;
  164.     NCBI_THROW(
  165.        CSplignAppException,
  166.        eInternal,
  167.        msg.c_str());
  168.   }
  169.   else {
  170.     const string& filename = m_filenames[im->second.m_filename_idx-m_min_idx];
  171.     input.reset(new ifstream (filename.c_str()));
  172.     input->seekg(im->second.m_offset);
  173.   }
  174.   
  175.   char buf [1024];
  176.   input->getline(buf, sizeof buf, 'n'); // info line
  177.   if(input->fail()) {
  178.     NCBI_THROW(
  179.        CSplignAppException,
  180.        eCannotReadFile,
  181.        "Unable to read sequence data");
  182.   }
  183.   seq->clear();
  184.   if(from == 0 && to == kMax_UInt) {
  185.     // read entire sequence until the next one or eof
  186.     while(*input) {
  187.       CT_POS_TYPE i0 = input->tellg();
  188.       input->getline(buf, sizeof buf, 'n');
  189.       if(!*input) {
  190. break;
  191.       }
  192.       CT_POS_TYPE i1 = input->tellg();
  193.       if(i1 - i0 > 1) {
  194. CT_OFF_TYPE line_size = i1 - i0;
  195. line_size = line_size - 1;
  196. if(buf[0] == '>') break;
  197. size_t size_old = seq->size();
  198. seq->resize(size_old + line_size);
  199. transform(buf, buf + line_size, seq->begin() + size_old,
  200.                   (int(*)(int))toupper);
  201.       }
  202.       else if (i0 == i1) {
  203. break; // GCC hack
  204.       }
  205.     }
  206.   }
  207.   else {
  208.     // read only a portion of a sequence
  209.     const size_t dst_seq_len = to - from + 1;
  210.     seq->resize(dst_seq_len + sizeof buf);
  211.     CT_POS_TYPE i0 = input->tellg(), i1;
  212.     CT_OFF_TYPE dst_read = 0, src_read = 0;
  213.     while(*input) {
  214.       input->getline(buf, sizeof buf, 'n');
  215.       if(buf[0] == '>' || !*input) {
  216. seq->resize(dst_read);
  217. return;
  218.       }
  219.       i1 = input->tellg();
  220.       CT_OFF_TYPE off = i1 - i0;
  221.       if (off > 1) {
  222. src_read += off - 1;
  223.       }
  224.       else if (off == 1) {
  225. continue;
  226.       }
  227.       else { 
  228. break; // GCC hack
  229.       }
  230.       if(src_read > CT_OFF_TYPE(from)) {
  231. CT_OFF_TYPE line_size = i1 - i0;
  232. line_size = line_size - 1;
  233. size_t start  = dst_read? 0: (line_size - (src_read - from));
  234. size_t finish = (src_read > CT_OFF_TYPE(to))?
  235.                 (line_size - (src_read - to) + 1):
  236.                 (size_t)line_size;
  237. transform(buf + start, buf + finish, seq->begin() + dst_read,
  238.                   (int(*)(int))toupper);
  239. dst_read += finish - start;
  240. if(dst_read >= CT_OFF_TYPE(dst_seq_len)) {
  241.   seq->resize(dst_seq_len);
  242.   return;
  243. }
  244.       }
  245.       i0 = i1;
  246.     }
  247.     seq->resize(dst_read);
  248.   }
  249. }
  250. CSeqLoaderPairwise::CSeqLoaderPairwise(const string& query_filename,
  251.                                        const string& subj_filename)
  252. {
  253.     CRef<CObjectManager> objmgr (new CObjectManager);
  254.     // load query (the spliced sequence)
  255.     CRef<CScope> scope_query (new CScope(*objmgr));
  256.     scope_query->AddDefaults();    
  257.     {{
  258.     CNcbiIfstream istream (query_filename.c_str());
  259.     CRef<CSeq_entry> se = ReadFasta(istream, fReadFasta_OneSeq);
  260.     scope_query->AddTopLevelSeqEntry(*se);
  261.     const CSeq_entry::TSeq& bioseq = se->GetSeq();    
  262.     const CSeq_entry::TSeq::TId& seqid = bioseq.GetId();
  263.     m_QueryId = seqid.front()->GetSeqIdString(true);    
  264.     m_se_query = se;
  265.     CBioseq_Handle bh = scope_query->GetBioseqHandle(*seqid.front());
  266.     CSeqVector sv = bh.GetSeqVector(CBioseq_Handle::eCoding_Iupac);
  267.     size_t dim = sv.size();
  268.     m_Query.resize(dim);
  269.     for(size_t i = 0; i < dim; ++i) {
  270.         m_Query[i] = sv[i];
  271.     }
  272.     }}
  273.     // load subj (the genomic sequence)
  274.     CRef<CScope> scope_subj (new CScope(*objmgr));
  275.     scope_subj->AddDefaults();    
  276.     {{
  277.     CNcbiIfstream istream (subj_filename.c_str());
  278.     CRef<CSeq_entry> se = ReadFasta(istream, fReadFasta_OneSeq);
  279.     scope_subj->AddTopLevelSeqEntry(*se);
  280.     const CSeq_entry::TSeq& bioseq = se->GetSeq();    
  281.     const CSeq_entry::TSeq::TId& seqid = bioseq.GetId();
  282.     m_SubjId = seqid.front()->GetSeqIdString(true);    
  283.     m_se_subj = se;
  284.     CBioseq_Handle bh = scope_subj->GetBioseqHandle(*seqid.front());
  285.     CSeqVector sv = bh.GetSeqVector(CBioseq_Handle::eCoding_Iupac);
  286.     size_t dim = sv.size();
  287.     m_Subj.resize(dim);
  288.     for(size_t i = 0; i < dim; ++i) {
  289.         m_Subj[i] = sv[i];
  290.     }
  291.     }}
  292. }
  293. void CSeqLoaderPairwise::Load(const string& id, vector<char> *seq,
  294.                               size_t start, size_t finish)
  295. {
  296.     if(seq == 0) {
  297.         NCBI_THROW( CSplignAppException,
  298.                     eInternal,
  299.                     "Null pointer passed to CSeqLoader::Load()");
  300.     }
  301.     if(start > finish) {
  302.         NCBI_THROW( CSplignAppException,
  303.                     eBadParameter,
  304.                     "Inconsistent parameters passed to passed to "
  305.                     "CSeqLoaderPairwise::Load()");
  306.     }
  307.     seq->clear();
  308.     vector<char>::const_iterator i0, i1;
  309.     if(id == m_QueryId) {
  310.         const size_t dim = m_Query.size();
  311.         if(start >= dim) {
  312.             return;
  313.         }
  314.         i0 = m_Query.begin() + start;
  315.         i1 = m_Query.begin() + (finish < dim? finish + 1: dim);
  316.     }
  317.     else if(id == m_SubjId) {
  318.         const size_t dim = m_Subj.size();
  319.         if(start >= dim) {
  320.             return;
  321.         }
  322.         i0 = m_Subj.begin() + start;
  323.         i1 = m_Subj.begin() + (finish < dim? finish + 1: dim);
  324.     }
  325.     else {
  326.         NCBI_THROW( CSplignAppException,
  327.                     eGeneral,
  328.                     "Unknolwn sequence requested from "
  329.                     "CSeqLoaderPairwise::Load()");
  330.     }
  331.     seq->resize(i1 - i0);
  332.     copy(i0, i1, seq->begin());
  333. }
  334. END_NCBI_SCOPE
  335. /*
  336.  * ===========================================================================
  337.  * $Log: seq_loader.cpp,v $
  338.  * Revision 1000.6  2004/06/01 18:05:20  gouriano
  339.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.17
  340.  *
  341.  * Revision 1.17  2004/05/21 21:41:02  gorelenk
  342.  * Added PCH ncbi_pch.hpp
  343.  *
  344.  * Revision 1.16  2004/05/10 21:50:03  kapustin
  345.  * Fixed some MSVC6.0 incompatibility issues
  346.  *
  347.  * Revision 1.15  2004/05/10 16:39:56  kapustin
  348.  * Add a pairwise mode sequence loader
  349.  *
  350.  * Revision 1.14  2004/04/23 14:33:32  kapustin
  351.  * *** empty log message ***
  352.  *
  353.  * Revision 1.12  2004/02/20 00:26:18  ucko
  354.  * Tweak previous fix for portability.
  355.  *
  356.  * Revision 1.11  2004/02/19 22:57:54  ucko
  357.  * Accommodate stricter implementations of CT_POS_TYPE.
  358.  *
  359.  * Revision 1.10  2004/02/18 16:04:16  kapustin
  360.  * Support lower case input sequences
  361.  *
  362.  * Revision 1.9  2003/12/09 13:20:50  ucko
  363.  * +<memory> for auto_ptr
  364.  *
  365.  * Revision 1.8  2003/12/03 19:45:33  kapustin
  366.  * Keep min index value to support non-zero based index
  367.  *
  368.  * Revision 1.7  2003/11/20 17:58:20  kapustin
  369.  * Make the code msvc6.0-friendly
  370.  *
  371.  * Revision 1.6  2003/11/14 13:13:29  ucko
  372.  * Fix #include directives: +<memory> for auto_ptr; -<fstream>
  373.  * (redundant, and seq_loader.hpp should be the first anyway)
  374.  *
  375.  * Revision 1.5  2003/11/06 02:07:41  kapustin
  376.  * Fix NCB_THROW usage
  377.  *
  378.  * Revision 1.4  2003/11/05 20:32:10  kapustin
  379.  * Include source information into the index
  380.  *
  381.  * Revision 1.2  2003/10/31 19:43:15  kapustin
  382.  * Format and compatibility update
  383.  *
  384.  * ===========================================================================
  385.  */