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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: feature.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:25:23  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: feature.cpp,v 1000.1 2004/06/01 19:25:23 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:  Clifford Clausen
  35. *
  36. * File Description:
  37. *   Sequence utilities
  38. */
  39. #include <ncbi_pch.hpp>
  40. #include <serial/object.hpp>
  41. #include <serial/objistr.hpp>
  42. #include <serial/serial.hpp>
  43. #include <serial/iterator.hpp>
  44. #include <serial/enumvalues.hpp>
  45. #include <objmgr/object_manager.hpp>
  46. #include <objmgr/scope.hpp>
  47. #include <objmgr/seq_vector.hpp>
  48. #include <objects/seqfeat/Seq_feat.hpp>
  49. #include <objects/seqfeat/SeqFeatXref.hpp>
  50. #include <objects/seqfeat/Imp_feat.hpp>
  51. #include <objects/seqfeat/Prot_ref.hpp>
  52. #include <objects/seqfeat/Gene_ref.hpp>
  53. #include <objects/seqfeat/RNA_ref.hpp>
  54. #include <objects/seqfeat/Org_ref.hpp>
  55. #include <objects/seqfeat/Rsite_ref.hpp>
  56. #include <objects/seqfeat/Trna_ext.hpp>
  57. #include <objects/seqfeat/Cdregion.hpp>
  58. #include <objects/seqfeat/Gb_qual.hpp>
  59. #include <objects/seqfeat/BioSource.hpp>
  60. #include <objects/seq/Bioseq.hpp>
  61. #include <objects/seq/seqport_util.hpp>
  62. #include <objects/seq/IUPACaa.hpp>
  63. #include <objects/seq/NCBIstdaa.hpp>
  64. #include <objects/seq/NCBIeaa.hpp>
  65. #include <objects/seq/NCBI8aa.hpp>
  66. #include <objects/seq/Pubdesc.hpp>
  67. #include <objects/seq/Heterogen.hpp>
  68. #include <objects/seqloc/Seq_loc.hpp>
  69. #include <objects/seqloc/Seq_loc_mix.hpp>
  70. #include <objects/seqfeat/SeqFeatData.hpp>
  71. #include <objects/general/Dbtag.hpp>
  72. #include <objects/general/Object_id.hpp>
  73. #include <objects/general/User_object.hpp>
  74. #include <objects/pub/Pub_equiv.hpp>
  75. #include <objects/pub/Pub.hpp>
  76. #include <objects/pub/Pub_set.hpp>
  77. #include <objmgr/util/feature.hpp>
  78. #include <objmgr/util/sequence.hpp>
  79. BEGIN_NCBI_SCOPE
  80. BEGIN_SCOPE(objects)
  81. BEGIN_SCOPE(feature)
  82. USING_SCOPE(sequence);
  83. // Appends a label onto "label" based on the type of feature       
  84. void s_GetTypeLabel(const CSeq_feat& feat, string* label)
  85. {    
  86.     string tlabel;
  87.     
  88.     // Determine typelabel
  89.     CSeqFeatData::ESubtype idx = feat.GetData().GetSubtype();
  90.     if ( idx != CSeqFeatData::eSubtype_bad ) {
  91.         tlabel = feat.GetData().GetKey();
  92.         if (feat.GetData().Which() == CSeqFeatData::e_Imp  && 
  93.             tlabel != "CDS") {
  94.             tlabel = "[" + tlabel + "]";
  95.         } else if (feat.GetData().Which() == CSeqFeatData::e_Region  && 
  96.             feat.GetData().GetRegion() == "Domain"  &&  feat.IsSetComment() ) {
  97.             tlabel = "Domain";
  98.         }
  99.     } else if (feat.GetData().Which() == CSeqFeatData::e_Imp) {
  100.         tlabel = "[" + feat.GetData().GetImp().GetKey() + "]";
  101.     } else {
  102.         tlabel = "Unknown=0";
  103.     }
  104.     *label += tlabel;  
  105. }
  106. // Appends a label onto tlabel for a CSeqFeatData::e_Cdregion
  107. inline
  108. static void s_GetCdregionLabel
  109. (const CSeq_feat& feat, 
  110.  string*          tlabel,
  111.  CScope*          scope)
  112. {
  113.     // Check that tlabel exists and that the feature data is Cdregion
  114.     if (!tlabel  ||  !feat.GetData().IsCdregion()) {
  115.         return;
  116.     }
  117.     
  118.     const CGene_ref* gref = 0;
  119.     const CProt_ref* pref = 0;
  120.     
  121.     // Look for CProt_ref object to create a label from
  122.     if (feat.IsSetXref()) {
  123.         ITERATE ( CSeq_feat::TXref, it, feat.GetXref()) {
  124.             switch ((**it).GetData().Which()) {
  125.             case CSeqFeatData::e_Prot:
  126.                 pref = &(**it).GetData().GetProt();
  127.                 break;
  128.             case CSeqFeatData::e_Gene:
  129.                 gref = &(**it).GetData().GetGene();
  130.                 break;
  131.             default:
  132.                 break;
  133.             }
  134.         }
  135.     }
  136.     
  137.     // Try and create a label from a CProt_ref in CSeqFeatXref in feature
  138.     if (pref) {
  139.         pref->GetLabel(tlabel);
  140.         return;
  141.     }
  142.     
  143.     // Try and create a label from a CProt_ref in the feat product and
  144.     // return if found 
  145.     if (feat.IsSetProduct()  &&  scope) {
  146.         try {
  147.             const CSeq_id& id = GetId(feat.GetProduct(), scope);            
  148.             CBioseq_Handle hnd = scope->GetBioseqHandle(id);
  149.             if (hnd) {
  150.                 const CBioseq& seq = hnd.GetBioseq();
  151.             
  152.                 // Now look for a CProt_ref feature in seq and
  153.                 // if found call GetLabel() on the CProt_ref
  154.                 CTypeConstIterator<CSeqFeatData> it = ConstBegin(seq);
  155.                 for (;it; ++it) {
  156.                     if (it->Which() == CSeqFeatData::e_Prot) {
  157.                         it->GetProt().GetLabel(tlabel);
  158.                         return;
  159.                     }
  160.                 }
  161.             }
  162.         } catch (CNotUnique&) {}
  163.     }
  164.     
  165.     // Try and create a label from a CGene_ref in CSeqFeatXref in feature
  166.     if (gref) {
  167.         gref->GetLabel(tlabel);
  168.     }
  169.     // check to see if the CDregion is just an open reading frame
  170.     if (feat.GetData().GetCdregion().IsSetOrf()  &&
  171.         feat.GetData().GetCdregion().GetOrf()) {
  172.         string str("open reading frame: ");
  173.         switch (feat.GetData().GetCdregion().GetFrame()) {
  174.         case CCdregion::eFrame_not_set:
  175.             str += "frame not set; ";
  176.             break;
  177.         case CCdregion::eFrame_one:
  178.             str += "frame 1; ";
  179.             break;
  180.         case CCdregion::eFrame_two:
  181.             str += "frame 2; ";
  182.             break;
  183.         case CCdregion::eFrame_three:
  184.             str += "frame 3; ";
  185.             break;
  186.         }
  187.         switch (sequence::GetStrand(feat.GetLocation())) {
  188.         case eNa_strand_plus:
  189.             str += "positive strand";
  190.             break;
  191.         case eNa_strand_minus:
  192.             str += "negative strand";
  193.             break;
  194.         case eNa_strand_both:
  195.             str += "both strands";
  196.             break;
  197.         case eNa_strand_both_rev:
  198.             str += "both strands (reverse)";
  199.             break;
  200.         default:
  201.             str += "strand unknown";
  202.             break;
  203.         }
  204.         *tlabel += str;
  205.     }
  206. }
  207. inline
  208. static void s_GetRnaRefLabelFromComment
  209. (const CSeq_feat& feat, 
  210.  string*          label,
  211.  ELabelType       label_type,
  212.  const string*    type_label)
  213. {
  214.     if (feat.IsSetComment()  &&  !feat.GetComment().empty()) {
  215.         if (label_type == eContent  &&  type_label != 0
  216.             &&  feat.GetComment().find(*type_label) == string::npos) {
  217.             *label += *type_label + "-" + feat.GetComment();
  218.         } else {
  219.             *label += feat.GetComment();
  220.         }
  221.     } else if (type_label) {
  222.         *label += *type_label;
  223.     }
  224. }
  225. // Appends a label onto "label" for a CRNA_ref
  226. inline
  227. static void s_GetRnaRefLabel
  228. (const CSeq_feat& feat, 
  229.  string*          label,
  230.  ELabelType       label_type,
  231.  const string*    type_label)
  232. {
  233.     // Check that label exists and that feature data is type RNA-ref
  234.     if (!label  ||  !feat.GetData().IsRna()) {
  235.         return;
  236.     }
  237.     
  238.     const CRNA_ref& rna = feat.GetData().GetRna();
  239.     
  240.     // Append the feature comment, the type label, or both  and return 
  241.     // if Ext is not set
  242.     if (!rna.IsSetExt()) {
  243.         s_GetRnaRefLabelFromComment(feat, label, label_type, type_label);
  244.         return;
  245.     }
  246.     
  247.     // Append a label based on the type of the type of the ext of the
  248.     // CRna_ref
  249.     string tmp_label;
  250.     switch (rna.GetExt().Which()) {
  251.     case CRNA_ref::C_Ext::e_not_set:
  252.         s_GetRnaRefLabelFromComment(feat, label, label_type, type_label);
  253.         break;
  254.     case CRNA_ref::C_Ext::e_Name:
  255.         tmp_label = rna.GetExt().GetName();
  256.         if (label_type == eContent  &&  type_label != 0  &&
  257.                 tmp_label.find(*type_label) == string::npos) {
  258.             *label += *type_label + "-" + tmp_label;
  259.         } else if (!tmp_label.empty()) {
  260.             *label += tmp_label;
  261.         } else if (type_label) {
  262.             *label += *type_label;
  263.         }
  264.         break;
  265.     case CRNA_ref::C_Ext::e_TRNA:
  266.     {
  267.         if ( !rna.GetExt().GetTRNA().IsSetAa() ) {
  268.             s_GetRnaRefLabelFromComment(feat, label, label_type, type_label);
  269.             break;                
  270.         }
  271.         try {
  272.             CTrna_ext::C_Aa::E_Choice aa_code_type = 
  273.                 rna.GetExt().GetTRNA().GetAa().Which();
  274.             int aa_code;
  275.             CSeq_data in_seq, out_seq;
  276.             string str_aa_code;
  277.             switch (aa_code_type) {
  278.             case CTrna_ext::C_Aa::e_Iupacaa:        
  279.                 // Convert an e_Iupacaa code to an Iupacaa3 code for the label
  280.                 aa_code = rna.GetExt().GetTRNA().GetAa().GetIupacaa();
  281.                 str_aa_code = CSeqportUtil::GetCode(CSeq_data::e_Iupacaa,
  282.                                                     aa_code); 
  283.                 in_seq.SetIupacaa().Set() = str_aa_code;
  284.                 CSeqportUtil::Convert(in_seq, &out_seq,
  285.                                       CSeq_data::e_Ncbistdaa);
  286.                 if (out_seq.GetNcbistdaa().Get().size()) {
  287.                     aa_code = out_seq.GetNcbistdaa().Get()[0];
  288.                     tmp_label = CSeqportUtil::GetIupacaa3(aa_code);
  289.                 } else {
  290.                     s_GetRnaRefLabelFromComment(feat, label, label_type,
  291.                                                 type_label);
  292.                 }
  293.                 break;
  294.             case CTrna_ext::C_Aa::e_Ncbieaa:
  295.                 // Convert an e_Ncbieaa code to an Iupacaa3 code for the label
  296.                 aa_code = rna.GetExt().GetTRNA().GetAa().GetNcbieaa();
  297.                 str_aa_code = CSeqportUtil::GetCode(CSeq_data::e_Ncbieaa,
  298.                                                     aa_code);
  299.                 in_seq.SetNcbieaa().Set() = str_aa_code;
  300.                 CSeqportUtil::Convert(in_seq, &out_seq,
  301.                                       CSeq_data::e_Ncbistdaa);
  302.                 if (out_seq.GetNcbistdaa().Get().size()) {
  303.                     aa_code = out_seq.GetNcbistdaa().Get()[0];
  304.                     tmp_label = CSeqportUtil::GetIupacaa3(aa_code);
  305.                 } else {
  306.                     s_GetRnaRefLabelFromComment(feat, label, label_type,
  307.                                                 type_label);
  308.                 }
  309.                 break;
  310.             case CTrna_ext::C_Aa::e_Ncbi8aa:
  311.                 // Convert an e_Ncbi8aa code to an Iupacaa3 code for the label
  312.                 aa_code = rna.GetExt().GetTRNA().GetAa().GetNcbi8aa();
  313.                 tmp_label = CSeqportUtil::GetIupacaa3(aa_code);
  314.                 break;
  315.             case CTrna_ext::C_Aa::e_Ncbistdaa:
  316.                 // Convert an e_Ncbistdaa code to an Iupacaa3 code for the label
  317.                 aa_code = rna.GetExt().GetTRNA().GetAa().GetNcbistdaa();
  318.                 tmp_label = CSeqportUtil::GetIupacaa3(aa_code);
  319.                 break;
  320.             default:
  321.                 break;
  322.             }
  323.         
  324.             // Append to label, depending on ELabelType
  325.             if (label_type == eContent  &&  type_label != 0) {
  326.                 *label += *type_label + "-" + tmp_label;
  327.             } else if (!tmp_label.empty()) {
  328.                 *label += tmp_label;
  329.             } else if (type_label) {
  330.                 *label += *type_label;
  331.             }
  332.         } catch (CSeqportUtil::CBadIndex&) {
  333.             // fall back to comment (if any)
  334.             s_GetRnaRefLabelFromComment(feat, label, label_type, type_label);
  335.         }
  336.         
  337.         break;
  338.     }}       
  339. }
  340. // Appends a label to tlabel for a CImp_feat. A return value of true indicates 
  341. // that the label was created for a CImp_feat key = "Site-ref" 
  342. inline
  343. static bool s_GetImpLabel
  344. (const CSeq_feat&      feat, 
  345.  string*               tlabel,
  346.  ELabelType            label_type,
  347.  const string*         type_label)
  348. {
  349.     // Return if tlablel does not exist or feature data is not Imp-feat
  350.     if (!tlabel  ||  !feat.GetData().IsImp()) {
  351.         return false;
  352.     }
  353.     
  354.     const string& key = feat.GetData().GetImp().GetKey();
  355.     bool empty = true;
  356.     
  357.     // If the key is Site-ref
  358.     if (!NStr::CompareNocase(key, "Site-ref")) {
  359.         if (feat.IsSetCit()) {
  360.             // Create label based on Pub-set
  361.             feat.GetCit().GetLabel(tlabel);
  362.             return true;
  363.         }
  364.     // else if the key is not Site-ref
  365.     } else if (label_type == eContent) {
  366.         // If the key is CDS
  367.         if (!NStr::CompareNocase(key, "CDS")) {
  368.             *tlabel += "[CDS]";
  369.         // else if the key is repeat_unit or repeat_region
  370.         } else if (!NStr::CompareNocase(key, "repeat_unit")  ||
  371.                    !NStr::CompareNocase(key, "repeat_region")) {
  372.             if (feat.IsSetQual()) {
  373.                 // Loop thru the feature qualifiers
  374.                 ITERATE( CSeq_feat::TQual, it, feat.GetQual()) {
  375.                     // If qualifier qual is rpt_family append qualifier val
  376.                     if (!NStr::CompareNocase((*it)->GetQual(),"rpt_family")) { 
  377.                         *tlabel += (*it)->GetVal();
  378.                         empty = false;
  379.                         break;
  380.                     }
  381.                 }
  382.             }
  383.             
  384.             // If nothing has been appended yet
  385.             if (empty) {
  386.                 *tlabel += type_label ? *type_label : string("");
  387.             }
  388.         // else if the key is STS
  389.         } else if (!NStr::CompareNocase(key, "STS")) {
  390.             if (feat.IsSetQual()) {
  391.                 ITERATE( CSeq_feat::TQual, it, feat.GetQual()) {
  392.                     if (!NStr::CompareNocase((*it)->GetQual(),"standard_name"))
  393.                     { 
  394.                            *tlabel = (*it)->GetVal();
  395.                            empty = false;
  396.                            break;
  397.                     }
  398.                 }
  399.             }
  400.             
  401.             // If nothing has been appended yet
  402.             if (empty) {
  403.                 if (feat.IsSetComment()) {
  404.                     size_t pos = feat.GetComment().find(";");
  405.                     if (pos == string::npos) {
  406.                         *tlabel += feat.GetComment();
  407.                     } else {
  408.                         *tlabel += feat.GetComment().substr(0, pos);
  409.                     } 
  410.                 } else {
  411.                     *tlabel += type_label ? *type_label : string("");
  412.                 }
  413.             }
  414.         // else if the key is misc_feature
  415.         } else if (NStr::CompareNocase(key, "misc_feature")) {
  416.             if (feat.IsSetQual()) {
  417.                 // Look for a single qualifier qual in order of preference 
  418.                 // "standard_name", "function", "number", any and
  419.                 // append to tlabel and return if found
  420.                 ITERATE(CSeq_feat::TQual, it, feat.GetQual()) {
  421.                     if (!NStr::CompareNocase((*it)->GetQual(),"standard_name"))
  422.                     {
  423.                          *tlabel += (*it)->GetVal();
  424.                          return false;
  425.                     }
  426.                 }
  427.                 ITERATE(CSeq_feat::TQual, it, feat.GetQual()) {
  428.                     if (!NStr::CompareNocase((*it)->GetQual(), "function")) {
  429.                          *tlabel += (*it)->GetVal();
  430.                          return false;
  431.                     }
  432.                 }
  433.                 ITERATE(CSeq_feat::TQual, it, feat.GetQual()) {
  434.                     if (!NStr::CompareNocase((*it)->GetQual(), "number")) {
  435.                         *tlabel += (*it)->GetVal();
  436.                         return false;
  437.                     }
  438.                 }
  439.                 ITERATE(CSeq_feat::TQual, it, feat.GetQual()) {
  440.                     *tlabel += (*it)->GetVal();
  441.                     return false;
  442.                 }
  443.                 // Append type_label if there is one
  444.                 if (empty) {
  445.                     *tlabel += type_label ? *type_label : string("");
  446.                     return false;
  447.                 }
  448.             }
  449.         }
  450.                 
  451.     } 
  452.     return false;                
  453. }
  454.  
  455. // Return a label based on the content of the feature
  456. void s_GetContentLabel
  457. (const CSeq_feat&      feat,
  458.  string*               label,
  459.  const string*         type_label,
  460.  ELabelType            label_type, 
  461.  CScope*               scope)
  462. {
  463.     string tlabel;
  464.     
  465.     // Get a content label dependent on the type of the feature data
  466.     switch (feat.GetData().Which()) {
  467.     case CSeqFeatData::e_Gene:
  468.         feat.GetData().GetGene().GetLabel(&tlabel);
  469.         break;
  470.     case CSeqFeatData::e_Org:
  471.         feat.GetData().GetOrg().GetLabel(&tlabel);
  472.         break;
  473.     case CSeqFeatData::e_Cdregion:
  474.         s_GetCdregionLabel(feat, &tlabel, scope);
  475.         break;
  476.     case CSeqFeatData::e_Prot:
  477.         feat.GetData().GetProt().GetLabel(&tlabel);
  478.         break;
  479.     case CSeqFeatData::e_Rna:
  480.         s_GetRnaRefLabel(feat, &tlabel, label_type, type_label);
  481.         break;  
  482.     case CSeqFeatData::e_Pub:
  483.         feat.GetData().GetPub().GetPub().GetLabel(&tlabel); 
  484.         break;
  485.     case CSeqFeatData::e_Seq:
  486.         break;
  487.     case CSeqFeatData::e_Imp:
  488.         if (s_GetImpLabel(feat, &tlabel, label_type, type_label)) {
  489.             *label += tlabel;
  490.             return;
  491.         }
  492.         break;
  493.     case CSeqFeatData::e_Region:
  494.         if (feat.GetData().GetRegion().find("Domain") != string::npos  && 
  495.                 feat.IsSetComment()) {
  496.             tlabel += feat.GetComment();
  497.         } else {
  498.             tlabel += feat.GetData().GetRegion();
  499.         }
  500.         break;
  501.     case CSeqFeatData::e_Comment:
  502.         tlabel += feat.IsSetComment() ? feat.GetComment() : string("");
  503.         break;
  504.     case CSeqFeatData::e_Bond:
  505.         // Get the ASN string name for the enumerated EBond type
  506.         tlabel += CSeqFeatData::GetTypeInfo_enum_EBond()
  507.             ->FindName(feat.GetData().GetBond(), true);
  508.         break;
  509.     case CSeqFeatData::e_Site:
  510.         // Get the ASN string name for the enumerated ESite type
  511.         tlabel += CSeqFeatData::GetTypeInfo_enum_ESite()
  512.             ->FindName(feat.GetData().GetSite(), true);
  513.         break;
  514.     case CSeqFeatData::e_Rsite:
  515.         switch (feat.GetData().GetRsite().Which()) {
  516.         case CRsite_ref::e_Str:
  517.             tlabel += feat.GetData().GetRsite().GetStr();
  518.             break;
  519.         case CRsite_ref::e_Db:
  520.             tlabel += feat.GetData().GetRsite().GetDb().GetTag().IsStr() ?
  521.                 feat.GetData().GetRsite().GetDb().GetTag().GetStr() : 
  522.                 string("?");
  523.             break;
  524.         default:
  525.             break;
  526.         }
  527.         break;
  528.     case CSeqFeatData::e_User:
  529.         if (feat.GetData().GetUser().IsSetClass()) {
  530.             tlabel += feat.GetData().GetUser().GetClass();
  531.         } else if (feat.GetData().GetUser().GetType().IsStr()) {
  532.             tlabel += feat.GetData().GetUser().GetType().GetStr();
  533.         }
  534.     case CSeqFeatData::e_Txinit:
  535.         break;
  536.     case CSeqFeatData::e_Num:
  537.         break;
  538.     case CSeqFeatData::e_Psec_str:
  539.         tlabel += CSeqFeatData::GetTypeInfo_enum_EPsec_str()
  540.             ->FindName(feat.GetData().GetPsec_str(), true);
  541.         break;    
  542.     case CSeqFeatData::e_Non_std_residue:
  543.         tlabel += feat.GetData().GetNon_std_residue();
  544.         break;
  545.     case CSeqFeatData::e_Het:
  546.         tlabel += feat.GetData().GetHet().Get();
  547.         break;        
  548.     case CSeqFeatData::e_Biosrc:
  549.         feat.GetData().GetBiosrc().GetOrg().GetLabel(&tlabel);
  550.         break;        
  551.     default:
  552.         break;
  553.     }
  554.     
  555.     // Return if a label has been calculated above
  556.     if (!tlabel.empty()) {
  557.         *label += tlabel;
  558.         return;
  559.     }
  560.     
  561.     // Put Seq-feat qual into label
  562.     if (feat.IsSetQual()) {
  563.         string prefix("/");
  564.         ITERATE(CSeq_feat::TQual, it, feat.GetQual()) {
  565.             tlabel += prefix + (**it).GetQual();
  566.             prefix = " ";
  567.             if (!(**it).GetVal().empty()) {
  568.                 tlabel += "=" + (**it).GetVal();
  569.             }
  570.         }
  571.     }
  572.     
  573.     // Put Seq-feat comment into label
  574.     if (feat.IsSetComment()) {
  575.         if (tlabel.empty()) {
  576.             tlabel = feat.GetComment();
  577.         } else {
  578.             tlabel += "; " + feat.GetComment();
  579.         }
  580.     }
  581.     
  582.     *label += tlabel;
  583. }
  584. void GetLabel
  585. (const CSeq_feat&    feat,
  586.  string*             label,
  587.  ELabelType          label_type,
  588.  CScope*             scope)
  589. {
  590.  
  591.     // Ensure that label exists
  592.     if (!label) {
  593.         return;
  594.     }
  595.     
  596.     // Get the type label
  597.     string type_label;
  598.     s_GetTypeLabel(feat, &type_label);
  599.     
  600.     // Append the type label and return if content label not required
  601.     if (label_type == eBoth) {
  602.         *label += type_label + ": ";
  603.     } else if (label_type == eType) {
  604.         *label += type_label;
  605.         return;
  606.     }
  607.     
  608.     // Append the content label
  609.     size_t label_len = label->size();
  610.     s_GetContentLabel(feat, label, &type_label, label_type, scope);
  611.     
  612.     // If there is no content label, append the type label
  613.     if (label->size() == label_len  &&  label_type == eContent) {
  614.         *label += type_label;
  615.     }
  616. }
  617. END_SCOPE(feature)
  618. END_SCOPE(objects)
  619. END_NCBI_SCOPE
  620. /*
  621. * ===========================================================================
  622. * $Log: feature.cpp,v $
  623. * Revision 1000.1  2004/06/01 19:25:23  gouriano
  624. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.13
  625. *
  626. * Revision 1.13  2004/05/21 21:42:14  gorelenk
  627. * Added PCH ncbi_pch.hpp
  628. *
  629. * Revision 1.12  2003/08/21 12:09:08  dicuccio
  630. * Added processing of CDS in case the CDS is just an open reading frame
  631. *
  632. * Revision 1.11  2003/08/08 18:12:19  dicuccio
  633. * Fixed bug in s_GetRnaRefLabel(): inadverted '&' instead of '&&'
  634. *
  635. * Revision 1.10  2003/07/22 21:48:26  vasilche
  636. * Use typedef for member access.
  637. *
  638. * Revision 1.9  2003/06/02 16:06:39  dicuccio
  639. * Rearranged src/objects/ subtree.  This includes the following shifts:
  640. *     - src/objects/asn2asn --> arc/app/asn2asn
  641. *     - src/objects/testmedline --> src/objects/ncbimime/test
  642. *     - src/objects/objmgr --> src/objmgr
  643. *     - src/objects/util --> src/objmgr/util
  644. *     - src/objects/alnmgr --> src/objtools/alnmgr
  645. *     - src/objects/flat --> src/objtools/flat
  646. *     - src/objects/validator --> src/objtools/validator
  647. *     - src/objects/cddalignview --> src/objtools/cddalignview
  648. * In addition, libseq now includes six of the objects/seq... libs, and libmmdb
  649. * replaces the three libmmdb? libs.
  650. *
  651. * Revision 1.8  2003/03/11 16:00:58  kuznets
  652. * iterate -> ITERATE
  653. *
  654. * Revision 1.7  2002/12/31 15:09:58  dicuccio
  655. * Removed unneeded headers for Featdef classes
  656. *
  657. * Revision 1.6  2002/12/26 21:17:06  dicuccio
  658. * Minor tweaks to avoid compiler warnings in MSVC (remove unused variables)
  659. *
  660. * Revision 1.5  2002/08/26 16:29:41  ucko
  661. * Be even more careful with TRNA extensions.
  662. *
  663. * Revision 1.4  2002/08/21 15:30:30  ucko
  664. * Handle empty tRNA extensions.
  665. *
  666. * Revision 1.3  2002/08/20 20:01:50  ucko
  667. * s_GetRnaRefLabel: factor out code to look at comments, and fall back
  668. * on it for bogus TRNA extensions.
  669. *
  670. * Revision 1.2  2002/06/07 16:11:21  ucko
  671. * Move everything into the "feature" namespace.
  672. *
  673. * Revision 1.1  2002/06/06 18:45:03  clausen
  674. * Initial version
  675. *
  676. * ===========================================================================
  677. */