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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: flat_loc.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:43:22  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: flat_loc.cpp,v 1000.1 2004/06/01 19:43:22 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 <objtools/flat/flat_formatter.hpp>
  43. #include <objects/general/Int_fuzz.hpp>
  44. #include <objects/seq/Bioseq.hpp>
  45. #include <objects/seqloc/seqloc__.hpp>
  46. #include <objmgr/scope.hpp>
  47. #include <objmgr/util/sequence.hpp>
  48. BEGIN_NCBI_SCOPE
  49. BEGIN_SCOPE(objects)
  50. CFlatLoc::CFlatLoc(const CSeq_loc& loc, CFlatContext& ctx)
  51. {
  52.     if (&loc == ctx.m_CachedLoc  &&  ctx.m_CachedFlatLoc != 0) {
  53.         *this = *ctx.m_CachedFlatLoc;
  54.         return;
  55.     }
  56.     CNcbiOstrstream oss;
  57.     x_Add(loc, oss, ctx);
  58.     m_String = CNcbiOstrstreamToString(oss);
  59.     
  60.     if (CanBeDeleted()) {
  61.         // Set m_CachedFlatLoc twice to maintain the invariant that it
  62.         // either corresponds to m_CachedLoc or is null
  63.         ctx.m_CachedFlatLoc.Reset();
  64.         ctx.m_CachedLoc.Reset(&loc);
  65.         ctx.m_CachedFlatLoc.Reset(this);
  66.     }
  67. }
  68. void CFlatLoc::x_Add(const CSeq_loc& loc, CNcbiOstrstream& oss,
  69.                      CFlatContext& ctx)
  70. {
  71.     string accn;
  72.     switch (loc.Which()) {
  73.     case CSeq_loc::e_Null:
  74.     case CSeq_loc::e_Empty:
  75.         oss << "gap()";
  76.         // Add anything to m_Intervals?
  77.         break;
  78.     case CSeq_loc::e_Whole:
  79.     {
  80.         x_AddID(loc.GetWhole(), oss, ctx, &accn);
  81.         TSeqPos l;
  82.         if (accn == ctx.GetAccession()) {
  83.             l = ctx.GetHandle().GetBioseqCore()->GetInst().GetLength();
  84.         } else {
  85.             l = sequence::GetLength(loc.GetWhole());
  86.         }
  87.         oss << "1.." << l;
  88.         x_AddInt(0, l - 1, accn);
  89.         break;
  90.     }
  91.     case CSeq_loc::e_Int:
  92.         x_Add(loc.GetInt(), oss, ctx);
  93.         break;
  94.     case CSeq_loc::e_Packed_int:
  95.     {
  96.         string delim("join(");
  97.         ITERATE (CPacked_seqint::Tdata, it, loc.GetPacked_int().Get()) {
  98.             oss << delim;
  99.             x_Add(**it, oss, ctx);
  100.             delim = ", b";
  101.         }
  102.         oss << ')';
  103.         break;
  104.     }
  105.     case CSeq_loc::e_Pnt:
  106.     {
  107.         const CSeq_point& pnt = loc.GetPnt();
  108.         TSeqPos           pos = pnt.GetPoint();
  109.         x_AddID(pnt.GetId(), oss, ctx, &accn);
  110.         if (pnt.IsSetStrand() && IsReverse(pnt.GetStrand())) {
  111.             oss << "complement(";
  112.             x_AddPnt(pos, pnt.IsSetFuzz() ? &pnt.GetFuzz() : 0, oss, ctx);
  113.             oss << ')';
  114.             x_AddInt(pos, pos, accn, SInterval::fReversed);
  115.         } else {
  116.             x_AddPnt(pos, pnt.IsSetFuzz() ? &pnt.GetFuzz() : 0, oss, ctx);
  117.             x_AddInt(pos, pos, accn);
  118.         }
  119.         break;
  120.     }
  121.     case CSeq_loc::e_Packed_pnt:
  122.     {
  123.         const CPacked_seqpnt& ppnt  = loc.GetPacked_pnt();
  124.         SInterval::TFlags     flags = 0;
  125.         x_AddID(ppnt.GetId(), oss, ctx, &accn);
  126.         if (ppnt.IsSetStrand() && IsReverse(ppnt.GetStrand())) {
  127.             oss << "complement(";
  128.             flags = SInterval::fReversed;
  129.         }
  130.         string delim("join(");
  131.         ITERATE (CPacked_seqpnt::TPoints, it, ppnt.GetPoints()) {
  132.             oss << delim;
  133.             x_AddPnt(*it, ppnt.IsSetFuzz() ? &ppnt.GetFuzz() : 0, oss, ctx);
  134.             x_AddInt(*it, *it, accn, flags);
  135.             delim = ", b";
  136.         }
  137.         if (ppnt.IsSetStrand() && IsReverse(ppnt.GetStrand())) {
  138.             oss << ")";
  139.         }
  140.         break;
  141.     }
  142.     case CSeq_loc::e_Mix:
  143.     {
  144.         string delim("join(");
  145.         ITERATE (CSeq_loc_mix::Tdata, it, loc.GetMix().Get()) {
  146.             oss << delim;
  147.             x_Add(**it, oss, ctx);
  148.             delim = ", b";
  149.         }
  150.         oss << ')';
  151.         break;
  152.     }
  153.     case CSeq_loc::e_Equiv:
  154.         // XXX - just take the first
  155.         x_Add(*loc.GetEquiv().Get().front(), oss, ctx);
  156.         break;
  157.     // XXX - bond? feat?
  158.     default:
  159.         NCBI_THROW(CException, eUnknown,
  160.                    "CFlatLoc::CFlatloc: unsupported (sub)location type "
  161.                    + NStr::IntToString(loc.Which()));
  162.     }
  163. }
  164. void CFlatLoc::x_Add(const CSeq_interval& si, CNcbiOstrstream& oss,
  165.                      CFlatContext& ctx)
  166. {
  167.     string            accn;
  168.     TSeqPos           from = si.GetFrom(), to = si.GetTo();
  169.     SInterval::TFlags flags = 0;
  170.     x_AddID(si.GetId(), oss, ctx, &accn);
  171.     if (si.IsSetStrand() && IsReverse(si.GetStrand())) {
  172.         oss << "complement(";
  173.     }
  174.     flags |= (x_AddPnt(from, si.IsSetFuzz_from() ? &si.GetFuzz_from() : 0,
  175.                        oss, ctx)
  176.               & SInterval::fPartialLeft);
  177.     oss << "..";
  178.     flags |= (x_AddPnt(to, si.IsSetFuzz_to() ? &si.GetFuzz_to() : 0, oss, ctx)
  179.               & SInterval::fPartialRight);
  180.     if (si.IsSetStrand() && IsReverse(si.GetStrand())) {
  181.         oss << ')';
  182.         x_AddInt(to, from, accn, flags | SInterval::fReversed);
  183.     } else {
  184.         x_AddInt(from, to, accn, flags);
  185.     }
  186. }
  187. CFlatLoc::SInterval::TFlags CFlatLoc::x_AddPnt(TSeqPos pnt,
  188.                                                const CInt_fuzz* fuzz,
  189.                                                CNcbiOstrstream& oss,
  190.                                                CFlatContext& ctx)
  191. {
  192.     CFlatLoc::SInterval::TFlags flags = 0;
  193.     // need to convert to 1-based coordinates
  194.     if (fuzz == 0) {
  195.         oss << pnt + 1;
  196.     } else if (fuzz->IsLim()) {
  197.         bool h = ctx.GetFormatter().DoHTML();
  198.         switch (fuzz->GetLim()) {
  199.         case CInt_fuzz::eLim_gt:
  200.             flags = SInterval::fPartialRight;
  201.             oss << (h ? "&gt;" : ">") << pnt + 1;
  202.             break;
  203.         case CInt_fuzz::eLim_lt:
  204.             flags = SInterval::fPartialLeft;
  205.             oss << (h ? "&lt;" : "<") << pnt + 1;
  206.             break;
  207.         case CInt_fuzz::eLim_tr: oss << pnt + 1 << '^' << pnt + 2;     break;
  208.         case CInt_fuzz::eLim_tl: oss << pnt     << '^' << pnt + 1;     break;
  209.         default:                 oss << pnt + 1;                       break;
  210.         }
  211.     } else {
  212.         TSeqPos from = pnt, to = pnt;
  213.         switch (fuzz->Which()) {
  214.         case CInt_fuzz::e_P_m:
  215.             from = pnt - fuzz->GetP_m();
  216.             to   = pnt + fuzz->GetP_m();
  217.             break;
  218.         case CInt_fuzz::e_Range:
  219.             from = fuzz->GetRange().GetMin();
  220.             to   = fuzz->GetRange().GetMax();
  221.             break;
  222.         case CInt_fuzz::e_Pct: // actually per thousand...
  223.         {
  224.             // calculate in floating point to avoid overflow
  225.             TSeqPos delta = static_cast<TSeqPos>(0.001 * pnt * fuzz->GetPct());
  226.             from = pnt - delta;
  227.             to   = pnt + delta;
  228.             break;
  229.         }
  230.         case CInt_fuzz::e_Alt:
  231.             ITERATE (CInt_fuzz::TAlt, it, fuzz->GetAlt()) {
  232.                 if (*it < from) {
  233.                     from = *it;
  234.                 } else if (*it > to) {
  235.                     to   = *it;
  236.                 }
  237.             }
  238.             break;
  239.         default:
  240.             break;
  241.         }
  242.         if (from == to) {
  243.             oss << from + 1;
  244.         } else {
  245.             oss << '(' << from + 1 << '.' << to + 1 << ')';
  246.         }
  247.     }
  248.     return flags;
  249. }
  250. void CFlatLoc::x_AddInt(TSeqPos from, TSeqPos to, const string& accn,
  251.                         CFlatLoc::SInterval::TFlags flags)
  252. {
  253.     // need to convert to 1-based coordinates
  254.     SInterval ival;
  255.     ival.m_Accession = accn;
  256.     ival.m_Range.SetFrom(from + 1);
  257.     ival.m_Range.SetTo  (to + 1);
  258.     ival.m_Flags = flags;
  259.     m_Intervals.push_back(ival);
  260. }
  261. void CFlatLoc::x_AddID(const CSeq_id& id, CNcbiOstrstream& oss,
  262.                        CFlatContext& ctx, string* s)
  263. {
  264.     const CSeq_id& id2 = ctx.GetPreferredSynonym(id);
  265.     string         acc = id2.GetSeqIdString(true);
  266.     if (&id2 != &ctx.GetPrimaryID()) {
  267.         oss << acc << ':';
  268.     }
  269.     if (s) {
  270.         *s = acc;
  271.     }
  272. }
  273. END_SCOPE(objects)
  274. END_NCBI_SCOPE
  275. /*
  276. * ===========================================================================
  277. *
  278. * $Log: flat_loc.cpp,v $
  279. * Revision 1000.1  2004/06/01 19:43:22  gouriano
  280. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  281. *
  282. * Revision 1.9  2004/05/21 21:42:53  gorelenk
  283. * Added PCH ncbi_pch.hpp
  284. *
  285. * Revision 1.8  2003/07/17 20:27:30  vasilche
  286. * Added check for IsSetStrand().
  287. *
  288. * Revision 1.7  2003/06/02 16:06:42  dicuccio
  289. * Rearranged src/objects/ subtree.  This includes the following shifts:
  290. *     - src/objects/asn2asn --> arc/app/asn2asn
  291. *     - src/objects/testmedline --> src/objects/ncbimime/test
  292. *     - src/objects/objmgr --> src/objmgr
  293. *     - src/objects/util --> src/objmgr/util
  294. *     - src/objects/alnmgr --> src/objtools/alnmgr
  295. *     - src/objects/flat --> src/objtools/flat
  296. *     - src/objects/validator --> src/objtools/validator
  297. *     - src/objects/cddalignview --> src/objtools/cddalignview
  298. * In addition, libseq now includes six of the objects/seq... libs, and libmmdb
  299. * replaces the three libmmdb? libs.
  300. *
  301. * Revision 1.6  2003/04/24 16:15:58  vasilche
  302. * Added missing includes and forward class declarations.
  303. *
  304. * Revision 1.5  2003/03/28 19:03:40  ucko
  305. * Add flags to intervals.
  306. *
  307. * Revision 1.4  2003/03/21 18:49:17  ucko
  308. * Turn most structs into (accessor-requiring) classes; replace some
  309. * formerly copied fields with pointers to the original data.
  310. *
  311. * Revision 1.3  2003/03/11 17:00:21  ucko
  312. * Delimit join(...) elements with ", b" as a hint to NStr::Wrap.
  313. *
  314. * Revision 1.2  2003/03/11 15:37:51  kuznets
  315. * iterate -> ITERATE
  316. *
  317. * Revision 1.1  2003/03/10 16:39:09  ucko
  318. * Initial check-in of new flat-file generator
  319. *
  320. *
  321. * ===========================================================================
  322. */