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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: flat_seqloc.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:44:19  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.10
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: flat_seqloc.cpp,v 1000.1 2004/06/01 19:44:19 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 -- location representation
  38. *
  39. * ===========================================================================
  40. */
  41. #include <ncbi_pch.hpp>
  42. #include <objects/general/Int_fuzz.hpp>
  43. #include <objects/seq/Bioseq.hpp>
  44. #include <objects/seqloc/seqloc__.hpp>
  45. #include <objmgr/scope.hpp>
  46. #include <objmgr/util/sequence.hpp>
  47. #include <objmgr/impl/synonyms.hpp>
  48. #include <objtools/format/items/flat_seqloc.hpp>
  49. #include <objtools/format/context.hpp>
  50. BEGIN_NCBI_SCOPE
  51. BEGIN_SCOPE(objects)
  52. USING_SCOPE(sequence);
  53. static bool s_IsVirtualId(const CSeq_id& id, CScope* scope)
  54. {
  55.     CBioseq_Handle bh = scope->GetBioseqHandle(id);
  56.     if ( bh ) {
  57.         return bh.GetBioseqCore()->GetInst().GetRepr() == CSeq_inst::eRepr_virtual;
  58.     }
  59.     return false;
  60. }
  61. static bool s_IsVirtualSeqInt(const CSeq_interval& seqint, CScope* scope)
  62. {
  63.     return seqint.CanGetId() ? s_IsVirtualId(seqint.GetId(), scope) : false;
  64. }
  65. static bool s_IsVirtualLocation(const CSeq_loc& loc, CScope* scope)
  66. {
  67.     const CSeq_id* id = 0;
  68.     switch ( loc.Which() ) {
  69.     case CSeq_loc::e_Whole:
  70.         id = &loc.GetWhole();
  71.         break;
  72.     case CSeq_loc::e_Int:
  73.         id = &loc.GetInt().GetId();
  74.         break;
  75.     case CSeq_loc::e_Pnt:
  76.         id = &loc.GetPnt().GetId();
  77.         break;
  78.     default:
  79.         return false;
  80.     }
  81.     return (id != 0) ? s_IsVirtualId(*id, scope) : false;
  82. }
  83. CFlatSeqLoc::CFlatSeqLoc
  84. (const CSeq_loc& loc,
  85.  CBioseqContext& ctx,
  86.  TType type)
  87. {
  88.     CNcbiOstrstream oss;
  89.     x_Add(loc, oss, ctx, type, true);
  90.     m_String = CNcbiOstrstreamToString(oss);
  91. }
  92. void CFlatSeqLoc::x_Add
  93. (const CSeq_loc& loc,
  94.  CNcbiOstrstream& oss,
  95.  CBioseqContext& ctx,
  96.  TType type,
  97.  bool show_comp)
  98. {
  99.     CScope* scope = &ctx.GetScope();
  100.     string prefix = "join(";
  101.     // deal with complement of entire location
  102.     if ( type == eType_location ) {
  103.         if ( show_comp  &&  GetStrand(loc, scope) == eNa_strand_minus ) {
  104.             CRef<CSeq_loc> rev_loc(SeqLocRevCmp(loc, scope));
  105.             oss << "complement(";
  106.             x_Add(*rev_loc, oss, ctx, type, false);
  107.             oss << ")";
  108.             return;
  109.         }
  110.     
  111.     
  112.         if ( loc.IsMix() ) {
  113.             ITERATE (CSeq_loc_mix::Tdata, it, loc.GetMix().Get()) {
  114.                 if ( (*it)->IsNull()  ||  s_IsVirtualLocation(**it, scope) ) {
  115.                     prefix = "order(";
  116.                     break;
  117.                 }
  118.             }
  119.         } else if ( loc.IsPacked_int() ) {
  120.             ITERATE (CPacked_seqint::Tdata, it, loc.GetPacked_int().Get()) {
  121.                 if ( s_IsVirtualSeqInt(**it, scope) ) {
  122.                     prefix = "order(";
  123.                     break;
  124.                 }
  125.             }
  126.         }
  127.     }
  128.     // handle each location component
  129.     switch ( loc.Which() ) {
  130.     case CSeq_loc::e_Null:
  131.     {
  132.         const CFlatGapLoc* gap = dynamic_cast<const CFlatGapLoc*>(&loc);
  133.         if ( gap == 0 ) {
  134.             oss << "gap()";
  135.         } else {
  136.             oss << "gap(" << gap->GetLength() << ")";
  137.         }
  138.         break;
  139.     }
  140.     case CSeq_loc::e_Empty:
  141.     {
  142.         oss << "gap()";
  143.         break;
  144.     }
  145.     case CSeq_loc::e_Whole:
  146.     {
  147.         x_AddID(loc.GetWhole(), oss, ctx, type);
  148.         oss << "1.." << sequence::GetLength(loc, &ctx.GetScope());
  149.         break;
  150.     }
  151.     case CSeq_loc::e_Int:
  152.     {
  153.         x_Add(loc.GetInt(), oss, ctx, type, show_comp);
  154.         break;
  155.     }
  156.     case CSeq_loc::e_Packed_int:
  157.     {
  158.         oss << prefix;
  159.         string delim;
  160.         ITERATE (CPacked_seqint::Tdata, it, loc.GetPacked_int().Get()) {
  161.             oss << delim;
  162.             x_Add(**it, oss, ctx, type, show_comp);
  163.             delim = ", b";
  164.         }
  165.         oss << ')';
  166.         break;
  167.     }
  168.     case CSeq_loc::e_Pnt:
  169.     {
  170.         x_Add(loc.GetPnt(), oss, ctx, type, show_comp);
  171.         break;
  172.     }
  173.     case CSeq_loc::e_Packed_pnt:
  174.     {
  175.         const CPacked_seqpnt& ppnt  = loc.GetPacked_pnt();
  176.         x_AddID(ppnt.GetId(), oss, ctx, type);
  177.         if ( ppnt.IsSetStrand() && IsReverse(ppnt.GetStrand())  &&  show_comp ) {
  178.             oss << "complement(";
  179.         }
  180.         oss << "join(";
  181.         string delim;
  182.         ITERATE (CPacked_seqpnt::TPoints, it, ppnt.GetPoints()) {
  183.             oss << delim;
  184.             x_Add(*it, ppnt.IsSetFuzz() ? &ppnt.GetFuzz() : 0, oss, ctx.Config().DoHTML());
  185.             delim = ", b";
  186.         }
  187.         if ( ppnt.IsSetStrand() && IsReverse(ppnt.GetStrand())  &&  show_comp ) {
  188.             oss << ")";
  189.         }
  190.         break;
  191.     }
  192.     case CSeq_loc::e_Mix:
  193.     {
  194.         string delim;
  195.         oss << prefix;
  196.         CSeq_loc_CI::EEmptyFlag empty = ((type == eType_location) ?
  197.             CSeq_loc_CI::eEmpty_Skip : CSeq_loc_CI::eEmpty_Allow);
  198.         for ( CSeq_loc_CI it(loc, empty); it; ++it ) {
  199.             oss << delim;
  200.             x_Add(it.GetSeq_loc(), oss, ctx, type, show_comp);
  201.             delim = ", b";
  202.         }
  203.         oss << ')';
  204.         break;
  205.     }
  206.     case CSeq_loc::e_Equiv:
  207.     {
  208.         string delim;
  209.         oss << "one-of(";
  210.         ITERATE (CSeq_loc_equiv::Tdata, it, loc.GetEquiv().Get()) {
  211.             oss << delim;
  212.             x_Add(**it, oss, ctx, type, show_comp);
  213.             delim = ", b";
  214.         }
  215.         oss << ')';
  216.         break;
  217.     }
  218.     case CSeq_loc::e_Bond:
  219.     {
  220.         const CSeq_bond& bond = loc.GetBond();
  221.         if ( !bond.CanGetA() ) {
  222.             return;
  223.         }
  224.         oss << "bond(";
  225.         x_Add(bond.GetA(), oss, ctx, type, show_comp);
  226.         if ( bond.CanGetB() ) {
  227.             oss << ", b";
  228.             x_Add(bond.GetB(), oss, ctx, type, show_comp);
  229.         }
  230.         oss << ")";
  231.     }
  232.     case CSeq_loc::e_Feat:
  233.     default:
  234.         NCBI_THROW(CException, eUnknown,
  235.                    "CFlatSeqLoc::CFlatSeqLoc: unsupported (sub)location type "
  236.                    + NStr::IntToString(loc.Which()));
  237.     }
  238. }
  239. void CFlatSeqLoc::x_Add
  240. (const CSeq_interval& si,
  241.  CNcbiOstrstream& oss,
  242.  CBioseqContext& ctx,
  243.  TType type,
  244.  bool show_comp)
  245. {
  246.     bool do_html = ctx.Config().DoHTML();
  247.     TSeqPos from = si.GetFrom(), to = si.GetTo();
  248.     ENa_strand strand = si.CanGetStrand() ? si.GetStrand() : eNa_strand_unknown;
  249.     bool comp = show_comp  &&  IsReverse(strand);
  250.     if ( type == eType_location ) {
  251.         if ( s_IsVirtualId(si.GetId(), &ctx.GetScope()) ) {
  252.             return;
  253.         }
  254.         x_AddID(si.GetId(), oss, ctx, type);
  255.         oss << (comp ? "complement(" : kEmptyStr);
  256.     } else {
  257.         oss << (comp ? "complement(" : kEmptyStr);
  258.         x_AddID(si.GetId(), oss, ctx, type);
  259.     }
  260.     x_Add(from, si.IsSetFuzz_from() ? &si.GetFuzz_from() : 0, oss, do_html);
  261.     oss << "..";
  262.     x_Add(to, si.IsSetFuzz_to() ? &si.GetFuzz_to() : 0, oss, do_html);
  263.     oss << (comp ? ")" : kEmptyStr);
  264. }
  265. void CFlatSeqLoc::x_Add
  266. (const CSeq_point& pnt,
  267.  CNcbiOstrstream& oss,
  268.  CBioseqContext& ctx,
  269.  TType type,
  270.  bool show_comp)
  271. {
  272.     if ( !pnt.CanGetPoint() ) {
  273.         return;
  274.     }
  275.     bool do_html = ctx.Config().DoHTML();
  276.     TSeqPos pos = pnt.GetPoint();
  277.     x_AddID(pnt.GetId(), oss, ctx, type);
  278.     if ( pnt.IsSetStrand()  &&  IsReverse(pnt.GetStrand())  &&  show_comp ) {
  279.         oss << "complement(";
  280.         x_Add(pos, pnt.IsSetFuzz() ? &pnt.GetFuzz() : 0, oss, do_html);
  281.         oss << ')';
  282.     } else {
  283.         x_Add(pos, pnt.IsSetFuzz() ? &pnt.GetFuzz() : 0, oss, do_html);
  284.     }
  285. }
  286. void CFlatSeqLoc::x_Add
  287. (TSeqPos pnt,
  288.  const CInt_fuzz* fuzz,
  289.  CNcbiOstrstream& oss,
  290.  bool html)
  291. {
  292.     // need to convert to 1-based coordinates
  293.     pnt += 1;
  294.     if ( fuzz != 0 ) {
  295.         switch ( fuzz->Which() ) {
  296.         case CInt_fuzz::e_P_m:
  297.             {
  298.                 oss << '(' << pnt - fuzz->GetP_m() << '.' 
  299.                     << pnt + fuzz->GetP_m() << ')';
  300.                 break;
  301.             }
  302.         case CInt_fuzz::e_Range:
  303.             {
  304.                 oss << '(' << (fuzz->GetRange().GetMin() + 1)
  305.                     << '.' << (fuzz->GetRange().GetMax() + 1) << ')';
  306.                 break;
  307.             }
  308.         case CInt_fuzz::e_Pct: // actually per thousand...
  309.             {
  310.                 // calculate in floating point to avoid overflow
  311.                 TSeqPos delta = 
  312.                     static_cast<TSeqPos>(0.001 * pnt * fuzz->GetPct());
  313.                 oss << '(' << pnt - delta << '.' << pnt + delta << ')';
  314.                 break;
  315.             }
  316.         case CInt_fuzz::e_Lim:
  317.             {
  318.                 switch ( fuzz->GetLim() ) {
  319.                 case CInt_fuzz::eLim_gt:
  320.                     oss << (html ? "&gt" : ">") << pnt;
  321.                     break;
  322.                 case CInt_fuzz::eLim_lt:
  323.                     oss << (html ? "&lt" : "<") << pnt;
  324.                     break;
  325.                 case CInt_fuzz::eLim_tr:
  326.                     oss << pnt << '^' << pnt + 1;
  327.                     break;
  328.                 case CInt_fuzz::eLim_tl:
  329.                     oss << pnt - 1 << '^' << pnt;
  330.                     break;
  331.                 default:
  332.                     oss << pnt;
  333.                     break;
  334.                 }
  335.                 break;
  336.             }
  337.         default:
  338.             {
  339.                 oss << pnt;
  340.                 break;
  341.             }
  342.         } // end of switch statement
  343.     } else {
  344.         oss << pnt;
  345.     }
  346. }
  347. void CFlatSeqLoc::x_AddID
  348. (const CSeq_id& id,
  349.  CNcbiOstrstream& oss,
  350.  CBioseqContext& ctx,
  351.  TType type)
  352. {
  353.     CBioseq_Handle bh = 
  354.         ctx.GetScope().GetBioseqHandleFromTSE(id, ctx.GetHandle());
  355.     if ( bh  &&  bh == ctx.GetHandle() ) {
  356.         if ( type == eType_assembly ) {
  357.             oss << ctx.GetAccession() << ':';
  358.         }
  359.         return;
  360.     }
  361.     const CSeq_id* idp = 0;
  362.     if ( bh ) {
  363.         idp = FindBestChoice(bh.GetBioseqCore()->GetId(), CSeq_id::Score);
  364.     } else {
  365.         if ( id.IsGi() ) {
  366.             // !!! use CID1_client to get accession from server
  367.             // idp = ???
  368.         }
  369.     }
  370.     if ( idp == 0 ) {
  371.         idp = &id;
  372.     }
  373.     string acc;
  374.     if ( idp->GetTextseq_Id() != 0 ) 
  375.         acc = idp->GetSeqIdString(true);
  376.     else {
  377.         acc = idp->AsFastaString();
  378.     }
  379.     oss << acc << ':';
  380. }
  381. END_SCOPE(objects)
  382. END_NCBI_SCOPE
  383. /*
  384. * ===========================================================================
  385. *
  386. * $Log: flat_seqloc.cpp,v $
  387. * Revision 1000.1  2004/06/01 19:44:19  gouriano
  388. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.10
  389. *
  390. * Revision 1.10  2004/05/21 21:42:54  gorelenk
  391. * Added PCH ncbi_pch.hpp
  392. *
  393. * Revision 1.9  2004/05/20 13:45:43  shomrat
  394. * fixed formatting of fuzz-range
  395. *
  396. * Revision 1.8  2004/04/22 15:58:01  shomrat
  397. * Changes in context
  398. *
  399. * Revision 1.7  2004/03/26 17:24:14  shomrat
  400. * Skip gaps when formatting a location
  401. *
  402. * Revision 1.6  2004/03/02 17:50:14  shomrat
  403. * Bug fix (missing break)
  404. *
  405. * Revision 1.5  2004/02/19 18:10:34  shomrat
  406. * added genome assembly formmating and some fixes
  407. *
  408. * Revision 1.4  2004/02/11 16:51:06  shomrat
  409. * use lenght from bioseq-handle
  410. *
  411. * Revision 1.3  2004/01/14 16:14:01  shomrat
  412. * minor fixes
  413. *
  414. * Revision 1.2  2003/12/18 17:43:33  shomrat
  415. * context.hpp moved
  416. *
  417. * Revision 1.1  2003/12/17 20:21:15  shomrat
  418. * Initial Revision (adapted from flat lib)
  419. *
  420. * Revision 1.8  2003/07/17 20:27:30  vasilche
  421. * Added check for IsSetStrand().
  422. *
  423. * Revision 1.7  2003/06/02 16:06:42  dicuccio
  424. * Rearranged src/objects/ subtree.  This includes the following shifts:
  425. *     - src/objects/asn2asn --> arc/app/asn2asn
  426. *     - src/objects/testmedline --> src/objects/ncbimime/test
  427. *     - src/objects/objmgr --> src/objmgr
  428. *     - src/objects/util --> src/objmgr/util
  429. *     - src/objects/alnmgr --> src/objtools/alnmgr
  430. *     - src/objects/flat --> src/objtools/flat
  431. *     - src/objects/validator --> src/objtools/validator
  432. *     - src/objects/cddalignview --> src/objtools/cddalignview
  433. * In addition, libseq now includes six of the objects/seq... libs, and libmmdb
  434. * replaces the three libmmdb? libs.
  435. *
  436. * Revision 1.6  2003/04/24 16:15:58  vasilche
  437. * Added missing includes and forward class declarations.
  438. *
  439. * Revision 1.5  2003/03/28 19:03:40  ucko
  440. * Add flags to intervals.
  441. *
  442. * Revision 1.4  2003/03/21 18:49:17  ucko
  443. * Turn most structs into (accessor-requiring) classes; replace some
  444. * formerly copied fields with pointers to the original data.
  445. *
  446. * Revision 1.3  2003/03/11 17:00:21  ucko
  447. * Delimit join(...) elements with ", b" as a hint to NStr::Wrap.
  448. *
  449. * Revision 1.2  2003/03/11 15:37:51  kuznets
  450. * iterate -> ITERATE
  451. *
  452. * Revision 1.1  2003/03/10 16:39:09  ucko
  453. * Initial check-in of new flat-file generator
  454. *
  455. *
  456. * ===========================================================================
  457. */