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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: cav_seqset.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:41:21  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: cav_seqset.cpp,v 1000.2 2004/06/01 19:41:21 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. * Authors:  Paul Thiessen
  35. *
  36. * File Description:
  37. *      Classes to hold sets of sequences
  38. *
  39. * ===========================================================================
  40. */
  41. #include <ncbi_pch.hpp>
  42. #include <corelib/ncbistd.hpp>
  43. #include <corelib/ncbistre.hpp>
  44. #include <objects/seq/Bioseq.hpp>
  45. #include <objects/seqloc/Seq_id.hpp>
  46. #include <objects/seqloc/PDB_seq_id.hpp>
  47. #include <objects/seqloc/PDB_mol_id.hpp>
  48. #include <objects/general/Object_id.hpp>
  49. #include <objects/seqset/Bioseq_set.hpp>
  50. #include <objects/seq/Seq_inst.hpp>
  51. #include <objects/seq/Seq_data.hpp>
  52. #include <objects/seq/NCBIeaa.hpp>
  53. #include <objects/seq/IUPACaa.hpp>
  54. #include <objects/seq/NCBI4na.hpp>
  55. #include <objects/seq/NCBI8na.hpp>
  56. #include <objects/seq/NCBI2na.hpp>
  57. #include <objects/seq/IUPACna.hpp>
  58. #include <objects/seq/NCBIstdaa.hpp>
  59. #include <objects/seq/Seq_annot.hpp>
  60. #include <objects/general/Dbtag.hpp>
  61. #include <objects/seqloc/Textseq_id.hpp>
  62. #include <objects/seq/Seq_descr.hpp>
  63. #include <objects/seq/Seqdesc.hpp>
  64. #include <objects/seqblock/PDB_block.hpp>
  65. #include <memory>
  66. #include <objtools/cddalignview/cav_seqset.hpp>
  67. #include <objtools/cddalignview/cddalignview.h>
  68. BEGIN_NCBI_SCOPE
  69. USING_SCOPE(objects);
  70. void SequenceSet::UnpackSeqSet(const CBioseq_set& bss)
  71. {
  72.     CBioseq_set::TSeq_set::const_iterator q, qe = bss.GetSeq_set().end();
  73.     for (q=bss.GetSeq_set().begin(); q!=qe; ++q) {
  74.         if (q->GetObject().IsSeq()) {
  75.             // only store amino acid or nucleotide sequences
  76.             if (q->GetObject().GetSeq().GetInst().GetMol() != CSeq_inst::eMol_aa &&
  77.                 q->GetObject().GetSeq().GetInst().GetMol() != CSeq_inst::eMol_dna &&
  78.                 q->GetObject().GetSeq().GetInst().GetMol() != CSeq_inst::eMol_rna &&
  79.                 q->GetObject().GetSeq().GetInst().GetMol() != CSeq_inst::eMol_na)
  80.                 continue;
  81.             const Sequence *sequence = new Sequence(q->GetObject().GetSeq());
  82.             if (!sequence || sequence->Status() != CAV_SUCCESS) {
  83.                 status = sequence->Status();
  84.                 return;
  85.             }
  86.             sequences.push_back(sequence);
  87.         } else { // Bioseq-set
  88.             UnpackSeqSet(q->GetObject().GetSet());
  89.         }
  90.     }
  91. }
  92. void SequenceSet::UnpackSeqEntry(const CSeq_entry& seqEntry)
  93. {
  94.     if (seqEntry.IsSeq()) {
  95.         const Sequence *sequence = new Sequence(seqEntry.GetSeq());
  96.         if (!sequence || sequence->Status() != CAV_SUCCESS) {
  97.             status = sequence->Status();
  98.             return;
  99.         }
  100.         sequences.push_back(sequence);
  101.     } else { // Bioseq-set
  102.         UnpackSeqSet(seqEntry.GetSet());
  103.     }
  104. }
  105. SequenceSet::SequenceSet(const CSeq_entry& seqEntry) :
  106.     master(NULL), status(CAV_SUCCESS)
  107. {
  108.     UnpackSeqEntry(seqEntry);
  109.     ERR_POST(Info << "number of sequences: " << sequences.size());
  110. }
  111. SequenceSet::SequenceSet(const SeqEntryList& seqEntries) :
  112.     master(NULL), status(CAV_SUCCESS)
  113. {
  114.     SeqEntryList::const_iterator s, se = seqEntries.end();
  115.     for (s=seqEntries.begin(); s!=se; ++s)
  116.         UnpackSeqEntry(s->GetObject());
  117.     ERR_POST(Info << "number of sequences: " << sequences.size());
  118. }
  119. SequenceSet::~SequenceSet(void)
  120. {
  121.     SequenceList::iterator s, se = sequences.end();
  122.     for (s=sequences.begin(); s!=se; ++s) delete *s;
  123. }
  124. const int Sequence::NOT_SET = -1;
  125. #define FIRSTOF2(byte) (((byte) & 0xF0) >> 4)
  126. #define SECONDOF2(byte) ((byte) & 0x0F)
  127. static void StringFrom4na(const vector< char >& vec, string *str, bool isDNA)
  128. {
  129.     if (SECONDOF2(vec.back()) > 0)
  130.         str->resize(vec.size() * 2);
  131.     else
  132.         str->resize(vec.size() * 2 - 1);
  133.     // first, extract 4-bit values
  134.     int i;
  135.     for (i=0; i<vec.size(); ++i) {
  136.         str->at(2*i) = FIRSTOF2(vec[i]);
  137.         if (SECONDOF2(vec[i]) > 0) str->at(2*i + 1) = SECONDOF2(vec[i]);
  138.     }
  139.     // then convert 4-bit values to ascii characters
  140.     for (i=0; i<str->size(); ++i) {
  141.         switch (str->at(i)) {
  142.             case 1: str->at(i) = 'A'; break;
  143.             case 2: str->at(i) = 'C'; break;
  144.             case 4: str->at(i) = 'G'; break;
  145.             case 8: isDNA ? str->at(i) = 'T' : str->at(i) = 'U'; break;
  146.             default:
  147.                 str->at(i) = 'X';
  148.         }
  149.     }
  150. }
  151. #define FIRSTOF4(byte) (((byte) & 0xC0) >> 6)
  152. #define SECONDOF4(byte) (((byte) & 0x30) >> 4)
  153. #define THIRDOF4(byte) (((byte) & 0x0C) >> 2)
  154. #define FOURTHOF4(byte) ((byte) & 0x03)
  155. static void StringFrom2na(const vector< char >& vec, string *str, bool isDNA)
  156. {
  157.     str->resize(vec.size() * 4);
  158.     // first, extract 4-bit values
  159.     int i;
  160.     for (i=0; i<vec.size(); ++i) {
  161.         str->at(4*i) = FIRSTOF4(vec[i]);
  162.         str->at(4*i + 1) = SECONDOF4(vec[i]);
  163.         str->at(4*i + 2) = THIRDOF4(vec[i]);
  164.         str->at(4*i + 3) = FOURTHOF4(vec[i]);
  165.     }
  166.     // then convert 4-bit values to ascii characters
  167.     for (i=0; i<str->size(); ++i) {
  168.         switch (str->at(i)) {
  169.             case 0: str->at(i) = 'A'; break;
  170.             case 1: str->at(i) = 'C'; break;
  171.             case 2: str->at(i) = 'G'; break;
  172.             case 3: isDNA ? str->at(i) = 'T' : str->at(i) = 'U'; break;
  173.         }
  174.     }
  175. }
  176. static void StringFromStdaa(const vector < char >& vec, std::string *str)
  177. {
  178.     static const char *stdaaMap = "-ABCDEFGHIKLMNPQRSTVWXYZU*";
  179.     str->resize(vec.size());
  180.     for (int i=0; i<vec.size(); ++i)
  181.         str->at(i) = stdaaMap[vec[i]];
  182. }
  183. Sequence::Sequence(const CBioseq& bioseq) :
  184.     gi(NOT_SET), pdbChain(' '), mmdbLink(NOT_SET), status(CAV_ERROR_SEQUENCES),
  185.     bioseqASN(&bioseq)
  186. {
  187.     // get Seq-id info
  188.     CBioseq::TId::const_iterator s, se = bioseq.GetId().end();
  189.     for (s=bioseq.GetId().begin(); s!=se; ++s) {
  190.         if (s->GetObject().IsGi()) {
  191.             gi = s->GetObject().GetGi();
  192.         } else if (s->GetObject().IsPdb()) {
  193.             pdbID = s->GetObject().GetPdb().GetMol().Get();
  194.             if (s->GetObject().GetPdb().IsSetChain())
  195.                 pdbChain = s->GetObject().GetPdb().GetChain();
  196.         } else if (s->GetObject().IsLocal() && s->GetObject().GetLocal().IsStr()) {
  197.             pdbID = s->GetObject().GetLocal().GetStr();
  198.         } else if (s->GetObject().IsGenbank() && s->GetObject().GetGenbank().IsSetAccession()) {
  199.             accession = s->GetObject().GetGenbank().GetAccession();
  200.         } else if (s->GetObject().IsSwissprot() && s->GetObject().GetSwissprot().IsSetAccession()) {
  201.             accession = s->GetObject().GetSwissprot().GetAccession();
  202.         }
  203.     }
  204.     if (gi == NOT_SET && pdbID.size() == 0 && accession.size() == 0) {
  205.         ERR_POST(Error << "Sequence::Sequence() - can't parse SeqId");
  206.         return;
  207.     }
  208.     // try to get description from title or compound
  209.     if (bioseq.IsSetDescr()) {
  210.         CSeq_descr::Tdata::const_iterator d, de = bioseq.GetDescr().Get().end();
  211.         for (d=bioseq.GetDescr().Get().begin(); d!=de; ++d) {
  212.             if (d->GetObject().IsTitle()) {
  213.                 description = d->GetObject().GetTitle();
  214.                 break;
  215.             } else if (d->GetObject().IsPdb() && d->GetObject().GetPdb().GetCompound().size() > 0) {
  216.                 description = d->GetObject().GetPdb().GetCompound().front();
  217.                 break;
  218.             }
  219.         }
  220.     }
  221.     // get link to MMDB id - mainly for CDD's where Biostrucs have to be loaded separately
  222.     if (bioseq.IsSetAnnot()) {
  223.         CBioseq::TAnnot::const_iterator a, ae = bioseq.GetAnnot().end();
  224.         for (a=bioseq.GetAnnot().begin(); a!=ae; ++a) {
  225.             if (a->GetObject().GetData().IsIds()) {
  226.                 CSeq_annot::C_Data::TIds::const_iterator i, ie = a->GetObject().GetData().GetIds().end();
  227.                 for (i=a->GetObject().GetData().GetIds().begin(); i!=ie; ++i) {
  228.                     if (i->GetObject().IsGeneral() &&
  229.                         i->GetObject().GetGeneral().GetDb() == "mmdb" &&
  230.                         i->GetObject().GetGeneral().GetTag().IsId()) {
  231.                         mmdbLink = i->GetObject().GetGeneral().GetTag().GetId();
  232.                         break;
  233.                     }
  234.                 }
  235.                 if (i != ie) break;
  236.             }
  237.         }
  238.     }
  239.     if (mmdbLink != NOT_SET)
  240.         ERR_POST(Info << "sequence gi " << gi << ", PDB '" << pdbID << "' chain '" << (char) pdbChain <<
  241.             "', is from MMDB id " << mmdbLink);
  242.     // get sequence string
  243.     if (bioseq.GetInst().GetRepr() == CSeq_inst::eRepr_raw && bioseq.GetInst().IsSetSeq_data()) {
  244.         // protein formats
  245.         if (bioseq.GetInst().GetSeq_data().IsNcbieaa()) {
  246.             sequenceString = bioseq.GetInst().GetSeq_data().GetNcbieaa().Get();
  247.         } else if (bioseq.GetInst().GetSeq_data().IsIupacaa()) {
  248.             sequenceString = bioseq.GetInst().GetSeq_data().GetIupacaa().Get();
  249.         } else if (bioseq.GetInst().GetSeq_data().IsNcbistdaa()) {
  250.             StringFromStdaa(bioseq.GetInst().GetSeq_data().GetNcbistdaa().Get(), &sequenceString);
  251.         }
  252.         // nucleotide formats
  253.         else if (bioseq.GetInst().GetSeq_data().IsIupacna()) {
  254.             sequenceString = bioseq.GetInst().GetSeq_data().GetIupacna().Get();
  255.         } else if (bioseq.GetInst().GetSeq_data().IsNcbi4na()) {
  256.             StringFrom4na(bioseq.GetInst().GetSeq_data().GetNcbi4na().Get(), &sequenceString,
  257.                 (bioseq.GetInst().GetMol() == CSeq_inst::eMol_dna));
  258.         } else if (bioseq.GetInst().GetSeq_data().IsNcbi8na()) {  // same repr. for non-X as 4na
  259.             StringFrom4na(bioseq.GetInst().GetSeq_data().GetNcbi8na().Get(), &sequenceString,
  260.                 (bioseq.GetInst().GetMol() == CSeq_inst::eMol_dna));
  261.         } else if (bioseq.GetInst().GetSeq_data().IsNcbi2na()) {
  262.             StringFrom2na(bioseq.GetInst().GetSeq_data().GetNcbi2na().Get(), &sequenceString,
  263.                 (bioseq.GetInst().GetMol() == CSeq_inst::eMol_dna));
  264.             if (bioseq.GetInst().IsSetLength() && bioseq.GetInst().GetLength() < sequenceString.length())
  265.                 sequenceString.resize(bioseq.GetInst().GetLength());
  266.         }
  267.         else {
  268.             ERR_POST(Critical << "Sequence::Sequence() - sequence " << gi
  269.                 << ": confused by sequence string format");
  270.             return;
  271.         }
  272.         if (bioseq.GetInst().IsSetLength() && bioseq.GetInst().GetLength() != sequenceString.length()) {
  273.             ERR_POST(Critical << "Sequence::Sequence() - sequence string length mismatch");
  274.             return;
  275.         }
  276.     } else {
  277.         ERR_POST(Critical << "Sequence::Sequence() - sequence " << gi
  278.                 << ": confused by sequence representation");
  279.         return;
  280.     }
  281.     status = CAV_SUCCESS;
  282. }
  283. CSeq_id * Sequence::CreateSeqId(void) const
  284. {
  285.     CSeq_id *sid = new CSeq_id();
  286.     if (pdbID.size() > 0) {
  287.         sid->SetPdb().SetMol().Set(pdbID);
  288.         if (pdbChain != ' ') sid->SetPdb().SetChain(pdbChain);
  289.     } else { // use gi
  290.         sid->SetGi(gi);
  291.     }
  292.     return sid;
  293. }
  294. string Sequence::GetTitle(void) const
  295. {
  296.     CNcbiOstrstream oss;
  297.     if (pdbID.size() > 0) {
  298.         oss << pdbID;
  299.         if (pdbChain != ' ') {
  300.             oss <<  '_' << (char) pdbChain;
  301.         }
  302.     } else if (gi != NOT_SET)
  303.         oss << "gi " << gi;
  304.     else if (accession.size() > 0)
  305.         oss << "acc " << accession;
  306.     else
  307.         oss << '?';
  308.     oss << '';
  309. auto_ptr<char> chars(oss.str()); // deletes memory upon function return
  310.     return string(oss.str());
  311. }
  312. END_NCBI_SCOPE
  313. /*
  314. * ---------------------------------------------------------------------------
  315. * $Log: cav_seqset.cpp,v $
  316. * Revision 1000.2  2004/06/01 19:41:21  gouriano
  317. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5
  318. *
  319. * Revision 1.5  2004/05/21 21:42:51  gorelenk
  320. * Added PCH ncbi_pch.hpp
  321. *
  322. * Revision 1.4  2004/05/08 10:56:20  thiessen
  323. * better handling of repeated sequences
  324. *
  325. * Revision 1.3  2004/03/15 18:51:27  thiessen
  326. * prefer prefix vs. postfix ++/-- operators
  327. *
  328. * Revision 1.2  2003/06/02 16:06:41  dicuccio
  329. * Rearranged src/objects/ subtree.  This includes the following shifts:
  330. *     - src/objects/asn2asn --> arc/app/asn2asn
  331. *     - src/objects/testmedline --> src/objects/ncbimime/test
  332. *     - src/objects/objmgr --> src/objmgr
  333. *     - src/objects/util --> src/objmgr/util
  334. *     - src/objects/alnmgr --> src/objtools/alnmgr
  335. *     - src/objects/flat --> src/objtools/flat
  336. *     - src/objects/validator --> src/objtools/validator
  337. *     - src/objects/cddalignview --> src/objtools/cddalignview
  338. * In addition, libseq now includes six of the objects/seq... libs, and libmmdb
  339. * replaces the three libmmdb? libs.
  340. *
  341. * Revision 1.1  2003/03/19 19:04:12  thiessen
  342. * move again
  343. *
  344. * Revision 1.2  2003/03/19 16:06:28  thiessen
  345. * add <memory>
  346. *
  347. * Revision 1.1  2003/03/19 05:33:43  thiessen
  348. * move to src/app/cddalignview
  349. *
  350. * Revision 1.9  2003/02/03 17:52:03  thiessen
  351. * move CVS Log to end of file
  352. *
  353. * Revision 1.8  2002/05/28 17:55:48  thiessen
  354. * cavpr
  355. *
  356. * Revision 1.7  2001/07/12 21:32:13  thiessen
  357. * update for swissprot accessions
  358. *
  359. * Revision 1.6  2001/01/29 18:13:34  thiessen
  360. * split into C-callable library + main
  361. *
  362. * Revision 1.5  2001/01/25 00:51:20  thiessen
  363. * add command-line args; can read asn data from stdin
  364. *
  365. * Revision 1.4  2001/01/23 20:42:01  thiessen
  366. * add description
  367. *
  368. * Revision 1.3  2001/01/23 17:34:12  thiessen
  369. * add HTML output
  370. *
  371. * Revision 1.2  2001/01/22 15:55:11  thiessen
  372. * correctly set up ncbi namespacing
  373. *
  374. * Revision 1.1  2001/01/22 13:15:24  thiessen
  375. * initial checkin
  376. *
  377. */