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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: comment_item.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:43:50  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: comment_item.cpp,v 1000.2 2004/06/01 19:43:50 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:  Mati Shomrat, NCBI
  35. *
  36. * File Description:
  37. *   flat-file generator -- comment item implementation
  38. *
  39. */
  40. #include <ncbi_pch.hpp>
  41. #include <corelib/ncbistd.hpp>
  42. #include <objects/seqfeat/Seq_feat.hpp>
  43. #include <objects/seq/Bioseq.hpp>
  44. #include <objects/seq/Seq_inst.hpp>
  45. #include <objects/seq/Seq_ext.hpp>
  46. #include <objects/seq/Delta_ext.hpp>
  47. #include <objects/seq/Delta_seq.hpp>
  48. #include <objects/seq/Seq_literal.hpp>
  49. #include <objects/seq/Seq_hist.hpp>
  50. #include <objects/seq/Seq_hist_rec.hpp>
  51. #include <objects/seq/Seqdesc.hpp>
  52. #include <objects/seq/MolInfo.hpp>
  53. #include <objects/seqfeat/BioSource.hpp>
  54. #include <objects/seqfeat/Org_ref.hpp>
  55. #include <objects/general/User_object.hpp>
  56. #include <objects/general/User_field.hpp>
  57. #include <objects/general/Object_id.hpp>
  58. #include <objects/general/Date.hpp>
  59. #include <objects/general/Dbtag.hpp>
  60. #include <objmgr/seqdesc_ci.hpp>
  61. #include <objtools/format/formatter.hpp>
  62. #include <objtools/format/text_ostream.hpp>
  63. #include <objtools/format/items/comment_item.hpp>
  64. #include <objtools/format/context.hpp>
  65. #include "utils.hpp"
  66. BEGIN_NCBI_SCOPE
  67. BEGIN_SCOPE(objects)
  68. // static variables initialization
  69. bool CCommentItem::sm_FirstComment = true;
  70. const string CCommentItem::kNsAreGaps = "The strings of n's in this record " 
  71. "represent gaps between contigs, and the length of each string corresponds " 
  72. "to the length of the gap.";
  73. /////////////////////////////////////////////////////////////////////////////
  74. //
  75. //  CCommentItem
  76. CCommentItem::CCommentItem(CBioseqContext& ctx) :
  77.     CFlatItem(&ctx), m_First(false)
  78. {
  79.     swap(m_First, sm_FirstComment);
  80. }
  81. CCommentItem::CCommentItem
  82. (const string& comment,
  83.  CBioseqContext& ctx,
  84.  const CSerialObject* obj) :
  85.     CFlatItem(&ctx), m_Comment(comment)
  86. {
  87.     swap(m_First, sm_FirstComment);
  88.     if ( obj != 0 ) {
  89.         x_SetObject(*obj);
  90.     }
  91. }
  92.     
  93. CCommentItem::CCommentItem(const CSeqdesc&  desc, CBioseqContext& ctx) :
  94.     CFlatItem(&ctx)
  95. {
  96.     swap(m_First, sm_FirstComment);
  97.     x_SetObject(desc);
  98.     x_GatherInfo(ctx);
  99.     if ( m_Comment.empty() ) {
  100.         x_SetSkip();
  101.     }
  102. }
  103. void CCommentItem::Format
  104. (IFormatter& formatter,
  105.  IFlatTextOStream& text_os) const
  106. {
  107.     formatter.FormatComment(*this, text_os);
  108. }
  109. string CCommentItem::GetStringForTPA
  110. (const CUser_object& uo,
  111.  CBioseqContext& ctx)
  112. {
  113.     static const string tpa_string = 
  114.         "THIRD PARTY ANNOTATION DATABASE: This TPA record uses data from DDBJ/EMBL/GenBank ";
  115.     if ( !ctx.IsTPA()  ||  ctx.IsRefSeq() ) {
  116.         return kEmptyStr;
  117.     }
  118.     if ( !uo.CanGetType()  ||  !uo.GetType().IsStr()  ||  
  119.          uo.GetType().GetStr() != "TpaAssembly" ) {
  120.         return kEmptyStr;
  121.     }
  122.     const CSeq_inst& inst = ctx.GetHandle().GetInst();
  123.     if ( inst.CanGetHist()  &&  inst.GetHist().CanGetAssembly() ) {
  124.         return kEmptyStr;
  125.     }
  126.     string id;
  127.     vector<string> accessions;
  128.     ITERATE (CUser_object::TData, curr, uo.GetData()) {
  129.         const CUser_field& uf = **curr;
  130.         if ( !uf.CanGetData()  ||  !uf.GetData().IsFields() ) {
  131.             continue;
  132.         }
  133.         ITERATE (CUser_field::C_Data::TFields, ufi, uf.GetData().GetFields()) {
  134.             if( !(*ufi)->CanGetData()  ||  !(*ufi)->GetData().IsStr()  ||
  135.                 !(*ufi)->CanGetLabel() ) {
  136.                 continue;
  137.             }
  138.             const CObject_id& oid = (*ufi)->GetLabel();
  139.             if ( oid.IsStr()  &&  
  140.                  (NStr::CompareNocase(oid.GetStr(), "accession") == 0) ) {
  141.                 string acc = (*ufi)->GetData().GetStr();
  142.                 if ( !acc.empty() ) {
  143.                     accessions.push_back(NStr::ToUpper(acc));
  144.                 }
  145.             }
  146.         }
  147.     }
  148.     if ( accessions.empty() ) {
  149.         return kEmptyStr;
  150.     }
  151.     CNcbiOstrstream text;
  152.     text << tpa_string << ((accessions.size() > 1) ? "entries " : "entry ");
  153.     size_t size = accessions.size();
  154.     size_t last = size - 1;
  155.     for ( size_t i = 0; i < size; ) {
  156.         text << accessions[i];
  157.         ++i;
  158.         if ( i < size ) {
  159.             text << ((i == last) ? " and " : ", ");
  160.         }
  161.     }
  162.     return CNcbiOstrstreamToString(text);
  163. }
  164. string CCommentItem::GetStringForBankIt(const CUser_object& uo)
  165. {
  166.     if ( !uo.CanGetType()  ||  !uo.GetType().IsStr()  ||
  167.          uo.GetType().GetStr() != "Submission" ) {
  168.         return kEmptyStr;
  169.     }
  170.     const string* uvc = 0, *bic = 0;
  171.     if ( uo.HasField("UniVecComment") ) {
  172.         const CUser_field& uf = uo.GetField("UniVecComment");
  173.         if ( uf.CanGetData()  &&  uf.GetData().IsStr() ) {
  174.             uvc = &(uf.GetData().GetStr());
  175.         } 
  176.     }
  177.     if ( uo.HasField("AdditionalComment") ) {
  178.         const CUser_field& uf = uo.GetField("AdditionalComment");
  179.         if ( uf.CanGetData()  &&  uf.GetData().IsStr() ) {
  180.             bic = &(uf.GetData().GetStr());
  181.         } 
  182.     }
  183.     CNcbiOstrstream text;
  184.     if ( uvc != 0  &&  bic != 0 ) {
  185.         text << "Vector Explanation: " << *uvc << "~Bankit Comment: " << *bic;
  186.     } else if ( uvc != 0 ) {
  187.         text << "Vector Explanation: " << *uvc;
  188.     } else if ( bic != 0 ) {
  189.          text << "Bankit Comment: " << *bic;
  190.     }
  191.     return CNcbiOstrstreamToString(text);
  192. }
  193. CCommentItem::TRefTrackStatus CCommentItem::GetRefTrackStatus
  194. (const CUser_object& uo,
  195.  string* st)
  196. {
  197.     TRefTrackStatus retval = eRefTrackStatus_Unknown;
  198.     if ( st != 0 ) {
  199.         st->erase();
  200.     }
  201.     if ( !uo.HasField("Status") ) {
  202.         return retval;
  203.     }
  204.     const CUser_field& field = uo.GetField("Status");
  205.     if ( field.GetData().IsStr() ) {
  206.         string status = field.GetData().GetStr();
  207.         if ( status == "Inferred" ) { 
  208.             retval = eRefTrackStatus_Inferred;
  209.         } else if ( status == "Provisional" ) {
  210.             retval = eRefTrackStatus_Provisional;
  211.         } else if ( status == "Predicted" ) {
  212.             retval = eRefTrackStatus_Predicted;
  213.         } else if ( status == "Validated" ) {
  214.             retval = eRefTrackStatus_Validated;
  215.         } else if ( status == "Reviewed" ) {
  216.             retval = eRefTrackStatus_Reviewd;
  217.         } else if ( status == "Model" ) {
  218.             retval = eRefTrackStatus_Model;
  219.         } else if ( status == "WGS" ) {
  220.             retval = eRefTrackStatus_WGS;
  221.         }
  222.         if ( st != 0  &&  retval != eRefTrackStatus_Unknown ) {
  223.             *st = NStr::ToUpper(status);
  224.         }
  225.     }
  226.     return retval;
  227. }
  228. string CCommentItem::GetStringForRefTrack(const CUser_object& uo)
  229. {
  230.     if ( !uo.CanGetType()  ||  !uo.GetType().IsStr()  ||
  231.          uo.GetType().GetStr() != "RefGeneTracking" ) {
  232.         return kEmptyStr;
  233.     }
  234.     string status_str;
  235.     TRefTrackStatus status = GetRefTrackStatus(uo, &status_str);
  236.     if ( status == eRefTrackStatus_Unknown ) {
  237.         return kEmptyStr;
  238.     }
  239.     string collaborator;
  240.     if ( uo.HasField("Collaborator") ) {
  241.         const CUser_field& colab_field = uo.GetField("Collaborator");
  242.         if ( colab_field.GetData().IsStr() ) {
  243.             collaborator = colab_field.GetData().GetStr();
  244.         }
  245.     }
  246.     string source;
  247.     if ( uo.HasField("GenomicSource") ) {
  248.         const CUser_field& source_field = uo.GetField("GenomicSource");
  249.         if ( source_field.GetData().IsStr() ) {
  250.             source = source_field.GetData().GetStr();
  251.         }
  252.     }
  253.     CNcbiOstrstream oss;
  254.     oss << status_str << " REFSEQ: ";
  255.     switch ( status ) {
  256.     case eRefTrackStatus_Inferred:
  257.         oss << "This record is predicted by genome sequence analysis and is "
  258.             << "not yet supported by experimental evidence.";
  259.         break;
  260.     case eRefTrackStatus_Provisional:
  261.         oss << "This record has not yet been subject to final NCBI review.";
  262.         break;
  263.     case eRefTrackStatus_Predicted:
  264.         oss << "The mRNA record is supported by experimental evidence;"
  265.             << "however, the coding sequence is predicted.";
  266.         break;
  267.     case eRefTrackStatus_Validated:
  268.         oss << "This record has undergone preliminary review of the sequence,"
  269.             << "but has not yet been subject to final review.";
  270.         break;
  271.     case eRefTrackStatus_Reviewd:
  272.         oss << "This record has been curated by " 
  273.             << (collaborator.empty() ? "NCBI staff" : collaborator) << '.';
  274.         break;
  275.     case eRefTrackStatus_Model:
  276.         oss << "This record is predicted by automated computational analysis.";
  277.         break;
  278.     case eRefTrackStatus_WGS:
  279.         oss << "This record is provided to represent a collection of "
  280.             << "whole genome shotgun sequences.";
  281.         break;
  282.     default:
  283.         break;
  284.     }
  285.     if ( status != eRefTrackStatus_Reviewd  &&  !collaborator.empty() ) {
  286.         oss << "This record has been curated by " << collaborator << '.';
  287.     }
  288.     if ( !source.empty() ) {
  289.         oss << "This record is derived from an annotated genomic sequence ("
  290.             << source << ").";
  291.     }
  292.     vector < pair<const string*, bool> > assembly;
  293.     if ( uo.HasField("Assembly") ) {
  294.         const CUser_field& field = uo.GetField("Assembly");
  295.         if ( field.GetData().IsFields() ) {
  296.             ITERATE (CUser_field::C_Data::TFields, fit, field.GetData().GetFields()) {
  297.                 if ( !(*fit)->GetData().IsFields() ) {
  298.                     continue;
  299.                 }
  300.                 ITERATE (CUser_field::C_Data::TFields, it, (*fit)->GetData().GetFields()) {
  301.                     const CUser_field& uf = **it;
  302.                     if ( !uf.CanGetLabel()  ||  !uf.GetLabel().IsStr() ) {
  303.                         continue;
  304.                     }
  305.                     const string& label = uf.GetLabel().GetStr();
  306.                     if ( label == "accession"  ||  label == "name" ) {
  307.                         bool is_accn = (label == "accession");
  308.                         if ( uf.GetData().IsStr()  &&  !uf.GetData().GetStr().empty() ) {
  309.                             assembly.push_back(make_pair(&uf.GetData().GetStr(), is_accn));
  310.                         }
  311.                     }
  312.                 }
  313.             }
  314.         }
  315.     }
  316.     if ( assembly.size() > 0 ) {
  317.         oss << " The reference sequence was derived from ";
  318.         size_t assembly_size = assembly.size();
  319.         for ( size_t i = 0; i < assembly_size; ++i ) {
  320.             if ( i > 0  ) {
  321.                 oss << ((i < assembly_size - 1) ? ", " : " and ");
  322.             }
  323.             oss << *(assembly[i].first);
  324.         }
  325.         oss << '.';
  326.     }
  327.     return CNcbiOstrstreamToString(oss);
  328. }
  329. bool CCommentItem::NsAreGaps(const CBioseq_Handle& seq, CBioseqContext& ctx)
  330. {
  331.     if ( !seq.IsSetInst()  ||  !seq.IsSetInst_Ext() ) {
  332.         return false;
  333.     }
  334.     if ( ctx.GetRepr() == CSeq_inst::eRepr_delta  &&  ctx.IsWGS()  &&
  335.          seq.GetInst_Ext().IsDelta() ) {
  336.         ITERATE (CDelta_ext::Tdata, iter, seq.GetInst_Ext().GetDelta().Get()) {
  337.             const CDelta_seq& dseg = **iter;
  338.             if ( dseg.IsLiteral() ) {
  339.                 const CSeq_literal& lit = dseg.GetLiteral();
  340.                 if ( !lit.CanGetSeq_data()  &&  lit.CanGetLength()  &&
  341.                       lit.GetLength() > 0 ) {
  342.                     return true;
  343.                 }
  344.             }
  345.         }
  346.     }
  347.     return false;
  348. }
  349. string CCommentItem::GetStringForWGS(CBioseqContext& ctx)
  350. {
  351.     static const string default_str = "?";
  352.     if ( !ctx.IsWGSMaster()  ||  ctx.GetWGSMasterAccn().empty() ) {
  353.         return kEmptyStr;
  354.     }
  355.     const string& wgsaccn = ctx.GetWGSMasterAccn();
  356.     const string* taxname = 0;
  357.     for (CSeqdesc_CI it(ctx.GetHandle(), CSeqdesc::e_Source); it; ++it) {
  358.         const CBioSource& src = it->GetSource();
  359.         if ( src.CanGetOrg()  &&  src.GetOrg().CanGetTaxname() ) {
  360.             taxname = &(src.GetOrg().GetTaxname());
  361.         }
  362.     }
  363.     const string* first = 0, *last = 0;
  364.     for (CSeqdesc_CI it(ctx.GetHandle(), CSeqdesc::e_User); it; ++it) {
  365.         const CUser_object& uo = it->GetUser();
  366.         if ( uo.CanGetType()  &&  uo.GetType().IsStr()  &&
  367.              NStr::CompareNocase(uo.GetType().GetStr(), "WGSProjects") == 0 ) {
  368.             if ( uo.HasField("WGS_accession_first") ) {
  369.                 const CUser_field& uf = uo.GetField("WGS_accession_first");
  370.                 if ( uf.CanGetData()  &&  uf.GetData().IsStr() ) {
  371.                     first = &(uf.GetData().GetStr());
  372.                 }
  373.             }
  374.             if ( uo.HasField("WGS_accession_last") ) {
  375.                 const CUser_field& uf = uo.GetField("WGS_accession_last");
  376.                 if ( uf.CanGetData()  &&  uf.GetData().IsStr() ) {
  377.                     last = &(uf.GetData().GetStr());
  378.                 }
  379.             }
  380.         }
  381.     }
  382.     if ( taxname == 0  ||  taxname->empty() ) {
  383.         taxname = &default_str;
  384.     }
  385.     if ( first == 0  ||  first->empty() ) {
  386.         first = &default_str;
  387.     }
  388.     if ( last == 0  ||  last->empty() ) {
  389.         last = &default_str;
  390.     }
  391.     string version = (wgsaccn.length() == 15) ? wgsaccn.substr(4) :
  392.                                                 wgsaccn.substr(7);
  393.     CNcbiOstrstream text;
  394.     text << "The " << *taxname 
  395.          << "whole genome shotgun (WGS) project has the project accession " 
  396.          << wgsaccn << ".  This version of the project (" << version 
  397.          << ") has the accession number " << ctx.GetWGSMasterName() << ",";
  398.     if ( (*first != *last) ) {
  399.         text << " and consists of sequences " << *first << "-" << *last;
  400.     } else {
  401.         text << " and consists of sequence " << *first;
  402.     }
  403.     return CNcbiOstrstreamToString(text);
  404. }
  405. string CCommentItem::GetStringForMolinfo(const CMolInfo& mi, CBioseqContext& ctx)
  406. {
  407.     _ASSERT(mi.CanGetCompleteness());
  408.     bool is_prot = ctx.IsProt();
  409.     switch ( mi.GetCompleteness() ) {
  410.     case CMolInfo::eCompleteness_complete:
  411.         return "COMPLETENESS: full length";
  412.     case CMolInfo::eCompleteness_partial:
  413.         return "COMPLETENESS: not full length";
  414.     case CMolInfo::eCompleteness_no_left:
  415.         return (is_prot ? "COMPLETENESS: incomplete on the amino end" :
  416.                           "COMPLETENESS: incomplete on the 5' end");
  417.     case CMolInfo::eCompleteness_no_right:
  418.         return (is_prot ? "COMPLETENESS: incomplete on the carboxy end" :
  419.                           "COMPLETENESS: incomplete on the 3' end");
  420.     case CMolInfo::eCompleteness_no_ends:
  421.         return "COMPLETENESS: incomplete on both ends";
  422.     case CMolInfo::eCompleteness_has_left:
  423.         return (is_prot ? "COMPLETENESS: complete on the amino end" :
  424.                           "COMPLETENESS: complete on the 5' end");
  425.     case CMolInfo::eCompleteness_has_right:
  426.         return (is_prot ? "COMPLETENESS: complete on the carboxy end" :
  427.                           "COMPLETENESS: complete on the 3' end");
  428.     default:
  429.         return "COMPLETENESS: unknown";
  430.     }
  431.     return kEmptyStr;
  432. }
  433. string CCommentItem::GetStringForHTGS(CBioseqContext& ctx)
  434. {
  435.     SDeltaSeqSummary summary;
  436.     if ( ctx.GetRepr() == CSeq_inst::eRepr_delta ) {
  437.         GetDeltaSeqSummary(ctx.GetHandle(), summary);
  438.     }
  439.     CMolInfo::TTech tech = ctx.GetTech();
  440.     CNcbiOstrstream text;
  441.     if ( tech == CMolInfo::eTech_htgs_0 ) {
  442.         if ( summary.num_segs > 0 ) {
  443.             text << "* NOTE: This record contains " << (summary.num_gaps + 1) << " individual~"
  444.                  << "* sequencing reads that have not been assembled into~"
  445.                  << "* contigs. Runs of N are used to separate the reads~"
  446.                  << "* and the order in which they appear is completely~"
  447.                  << "* arbitrary. Low-pass sequence sampling is useful for~"
  448.                  << "* identifying clones that may be gene-rich and allows~"
  449.                  << "* overlap relationships among clones to be deduced.~"
  450.                  << "* However, it should not be assumed that this clone~"
  451.                  << "* will be sequenced to completion. In the event that~"
  452.                  << "* the record is updated, the accession number will~"
  453.                  << "* be preserved.";
  454.         }
  455.         text << "~";
  456.         text << summary.text;
  457.     } else if ( tech == CMolInfo::eTech_htgs_1 ) {
  458.         text << "* NOTE: This is a "working draft" sequence.";
  459.         if ( summary.num_segs > 0 ) {
  460.             text << " It currently~"
  461.                  << "* consists of " << (summary.num_gaps + 1) << " contigs. The true order of the pieces~"
  462.                  << "* is not known and their order in this sequence record is~"
  463.                  << "* arbitrary. Gaps between the contigs are represented as~"
  464.                  << "* runs of N, but the exact sizes of the gaps are unknown.";
  465.         }
  466.         text << "~* This record will be updated with the finished sequence~"
  467.              << "* as soon as it is available and the accession number will~"
  468.              << "* be preserved."
  469.              << "~"
  470.              << summary.text;
  471.     } else if ( tech == CMolInfo::eTech_htgs_2 ) {
  472.         text << "* NOTE: This is a "working draft" sequence.";
  473.         if ( summary.num_segs > 0 ) {
  474.             text << " It currently~* consists of " << (summary.num_gaps + 1) 
  475.                  << " contigs. Gaps between the contigs~"
  476.                  << "* are represented as runs of N. The order of the pieces~"
  477.                  << "* is believed to be correct as given, however the sizes~"
  478.                  << "* of the gaps between them are based on estimates that have~"
  479.                  << "* provided by the submittor.";
  480.         }
  481.         text << "~* This sequence will be replaced~"
  482.              << "* by the finished sequence as soon as it is available and~"
  483.              << "* the accession number will be preserved."
  484.              << "~"
  485.              << summary.text;
  486.     } else if ( !GetTechString(tech).empty() ) {
  487.         text << "Method: " << GetTechString(tech) << ".";
  488.     }
  489.     return CNcbiOstrstreamToString(text);
  490. }
  491. string CCommentItem::GetStringForModelEvidance(const SModelEvidance& me)
  492. {
  493.     CNcbiOstrstream text;
  494.     text << "MODEL " << "REFSEQ" << ":  " << "This record is predicted by "
  495.          << "automated computational analysis. This record is derived from"
  496.          << "an annotated genomic sequence (" << me.name << ")";
  497.     if ( !me.method.empty() ) {
  498.         text << " using gene prediction method: " << me.method;
  499.     }
  500.     if ( me.mrnaEv  ||  me.estEv ) {
  501.         text << ", supported by ";
  502.         if ( me.mrnaEv  &&  me.estEv ) {
  503.             text << "mRNA and EST ";
  504.         } else if ( me.mrnaEv ) {
  505.             text << "mRNA ";
  506.         } else {
  507.             text << "EST ";
  508.         }
  509.         // !!! for html we need much more !!!
  510.         text << "evidence";
  511.     }
  512.     text << "." << ExpandTildes("~Also see:~    ", eTilde_newline) 
  513.          << "Documentation" 
  514.          << ExpandTildes(" of NCBI's Annotation Process~    ", eTilde_newline);
  515.     return CNcbiOstrstreamToString(text);
  516. }
  517. /***************************************************************************/
  518. /*                                 PROTECTED                               */
  519. /***************************************************************************/
  520. void CCommentItem::x_GatherInfo(CBioseqContext& ctx)
  521. {
  522.     const CSeqdesc* desc = dynamic_cast<const CSeqdesc*>(GetObject());
  523.     if ( desc != 0 ) {
  524.         x_GatherDescInfo(*desc);
  525.         return;
  526.     }
  527.     const CSeq_feat* feat = dynamic_cast<const CSeq_feat*>(GetObject());
  528.     if ( feat != 0 ) {
  529.         x_GatherFeatInfo(*feat, ctx);
  530.     }
  531. }
  532. void CCommentItem::x_GatherDescInfo(const CSeqdesc& desc)
  533. {
  534.     string prefix, str, suffix;
  535.     switch ( desc.Which() ) {
  536.     case CSeqdesc::e_Comment:
  537.         {{
  538.             str = desc.GetComment();
  539.         }}
  540.         break;
  541.     case CSeqdesc::e_Maploc:
  542.         {{
  543.             const CDbtag& dbtag = desc.GetMaploc();
  544.             if ( dbtag.CanGetTag() ) {
  545.                 const CObject_id& oid = dbtag.GetTag();
  546.                 if ( oid.IsStr() ) {
  547.                     prefix = "Map location: ";
  548.                     str = oid.GetStr();
  549.                 } else if ( oid.IsId()  &&  dbtag.CanGetDb() ) {
  550.                     prefix = "Map location: (Database ";
  551.                     str = dbtag.GetDb();
  552.                     suffix = "; id # " + NStr::IntToString(oid.GetId()) + ").";
  553.                 }
  554.             }
  555.         }}
  556.         break;
  557.     case CSeqdesc::e_Region:
  558.         {{
  559.             prefix = "Region: ";
  560.             str = desc.GetRegion();
  561.         }}
  562.         break;
  563.     default:
  564.         break;
  565.     }
  566.     if ( str.empty() ) {
  567.         return;
  568.     }
  569.     x_SetCommentWithURLlinks(prefix, str, suffix);
  570.     
  571. }
  572. void CCommentItem::x_GatherFeatInfo(const CSeq_feat&, CBioseqContext&)
  573. {
  574.     // !!!
  575. }
  576. void CCommentItem::x_SetSkip(void)
  577. {
  578.     CFlatItem::x_SetSkip();
  579.     swap(m_First, sm_FirstComment);
  580. }
  581. void CCommentItem::x_SetCommentWithURLlinks
  582. (const string& prefix,
  583.  const string& str,
  584.  const string& suffix)
  585. {
  586.     // !!! test for html - find links within the comment string
  587.     string comment = ExpandTildes(prefix + str + suffix, eTilde_newline);
  588.     size_t pos = comment.find_last_not_of(" ntr");
  589.     if ( pos != NPOS ) {
  590.         comment.erase(pos + 1);
  591.     }
  592.     if ( NStr::EndsWith(str, "..")  &&  !NStr::EndsWith(str, "...") ) {
  593.         comment.erase(str.length() - 1);
  594.     }
  595.     if ( !NStr::EndsWith(str, ".") ) {
  596.         comment += ".";
  597.     }
  598.     
  599.     m_Comment =  comment;
  600. }
  601. /////////////////////////////////////////////////////////////////////////////
  602. //
  603. // Derived Classes
  604. // --- CGenomeAnnotComment
  605. CGenomeAnnotComment::CGenomeAnnotComment
  606. (CBioseqContext& ctx,
  607.  const string& build_num) :
  608.     CCommentItem(ctx), m_GenomeBuildNumber(build_num)
  609. {
  610.     x_GatherInfo(ctx);
  611. }
  612. void CGenomeAnnotComment::x_GatherInfo(CBioseqContext&)
  613. {
  614.     CNcbiOstrstream text;
  615.     text << "GENOME ANNOTATION " << "REFSEQ" << ":  ";
  616.     if ( !m_GenomeBuildNumber.empty() ) {
  617.          text << "Features on this sequence have been produced for build "
  618.               << m_GenomeBuildNumber << " of the NCBI's genome annotation"
  619.               << " [see " << "documentation" << "].";
  620.     } else {
  621.         text << "NCBI contigs are derived from assembled genomic sequence data."
  622.              << "~Also see:~    " << "Documentation" 
  623.              << " of NCBI's Annotation Process~ ";
  624.     }
  625.     
  626.     x_SetComment(ExpandTildes(CNcbiOstrstreamToString(text), eTilde_newline));
  627. }
  628. // --- CHistComment
  629. CHistComment::CHistComment
  630. (EType type,
  631.  const CSeq_hist& hist,
  632.  CBioseqContext& ctx) : 
  633.     CCommentItem(ctx), m_Type(type), m_Hist(&hist)
  634. {
  635.     x_GatherInfo(ctx);
  636.     m_Hist.Reset();
  637. }
  638. string s_CreateHistCommentString
  639. (const string& prefix,
  640.  const string& suffix,
  641.  const CSeq_hist_rec& hist)
  642. {
  643.     _ASSERT(hist.CanGetDate());
  644.     _ASSERT(hist.CanGetIds());
  645.     string date;
  646.     hist.GetDate().GetDate(&date, "%3N %2D, %4Y");
  647.     vector<int> gis;
  648.     ITERATE (CSeq_hist_rec::TIds, id, hist.GetIds()) {
  649.         if ( (*id)->IsGi() ) {
  650.             gis.push_back((*id)->GetGi());
  651.         }
  652.     }
  653.     CNcbiOstrstream text;
  654.     text << prefix << ((gis.size() > 1) ? " or before " : " ") << date 
  655.          << ' ' << suffix;
  656.     if ( gis.empty() ) {
  657.         text << " gi:?";
  658.         return CNcbiOstrstreamToString(text);
  659.     }
  660.     for ( size_t count = 0; count < gis.size(); ++count ) {
  661.         if ( count != 0 ) {
  662.             text << ",";
  663.         }
  664.         text << " gi:" << NStr::IntToString(gis[count]);
  665.     }
  666.     text << '.';
  667.     return CNcbiOstrstreamToString(text);
  668. }
  669. void CHistComment::x_GatherInfo(CBioseqContext&)
  670. {
  671.     _ASSERT(m_Hist);
  672.     switch ( m_Type ) {
  673.     case eReplaced_by:
  674.         x_SetComment(s_CreateHistCommentString(
  675.             "[WARNING] On",
  676.             "this sequence was replaced by a newer version",
  677.             m_Hist->GetReplaced_by()));
  678.         break;
  679.     case eReplaces:
  680.         x_SetComment(s_CreateHistCommentString(
  681.             "On",
  682.             "this sequence version replaced",
  683.             m_Hist->GetReplaces()));
  684.         break;
  685.     }
  686. }
  687. // --- CGsdbComment
  688. CGsdbComment::CGsdbComment(const CDbtag& dbtag, CBioseqContext& ctx) :
  689.     CCommentItem(ctx), m_Dbtag(&dbtag)
  690. {
  691.     x_GatherInfo(ctx);
  692. }
  693. void CGsdbComment::x_GatherInfo(CBioseqContext&)
  694. {
  695.     x_SetComment("GSDB:S:" + m_Dbtag->GetTag().GetId());
  696. }
  697. // --- CLocalIdComment
  698. CLocalIdComment::CLocalIdComment(const CObject_id& oid, CBioseqContext& ctx) :
  699.     CCommentItem(ctx), m_Oid(&oid)
  700. {
  701.     x_GatherInfo(ctx);
  702. }
  703. void CLocalIdComment::x_GatherInfo(CBioseqContext&)
  704. {
  705.     CNcbiOstrstream msg;
  706.     switch ( m_Oid->Which() ) {
  707.     case CObject_id::e_Id:
  708.         msg << "LocalID: " << m_Oid->GetId();    
  709.         break;
  710.     case CObject_id::e_Str:
  711.         if ( m_Oid->GetStr().length() < 100 ) {
  712.             msg << "LocalID: " << m_Oid->GetStr();
  713.         } else {
  714.             msg << "LocalID string too large";
  715.         }
  716.         break;
  717.     default:
  718.         break;
  719.     }
  720.     x_SetComment(CNcbiOstrstreamToString(msg));
  721. }
  722. END_SCOPE(objects)
  723. END_NCBI_SCOPE
  724. /*
  725. * ===========================================================================
  726. *
  727. * $Log: comment_item.cpp,v $
  728. * Revision 1000.2  2004/06/01 19:43:50  gouriano
  729. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.8
  730. *
  731. * Revision 1.8  2004/05/21 21:42:54  gorelenk
  732. * Added PCH ncbi_pch.hpp
  733. *
  734. * Revision 1.7  2004/05/06 17:45:43  shomrat
  735. * + CLocalIdComment
  736. *
  737. * Revision 1.6  2004/04/22 15:51:13  shomrat
  738. * Changes in context
  739. *
  740. * Revision 1.5  2004/04/13 16:45:22  shomrat
  741. * Fixed comment cleanup
  742. *
  743. * Revision 1.4  2004/03/26 17:22:51  shomrat
  744. * Minor fixes to comment string
  745. *
  746. * Revision 1.3  2004/03/05 18:44:05  shomrat
  747. * fixed RefTRack comments
  748. *
  749. * Revision 1.2  2003/12/18 17:43:31  shomrat
  750. * context.hpp moved
  751. *
  752. * Revision 1.1  2003/12/17 20:18:17  shomrat
  753. * Initial Revision (adapted from flat lib)
  754. *
  755. *
  756. * ===========================================================================
  757. */