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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: context.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 19:43:52  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.18
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: context.cpp,v 1000.1 2004/06/01 19:43:52 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. *          Mati Shomrat
  36. *
  37. * File Description:
  38. *   new (early 2003) flat-file generator -- context needed when (pre)formatting
  39. *
  40. * ===========================================================================
  41. */
  42. #include <ncbi_pch.hpp>
  43. #include <corelib/ncbistd.hpp>
  44. #include <objects/seq/Bioseq.hpp>
  45. #include <objects/seq/Seq_ext.hpp>
  46. #include <objects/seq/Seg_ext.hpp>
  47. #include <objects/seq/Delta_ext.hpp>
  48. #include <objects/seq/Delta_seq.hpp>
  49. #include <objects/seqset/Bioseq_set.hpp>
  50. #include <objects/seqloc/Textseq_id.hpp>
  51. #include <objects/general/Dbtag.hpp>
  52. #include <objmgr/scope.hpp>
  53. #include <objmgr/bioseq_handle.hpp>
  54. #include <objmgr/seq_entry_handle.hpp>
  55. #include <objmgr/seq_entry_ci.hpp>
  56. #include <objmgr/seqdesc_ci.hpp>
  57. #include <objmgr/util/sequence.hpp>
  58. #include <objmgr/seq_loc_mapper.hpp>
  59. #include <objtools/format/context.hpp>
  60. BEGIN_NCBI_SCOPE
  61. BEGIN_SCOPE(objects)
  62. USING_SCOPE(sequence);
  63. /////////////////////////////////////////////////////////////////////////////
  64. //
  65. // CBioseqContext
  66. // constructor
  67. CBioseqContext::CBioseqContext
  68. (const CBioseq_Handle& seq,
  69.  CFlatFileContext& ffctx,
  70.  CMasterContext* mctx) :
  71.     m_Handle(seq),
  72.     m_Repr(CSeq_inst::eRepr_not_set),
  73.     m_Mol(CSeq_inst::eMol_not_set),
  74.     m_HasParts(false),
  75.     m_IsPart(false),
  76.     m_PartNumber(0),
  77.     m_IsDeltaLitOnly(false),
  78.     m_IsProt(false),
  79.     m_IsInGPS(false),
  80.     m_IsInNucProt(false),
  81.     m_IsGED(false),
  82.     m_IsEMBL(false),
  83.     m_IsPDB(false),
  84.     m_IsSP(false),
  85.     m_IsTPA(false),
  86.     m_IsRefSeq(false),
  87.     m_RefseqInfo(0),
  88.     m_IsGbGenomeProject(false),  // GenBank Genome project data (AE)
  89.     m_IsNcbiCONDiv(false),       // NCBI CON division (CH)
  90.     m_IsPatent(false),
  91.     m_IsGI(false),
  92.     m_IsWGS(false),
  93.     m_IsWGSMaster(false),
  94.     m_IsHup(false),
  95.     m_Gi(0),
  96.     m_ShowGBBSource(false),
  97.     m_FFCtx(ffctx),
  98.     m_Master(mctx)
  99. {
  100.     x_Init(seq, m_FFCtx.GetLocation());
  101. }
  102. // destructor
  103. CBioseqContext::~CBioseqContext(void)
  104. {
  105. }
  106. const CSeq_id& CBioseqContext::GetPreferredSynonym(const CSeq_id& id) const
  107. {
  108.     if ( id.IsGi()  &&  id.GetGi() == m_Gi ) {
  109.         return *m_PrimaryId;
  110.     }
  111.     CBioseq_Handle h = m_Handle.GetScope().GetBioseqHandleFromTSE(id, m_Handle);
  112.     if ( h ) {
  113.         if ( h == m_Handle ) {
  114.             return *m_PrimaryId;
  115.         } else if ( h.GetSeqId().NotEmpty() ) {
  116.             return *FindBestChoice(h.GetBioseqCore()->GetId(), CSeq_id::Score);
  117.         }
  118.     }
  119.     return id;
  120. }
  121. // initialization
  122. void CBioseqContext::x_Init(const CBioseq_Handle& seq, const CSeq_loc* user_loc)
  123. {
  124.     _ASSERT(seq);
  125.     _ASSERT(seq.IsSetInst());
  126.     // NB: order of execution is important
  127.     x_SetId();
  128.     m_Repr = x_GetRepr();
  129.     m_Mol  = seq.GetInst_Mol();
  130.     m_Molinfo.Reset(x_GetMolInfo());
  131.     if ( IsSegmented() ) {
  132.         m_HasParts = x_HasParts();
  133.     }
  134.     m_IsPart = x_IsPart();
  135.     if ( m_IsPart ) {
  136.         _ASSERT(m_Master);
  137.         m_PartNumber = x_GetPartNumber();
  138.     }
  139.     if ( IsDelta() ) {
  140.         m_IsDeltaLitOnly = x_IsDeltaLitOnly();
  141.     }
  142.     m_IsProt = CSeq_inst::IsAa(seq.GetInst_Mol());
  143.     m_IsInGPS     = x_IsInGPS();
  144.     m_IsInNucProt = x_IsInNucProt();
  145.     x_SetLocation(user_loc);
  146.     
  147. }
  148. void CBioseqContext::x_SetLocation(const CSeq_loc* user_loc)
  149. {
  150.     _ASSERT(user_loc == 0  ||  user_loc->IsInt()  ||  user_loc->IsWhole());
  151.     CRef<CSeq_loc> source;
  152.     if ( user_loc != 0 ) {
  153.         // map the location to the current bioseq
  154.         CSeq_loc_Mapper mapper(m_Handle);
  155.         mapper.SetMergeAll();  // just to be safe
  156.         source.Reset(mapper.Map(*user_loc));
  157.         
  158.         // no need to map if doing the entire bioseq
  159.         if ( source->IsWhole()  ||
  160.              source->GetStart(kInvalidSeqPos) == 0  &&
  161.              source->GetEnd(kInvalidSeqPos) == m_Handle.GetInst_Length() - 1) {
  162.             source.Reset();
  163.         }
  164.         _ASSERT(!source  ||  source->IsInt());
  165.         if ( source ) {
  166.             CScope& scope = GetScope();
  167.             CSeq_loc target;
  168.             target.SetInt().SetFrom(0);
  169.             target.SetInt().SetTo(GetLength(*source, &scope) - 1);
  170.             target.SetId(*m_PrimaryId);
  171.             m_Mapper.Reset(new CSeq_loc_Mapper(*source, target, &scope));
  172.             m_Mapper->SetMergeAbutting();
  173.             m_Mapper->PreserveDestinationLocs();  // ???
  174.             m_Mapper->KeepNonmappingRanges();
  175.         }
  176.     }
  177.     // if no location is specified do the entire sequence
  178.     if ( !source ) {
  179.         source.Reset(new CSeq_loc);
  180.         source->SetWhole(*m_PrimaryId);
  181.     }
  182.     _ASSERT(source);
  183.     m_Location = source;
  184.     
  185. }
  186. void CBioseqContext::x_SetId(void)
  187. {
  188.     m_PrimaryId.Reset(new CSeq_id);
  189.     m_PrimaryId->Assign(sequence::GetId(m_Handle, sequence::eGetId_Best));
  190.     m_Accession.erase();
  191.     m_PrimaryId->GetLabel(&m_Accession, CSeq_id::eContent);
  192.     ITERATE (CBioseq::TId, id_iter, m_Handle.GetBioseqCore()->GetId()) {
  193.         const CSeq_id& id = **id_iter;
  194.         const CTextseq_id* tsip = id.GetTextseq_Id();
  195.         const string& acc = (tsip != 0  &&  tsip->CanGetAccession()) ?
  196.             tsip->GetAccession() : kEmptyStr;
  197.         CSeq_id::EAccessionInfo acc_info = id.IdentifyAccession();
  198.         unsigned int acc_type = acc_info & CSeq_id::eAcc_type_mask;
  199.         unsigned int acc_div =  acc_info & CSeq_id::eAcc_division_mask;
  200.         switch ( id.Which() ) {
  201.         // Genbank, Embl or Ddbj
  202.         case CSeq_id::e_Embl:
  203.             m_IsEMBL = true;
  204.             // intentional fall through
  205.         case CSeq_id::e_Genbank:
  206.         case CSeq_id::e_Ddbj:
  207.             m_IsGED = true;
  208.             m_IsGbGenomeProject = m_IsGbGenomeProject  ||
  209.                 ((acc_type & CSeq_id::eAcc_gb_genome) != 0);
  210.             m_IsNcbiCONDiv = m_IsNcbiCONDiv  ||
  211.                 ((acc_type & CSeq_id::eAcc_gb_con) != 0);
  212.             break;
  213.         // Patent
  214.         case CSeq_id::e_Patent:
  215.             m_IsPatent = true;
  216.             break;
  217.         // RefSeq
  218.         case CSeq_id::e_Other:
  219.             m_IsRefSeq = true;
  220.             m_RefseqInfo = acc_info;
  221.             break;
  222.         // Gi
  223.         case CSeq_id::e_Gi:
  224.             m_IsGI = true;
  225.             m_Gi = id.GetGi();
  226.             break;
  227.         // PDB
  228.         case CSeq_id::e_Pdb:
  229.             m_IsPDB = true;
  230.             break;
  231.         // TPA
  232.         case CSeq_id::e_Tpg:
  233.         case CSeq_id::e_Tpe:
  234.         case CSeq_id::e_Tpd:
  235.             m_IsTPA = true;
  236.             break;
  237.         case CSeq_id::e_General:
  238.             if ( id.GetGeneral().CanGetDb() ) {
  239.                 if ( !NStr::CompareCase(id.GetGeneral().GetDb(), "BankIt") ) {
  240.                     m_IsTPA = true;
  241.                 }
  242.             }
  243.             break;
  244.         // nothing special
  245.         case CSeq_id::e_not_set:
  246.         case CSeq_id::e_Local:
  247.         case CSeq_id::e_Gibbsq:
  248.         case CSeq_id::e_Gibbmt:
  249.         case CSeq_id::e_Giim:
  250.         case CSeq_id::e_Pir:
  251.         case CSeq_id::e_Swissprot:
  252.             m_IsSP = true;
  253.             break;
  254.         case CSeq_id::e_Prf:
  255.         default:
  256.             break;
  257.         }
  258.         // WGS
  259.         m_IsWGS = m_IsWGS  ||  (acc_div == CSeq_id::eAcc_wgs);
  260.         
  261.         if ( m_IsWGS  &&  !acc.empty() ) {
  262.             size_t len = acc.length();
  263.             m_IsWGSMaster = 
  264.                 ((len == 12  ||  len == 15)  &&  NStr::EndsWith(acc, "000000"))  ||
  265.                 (len == 13  &&  NStr::EndsWith(acc, "0000000"));
  266.             if ( m_IsWGSMaster ) {
  267.                 m_WGSMasterAccn = acc;
  268.                 m_WGSMasterName = tsip->CanGetName() ? tsip->GetName() : kEmptyStr;
  269.             }
  270.         } 
  271.         // GBB source
  272.         m_ShowGBBSource = m_ShowGBBSource  ||  
  273.                           ((acc_type & CSeq_id::eAcc_gsdb_dirsub) != 0);
  274.     }
  275. }
  276. CSeq_inst::TRepr CBioseqContext::x_GetRepr(void) const
  277. {
  278.     return m_Handle.IsSetInst_Repr() ?
  279.         m_Handle.GetInst_Repr() : CSeq_inst::eRepr_not_set;
  280. }
  281. const CMolInfo* CBioseqContext::x_GetMolInfo(void) const
  282. {
  283.     CSeqdesc_CI desc(m_Handle, CSeqdesc::e_Molinfo);
  284.     return desc ? &desc->GetMolinfo() : 0;
  285. }
  286. bool CBioseqContext::x_IsPart() const
  287. {
  288.     if ( m_Repr == CSeq_inst::eRepr_raw    ||
  289.          m_Repr == CSeq_inst::eRepr_const  ||
  290.          m_Repr == CSeq_inst::eRepr_delta  ||
  291.          m_Repr == CSeq_inst::eRepr_virtual ) {
  292.         CSeq_entry_Handle eh = m_Handle.GetParentEntry();
  293.         _ASSERT(eh  &&  eh.IsSeq());
  294.         eh = eh.GetParentEntry();
  295.         if ( eh  &&  eh.IsSet() ) {
  296.             CBioseq_set_Handle bsst = eh.GetSet();
  297.             if ( bsst.IsSetClass()  &&  
  298.                  bsst.GetClass() == CBioseq_set::eClass_parts ) {
  299.                 return true;
  300.             }
  301.         }
  302.     }
  303.     return false;
  304. }
  305. bool CBioseqContext::x_HasParts(void) const
  306. {
  307.     _ASSERT(IsSegmented());
  308.     CSeq_entry_Handle h =
  309.         m_Handle.GetExactComplexityLevel(CBioseq_set::eClass_segset);
  310.     if ( !h ) {
  311.         return false;
  312.     }
  313.     
  314.     // make sure the segmented set contains our bioseq
  315.     {{
  316.         bool has_seq = false;
  317.         for ( CSeq_entry_CI it(h); it; ++it ) {
  318.             if ( it->IsSeq()  &&  it->GetSeq() == m_Handle ) {
  319.                 has_seq = true;
  320.                 break;
  321.             }
  322.         }
  323.         if ( !has_seq ) {
  324.             return false;
  325.         }
  326.     }}
  327.     // find the parts set
  328.     {{
  329.         for ( CSeq_entry_CI it(h); it; ++it ) {
  330.             if ( it->IsSet()  &&  it->GetSet().IsSetClass()  &&
  331.                 it->GetSet().GetClass() == CBioseq_set::eClass_parts ) {
  332.                 return true;
  333.             }
  334.         }
  335.     }}
  336.     return false;
  337. }
  338. bool CBioseqContext::x_IsDeltaLitOnly(void) const
  339. {
  340.     _ASSERT(IsDelta());
  341.     if ( m_Handle.IsSetInst_Ext() ) {
  342.         const CBioseq_Handle::TInst_Ext& ext = m_Handle.GetInst_Ext();
  343.         if ( ext.IsDelta() ) {
  344.             ITERATE (CDelta_ext::Tdata, it, ext.GetDelta().Get()) {
  345.                 if ( (*it)->IsLoc() ) {
  346.                     return false;
  347.                 }
  348.             }
  349.         }
  350.     }
  351.     return true;
  352. }
  353. SIZE_TYPE CBioseqContext::x_GetPartNumber(void)
  354. {
  355.     return m_Master ? m_Master->GetPartNumber(m_Handle) : 0;
  356. }
  357. bool CBioseqContext::x_IsInGPS(void) const
  358. {
  359.     CSeq_entry_Handle e = 
  360.         m_Handle.GetExactComplexityLevel(CBioseq_set::eClass_gen_prod_set);
  361.     return e;
  362. }
  363. bool CBioseqContext::x_IsInNucProt(void) const
  364. {
  365.     CSeq_entry_Handle e = 
  366.         m_Handle.GetExactComplexityLevel(CBioseq_set::eClass_nuc_prot);
  367.     return e;
  368. }
  369. bool CBioseqContext::DoContigStyle(void) const
  370. {
  371.     const CFlatFileConfig& cfg = Config();
  372.     if ( cfg.IsStyleContig() ) {
  373.         return true;
  374.     } else if ( cfg.IsStyleNormal() ) {
  375.         if ( (IsSegmented()  &&  !HasParts())  ||
  376.              (IsDelta()  &&  !IsDeltaLitOnly()) ) {
  377.             return true;
  378.         }
  379.     }
  380.     return false;
  381. }
  382. /////////////////////////////////////////////////////////////////////////////
  383. //
  384. // CMasterContext
  385. CMasterContext::CMasterContext(const CBioseq_Handle& seq) :
  386.     m_Handle(seq)
  387. {
  388.     _ASSERT(seq);
  389.     _ASSERT(seq.GetInst_Ext().IsSeg());
  390.     x_SetNumParts();
  391.     x_SetBaseName();
  392. }
  393. CMasterContext::~CMasterContext(void)
  394. {
  395. }
  396. SIZE_TYPE CMasterContext::GetPartNumber(const CBioseq_Handle& part)
  397. {
  398.     if ( !part ) {
  399.         return 0;
  400.     }
  401.     CScope& scope = m_Handle.GetScope();
  402.     SIZE_TYPE serial = 1;
  403.     ITERATE (CSeg_ext::Tdata, it, m_Handle.GetInst_Ext().GetSeg().Get()) {
  404.         if ( (*it)->IsNull() ) {
  405.             continue;
  406.         }
  407.         const CSeq_id& id = GetId(**it);
  408.         CBioseq_Handle bsh = scope.GetBioseqHandleFromTSE(id, m_Handle);
  409.         if ( bsh   &&  bsh == part ) {
  410.             return serial;
  411.         }
  412.         ++serial;
  413.     }
  414.     return 0;
  415. }
  416. void CMasterContext::x_SetNumParts(void)
  417. {
  418.     SIZE_TYPE count = 0;
  419.     // count only non-gap parts
  420.     ITERATE (CSeg_ext::Tdata, it, m_Handle.GetInst_Ext().GetSeg().Get()) {
  421.         if ( (*it)->IsNull() ) {
  422.             continue;
  423.         }
  424.         ++count;
  425.     }
  426.     m_NumParts = count;
  427. }
  428. void CMasterContext::x_SetBaseName(void)
  429. {
  430.     // !!!
  431. }
  432. END_SCOPE(objects)
  433. END_NCBI_SCOPE
  434. /*
  435. * ===========================================================================
  436. *
  437. * $Log: context.cpp,v $
  438. * Revision 1000.1  2004/06/01 19:43:52  gouriano
  439. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.18
  440. *
  441. * Revision 1.18  2004/05/21 21:42:54  gorelenk
  442. * Added PCH ncbi_pch.hpp
  443. *
  444. * Revision 1.17  2004/05/08 12:11:39  dicuccio
  445. * Use CSeq_id::GetLabel() instead of GetSeqIdString()
  446. *
  447. * Revision 1.16  2004/05/06 17:48:49  shomrat
  448. * + IsEMBL and IsInNucProt
  449. *
  450. * Revision 1.15  2004/04/27 15:12:24  shomrat
  451. * Added logic for partial range formatting
  452. *
  453. * Revision 1.14  2004/04/22 15:52:00  shomrat
  454. * Refactring of context
  455. *
  456. * Revision 1.13  2004/03/31 17:15:09  shomrat
  457. * name changes
  458. *
  459. * Revision 1.12  2004/03/26 17:23:38  shomrat
  460. * fixed initialization of m_IsWGS
  461. *
  462. * Revision 1.11  2004/03/25 20:36:02  shomrat
  463. * Use handles
  464. *
  465. * Revision 1.10  2004/03/24 18:57:04  vasilche
  466. * CBioseq_Handle::GetComplexityLevel() now returns CSeq_entry_Handle.
  467. *
  468. * Revision 1.9  2004/03/18 15:36:26  shomrat
  469. * + new flag ShowFtableRefs
  470. *
  471. * Revision 1.8  2004/03/10 21:25:42  shomrat
  472. * Fix m_RefseqInfo initialization
  473. *
  474. * Revision 1.7  2004/03/05 18:46:26  shomrat
  475. * Added customization flags
  476. *
  477. * Revision 1.6  2004/02/19 18:03:29  shomrat
  478. * changed implementation of GetPreferredSynonym
  479. *
  480. * Revision 1.5  2004/02/11 22:49:04  shomrat
  481. * using types in flag file
  482. *
  483. * Revision 1.4  2004/02/11 16:49:16  shomrat
  484. * added user customization flags
  485. *
  486. * Revision 1.3  2004/01/14 16:09:04  shomrat
  487. * multiple changes (work in progress)
  488. *
  489. * Revision 1.2  2003/12/18 17:43:31  shomrat
  490. * context.hpp moved
  491. *
  492. * Revision 1.1  2003/12/17 20:18:44  shomrat
  493. * Initial Revision (adapted from flat lib)
  494. *
  495. * Revision 1.4  2003/06/02 16:06:42  dicuccio
  496. * Rearranged src/objects/ subtree.  This includes the following shifts:
  497. *     - src/objects/asn2asn --> arc/app/asn2asn
  498. *     - src/objects/testmedline --> src/objects/ncbimime/test
  499. *     - src/objects/objmgr --> src/objmgr
  500. *     - src/objects/util --> src/objmgr/util
  501. *     - src/objects/alnmgr --> src/objtools/alnmgr
  502. *     - src/objects/flat --> src/objtools/flat
  503. *     - src/objects/validator --> src/objtools/validator
  504. *     - src/objects/cddalignview --> src/objtools/cddalignview
  505. * In addition, libseq now includes six of the objects/seq... libs, and libmmdb
  506. * replaces the three libmmdb? libs.
  507. *
  508. * Revision 1.3  2003/03/21 18:49:17  ucko
  509. * Turn most structs into (accessor-requiring) classes; replace some
  510. * formerly copied fields with pointers to the original data.
  511. *
  512. * Revision 1.2  2003/03/11 15:37:51  kuznets
  513. * iterate -> ITERATE
  514. *
  515. * Revision 1.1  2003/03/10 16:39:09  ucko
  516. * Initial check-in of new flat-file generator
  517. *
  518. *
  519. * ===========================================================================
  520. */