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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: flat_formatter.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:43:08  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: flat_formatter.cpp,v 1000.2 2004/06/01 19:43:08 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:  Aaron Ucko, NCBI
  35. *
  36. * File Description:
  37. *   new (early 2003) flat-file generator -- base formatter class
  38. *
  39. * ===========================================================================
  40. */
  41. #include <ncbi_pch.hpp>
  42. #include <objtools/flat/flat_items.hpp>
  43. #include <objects/seq/Bioseq.hpp>
  44. #include <objects/seq/Seg_ext.hpp>
  45. #include <objects/seq/Seq_ext.hpp>
  46. #include <objects/seqset/Bioseq_set.hpp>
  47. #include <objects/seqset/Seq_entry.hpp>
  48. #include <objmgr/scope.hpp>
  49. #include <objmgr/seqdesc_ci.hpp>
  50. #include <objmgr/util/sequence.hpp>
  51. BEGIN_NCBI_SCOPE
  52. BEGIN_SCOPE(objects)
  53. void IFlatFormatter::Format(const CSeq_entry& entry, IFlatItemOStream& out,
  54.                             IFlatFormatter::TFilterFlags flags,
  55.                             CFlatContext* ctx)
  56. {
  57.     CRef<CFlatContext> ctx0;
  58.     if (ctx == 0) {
  59.         ctx0.Reset(new CFlatContext);
  60.         ctx = ctx0;
  61.         ctx->SetFlags(entry, true);
  62.     } else {
  63.         ctx->SetFlags(entry, false);
  64.     }
  65.     if (entry.IsSeq()) {
  66.         const CBioseq& seq   = entry.GetSeq();
  67.         if (flags & (seq.IsAa() ? fSkipProteins : fSkipNucleotides)) {
  68.             return;
  69.         }
  70.         Format(seq, out, ctx);
  71.     } else {
  72.         const CBioseq_set& bss = entry.GetSet();
  73.         ITERATE (CBioseq_set::TSeq_set, it, bss.GetSeq_set()) {
  74.             if (ctx->InSegSet()  &&  (*it)->IsSet()
  75.                 &&  (*it)->GetSet().GetClass() == CBioseq_set::eClass_parts) {
  76.                 // skip internal parts sets -- covered indirectly
  77.                 continue;
  78.             }
  79.             CRef<CFlatContext> ctx2(new CFlatContext(*ctx));
  80.             Format(**it, out, flags, ctx2);
  81.             if (ctx->GetSegmentCount() > 0) {
  82.                 ++ctx->m_SegmentNum;
  83.             }
  84.         }
  85.     }
  86. }
  87. void IFlatFormatter::Format(const CBioseq& seq, IFlatItemOStream& out,
  88.                             CFlatContext* ctx)
  89. {
  90.     CRef<CFlatContext> ctx0;
  91.     if (ctx == 0) {
  92.         ctx0.Reset(new CFlatContext);
  93.         ctx = ctx0;
  94.         if (seq.GetParentEntry()) {
  95.             ctx->SetFlags(*seq.GetParentEntry(), true);
  96.         }
  97.     }
  98.     // XXX - also count deltas containing external references
  99.     bool contig = false; // put in ctx instead?
  100.     if (seq.GetInst().GetRepr() == CSeq_inst::eRepr_seg) {
  101.         if (x_FormatSegments(seq, out, *ctx)) {
  102.             return;
  103.         } else if (m_Style != eStyle_Master
  104.                    ||  (m_Flags & fShowContigInMaster)) {
  105.             contig = true;
  106.         }
  107.     }
  108.     ctx->m_Formatter = const_cast<IFlatFormatter*>(this);
  109.     ctx->m_Handle    = m_Scope->GetBioseqHandle(seq);
  110.     ctx->m_References.clear();
  111.     ctx->m_Mol       = seq.GetInst().GetMol();
  112.     ctx->m_IsProt    = seq.IsAa();
  113.     if ( !ctx->m_Location ) {
  114.         CRef<CSeq_loc> loc(new CSeq_loc);
  115.         loc->SetWhole().Assign(*ctx->m_Handle.GetSeqId());
  116.         ctx->m_Location = loc;
  117.     }
  118.     out << new CFlatForehead(*ctx);
  119.     out << new CFlatHead(*ctx);
  120.     out << new CFlatKeywords(*ctx);
  121.     if (ctx->GetSegmentCount()) {
  122.         out << new CFlatSegment(*ctx);
  123.     }
  124.     out << new CFlatSource(*ctx);
  125.     x_FormatReferences(*ctx, out);
  126.     out << new CFlatComment(*ctx);
  127.     if (ctx->IsTPA()) { // also some types of refseq...
  128.         out << new CFlatPrimary(*ctx);
  129.     }
  130.     out << new CFlatFeatHeader;
  131.     x_FormatFeatures(*ctx, out, true);
  132.     if (ctx->IsWGSMaster()) {
  133.         out << new CFlatWGSRange(*ctx);
  134.     } else if (ctx->IsRefSeqGenome()) { // NS_
  135.         out << new CFlatGenomeInfo(*ctx);
  136.     } else {
  137.         if ( !contig  ||  (m_Flags & fShowContigFeatures)
  138.             ||  m_Style == eStyle_Master) {
  139.             x_FormatFeatures(*ctx, out, false);
  140.         }
  141.         if (contig) {
  142.             out << new CFlatContig(*ctx);
  143.         }
  144.         if ( !contig  ||  m_Style == eStyle_Master) {
  145.             out << new CFlatDataHeader(*ctx);
  146.             out << new CFlatData(*ctx);
  147.         }
  148.     }
  149.     out << new CFlatTail;
  150. }
  151. void IFlatFormatter::Format(const CSeq_loc& loc, bool adjust_coords,
  152.                             IFlatItemOStream& out, CFlatContext* ctx)
  153. {
  154.     if ( !adjust_coords ) {
  155.         _ASSERT(sequence::IsOneBioseq(loc)); // otherwise, should split...
  156.     }
  157.     CBioseq_Handle h = m_Scope->GetBioseqHandle(loc);
  158.     CRef<CFlatContext> ctx0;
  159.     if (ctx == 0) {
  160.         ctx0.Reset(new CFlatContext);
  161.         ctx = ctx0;
  162.         ctx->SetFlags(*h.GetBioseqCore()->GetParentEntry(), true);
  163.     }
  164.     ctx->m_Location.Reset(&loc);
  165.     ctx->m_AdjustCoords = adjust_coords;
  166.     Format(h.GetBioseq(), out, ctx);
  167. }
  168. string IFlatFormatter::ExpandTildes(const string& s, ETildeStyle style)
  169. {
  170.     if (style == eTilde_tilde) {
  171.         return s;
  172.     }
  173.     SIZE_TYPE start = 0, tilde, length = s.size();
  174.     string result;
  175.     while (start < length  &&  (tilde = s.find('~', start)) != NPOS) {
  176.         result += s.substr(start, tilde - start);
  177.         start = tilde + 1;
  178.         char next = start < length ? s[start] : 0;
  179.         switch (style) {
  180.         case eTilde_space:
  181.             if ((start < length  &&  isdigit(next))
  182.                 ||  (start + 1 < length  &&  (next == ' '  ||  next == '(')
  183.                      &&  isdigit(s[start + 1]))) {
  184.                 result += '~';
  185.             } else {
  186.                 result += ' ';
  187.             }
  188.             break;
  189.         case eTilde_newline:
  190.             if (next == '~') {
  191.                 result += '~';
  192.                 ++start;
  193.             } else {
  194.                 result += 'n';
  195.             }
  196.             break;
  197.         default: // just keep it, for lack of better ideas
  198.             result += '~';
  199.             break;
  200.         }
  201.     }
  202.     result += s.substr(start);
  203.     return result;
  204. }
  205. bool IFlatFormatter::x_FormatSegments(const CBioseq& seq,
  206.                                       IFlatItemOStream& out, CFlatContext& ctx)
  207. {
  208.     // Proceed iff either the style is segmented or the style is
  209.     // normal and we have near segments
  210.     if (m_Style != eStyle_Segment
  211.         &&  (m_Style != eStyle_Normal  ||  !ctx.InSegSet())) {
  212.         return false; // just treat as a normal sequence
  213.     }
  214.     const CSeg_ext::Tdata& segs = seq.GetInst().GetExt().GetSeg().Get();
  215.     ctx.m_SegmentCount = 0;
  216.     ITERATE (CSeg_ext::Tdata, it, segs) {
  217.         if ( !(*it)->IsNull() ) {
  218.             ++ctx.m_SegmentCount;
  219.         }
  220.     }
  221.     ctx.m_SegmentNum = 1;
  222.     ITERATE (CSeg_ext::Tdata, it, segs) {
  223.         CRef<CFlatContext> ctx2(new CFlatContext(ctx));
  224.         if ( !(*it)->IsNull() ) {
  225.             Format(**it, true, out, ctx2);
  226.             ++ctx.m_SegmentNum;
  227.         }
  228.     }
  229.     return true;
  230. }
  231. void IFlatFormatter::x_FormatReferences(CFlatContext& ctx,
  232.                                         IFlatItemOStream& out)
  233. {
  234.     typedef CRef<CFlatReference> TRefRef;
  235.     for (CSeqdesc_CI it(ctx.GetHandle(), CSeqdesc::e_Pub);  it;  ++it) {
  236.         ctx.m_References.push_back
  237.             (TRefRef(new CFlatReference(it->GetPub(), 0, ctx)));
  238.     }
  239.     for (CFeat_CI it(ctx.GetHandle().GetScope(), ctx.GetLocation(),
  240.                      CSeqFeatData::e_Pub);
  241.          it;  ++it) {
  242.         ctx.m_References.push_back
  243.             (TRefRef(new CFlatReference(it->GetData().GetPub(),
  244.                                         &it->GetLocation(), ctx)));
  245.     }
  246.     CFlatReference::Sort(ctx.m_References, ctx);
  247.     ITERATE (vector<TRefRef>, it, ctx.m_References) {
  248.         out << *it;
  249.     }
  250. }
  251. inline
  252. static bool operator <(const CConstRef<IFlattishFeature>& f1,
  253.        const CConstRef<IFlattishFeature>& f2)
  254. {
  255.     return *f1 < *f2;
  256. }
  257. void IFlatFormatter::x_FormatFeatures(CFlatContext& ctx,
  258.                                       IFlatItemOStream& out, bool source)
  259. {
  260.     CScope& scope = ctx.GetHandle().GetScope();
  261.     typedef CConstRef<IFlattishFeature> TFFRef;
  262.     list<TFFRef> l, l2;
  263.     // XXX -- should select according to flags; may require merging/re-sorting.
  264.     // (Generally needs lots of additional logic, basically...)
  265.     if (source) {
  266.         for (CSeqdesc_CI it(ctx.GetHandle());  it;  ++it) {
  267.             switch (it->Which()) {
  268.             case CSeqdesc::e_Org:
  269.                 out << new CFlattishSourceFeature(it->GetOrg(), ctx);
  270.                 break;
  271.             case CSeqdesc::e_Source:
  272.                 out << new CFlattishSourceFeature(it->GetSource(), ctx);
  273.                 break;
  274.             default:
  275.                 break;
  276.             }
  277.         }
  278.     } else if (ctx.IsProt()) { // broaden condition?
  279.         for (CFeat_CI it(scope, ctx.GetLocation(), CSeqFeatData::e_not_set,
  280.                          SAnnotSelector::eOverlap_Intervals,
  281.                          SAnnotSelector::eResolve_All, CFeat_CI::e_Product);
  282.              it;  ++it) {
  283.             l.push_back(TFFRef(new CFlattishFeature
  284.                                (*it, ctx, &it->GetProduct(), true)));
  285.         }
  286.     }
  287.     for (CFeat_CI it(scope, ctx.GetLocation(), CSeqFeatData::e_not_set,
  288.                      SAnnotSelector::eOverlap_Intervals,
  289.                      SAnnotSelector::eResolve_All);
  290.          it;  ++it) {
  291.         switch (it->GetData().Which()) {
  292.         case CSeqFeatData::e_Pub:  // done as REFERENCEs
  293.             break;
  294.         case CSeqFeatData::e_Org:
  295.         case CSeqFeatData::e_Biosrc:
  296.             if (source) {
  297.                 out << new CFlattishSourceFeature(*it, ctx);
  298.             }
  299.             break;
  300.         default:
  301.             if ( !source ) {
  302.                 if (l.empty()) { // no merging to worry about
  303.                     out << new CFlattishFeature(*it, ctx);
  304.                 } else {
  305.                     l2.push_back(TFFRef(new CFlattishFeature(*it, ctx)));
  306.                 }
  307.             }
  308.             break;
  309.         }
  310.     }
  311.     if ( !l.empty() ) {
  312.         l.merge(l2);
  313.         ITERATE (list<TFFRef>, it, l) { 
  314.             out << *it;
  315.         }
  316.     }
  317. }
  318. END_SCOPE(objects)
  319. END_NCBI_SCOPE
  320. /*
  321. * ===========================================================================
  322. *
  323. * $Log: flat_formatter.cpp,v $
  324. * Revision 1000.2  2004/06/01 19:43:08  gouriano
  325. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  326. *
  327. * Revision 1.9  2004/05/21 21:42:53  gorelenk
  328. * Added PCH ncbi_pch.hpp
  329. *
  330. * Revision 1.8  2004/04/05 15:56:15  grichenk
  331. * Redesigned CAnnotTypes_CI: moved all data and data collecting
  332. * functions to CAnnotDataCollector. CAnnotTypes_CI is no more
  333. * inherited from SAnnotSelector.
  334. *
  335. * Revision 1.7  2003/12/02 19:21:26  ucko
  336. * Fix a potential infinite loop in tilde expansion.
  337. *
  338. * Revision 1.6  2003/06/02 16:06:42  dicuccio
  339. * Rearranged src/objects/ subtree.  This includes the following shifts:
  340. *     - src/objects/asn2asn --> arc/app/asn2asn
  341. *     - src/objects/testmedline --> src/objects/ncbimime/test
  342. *     - src/objects/objmgr --> src/objmgr
  343. *     - src/objects/util --> src/objmgr/util
  344. *     - src/objects/alnmgr --> src/objtools/alnmgr
  345. *     - src/objects/flat --> src/objtools/flat
  346. *     - src/objects/validator --> src/objtools/validator
  347. *     - src/objects/cddalignview --> src/objtools/cddalignview
  348. * In addition, libseq now includes six of the objects/seq... libs, and libmmdb
  349. * replaces the three libmmdb? libs.
  350. *
  351. * Revision 1.5  2003/03/21 18:49:17  ucko
  352. * Turn most structs into (accessor-requiring) classes; replace some
  353. * formerly copied fields with pointers to the original data.
  354. *
  355. * Revision 1.4  2003/03/18 21:56:06  grichenk
  356. * Removed obsolete class CAnnot_CI
  357. *
  358. * Revision 1.3  2003/03/11 15:37:51  kuznets
  359. * iterate -> ITERATE
  360. *
  361. * Revision 1.2  2003/03/10 22:02:14  ucko
  362. * Rename s_FFLess to operator <, due to bogus MSVC pickiness.
  363. *
  364. * Revision 1.1  2003/03/10 16:39:09  ucko
  365. * Initial check-in of new flat-file generator
  366. *
  367. *
  368. * ===========================================================================
  369. */