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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: Seq_id.cpp,v $
  4.  * PRODUCTION Revision 1000.4  2004/06/01 19:34:28  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.81
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* $Id: Seq_id.cpp,v 1000.4 2004/06/01 19:34:28 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:  .......
  35.  *
  36.  * File Description:
  37.  *   .......
  38.  *
  39.  * Remark:
  40.  *   This code was originally generated by application DATATOOL
  41.  *   using specifications from the ASN data definition file
  42.  *   'seqloc.asn'.
  43.  */
  44. // standard includes
  45. // generated includes
  46. #include <ncbi_pch.hpp>
  47. #include <corelib/ncbiutil.hpp>
  48. #include <objects/seq/Bioseq.hpp>
  49. #include <objects/seq/Seq_inst.hpp>
  50. #include <objects/seqloc/Seq_id.hpp>
  51. #include <objects/seqloc/Textseq_id.hpp>
  52. #include <objects/seqloc/Giimport_id.hpp>
  53. #include <objects/seqloc/Patent_seq_id.hpp>
  54. #include <objects/seqloc/PDB_seq_id.hpp>
  55. #include <objects/biblio/Id_pat.hpp>
  56. #include <objects/general/Object_id.hpp>
  57. #include <objects/general/Dbtag.hpp>
  58. #include <objects/general/Date.hpp>
  59. #include <objects/general/Date_std.hpp>
  60. #include <objects/general/Date.hpp>
  61. // generated classes
  62. BEGIN_NCBI_SCOPE
  63. BEGIN_objects_SCOPE // namespace ncbi::objects::
  64. // constructor
  65. CSeq_id::CSeq_id(void)
  66. {
  67.     return;
  68. }
  69. // destructor
  70. CSeq_id::~CSeq_id(void)
  71. {
  72.     return;
  73. }
  74. const CTextseq_id* CSeq_id::GetTextseq_Id(void) const
  75. {
  76.     switch ( Which() ) {
  77.     case e_Genbank:
  78.         return &GetGenbank();
  79.     case e_Embl:
  80.         return &GetEmbl();
  81.     case e_Ddbj:
  82.         return &GetDdbj();
  83.     case e_Pir:
  84.         return &GetPir();
  85.     case e_Swissprot:
  86.         return &GetSwissprot();
  87.     case e_Other:
  88.         return &GetOther();
  89.     case e_Prf:
  90.         return &GetPrf();
  91.     case e_Tpg:
  92.         return &GetTpg();
  93.     case e_Tpe:
  94.         return &GetTpe();
  95.     case e_Tpd:
  96.         return &GetTpd();
  97.     default:
  98.         return 0;
  99.     }
  100. }
  101. inline
  102. void x_Assign(CObject_id& dst, const CObject_id& src)
  103. {
  104.     switch ( src.Which() ) {
  105.     case CObject_id::e_not_set:
  106.         dst.Reset();
  107.         return;
  108.     case CObject_id::e_Id:
  109.         dst.SetId(src.GetId());
  110.         return;
  111.     case CObject_id::e_Str:
  112.         dst.SetStr(src.GetStr());
  113.         return;
  114.     default:
  115.         THROW1_TRACE(runtime_error, "invalid Object-id variant");
  116.     }
  117. }
  118. inline
  119. void x_Assign(CGiimport_id& dst, const CGiimport_id& src)
  120. {
  121.     dst.SetId(src.GetId());
  122.     if ( src.IsSetDb() ) {
  123.         dst.SetDb(src.GetDb());
  124.     }
  125.     else {
  126.         dst.ResetDb();
  127.     }
  128.     if ( src.IsSetRelease() ) {
  129.         dst.SetRelease(src.GetRelease());
  130.     }
  131.     else {
  132.         dst.ResetRelease();
  133.     }
  134. }
  135. inline
  136. void x_Assign(CTextseq_id& dst, const CTextseq_id& src)
  137. {
  138.     if ( src.IsSetName() ) {
  139.         dst.SetName(src.GetName());
  140.     }
  141.     else {
  142.         dst.ResetName();
  143.     }
  144.     if ( src.IsSetAccession() ) {
  145.         dst.SetAccession(src.GetAccession());
  146.     }
  147.     else {
  148.         dst.ResetAccession();
  149.     }
  150.     if ( src.IsSetRelease() ) {
  151.         dst.SetRelease(src.GetRelease());
  152.     }
  153.     else {
  154.         dst.ResetRelease();
  155.     }
  156.     if ( src.IsSetVersion() ) {
  157.         dst.SetVersion(src.GetVersion());
  158.     }
  159.     else {
  160.         dst.ResetVersion();
  161.     }
  162. }
  163. inline
  164. void x_Assign(CDbtag& dst, const CDbtag& src)
  165. {
  166.     dst.SetDb(src.GetDb());
  167.     x_Assign(dst.SetTag(), src.GetTag());
  168. }
  169. inline
  170. void x_Assign(CPatent_seq_id& dst, const CPatent_seq_id& src)
  171. {
  172.     dst.SetSeqid(src.GetSeqid());
  173.     dst.SetCit().Assign(src.GetCit());
  174. }
  175. inline
  176. void x_Assign(CDate& dst, const CDate& src)
  177. {
  178.     dst.Assign(src);
  179. }
  180. inline
  181. void x_Assign(CPDB_seq_id& dst, const CPDB_seq_id& src)
  182. {
  183.     dst.SetMol().Set(src.GetMol());
  184.     if ( src.IsSetChain() ) {
  185.         dst.SetChain(src.GetChain());
  186.     }
  187.     else {
  188.         dst.ResetChain();
  189.     }
  190.     if ( src.IsSetRel() ) {
  191.         dst.SetRel().Assign(src.GetRel());
  192.     }
  193.     else {
  194.         dst.ResetRel();
  195.     }
  196. }
  197. void CSeq_id::Assign(const CSerialObject& obj, ESerialRecursionMode how)
  198. {
  199.     if ( GetTypeInfo() == obj.GetThisTypeInfo() ) {
  200.         const CSeq_id& id = static_cast<const CSeq_id&>(obj);
  201.         switch ( id.Which() ) {
  202.         case e_not_set:
  203.             Reset();
  204.             return;
  205.         case e_Local:
  206.             x_Assign(SetLocal(), id.GetLocal());
  207.             return;
  208.         case e_Gibbsq:
  209.             SetGibbsq(id.GetGibbsq());
  210.             return;
  211.         case e_Gibbmt:
  212.             SetGibbmt(id.GetGibbmt());
  213.             return;
  214.         case e_Giim:
  215.             x_Assign(SetGiim(), id.GetGiim());
  216.             return;
  217.         case e_Pir:
  218.             x_Assign(SetPir(), id.GetPir());
  219.             return;
  220.         case e_Swissprot:
  221.             x_Assign(SetSwissprot(), id.GetSwissprot());
  222.             return;
  223.         case e_Patent:
  224.             x_Assign(SetPatent(), id.GetPatent());
  225.             return;
  226.         case e_Other:
  227.             x_Assign(SetOther(), id.GetOther());
  228.             return;
  229.         case e_General:
  230.             x_Assign(SetGeneral(), id.GetGeneral());
  231.             return;
  232.         case e_Gi:
  233.             SetGi(id.GetGi());
  234.             return;
  235.         case e_Prf:
  236.             x_Assign(SetPrf(), id.GetPrf());
  237.             return;
  238.         case e_Pdb:
  239.             x_Assign(SetPdb(), id.GetPdb());
  240.             return;
  241.         case e_Genbank:
  242.             x_Assign(SetGenbank(), id.GetGenbank());
  243.             return;
  244.         case e_Embl:
  245.             x_Assign(SetEmbl(), id.GetEmbl());
  246.             return;
  247.         case e_Ddbj:
  248.             x_Assign(SetDdbj(), id.GetDdbj());
  249.             return;
  250.         case e_Tpg:
  251.             x_Assign(SetTpg(), id.GetTpg());
  252.             return;
  253.         case e_Tpe:
  254.             x_Assign(SetTpe(), id.GetTpe());
  255.             return;
  256.         case e_Tpd:
  257.             x_Assign(SetTpd(), id.GetTpd());
  258.             return;
  259.         }
  260.     }
  261.     CSerialObject::Assign(obj, how);
  262. }
  263. // Compare() - are SeqIds equivalent?
  264. CSeq_id::E_SIC CSeq_id::Compare(const CSeq_id& sid2) const
  265. {
  266.     if ( Which() != sid2.Which() ) { // Only one case where this will work
  267.         const CTextseq_id *tsip1 = GetTextseq_Id();
  268.         if ( !tsip1 )
  269.             return e_DIFF;
  270.         const CTextseq_id *tsip2 = sid2.GetTextseq_Id();
  271.         if ( !tsip2 )
  272.             return e_DIFF;
  273.         if ( tsip1->Match(*tsip2) ) // id Textseq_id match
  274.             return e_YES;
  275.         else
  276.             return e_NO;
  277.     }
  278.     switch ( Which() ) { // Now we only need to know one
  279.     case e_Local:
  280.         return GetLocal().Match(sid2.GetLocal()) ? e_YES : e_NO;
  281.     case e_Gibbsq:
  282.         return GetGibbsq() == sid2.GetGibbsq() ? e_YES : e_NO;
  283.     case e_Gibbmt:
  284.         return GetGibbmt() == sid2.GetGibbmt() ? e_YES : e_NO;
  285.     case e_Giim:
  286.         return GetGiim().GetId() == sid2.GetGiim().GetId() ? e_YES : e_NO;
  287.     case e_Pir:
  288.         return GetPir().Match(sid2.GetPir()) ? e_YES : e_NO;
  289.     case e_Swissprot:
  290.         return GetSwissprot().Match(sid2.GetSwissprot()) ? e_YES : e_NO;
  291.     case e_Patent:
  292.         return GetPatent().Match(sid2.GetPatent()) ? e_YES : e_NO;
  293.     case e_Other:
  294.         return GetOther().Match(sid2.GetOther()) ? e_YES : e_NO;
  295.     case e_General:
  296.         return GetGeneral().Match(sid2.GetGeneral()) ? e_YES : e_NO;
  297.     case e_Gi:
  298.         return GetGi() == sid2.GetGi() ? e_YES : e_NO;
  299.     case e_Prf:
  300.         return GetPrf().Match(sid2.GetPrf()) ? e_YES : e_NO;
  301.     case e_Pdb:
  302.         return GetPdb().Match(sid2.GetPdb()) ? e_YES : e_NO;
  303.     case e_Genbank:
  304.         return GetGenbank().Match(sid2.GetGenbank()) ? e_YES : e_NO;
  305.     case e_Embl:
  306.         return GetEmbl().Match(sid2.GetEmbl()) ? e_YES : e_NO;
  307.     case e_Ddbj:
  308.         return GetDdbj().Match(sid2.GetDdbj()) ? e_YES : e_NO;
  309.     case e_Tpg:
  310.         return GetTpg().Match(sid2.GetTpg()) ? e_YES : e_NO;
  311.     case e_Tpe:
  312.         return GetTpe().Match(sid2.GetTpe()) ? e_YES : e_NO;
  313.     case e_Tpd:
  314.         return GetTpd().Match(sid2.GetTpd()) ? e_YES : e_NO;
  315.     default:
  316.         return e_error;
  317.     }
  318. }
  319. int CSeq_id::CompareOrdered(const CSeq_id& sid2) const
  320. {
  321.     int ret = Which() - sid2.Which();
  322.     if ( ret != 0 ) {
  323.         return ret;
  324.     }
  325.     const CTextseq_id *tsip1 = GetTextseq_Id();
  326.     const CTextseq_id *tsip2 = sid2.GetTextseq_Id();
  327.     if ( tsip1 && tsip2 ) {
  328.         return tsip1->Compare(*tsip2);
  329.     }
  330.     switch ( Which() ) { // Now we only need to know one
  331.     case e_Local:
  332.         return GetLocal().Compare(sid2.GetLocal());
  333.     case e_Gibbsq:
  334.         return GetGibbsq() - sid2.GetGibbsq();
  335.     case e_Gibbmt:
  336.         return GetGibbmt() - sid2.GetGibbmt();
  337.     case e_Giim:
  338.         return GetGiim().GetId() - sid2.GetGiim().GetId();
  339.     case e_Patent:
  340.         return GetPatent().Compare(sid2.GetPatent());
  341.     case e_General:
  342.         return GetGeneral().Compare(sid2.GetGeneral());
  343.     case e_Gi:
  344.         return GetGi() - sid2.GetGi();
  345.     case e_Pdb:
  346.         return 0;
  347.     default:
  348.         return this == &sid2? 0: this < &sid2? -1: 1;
  349.     }
  350. }
  351. static const char* const s_TextId[20] = {   // FASTA_LONG formats
  352.     "???" , // not-set = ???
  353.     "lcl",  // local = lcl|integer or string
  354.     "bbs",  // gibbsq = bbs|integer
  355.     "bbm",  // gibbmt = bbm|integer
  356.     "gim",  // giim = gim|integer
  357.     "gb", // genbank = gb|accession|locus
  358.     "emb",  // embl = emb|accession|locus
  359.     "pir",  // pir = pir|accession|name
  360.     "sp", // swissprot = sp|accession|name
  361.     "pat",  // patent = pat|country|patent number (string)|seq number (integer)
  362.     "ref",  // other = ref|accession|name|release - changed from oth to ref
  363.     "gnl",  // general = gnl|database(string)|id (string or number)
  364.     "gi", // gi = gi|integer
  365.     "dbj",  // ddbj = dbj|accession|locus
  366.     "prf",  // prf = prf|accession|name
  367.     "pdb",  // pdb = pdb|entry name (string)|chain id (char)
  368.     "tpg",  // tpg = tpg|accession|name
  369.     "tpe",  // tpe = tpe|accession|name
  370.     "tpd",  // tpd = tpd|accession|name
  371.     ""  // Placeholder for end of list
  372. };
  373. CSeq_id::E_Choice CSeq_id::WhichInverseSeqId(const char* SeqIdCode)
  374. {
  375.     int retval = 0;
  376.     int dex;
  377.     // Last item in list has null byte for first character, so
  378.     // *s_TextId[dex] will be zero at end.
  379.     for (dex = 0;  *s_TextId[dex];  dex++) {
  380.         if ( !NStr::CompareNocase(s_TextId[dex], SeqIdCode) ) {
  381.             break;
  382.         }
  383.     }
  384.     if ( !*s_TextId[dex] ) {
  385.         retval = 0;
  386.     } else {
  387.         retval = dex;
  388.     }
  389.     return static_cast<CSeq_id_Base::E_Choice> (retval);
  390. }
  391. static CSeq_id::EAccessionInfo s_IdentifyNAcc(const string& acc)
  392. {
  393.     _ASSERT(acc[0] == 'N');
  394.     int n = NStr::StringToInt(acc.substr(1), 10, NStr::eCheck_Skip);
  395.     if (n >= 20000) {
  396.         return CSeq_id::eAcc_gb_est;
  397.     } else { // big mess; fortunately, these are all secondary
  398.         switch (n) {
  399.         case 1: case 2: case 11: case 57:
  400.             return CSeq_id::eAcc_gb_embl;
  401.         case 3: case 4: case 6: case 7: case 10: case 14: case 15:
  402.         case 16: case 17: case 21: case 23: case 24: case 26: case 29:
  403.         case 30: case 31: case 32: case 33: case 34: case 36: case 38:
  404.         case 39: case 40: case 42: case 43: case 44: case 45: case 47:
  405.         case 49: case 50: case 51: case 55: case 56: case 59:
  406.             return CSeq_id::eAcc_gb_ddbj;
  407.         case 5: case 9: case 12: case 20: case 22: case 25: case 58:
  408.             return CSeq_id::eAcc_gb_embl_ddbj;
  409.         case 8: case 13: case 18: case 19: case 27: case 41: case 46:
  410.         case 48: case 52: case 54: case 18624:
  411.             return CSeq_id::eAcc_gb_other_nuc;
  412.         case 28: case 35: case 37: case 53: case 61: case 62: case 63:
  413.         case 65: case 66: case 67: case 68: case 69: case 78: case 79:
  414.         case 83: case 88: case 90: case 91: case 92: case 93: case 94:
  415.             return CSeq_id::eAcc_ddbj_other_nuc;
  416.         case 60: case 64:
  417.             return CSeq_id::eAcc_embl_other_nuc;
  418.         case 70:
  419.             return CSeq_id::eAcc_embl_ddbj;
  420.         default: // unassigned or ambiguous
  421.             return CSeq_id::eAcc_unknown;
  422.         }
  423.     }
  424. }
  425. CSeq_id::EAccessionInfo CSeq_id::IdentifyAccession(const string& acc)
  426. {
  427.     SIZE_TYPE digit_pos = acc.find_first_of("0123456789");
  428.     if (digit_pos == NPOS) {
  429.         return eAcc_unknown;
  430.     }
  431.     SIZE_TYPE main_size = acc.find('.');
  432.     if (main_size == NPOS) {
  433.         main_size = acc.size();
  434.     }
  435.     string pfx = acc.substr(0, digit_pos);
  436.     NStr::ToUpper(pfx);
  437.     switch (pfx.size()) {
  438.     case 0:
  439.         if (acc.find_first_not_of("0123456789") == NPOS) { // just digits
  440.             return eAcc_gi;
  441.         } else if (main_size == 4  ||  (main_size > 4  &&  acc[4] == '|')) {
  442.             return eAcc_pdb;
  443.         } else {
  444.             return eAcc_unknown;
  445.         }
  446.     case 1:
  447.         switch (pfx[0]) {
  448.         case 'A':                                return eAcc_embl_patent;
  449.         case 'B':                                return eAcc_gb_gss;
  450.         case 'C':                                return eAcc_ddbj_est;
  451.         case 'D':                                return eAcc_ddbj_dirsub;
  452.         case 'E':                                return eAcc_ddbj_patent;
  453.         case 'F':                                return eAcc_embl_est;
  454.         case 'G':                                return eAcc_gb_sts;
  455.         case 'H': case 'R': case 'T': case 'W':  return eAcc_gb_est;
  456.         case 'I':                                return eAcc_gb_patent;
  457.         case 'J': case 'K': case 'L': case 'M':  return eAcc_gsdb_dirsub;
  458.         case 'N':                                return s_IdentifyNAcc(acc);
  459.         case 'O': case 'P': case 'Q':            return eAcc_swissprot;
  460.         case 'S':                                return eAcc_gb_backbone;
  461.         case 'U':                                return eAcc_gb_dirsub;
  462.         case 'V': case 'X': case 'Y': case 'Z':  return eAcc_embl_dirsub;
  463.         default:                                 return eAcc_unreserved_nuc;
  464.         }
  465.     case 2:
  466.         switch (pfx[0]) {
  467.         case 'A':
  468.             switch (pfx[1]) {
  469.             case 'A': case 'I': case 'W': return eAcc_gb_est;
  470.             case 'B':                     return eAcc_ddbj_dirsub;
  471.             case 'C':                     return eAcc_gb_htgs;
  472.             case 'D':                     return eAcc_gb_gsdb;
  473.             case 'E':                     return eAcc_gb_genome;
  474.             case 'F': case 'Y':           return eAcc_gb_dirsub;
  475.             case 'G': case 'P':           return eAcc_ddbj_genome;
  476.             case 'H':                     return eAcc_gb_con;
  477.             case 'J': case 'M':           return eAcc_embl_dirsub;
  478.             case 'K':                     return eAcc_ddbj_htgs;
  479.             case 'L':                     return eAcc_embl_genome;
  480.             case 'N':                     return eAcc_embl_con;
  481.             case 'Q': case 'Z':           return eAcc_gb_gss;
  482.             case 'R':                     return eAcc_gb_patent;
  483.             case 'S':                     return eAcc_gb_other_nuc;
  484.             case 'T': case 'U': case 'V': return eAcc_ddbj_est;
  485.             case 'X':                     return eAcc_embl_patent;
  486.             default:                      return eAcc_unreserved_nuc;
  487.             }
  488.         case 'B':
  489.             switch (pfx[1]) {
  490.             case 'A':                               return eAcc_ddbj_con;
  491.             case 'B': case 'J': case 'P': case 'W':
  492.             case 'Y':                               return eAcc_ddbj_est;
  493.             case 'C': case 'T':                     return eAcc_gb_cdna;
  494.             case 'D':                               return eAcc_ddbj_patent;
  495.             case 'E': case 'F': case 'G': case 'I':
  496.             case 'M': case 'Q': case 'U':           return eAcc_gb_est;
  497.             case 'H': case 'Z':                     return eAcc_gb_gss;
  498.             case 'K': case 'L':                     return eAcc_gb_tpa_nuc;
  499.             case 'N':                               return eAcc_embl_tpa_nuc;
  500.             case 'R':                               return eAcc_ddbj_tpa_nuc;
  501.             case 'S':                               return eAcc_ddbj_genome;
  502.                 // BS is actually chimp genomes.
  503.             case 'V':                               return eAcc_gb_sts;
  504.             case 'X':                               return eAcc_embl_genome;
  505.             default:                                return eAcc_unreserved_nuc;
  506.             }
  507.         case 'C':
  508.             switch (pfx[1]) {
  509.             case 'A': case 'B': case 'D': case 'F':
  510.             case 'K': case 'N':                     return eAcc_gb_est;
  511.             case 'C': case 'E': case 'G': case 'L': return eAcc_gb_gss;
  512.             case 'H': case 'M':                     return eAcc_gb_con;
  513.             case 'I': case 'J':                     return eAcc_ddbj_est;
  514.                 // no specific assignment for CO-CP yet
  515.             case 'O': case 'P':                     return eAcc_gb_other_nuc;
  516.             case 'Q':                               return eAcc_embl_patent;
  517.             case 'R':                               return eAcc_embl_genome;
  518.             case 'S': case 'T': case 'U':           return eAcc_embl_other_nuc;
  519.             default:                                return eAcc_unreserved_nuc;
  520.             }
  521.         default: return eAcc_unreserved_nuc;
  522.         }
  523.     case 3:
  524.         if (pfx[2] == '_') { // refseq-style
  525.             if      (pfx == "NC_") { return eAcc_refseq_chromosome;      }
  526.             else if (pfx == "NG_") { return eAcc_refseq_genomic;         }
  527.             else if (pfx == "NM_") { return eAcc_refseq_mrna;            }
  528.             else if (pfx == "NP_") { return eAcc_refseq_prot;            }
  529.             else if (pfx == "NR_") { return eAcc_refseq_ncrna;           }
  530.             else if (pfx == "NS_") { return eAcc_refseq_genome; /* ? */  }
  531.             else if (pfx == "NT_") { return eAcc_refseq_contig;          }
  532.             else if (pfx == "NW_") { return eAcc_refseq_wgs_intermed;    }
  533.             // else if (pfx == "NZ_") { return eAcc_refseq_wgs_nuc;         }
  534.             else if (pfx == "XM_") { return eAcc_refseq_mrna_predicted;  }
  535.             else if (pfx == "XP_") { return eAcc_refseq_prot_predicted;  }
  536.             else if (pfx == "XR_") { return eAcc_refseq_ncrna_predicted; }
  537.             else if (pfx == "ZP_") { return eAcc_refseq_wgs_prot;        }
  538.             else                   { return eAcc_refseq_unreserved;      }
  539.         } else { // protein
  540.             switch (pfx[0]) {
  541.             case 'A': return (pfx == "AAE") ? eAcc_gb_patent_prot
  542.                           : eAcc_gb_prot;
  543.             case 'B': return eAcc_ddbj_prot;
  544.             case 'C': return eAcc_embl_prot;
  545.             case 'D': return eAcc_gb_tpa_prot;
  546.             case 'E': return eAcc_gb_wgs_prot;
  547.             case 'F': return eAcc_ddbj_tpa_prot;
  548.             case 'G': return eAcc_ddbj_wgs_prot;
  549.             default:  return eAcc_unreserved_prot;
  550.             }
  551.         }
  552.     case 4:
  553.         switch (pfx[0]) {
  554.         case 'A': return eAcc_gb_wgs_nuc;
  555.         case 'B': return eAcc_ddbj_wgs_nuc;
  556.         case 'C': return eAcc_embl_wgs_nuc;
  557.         default:  return eAcc_unknown;
  558.         }
  559.     case 7:
  560.         if (NStr::StartsWith(acc, "NZ_")) {
  561.             return eAcc_refseq_wgs_nuc;
  562.         } else {
  563.             return eAcc_unknown;
  564.         }
  565.     default:
  566.         return eAcc_unknown;
  567.     }
  568. }
  569. CSeq_id::EAccessionInfo CSeq_id::IdentifyAccession(void) const
  570. {
  571.     EAccessionInfo type = (EAccessionInfo)Which();
  572.     switch (type) {
  573.     case CSeq_id::e_Pir: case CSeq_id::e_Swissprot: case CSeq_id::e_Prf:
  574.     case CSeq_id::e_Pdb:
  575.         return (EAccessionInfo)(type | fAcc_prot); // always just protein
  576.         
  577.     case CSeq_id::e_Genbank: case CSeq_id::e_Embl: case CSeq_id::e_Ddbj:
  578.     case CSeq_id::e_Tpg:     case CSeq_id::e_Tpe:  case CSeq_id::e_Tpd:
  579.     case CSeq_id::e_Other:
  580.     {
  581.         const CTextseq_id* tsid = GetTextseq_Id();
  582.         if (tsid->IsSetAccession()) {
  583.             EAccessionInfo ai = IdentifyAccession(tsid->GetAccession());
  584.             if ((ai & eAcc_type_mask) == e_not_set) {
  585.                 // We *know* what the type should be....
  586.                 return (EAccessionInfo)((ai & eAcc_flag_mask) | type);
  587.             } else if ((ai & eAcc_type_mask) == type) {
  588.                 return ai;
  589.             } else { // misidentified or mislabeled; assume the former
  590.                 return type;
  591.             }
  592.         } else {
  593.             return type;
  594.         }
  595.     }
  596.     
  597.     default:
  598.         return type;
  599.     }
  600. }
  601. static inline
  602. void x_GetLabel_Type(const CSeq_id& id, string* label,
  603.                      CSeq_id::TLabelFlags flags)
  604. {
  605.     CSeq_id::E_Choice choice = id.Which();
  606.     _ASSERT(choice < CSeq_id::e_MaxChoice);
  607.     if (choice >= CSeq_id::e_MaxChoice) {
  608.         return;
  609.     }
  610.     switch (choice) {   
  611.     default:
  612.         *label += s_TextId[choice];
  613.         break;
  614.     case CSeq_id::e_General:
  615.         // for general IDs, use the db-name only
  616.         *label += "gnl";
  617.         break;
  618.     }
  619.     // no extra flag interpretation currently
  620. }
  621. static inline
  622. void x_GetLabel_Content(const CSeq_id& id, string* label,
  623.                         CSeq_id::TLabelFlags flags)
  624. {
  625.     const CTextseq_id* tsid = id.GetTextseq_Id();
  626.     //text id
  627.     if (tsid) {
  628.         string str;
  629.         if (tsid->IsSetAccession()) {
  630.             str = tsid->GetAccession();
  631.         } else if (tsid->IsSetName()) {
  632.             str = tsid->GetName();
  633.         }
  634.         if ( !str.empty() ) {
  635.             if ( (flags & CSeq_id::fLabel_Version)  &&  tsid->IsSetVersion()) {
  636.                 str += "." + NStr::IntToString(tsid->GetVersion());
  637.             }
  638.         }
  639.         *label += str;
  640.     } else { //non-text id
  641.         switch (id.Which()) {   
  642.         case CSeq_id::e_not_set:
  643.             break;
  644.         case CSeq_id::e_Local:
  645.             {{
  646.                 const CObject_id& oid = id.GetLocal();
  647.                 if (oid.Which() == CObject_id::e_Id) {
  648.                     *label += NStr::IntToString(oid.GetId());
  649.                 } else if (oid.Which() == CObject_id::e_Str) {
  650.                     *label += oid.GetStr(); 
  651.                 }
  652.             }}
  653.             break;
  654.         case CSeq_id::e_Gibbsq:
  655.             *label += NStr::IntToString(id.GetGibbsq());
  656.             break;
  657.         case CSeq_id::e_Gibbmt:
  658.             *label += NStr::IntToString(id.GetGibbmt());
  659.             break;
  660.         case CSeq_id::e_Giim:
  661.             *label += NStr::IntToString(id.GetGiim().GetId());
  662.             break;
  663.         case CSeq_id::e_General:
  664.             {{
  665.                 const CDbtag& dbt = id.GetGeneral();
  666.                 *label += dbt.GetDb() + '|';
  667.                 if (dbt.GetTag().Which() == CObject_id::e_Id) {
  668.                     *label += NStr::IntToString(dbt.GetTag().GetId());
  669.                 } else if (dbt.GetTag().Which()==CObject_id::e_Str) {
  670.                     *label += dbt.GetTag().GetStr();
  671.                 }
  672.             }}
  673.             break;
  674.         case CSeq_id::e_Patent:
  675.             {{
  676.                 const CId_pat& idp = id.GetPatent().GetCit();
  677.                 *label += idp.GetCountry() +
  678.                     (idp.GetId().IsNumber() ?
  679.                         idp.GetId().GetNumber() :
  680.                         idp.GetId().GetApp_number()) +
  681.                     NStr::IntToString(id.GetPatent().GetSeqid());
  682.             }}
  683.             break;
  684.         case CSeq_id::e_Gi:
  685.             *label += NStr::IntToString(id.GetGi());
  686.             break;
  687.         case CSeq_id::e_Pdb:
  688.             {{
  689.                 const CPDB_seq_id& pid = id.GetPdb();
  690.                 char chain = (char)pid.GetChain();
  691.                 if (chain == '|') {
  692.                     *label += pid.GetMol().Get() + "|VB";
  693.                 } else if (islower(chain) != 0) {
  694.                     *label += pid.GetMol().Get() + "-" + (char) toupper(chain);
  695.                 } else if ( chain == '' ) {
  696.                     *label += pid.GetMol().Get() + "-";
  697.                 } else {
  698.                     *label += pid.GetMol().Get() + "-" + chain; 
  699.                 }
  700.             }}
  701.             break;
  702.         default:
  703.             break;
  704.         }
  705.     }
  706. }
  707. void CSeq_id::GetLabel(string* label, ELabelType type, TLabelFlags flags) const
  708. {
  709.     if ( !label ) {
  710.         return;
  711.     }
  712.     switch (type) {
  713.     case eFasta:
  714.         *label = AsFastaString();
  715.         break;
  716.     case eBoth:
  717.         x_GetLabel_Type(*this, label, flags);
  718.         *label += "|";
  719.         x_GetLabel_Content(*this, label, flags);
  720.         break;
  721.     case eType:
  722.         x_GetLabel_Type(*this, label, flags);
  723.         break;
  724.     case eContent:
  725.         x_GetLabel_Content(*this, label, flags);
  726.         break;
  727.     }
  728. }
  729. /*Return seqid string with optional version for text seqid type 
  730. (default no version).*/ 
  731. string CSeq_id::GetSeqIdString(bool with_version) const
  732. {
  733.     string label;
  734.     TLabelFlags flags = 0;
  735.     if (with_version) {
  736.         flags |= fLabel_Version;
  737.     }
  738.     GetLabel(&label, eContent, flags);
  739.     return label;
  740. }
  741. void CSeq_id::WriteAsFasta(ostream& out)
  742.     const
  743. {
  744.     E_Choice the_type = Which();
  745.     if (the_type > e_Tpd)  // New SeqId type
  746.         the_type = e_not_set;
  747.     out << s_TextId[the_type] << '|';
  748.     switch (the_type) {
  749.     case e_not_set:
  750.         break;
  751.     case e_Local:
  752.         GetLocal().AsString(out);
  753.         break;
  754.     case e_Gibbsq:
  755.         out << GetGibbsq();
  756.         break;
  757.     case e_Gibbmt:
  758.         out << GetGibbmt();
  759.         break;
  760.     case e_Giim:
  761.         out << (GetGiim().GetId());
  762.         break;
  763.     case e_Genbank:
  764.         GetGenbank().AsFastaString(out);
  765.         break;
  766.     case e_Embl:
  767.         GetEmbl().AsFastaString(out);
  768.         break;
  769.     case e_Pir:
  770.         GetPir().AsFastaString(out);
  771.         break;
  772.     case e_Swissprot:
  773.         GetSwissprot().AsFastaString(out);
  774.         break;
  775.     case e_Patent:
  776.         GetPatent().AsFastaString(out);
  777.         break;
  778.     case e_Other:
  779.         GetOther().AsFastaString(out);
  780.         break;
  781.     case e_General:
  782.         {
  783.             const CDbtag& dbt = GetGeneral();
  784.             out << (dbt.GetDb()) << '|';  // no Upcase per Ostell - Karl 7/2001
  785.             dbt.GetTag().AsString(out);
  786.         }
  787.         break;
  788.     case e_Gi:
  789.         out << GetGi();
  790.         break;
  791.     case e_Ddbj:
  792.         GetDdbj().AsFastaString(out);
  793.         break;
  794.     case e_Prf:
  795.         GetPrf().AsFastaString(out);
  796.         break;
  797.     case e_Pdb:
  798.         GetPdb().AsFastaString(out);
  799.         break;
  800.     case e_Tpg:
  801.         GetTpg().AsFastaString(out);
  802.         break;
  803.     case e_Tpe:
  804.         GetTpe().AsFastaString(out);
  805.         break;
  806.     case e_Tpd:
  807.         GetTpd().AsFastaString(out);
  808.         break;
  809.     default:
  810.         out << "[UnknownSeqIdType]";
  811.         break;
  812.     }
  813. }
  814. const string CSeq_id::AsFastaString(void) const
  815. {
  816.     CNcbiOstrstream str;
  817.     WriteAsFasta(str);
  818.     return CNcbiOstrstreamToString(str);
  819. }
  820. //
  821. // Local functions for producing a sequence ID 'score'
  822. // These functions produce scores in FastA order
  823. //
  824. static int s_ScoreNAForFasta(const CSeq_id* id)
  825. {
  826.     switch (id->Which()) {
  827.     case CSeq_id::e_not_set:
  828.     case CSeq_id::e_Giim:
  829.     case CSeq_id::e_Pir:
  830.     case CSeq_id::e_Swissprot:
  831.     case CSeq_id::e_Prf:       return kMax_Int;
  832.     case CSeq_id::e_Local:     return 230;
  833.     case CSeq_id::e_Gi:        return 120;
  834.     case CSeq_id::e_General:   return 50;
  835.     case CSeq_id::e_Patent:    return 40;
  836.     case CSeq_id::e_Gibbsq:
  837.     case CSeq_id::e_Gibbmt:
  838.     case CSeq_id::e_Pdb:       return 30;
  839.     case CSeq_id::e_Other:     return 15;
  840.     default:                   return 20; // [third party] GenBank/EMBL/DDBJ
  841.     }
  842. }
  843. static int s_ScoreAAForFasta(const CSeq_id* id)
  844. {
  845.     switch (id->Which()) {
  846.     case CSeq_id::e_not_set:
  847.     case CSeq_id::e_Giim:      return kMax_Int;
  848.     case CSeq_id::e_Local:     return 230;
  849.     case CSeq_id::e_Gi:        return 120;
  850.     case CSeq_id::e_General:   return 90;
  851.     case CSeq_id::e_Patent:    return 80;
  852.     case CSeq_id::e_Prf:       return 70;
  853.     case CSeq_id::e_Pdb:       return 50;
  854.     case CSeq_id::e_Gibbsq:
  855.     case CSeq_id::e_Gibbmt:    return 40;
  856.     case CSeq_id::e_Pir:       return 30;
  857.     case CSeq_id::e_Swissprot: return 20;
  858.     case CSeq_id::e_Other:     return 15;
  859.     default:                   return 60; // [third party] GenBank/EMBL/DDBJ
  860.     }
  861. }
  862. //
  863. // GetStringDescr()
  864. // Given a bioseq, return the best possible ID description, in a number of
  865. // appealing formats.  This function can produce FastA-formatted titles or a
  866. // number of sub-titles (GI only, Best Accession with or without version).
  867. //
  868. string CSeq_id::GetStringDescr(const CBioseq& bioseq, EStringFormat fmt)
  869. {
  870.     bool is_na            = bioseq.GetInst().GetMol() != CSeq_inst::eMol_aa;
  871.     CRef<CSeq_id> best_id = FindBestChoice(bioseq.GetId(),
  872.                                            is_na ? s_ScoreNAForFasta
  873.                                            : s_ScoreAAForFasta);
  874.     switch (fmt) {
  875.     case eFormat_FastA:
  876.         {{
  877.             // FastA format
  878.             // Here we have something like:
  879.             //      gi|###|SOME_ACCESSION|title
  880.             bool found_gi = false;
  881.             CNcbiOstrstream out_str;
  882.             ITERATE (CBioseq::TId, id, bioseq.GetId()) {
  883.                 if ((*id)->IsGi()) {
  884.                     (*id)->WriteAsFasta(out_str);
  885.                     found_gi = true;
  886.                     break;
  887.                 }
  888.             }
  889.             if (best_id.NotEmpty()  &&  best_id->Which() != CSeq_id::e_Gi) {
  890.                 if (found_gi) {
  891.                     out_str << '|';
  892.                 }
  893.                 best_id->WriteAsFasta(out_str);
  894.             }
  895.             return CNcbiOstrstreamToString(out_str);
  896.         }}
  897.         break;
  898.     case eFormat_ForceGI:
  899.         // eForceGI produces a string containing only the GI in FastA format
  900.         // so we have:
  901.         //    gi|####
  902.         ITERATE (CBioseq::TId, iter, bioseq.GetId()) {
  903.             if ( (*iter)->IsGi() ) {
  904.                 CNcbiOstrstream out_str;
  905.                 (*iter)->WriteAsFasta(out_str);
  906.                 return CNcbiOstrstreamToString(out_str);
  907.             }
  908.         }
  909.         break;
  910.     case eFormat_BestWithVersion:
  911.         // eBestWithVersion produces only the 'best' accession name, with
  912.         // its version indicator
  913.         if (best_id.NotEmpty()) {
  914.             string label;
  915.             best_id->GetLabel(&label, eDefault, fLabel_Version);
  916.             return label;
  917.         }
  918.         break;
  919.         
  920.     case eFormat_BestWithoutVersion:
  921.         // eBestWithoutVersion produces only the 'best' accession name,
  922.         // without its version indicator
  923.         if (best_id.NotEmpty()) {
  924.             string label;
  925.             best_id->GetLabel(&label, eDefault, 0);
  926.             return label;
  927.         }
  928.         break;
  929.     }
  930.     // catch-all for unusual events
  931.     return "";
  932. }
  933. CSeq_id::CSeq_id(const CDbtag& dbtag, bool set_as_general)
  934. {
  935.     int version = -1;
  936.     string acc;
  937.     if (dbtag.GetTag().IsStr()) {
  938.         acc = dbtag.GetTag().GetStr();
  939.         string::size_type pos = acc.find_last_of(".");
  940.         if (pos != string::npos) {
  941.             version = NStr::StringToInt(acc.substr(pos + 1, acc.length() - pos));
  942.             acc.erase(pos);
  943.         }
  944.     }
  945.     switch (dbtag.GetType()) {
  946.     case CDbtag::eDbtagType_GenBank:
  947.         try {
  948.             int gi = NStr::StringToInt(acc);
  949.             SetGi(gi);
  950.         }
  951.         catch (...) {
  952.             SetGenbank().SetAccession(acc);
  953.             if (version != -1) {
  954.                 SetGenbank().SetVersion(version);
  955.             }
  956.         }
  957.         break;
  958.     case CDbtag::eDbtagType_EMBL:
  959.         SetEmbl().SetAccession(acc);
  960.         if (version != -1) {
  961.             SetEmbl().SetVersion(version);
  962.         }
  963.         break;
  964.     case CDbtag::eDbtagType_DDBJ:
  965.         SetDdbj().SetAccession(acc);
  966.         if (version != -1) {
  967.             SetDdbj().SetVersion(version);
  968.         }
  969.         break;
  970.     case CDbtag::eDbtagType_GI:
  971.         if (dbtag.GetTag().IsStr()) {
  972.             SetGi(NStr::StringToInt(dbtag.GetTag().GetStr()));
  973.         } else {
  974.             SetGi(dbtag.GetTag().GetId());
  975.         }
  976.         break;
  977.     case CDbtag::eDbtagType_bad:
  978.     default:
  979.         // not understood as a sequence id - leave as e_not_set
  980.         if (set_as_general) {
  981.             SetGeneral().Assign(dbtag);
  982.         }
  983.         break;
  984.     }
  985. }
  986. //SeqIdFastAConstructors
  987. CSeq_id::CSeq_id( const string& the_id )
  988. {
  989.     // If no vertical bar, tries to interpret the string as a pure
  990.     // accession, inferring the type from the initial letter(s).
  991.     if (the_id.find('|') == NPOS) {
  992.         SIZE_TYPE      dot    = the_id.find('.');
  993.         string         acc_in = the_id.substr(0, dot);
  994.         EAccessionInfo info   = IdentifyAccession(acc_in);
  995.         int            ver    = 0;
  996.         if (dot != NPOS) {
  997.             ver = NStr::StringToNumeric(the_id.substr(dot + 1));
  998.         }
  999.         if (GetAccType(info) != e_not_set) {
  1000.             x_Init(GetAccType(info), acc_in, kEmptyStr, ver);
  1001.         }
  1002.         return;
  1003.     }
  1004.     // Create an istrstream on string the_id
  1005.     std::istrstream  myin(the_id.c_str() );
  1006.     string the_type_in, acc_in, name_in, version_in, release_in;
  1007.     // Read the part of the_id up to the vertical bar ( "|" )
  1008.     NcbiGetline(myin, the_type_in, '|');
  1009.     // Remove spaces from front and back of the_type_in
  1010.     string the_type_use = NStr::TruncateSpaces(the_type_in, NStr::eTrunc_Both);
  1011.     // Determine the type from the string
  1012.     CSeq_id_Base::E_Choice the_type = WhichInverseSeqId(the_type_use.c_str());
  1013.     // Construct according to type
  1014.     if ( the_type == CSeq_id::e_Local ) {
  1015.         NcbiGetline( myin, acc_in, 0 ); // take rest
  1016.         x_Init( the_type, acc_in );
  1017.         return;
  1018.     }
  1019.     if ( !NcbiGetline( myin, acc_in, '|' ) )
  1020.         return;
  1021.     if ( the_type == CSeq_id::e_General  ||  the_type == CSeq_id::e_Pdb ) {
  1022.         //Take the rest of the line
  1023.         NcbiGetline( myin, name_in, 0 );
  1024.         x_Init( the_type, acc_in, name_in );
  1025.         return;
  1026.     } else if ( the_type == CSeq_id::e_Gi ) {
  1027.         x_Init( the_type, acc_in );
  1028.         return;
  1029.     }
  1030.     if ( NcbiGetline(myin, name_in, '|') ) {
  1031.         if ( NcbiGetline(myin, version_in, '|') ) {
  1032.             NcbiGetline(myin, release_in, '|');
  1033.         }
  1034.     }
  1035.     string version = NStr::TruncateSpaces( version_in, NStr::eTrunc_Both );
  1036.     int ver = 0;
  1037.     if ( ! version.empty() ) {
  1038.         if ( (ver = NStr::StringToNumeric(version) ) < 0) {
  1039.             THROW1_TRACE(invalid_argument,
  1040.                          "Unexpected non-numeric version: " +
  1041.                          version +
  1042.                          "nthe_id: " + the_id);
  1043.         }
  1044.     }
  1045.     x_Init(the_type, acc_in, name_in, ver, release_in);
  1046. }
  1047. // acc_in is just first string, as in text seqid, for
  1048. // wierd cases (patents, pdb) not really an acc
  1049. CSeq_id::CSeq_id
  1050. (CSeq_id_Base::E_Choice the_type,
  1051.  const string&          acc_in,
  1052.  const string&          name_in,
  1053.  const string&          version_in,
  1054.  const string&          release_in )
  1055. {
  1056.     string version = NStr::TruncateSpaces(version_in, NStr::eTrunc_Both);
  1057.     int ver = 0;
  1058.     if ( !version.empty() ) {
  1059.         if ( (ver = NStr::StringToNumeric(version)) < 0 ) {
  1060.             THROW1_TRACE(invalid_argument,
  1061.                          "Unexpected non-numeric version. "
  1062.                          "nthe_type = " + string(s_TextId[the_type]) +
  1063.                          "nacc_in = " + acc_in +
  1064.                          "nname_in = " + name_in +
  1065.                          "version_in = " + version_in +
  1066.                          "nrelease_in = " + release_in);
  1067.         }
  1068.     }
  1069.     x_Init(the_type, acc_in, name_in, ver, release_in);
  1070. }
  1071. static void s_InitThrow
  1072. (const string& message,
  1073.  const string& type,
  1074.  const string& acc,
  1075.  const string& name,
  1076.  const string& version,
  1077.  const string& release)
  1078. {
  1079.     THROW1_TRACE(invalid_argument,
  1080.                  "CSeq_id:: " + message +
  1081.                  "ntype      = " + type +
  1082.                  "naccession = " + acc +
  1083.                  "nname      = " + name +
  1084.                  "nversion   = " + version +
  1085.                  "nrelease   = " + release);
  1086. }
  1087. CSeq_id::CSeq_id
  1088. (const string& the_type_in,
  1089.  const string& acc_in,
  1090.  const string& name_in,
  1091.  const string& version_in,
  1092.  const string& release_in)
  1093. {
  1094.     string the_type_use = NStr::TruncateSpaces(the_type_in, NStr::eTrunc_Both);
  1095.     string version      = NStr::TruncateSpaces(version_in,  NStr::eTrunc_Both);
  1096.     int ver = 0;
  1097.     CSeq_id_Base::E_Choice the_type = WhichInverseSeqId(the_type_use.c_str());
  1098.     if ( !version.empty() ) {
  1099.         if ( (ver = NStr::StringToNumeric(version)) < 0) {
  1100.             s_InitThrow("Unexpected non-numeric version.",
  1101.                         the_type_in, acc_in, name_in, version_in, release_in);
  1102.         }
  1103.     }
  1104.     x_Init(the_type, acc_in, name_in, ver, release_in);
  1105. }
  1106. CSeq_id::CSeq_id
  1107. (const string& the_type_in,
  1108.  const string& acc_in,
  1109.  const string& name_in,
  1110.  int           version,
  1111.  const string& release_in )
  1112. {
  1113.     string the_type_use = NStr::TruncateSpaces(the_type_in, NStr::eTrunc_Both);
  1114.     CSeq_id_Base::E_Choice the_type = WhichInverseSeqId (the_type_use.c_str());
  1115.     x_Init(the_type, acc_in, name_in, version, release_in);
  1116. }
  1117. CSeq_id::CSeq_id
  1118. ( CSeq_id_Base::E_Choice the_type,
  1119.   const string&          acc_in,
  1120.   const string&          name_in,
  1121.   int                    version,
  1122.   const string&          release_in)
  1123. {
  1124.     x_Init(the_type, acc_in, name_in, version, release_in);
  1125. }
  1126. CSeq_id::CSeq_id
  1127. ( CSeq_id_Base::E_Choice the_type,
  1128.   int           the_id)
  1129. {
  1130.   if(the_id<=0)
  1131.     THROW1_TRACE(invalid_argument, "Specified Seq-id value is negative");
  1132.   
  1133.   switch (the_type) {
  1134.   case CSeq_id::e_Local:
  1135.     SetLocal().SetId(the_id);
  1136.     break;
  1137.   case CSeq_id::e_Gibbsq:
  1138.     SetGibbsq(the_id);
  1139.     break;
  1140.   case CSeq_id::e_Gibbmt:
  1141.     SetGibbmt(the_id);
  1142.     break;
  1143.   case CSeq_id::e_Giim:
  1144.     SetGiim().SetId(the_id);
  1145.     break;
  1146.   case CSeq_id::e_Gi:
  1147.     SetGi(the_id);
  1148.     break;
  1149.   default:
  1150.     THROW1_TRACE(invalid_argument, "Specified Seq-id type is not numeric seq-id");
  1151.   }  
  1152. }
  1153. // Karl Sirotkin 7/2001
  1154. void
  1155. CSeq_id::x_Init
  1156. ( CSeq_id_Base::E_Choice the_type,
  1157.   const string&          acc_in,
  1158.   const string&          name_in,
  1159.   int                    version ,
  1160.   const string&          release_in)
  1161. {
  1162.     int the_id;
  1163.     string acc     = NStr::TruncateSpaces(acc_in,     NStr::eTrunc_Both);
  1164.     string name    = NStr::TruncateSpaces(name_in,    NStr::eTrunc_Both);
  1165.     string release = NStr::TruncateSpaces(release_in, NStr::eTrunc_Both);
  1166.     switch (the_type) {
  1167.     case CSeq_id::e_not_set: // Will cause unspecified SeqId to be returned.
  1168.         break;
  1169.     case CSeq_id::e_Local:
  1170.         {
  1171.             CSeq_id::TLocal & loc = SetLocal();
  1172.             string::const_iterator it = acc.begin();
  1173.             if ( (the_id = NStr::StringToNumeric(acc)) >= 0 && *it != '0' ) {
  1174.                 loc.SetId(the_id);
  1175.             } else { // to cover case where embedded vertical bar in
  1176.                 // string, could add code here, to concat a
  1177.                 // '|' and name string, if not null/empty
  1178.                 loc.SetStr(acc);
  1179.             }
  1180.             break;
  1181.         }
  1182.     case CSeq_id::e_Gibbsq:
  1183.         if ( (the_id = NStr::StringToNumeric (acc)) >= 0 ) {
  1184.             SetGibbsq(the_id);
  1185.         } else {
  1186.              s_InitThrow("Unexpected non-numeric accession.",
  1187.                          string(s_TextId[the_type]), acc_in, name_in,
  1188.                          NStr::IntToString(version), release_in);
  1189.         }
  1190.         break;
  1191.     case CSeq_id::e_Gibbmt:
  1192.         if ( (the_id =NStr::StringToNumeric (acc)) >= 0 ) {
  1193.             SetGibbmt(the_id);
  1194.         } else {
  1195.              s_InitThrow("Unexpected non-numeric accession.",
  1196.                          string(s_TextId[the_type]), acc_in, name_in,
  1197.                          NStr::IntToString(version), release_in);
  1198.         }
  1199.         break;
  1200.     case CSeq_id::e_Giim:
  1201.         {
  1202.             CGiimport_id &  giim = SetGiim();
  1203.             if ( (the_id =NStr::StringToNumeric (acc)) >= 0 ) {
  1204.                 giim.SetId(the_id);
  1205.             } else {
  1206.                 s_InitThrow("Unexpected non-numeric accession.",
  1207.                             string(s_TextId[the_type]), acc_in, name_in,
  1208.                             NStr::IntToString(version), release_in);
  1209.             }
  1210.             break;
  1211.         }
  1212.     case CSeq_id::e_Genbank:
  1213.         {
  1214.             CTextseq_id* text
  1215.                 = new CTextseq_id(acc, name, version, release);
  1216.             SetGenbank(*text );
  1217.             break;
  1218.         }
  1219.     case CSeq_id::e_Embl:
  1220.         {
  1221.             CTextseq_id* text
  1222.                = new CTextseq_id(acc, name, version, release);
  1223.             SetEmbl(*text);
  1224.             break;
  1225.         }
  1226.     case CSeq_id::e_Pir:
  1227.         {
  1228.             CTextseq_id* text
  1229.                 = new CTextseq_id(acc, name, version, release, false);
  1230.             SetPir(*text);
  1231.             break;
  1232.         }
  1233.     case CSeq_id::e_Swissprot:
  1234.         {
  1235.             CTextseq_id* text
  1236.                 = new CTextseq_id(acc, name, version, release, false);
  1237.             SetSwissprot(*text);
  1238.             break;
  1239.         }
  1240.     case CSeq_id::e_Tpg:
  1241.         {
  1242.             CTextseq_id* text
  1243.                 = new CTextseq_id(acc, name, version, release);
  1244.             SetTpg(*text);
  1245.             break;
  1246.         }
  1247.     case CSeq_id::e_Tpe:
  1248.         {
  1249.             CTextseq_id* text
  1250.                 = new CTextseq_id(acc, name, version, release);
  1251.             SetTpe(*text);
  1252.             break;
  1253.         }
  1254.     case CSeq_id::e_Tpd:
  1255.         {
  1256.             CTextseq_id* text
  1257.                 = new CTextseq_id(acc, name, version, release);
  1258.             SetTpd(*text);
  1259.             break;
  1260.         }
  1261.     case CSeq_id::e_Patent:
  1262.         {
  1263.             CPatent_seq_id&  pat    = SetPatent();
  1264.             CId_pat&         id_pat = pat.SetCit();
  1265.             CId_pat::C_Id&   id_pat_id = id_pat.SetId();
  1266.             id_pat.SetCountry(acc);
  1267.             const char      app_str[] = "App=";
  1268.             const SIZE_TYPE app_str_len = sizeof(app_str) - 1;
  1269.             if (name.substr(0, app_str_len) == app_str) {
  1270.                 id_pat_id.SetApp_number(name.substr(app_str_len));
  1271.             } else {
  1272.                 id_pat_id.SetNumber(name);
  1273.             }
  1274.             pat.SetSeqid(version);
  1275.             break;
  1276.         }
  1277.     case CSeq_id::e_Other: // RefSeq, allow dot version
  1278.         {
  1279.             CTextseq_id* text
  1280.                 = new CTextseq_id(acc,name,version,release);
  1281.             SetOther(*text);
  1282.             break;
  1283.         }
  1284.     case CSeq_id::e_General:
  1285.         {
  1286.             CDbtag& dbt = SetGeneral();
  1287.             dbt.SetDb(acc);
  1288.             CObject_id& oid = dbt.SetTag();
  1289.             the_id = NStr::StringToNumeric(name);
  1290.             if (the_id >= 0  &&  (name.size() == 1 || name[0] != '0')) {
  1291.                 oid.SetId(the_id);
  1292.             }else{
  1293.                 oid.SetStr(name);
  1294.             }
  1295.             break;
  1296.         }
  1297.     case CSeq_id::e_Gi:
  1298.         the_id = NStr::StringToNumeric(acc);
  1299.         if (the_id >= 0 ) {
  1300.             SetGi(the_id);
  1301.         } else {
  1302.              s_InitThrow("Unexpected non-numeric accession.",
  1303.                          string(s_TextId[the_type]), acc_in, name_in,
  1304.                          NStr::IntToString(version), release_in);
  1305.         }
  1306.         break;
  1307.     case CSeq_id::e_Ddbj:
  1308.         {
  1309.             CTextseq_id* text
  1310.                 = new CTextseq_id(acc,name,version,release);
  1311.             SetDdbj(*text);
  1312.             break;
  1313.         }
  1314.     case CSeq_id::e_Prf:
  1315.         {
  1316.             CTextseq_id* text
  1317.                 = new CTextseq_id(acc,name,version,release,false);
  1318.             SetPrf(*text);
  1319.             break;
  1320.         }
  1321.     case CSeq_id::e_Pdb:
  1322.         {
  1323.             CPDB_seq_id& pdb     = SetPdb();
  1324.             CPDB_mol_id& pdb_mol = pdb.SetMol();
  1325.             pdb_mol.Set(acc);
  1326.             if (name.empty()) {
  1327.                 pdb.SetChain(' ');
  1328.             } else if (name.size() == 1) {
  1329.                 pdb.SetChain(static_cast<unsigned char> (name[0]));
  1330.             } else if ( name.compare("VB") == 0) {
  1331.                 pdb.SetChain('|');
  1332.             } else if (name.size() == 2  &&  name[0] ==  name[1]) {
  1333.                 pdb.SetChain( Locase(static_cast<unsigned char> (name[0])) );
  1334.             } else {
  1335.                 s_InitThrow("Unexpected PDB chain id.",
  1336.                             string(s_TextId[the_type]), acc_in, name_in,
  1337.                             NStr::IntToString(version), release_in);
  1338.             }
  1339.             break;
  1340.         }
  1341.     default:
  1342.         THROW1_TRACE(invalid_argument, "Specified Seq-id type not supported");
  1343.     }
  1344. }
  1345. bool CSeq_id::Equals(const CSerialObject& object, ESerialRecursionMode how) const
  1346. {
  1347.     if ( typeid(object) != typeid(*this) ) {
  1348.         ERR_POST(Fatal <<
  1349.             "CSeq_id::Assign() -- Assignment of incompatible types: " <<
  1350.             typeid(*this).name() << " = " << typeid(object).name());
  1351.     }
  1352.     return CSerialObject::Equals(object, how);
  1353. }
  1354. END_objects_SCOPE // namespace ncbi::objects::
  1355. END_NCBI_SCOPE
  1356. /*
  1357.  * ===========================================================================
  1358.  *
  1359.  * $Log: Seq_id.cpp,v $
  1360.  * Revision 1000.4  2004/06/01 19:34:28  gouriano
  1361.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R6.81
  1362.  *
  1363.  * Revision 6.81  2004/06/01 15:26:07  johnson
  1364.  * Make CompareOrdered a true model of strict weak ordering
  1365.  *
  1366.  * Revision 6.80  2004/05/28 20:09:44  johnson
  1367.  * Added Compare for seq-id type General (CDbtag)
  1368.  *
  1369.  * Revision 6.79  2004/05/21 14:41:46  dicuccio
  1370.  * Moved database tag for general IDs to content part of label
  1371.  *
  1372.  * Revision 6.78  2004/05/19 17:26:25  gorelenk
  1373.  * Added include of PCH - ncbi_pch.hpp
  1374.  *
  1375.  * Revision 6.77  2004/05/16 16:57:44  dicuccio
  1376.  * Removed insertion of db type in general seq-id labels of type content - led to
  1377.  * duplicates of type
  1378.  *
  1379.  * Revision 6.76  2004/05/14 14:34:02  dicuccio
  1380.  * Include database name in label content if the db-tag is just an integer
  1381.  *
  1382.  * Revision 6.75  2004/03/25 15:59:06  gouriano
  1383.  * Added possibility to copy and compare serial object non-recursively
  1384.  *
  1385.  * Revision 6.74  2004/03/22 16:24:19  ucko
  1386.  * CN is now specifically assigned to GenBank ESTs.
  1387.  *
  1388.  * Revision 6.73  2004/01/22 21:03:58  dicuccio
  1389.  * Separated functionality of enums in GetLabel() into discrete mode and flags
  1390.  *
  1391.  * Revision 6.72  2004/01/22 18:45:46  dicuccio
  1392.  * Added new API: CSeq_id::GetLabel().  Rewired GetSeqIdString() to feed into
  1393.  * GetLabel().  Rewired GetStringDescr() to feed into GetLabel() directly instead
  1394.  * of feeding through GetSeqIdString().
  1395.  *
  1396.  * Revision 6.71  2004/01/21 22:55:47  ucko
  1397.  * GetSeqIdString: drop the database name from general IDs for
  1398.  * compatibility with code that can't handle its presence.
  1399.  *
  1400.  * Revision 6.70  2004/01/21 18:04:20  dicuccio
  1401.  * Added ctor to create a seq-id from a given dbtag, performing conversion to
  1402.  * specific seq-id types where possible
  1403.  *
  1404.  * Revision 6.69  2004/01/20 16:59:38  ucko
  1405.  * CSeq_id::IdentifyAccession: identify IDs consisting solely of digits as GIs.
  1406.  *
  1407.  * Revision 6.68  2004/01/16 17:39:17  vasilche
  1408.  * Fixed parsing 'gnl|xxx|999' format - integer tag detection.
  1409.  *
  1410.  * Revision 6.67  2004/01/16 15:58:19  ucko
  1411.  * CM now specifically assigned to eAcc_gb_con.
  1412.  *
  1413.  * Revision 6.66  2003/12/18 18:55:59  ucko
  1414.  * CSeq_id::IdentifyAccession: CQ is EMBL patents, CR is EMBL genomes,
  1415.  * CS-CU are reserved for future EMBL nucleotide use.
  1416.  *
  1417.  * Revision 6.65  2003/12/16 16:00:16  ucko
  1418.  * CSeq_id::IdentifyAccession: CL is GenBank GSS, CM-CP are GenBank
  1419.  * nucleotides to be assigned to specific projects as needed.
  1420.  *
  1421.  * Revision 6.64  2003/11/10 15:05:42  ucko
  1422.  * +CK to eAcc_gb_est
  1423.  *
  1424.  * Revision 6.63  2003/10/31 20:16:07  ucko
  1425.  * CSeq_id::IdentifyAccession: CI and CJ are both DDBJ EST.
  1426.  *
  1427.  * Revision 6.62  2003/10/24 14:57:03  ucko
  1428.  * IdentifyAccession: CH -> eAcc_gb_con.
  1429.  * GetSeqIdString: include the database name for IDs of type general.
  1430.  *
  1431.  * Revision 6.61  2003/08/25 21:15:41  ucko
  1432.  * Tweak slightly for efficiency.
  1433.  *
  1434.  * Revision 6.60  2003/08/22 15:16:48  dondosha
  1435.  * Correction in CSeq_id constructor, to allow id strings starting with a gi id
  1436.  *
  1437.  * Revision 6.59  2003/08/11 14:37:20  ucko
  1438.  * IdentifyAccession: "CG" is GenBank GSS.
  1439.  *
  1440.  * Revision 6.58  2003/07/14 20:11:59  ucko
  1441.  * +CF (eAcc_gb_est)
  1442.  *
  1443.  * Revision 6.57  2003/07/02 13:46:14  ucko
  1444.  * +CE (eAcc_gb_gss)
  1445.  *
  1446.  * Revision 6.56  2003/06/24 16:33:48  ucko
  1447.  * CSeq_id::IdentifyAccession: always return unknown for accessions that
  1448.  * contain no digits, even if they happen to look like prefixes.
  1449.  *
  1450.  * Revision 6.55  2003/05/09 14:22:56  ucko
  1451.  * CSeq_id::x_Init: treat missing (chain) names as spaces (reported by
  1452.  * Michel Dumontier) and get rid of some unnecessary calls to c_str().
  1453.  *
  1454.  * Revision 6.54  2003/04/30 14:41:01  ucko
  1455.  * CSeq_id::IdentifyAccession: CDnnnnnn -> eAcc_gb_est
  1456.  *
  1457.  * Revision 6.53  2003/03/25 15:37:18  ucko
  1458.  * CSeq_id::IdentifyAccession("CC...") -> eAcc_gb_gss
  1459.  *
  1460.  * Revision 6.52  2003/03/11 15:55:44  kuznets
  1461.  * iterate -> ITERATE
  1462.  *
  1463.  * Revision 6.51  2003/02/06 22:23:29  vasilche
  1464.  * Added CSeq_id::Assign(), CSeq_loc::Assign().
  1465.  * Added int CSeq_id::Compare() (not safe).
  1466.  * Added caching of CSeq_loc::GetTotalRange().
  1467.  *
  1468.  * Revision 6.50  2003/02/04 15:15:12  grichenk
  1469.  * Overrided Assign() for CSeq_loc and CSeq_id
  1470.  *
  1471.  * Revision 6.49  2003/01/18 08:40:03  kimelman
  1472.  * addes seqid constructor for numeric types
  1473.  *
  1474.  * Revision 6.48  2003/01/15 18:27:13  ucko
  1475.  * +AK (accidentally skipped earlier -- sigh)
  1476.  *
  1477.  * Revision 6.47  2003/01/10 15:57:30  ucko
  1478.  * Identify CB as gb_est.
  1479.  *
  1480.  * Revision 6.46  2003/01/08 16:48:03  ucko
  1481.  * +AL (accidentally skipped earlier)
  1482.  *
  1483.  * Revision 6.45  2003/01/07 19:52:15  ucko
  1484.  * Add more refseq types (NR_, NS_, NW_).
  1485.  *
  1486.  * Revision 6.44  2002/12/30 23:44:42  vakatov
  1487.  * CSeq_id::GetStringDescr() -- un-freeze "strstream" to avoid a mem.leak
  1488.  *
  1489.  * Revision 6.43  2002/12/26 16:39:25  vasilche
  1490.  * Object manager class CSeqMap rewritten.
  1491.  *
  1492.  * Revision 6.42  2002/12/03 15:55:12  dicuccio
  1493.  * Corrected processing of text id accessions with no accession set (in
  1494.  * GetSeqIdString()) - use name instead.
  1495.  *
  1496.  * Revision 6.41  2002/11/26 15:13:32  dicuccio
  1497.  * Added CSeq_id::GetStringDescr() - provides text representations of seq-ids in a
  1498.  * number of formats.
  1499.  *
  1500.  * Revision 6.40  2002/10/23 18:23:07  ucko
  1501.  * Add self-classification (using known type information).
  1502.  *
  1503.  * Revision 6.39  2002/10/22 20:19:14  jianye
  1504.  * Added GetSeqIdString()
  1505.  *
  1506.  * Revision 6.38  2002/10/18 16:03:08  ucko
  1507.  * +CA (eAcc_gb_est)
  1508.  *
  1509.  * Revision 6.37  2002/10/03 18:55:04  clausen
  1510.  * Removed extra whitespace
  1511.  *
  1512.  * Revision 6.36  2002/10/03 17:17:11  clausen
  1513.  * Added BestRank() and WorstRank()
  1514.  *
  1515.  * Revision 6.35  2002/10/03 16:03:00  ucko
  1516.  * +BZ (eAcc_gb_gss)
  1517.  *
  1518.  * Revision 6.34  2002/09/23 16:43:46  ucko
  1519.  * Change check for absence of '|' to use string::find.
  1520.  *
  1521.  * Revision 6.33  2002/09/20 19:55:29  ucko
  1522.  * +BY (eAcc_ddbj_est)
  1523.  *
  1524.  * Revision 6.32  2002/08/28 14:07:56  ucko
  1525.  * IdentifyAccession: handle BX (EMBL genome)
  1526.  *
  1527.  * Revision 6.31  2002/08/26 20:44:06  ucko
  1528.  * CSeq_id::IdentifyAccession: +BW (DDBJ EST)
  1529.  *
  1530.  * Revision 6.30  2002/08/19 16:54:30  ucko
  1531.  * IdentifyAccession: add BV (eAcc_gb_sts).
  1532.  *
  1533.  * Revision 6.29  2002/08/19 15:42:14  ucko
  1534.  * IdentifyAccession: add BU (eAcc_gb_est).
  1535.  *
  1536.  * Revision 6.28  2002/08/16 19:27:01  ucko
  1537.  * Recognize new WGS RefSeq accessions.
  1538.  *
  1539.  * Revision 6.27  2002/08/14 15:52:27  ucko
  1540.  * Add BT and XR_.
  1541.  *
  1542.  * Revision 6.26  2002/08/06 18:22:19  ucko
  1543.  * Properly handle versioned PDB accessions.
  1544.  *
  1545.  * Revision 6.25  2002/08/01 20:33:10  ucko
  1546.  * s_IdentifyAccession -> IdentifyAccession; s_ is only for module-static names.
  1547.  *
  1548.  * Revision 6.24  2002/07/30 19:42:44  ucko
  1549.  * Add s_IdentifyAccession, and use it in the string-based constructor if
  1550.  * the input isn't FASTA-format.
  1551.  * Move CVS log to end.
  1552.  *
  1553.  * Revision 6.23  2002/06/06 20:31:33  clausen
  1554.  * Moved methods using object manager to objects/util
  1555.  *
  1556.  * Revision 6.22  2002/05/22 14:03:40  grichenk
  1557.  * CSerialUserOp -- added prefix UserOp_ to Assign() and Equals()
  1558.  *
  1559.  * Revision 6.21  2002/05/06 03:39:12  vakatov
  1560.  * OM/OM1 renaming
  1561.  *
  1562.  * Revision 6.20  2002/05/03 21:28:17  ucko
  1563.  * Introduce T(Signed)SeqPos.
  1564.  *
  1565.  * Revision 6.19  2002/01/16 18:56:32  grichenk
  1566.  * Removed CRef<> argument from choice variant setter, updated sources to
  1567.  * use references instead of CRef<>s
  1568.  *
  1569.  * Revision 6.18  2002/01/10 19:00:04  clausen
  1570.  * Added GetLength
  1571.  *
  1572.  * Revision 6.17  2002/01/09 15:59:30  grichenk
  1573.  * Fixed includes
  1574.  *
  1575.  * Revision 6.16  2001/10/15 23:00:00  vakatov
  1576.  * CSeq_id::x_Init() -- get rid of unreachable "break;"
  1577.  *
  1578.  * Revision 6.15  2001/08/31 20:05:44  ucko
  1579.  * Fix ICC build.
  1580.  *
  1581.  * Revision 6.14  2001/08/31 16:02:10  clausen
  1582.  * Added new constructors for Fasta and added new id types, tpd, tpe, tpg
  1583.  *
  1584.  * Revision 6.13  2001/07/16 16:22:48  grichenk
  1585.  * Added CSerialUserOp class to create Assign() and Equals() methods for
  1586.  * user-defind classes.
  1587.  * Added SerialAssign<>() and SerialEquals<>() functions.
  1588.  *
  1589.  * Revision 6.12  2001/05/24 20:24:27  grichenk
  1590.  * Renamed seq/objmgrstub.hpp -> obgmgr/objmgr_base.hpp
  1591.  * Added Genbank, Embl and Ddbj support in CSeq_id::Compare()
  1592.  * Fixed General output by CSeq_id::WriteAsFasta()
  1593.  *
  1594.  * Revision 6.11  2001/04/17 04:14:49  vakatov
  1595.  * CSeq_id::AsFastaString() --> CSeq_id::WriteAsFasta()
  1596.  *
  1597.  * Revision 6.10  2001/01/03 16:39:05  vasilche
  1598.  * Added CAbstractObjectManager - stub for object manager.
  1599.  * CRange extracted to separate file.
  1600.  *
  1601.  * Revision 6.9  2000/12/26 17:28:55  vasilche
  1602.  * Simplified and formatted code.
  1603.  *
  1604.  * Revision 6.8  2000/12/15 19:30:31  ostell
  1605.  * Used Upcase() in AsFastaString() and changed to PNocase().Equals() style
  1606.  *
  1607.  * Revision 6.7  2000/12/08 22:19:45  ostell
  1608.  * changed MakeFastString to AsFastaString and to use ostream instead of string
  1609.  *
  1610.  * Revision 6.6  2000/12/08 20:45:14  ostell
  1611.  * added MakeFastaString()
  1612.  *
  1613.  * Revision 6.5  2000/12/04 15:09:41  vasilche
  1614.  * Added missing include.
  1615.  *
  1616.  * Revision 6.4  2000/11/30 22:08:18  ostell
  1617.  * finished Match()
  1618.  *
  1619.  * Revision 6.3  2000/11/30 16:13:12  ostell
  1620.  * added support for Textseq_id to Seq_id.Match()
  1621.  *
  1622.  * Revision 6.2  2000/11/28 12:47:41  ostell
  1623.  * fixed first switch statement to break properly
  1624.  *
  1625.  * Revision 6.1  2000/11/21 18:58:29  vasilche
  1626.  * Added Match() methods for CSeq_id, CObject_id and CDbtag.
  1627.  *
  1628.  * ===========================================================================
  1629.  */