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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: phylo_tree_ds.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 21:11:37  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.18
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: phylo_tree_ds.cpp,v 1000.1 2004/06/01 21:11:37 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.  * Authors:  Vladimir Tereshkov
  35.  *
  36.  * File Description:
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <corelib/ncbiobj.hpp>
  41. #include <corelib/ncbistd.hpp>
  42. #include <algorithm>
  43. #include <gui/objutils/utils.hpp>
  44. #include <gui/widgets/phylo_tree/phylo_tree_ds.hpp>
  45. BEGIN_NCBI_SCOPE
  46. CPhyloTreeDataSource::CPhyloTreeDataSource() : m_Level(0), m_Size(0), m_Width(0)
  47. {   
  48.     m_Level = m_Size = m_Width = 0;
  49.     m_Hash.clear();
  50.     m_Root  = new CPhyloTreeNode;
  51. }
  52. CPhyloTreeDataSource::~CPhyloTreeDataSource()
  53. {   
  54. }
  55. CPhyloTreeDataSource::CPhyloTreeDataSource(IPhyloTreeReader * reader) 
  56. {
  57.     m_Level = m_Size = m_Width = 0;    
  58.     m_Hash.clear();
  59.     Init(reader);
  60.     x_MeasureTree(m_Root);
  61. }
  62. CPhyloTreeDataSource::CPhyloTreeDataSource(TPhyTreeNode& node, 
  63.                                            const TIds& seqids, 
  64.                                            objects::CScope& scope)
  65. :   m_SeqIds(seqids),
  66.     m_Scope(&scope)
  67. {
  68.     m_Level = m_Size = m_Width = 0;
  69.     m_Hash.clear();
  70.     m_Root = new CPhyloTreeNode;
  71.     Init(node, m_Root);   
  72.     x_MeasureTree(m_Root);
  73. }
  74. void CPhyloTreeDataSource::Init(IPhyloTreeReader * reader)
  75. {    
  76.     m_Root = reader->GetTree();
  77. }
  78. void CPhyloTreeDataSource::Init(TPhyTreeNode & node, CPhyloTreeNode * pos)
  79. {       
  80.     for (TPhyTreeNode::TNodeList_CI it = node.SubNodeBegin();  it != node.SubNodeEnd();  it++) {
  81.        if (!(*it)->IsLeaf()){            
  82.            CPhyloTreeNode * internal =   new CPhyloTreeNode((*it)->GetValue().GetId(), (*it)->GetValue().GetLabel(), (*it)->GetValue().IsSetDist()?(*it)->GetValue().GetDist():-1);
  83.            pos->InsertNode(pos->SubNodeBegin(), internal);
  84.            Init(**it,  internal);
  85.        }
  86.        else {
  87.            pos->InsertNode(pos->SubNodeBegin(), new CPhyloTreeNode((*it)->GetValue().GetId(), (*it)->GetValue().GetLabel(), (*it)->GetValue().IsSetDist()?(*it)->GetValue().GetDist():-1));
  88.        }
  89.     }    
  90. }
  91. CPhyloTreeNode * CPhyloTreeDataSource::GetTree(void)
  92. {
  93.     return m_Root;         
  94. }
  95. void CPhyloTreeDataSource::x_MeasureTree(CPhyloTreeNode * node)
  96. {   
  97.     m_Hash.insert(pair<int, CPhyloTreeNode *>(node->GetID(), node));
  98.     node->IDX().first  = m_Level;
  99.     node->IDX().second = m_Size;
  100.     if (node->GetParent()){
  101.         // any other node
  102.         node->SetAnnWedge(node->GetParent()->GetValue()->GetAnnWedge() * node->CountLeafs() / node->GetParent()->GetValue()->CountLeafs());
  103.     }
  104.     else { 
  105.         //root
  106.         node->SetAnnWedge(6.28);
  107.     }
  108.     if (node->IsLeaf()) m_Size++;
  109.     else {        
  110.         for(CPhyloTreeNode::TNodeList_I  it = node->SubNodeBegin();  it != node->SubNodeEnd(); it++ )  {            
  111.             m_Level++;
  112.             if (m_Width < m_Level) m_Width = m_Level;    
  113.             x_MeasureTree((*it)->GetValue());              
  114.             m_Level--;
  115.         }
  116.     }    
  117. }
  118. void  CPhyloTreeDataSource::SetSelection(CPhyloTreeNode * node, bool bSel, bool andChilds, bool checkParents)
  119. {
  120.     node->SetSelected(bSel);
  121.     if (andChilds)      x_DescentToChilds(node, bSel);
  122.     if (checkParents)   x_AscendToRoot(node, bSel);
  123. }
  124. void  CPhyloTreeDataSource::x_DescentToChilds(CPhyloTreeNode * node, bool bSel)
  125.     node->SetSelected(bSel);
  126.     if (!node->IsLeaf()) {        
  127.         for(CPhyloTreeNode::TNodeList_I  it = node->SubNodeBegin();  it != node->SubNodeEnd(); it++ )  {            
  128.              x_DescentToChilds((*it)->GetValue(), bSel);
  129.         }
  130.     } 
  131. }
  132. void  CPhyloTreeDataSource::x_AscendToRoot(CPhyloTreeNode * node, bool bSel)
  133. {
  134.     CPhyloTreeNode * parent = node->GetParent()?node->GetParent()->GetValue():NULL;
  135.     if (parent){
  136.         bool bAllSelected = true;
  137.         for (CPhyloTreeNode::TNodeList_I  it = parent->SubNodeBegin();  it != parent->SubNodeEnd(); it++ ) {
  138.             bAllSelected = (*it)->GetValue()->GetSelected();
  139.             if (!bAllSelected) break;
  140.         }
  141.         if (bAllSelected && bSel) parent->SetSelected(bSel);        
  142.         x_AscendToRoot(parent, bSel);
  143.     }
  144. }
  145. CPhyloTreeNode * CPhyloTreeDataSource::GetNode(int idx)
  146. {    
  147.     map <int, CPhyloTreeNode *>::iterator itf = m_Hash.find(idx);
  148.     return (itf!=m_Hash.end()) ? itf->second : NULL;
  149. }
  150. CPhyloTreeDataSource::TIds
  151. CPhyloTreeDataSource::ConvertId2SeqId(const vector<int> & ids)
  152. {
  153.     CPhyloTreeDataSource::TIds retValue;
  154.     retValue.clear();
  155.     ITERATE (vector<int>, it, ids) {
  156.         if (*it >= 0  &&  *it < m_SeqIds.size()) {
  157.             retValue.push_back(m_SeqIds[*it]);
  158.         }
  159.     }
  160.     return retValue;
  161. }
  162. vector<int> CPhyloTreeDataSource::ConvertSeqId2Id(const CPhyloTreeDataSource::TIds & seqids)
  163. {
  164.     vector <int> retValue;
  165.     retValue.clear();
  166.     ITERATE (TIds, it, seqids) {        
  167.         ITERATE(TIds, itS, m_SeqIds)   {
  168.             if(CSeqUtils::Match(**it, **itS, m_Scope))    {
  169.                 retValue.push_back(itS - m_SeqIds.begin());
  170.                 break;
  171.             }
  172.         }
  173.     }
  174.     return retValue;
  175. }
  176.     
  177. vector<int> CPhyloTreeDataSource::GetSelectedIds(void) const
  178. {
  179.     vector <int> retValue;
  180.     ITERATE(TNodeHash, it, m_Hash) {
  181.         if (it->second->GetSelected())  {
  182.             retValue.push_back(it->first);
  183.         }
  184.     }
  185.     return retValue;
  186. }
  187. const TModelRect CPhyloTreeDataSource::GetBoundRect(void)
  188. {
  189.     TModelRect brect(0,0,0,0);
  190.     
  191.     if (m_Hash.size()>0){
  192.         CPhyloTreeNode * firstNode = m_Hash.begin()->second;
  193.         brect.Init(firstNode->XY().first, firstNode->XY().second,
  194.                    firstNode->XY().first, firstNode->XY().second);
  195.     }    
  196.         
  197.     ITERATE(TNodeHash, it, m_Hash) {
  198.         CPhyloTreeNode * node = it->second;
  199.         if (brect.Left()  > node->XY().first) {
  200.             brect.SetLeft(node->XY().first);
  201.         }
  202.         if (brect.Right() < node->XY().first) {
  203.             brect.SetRight(node->XY().first);
  204.         }
  205.         if (brect.Top()   > node->XY().second) {
  206.             brect.SetTop(node->XY().second);
  207.         }
  208.         if (brect.Bottom()< node->XY().second) {
  209.             brect.SetBottom(node->XY().second);
  210.         }
  211.     }
  212.     return brect;
  213. }
  214. const double CPhyloTreeDataSource::GetNormDistance(bool fromRoot)
  215. {
  216.      double norm = 0; 
  217.      ITERATE(TNodeHash, it, m_Hash) {
  218.         double dist = fromRoot?it->second->GetDistFromRoot():it->second->GetDistance();
  219.         if (dist > norm) norm = dist;
  220.      }
  221.      return norm;
  222. }
  223.   
  224. END_NCBI_SCOPE
  225. /*
  226.  * ===========================================================================
  227.  * $Log: phylo_tree_ds.cpp,v $
  228.  * Revision 1000.1  2004/06/01 21:11:37  gouriano
  229.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.18
  230.  *
  231.  * Revision 1.18  2004/05/21 22:27:54  gorelenk
  232.  * Added PCH ncbi_pch.hpp
  233.  *
  234.  * Revision 1.17  2004/05/11 20:53:12  tereshko
  235.  * Work in progress
  236.  *
  237.  * Revision 1.16  2004/05/07 15:36:41  dicuccio
  238.  * Formatting changes.  Use ITERATE() instead of for(;;)
  239.  *
  240.  * Revision 1.15  2004/05/03 13:23:57  dicuccio
  241.  * gui/utils --> gui/objutils where needed
  242.  *
  243.  * Revision 1.14  2004/04/28 19:27:10  tereshko
  244.  * Added support for distances rendering
  245.  *
  246.  * Revision 1.13  2004/04/20 21:57:19  tereshko
  247.  * Major rendering, labeling and performance improvements
  248.  *
  249.  * Revision 1.12  2004/04/16 16:40:13  dicuccio
  250.  * Use typedef instead of raw STL container for IDs
  251.  *
  252.  * Revision 1.11  2004/04/16 14:51:00  dicuccio
  253.  * Pass CScope as non-const reference, not CRef<>
  254.  *
  255.  * Revision 1.10  2004/04/13 20:28:53  tereshko
  256.  * Numerous renderers improvements
  257.  *
  258.  * Revision 1.9  2004/04/07 13:08:42  dicuccio
  259.  * Changed CSeqUtils::Match() - scope is optional (pointer) parameter
  260.  *
  261.  * Revision 1.8  2004/04/02 16:21:06  yazhuk
  262.  * Replaced vector<CRef<>> with vector<CConstRef<>>, added Scope data member,
  263.  * using CSeqUtils::Match() to compare ids
  264.  *
  265.  * Revision 1.7  2004/04/01 21:46:37  tereshko
  266.  * Added ability of auto-selecting parent nodes
  267.  *
  268.  * Revision 1.6  2004/03/31 17:53:34  tereshko
  269.  * Added function for retrieval of preprocessed selection
  270.  *
  271.  * Revision 1.5  2004/03/30 17:11:44  tereshko
  272.  * Added support for events broadcasting
  273.  *
  274.  * Revision 1.4  2004/03/09 15:26:18  jcherry
  275.  * Distances and labels for internal nodes too
  276.  *
  277.  * Revision 1.3  2004/03/02 18:28:26  tereshko
  278.  * Added support for calculating annual vertex weight
  279.  *
  280.  * Revision 1.2  2004/02/17 23:44:41  tereshko
  281.  * Changes due to integration into viewer
  282.  *
  283.  * Revision 1.1  2004/02/13 17:05:01  tereshko
  284.  * Phylogenetic Tree Widget initial revision
  285.  *
  286.  * ===========================================================================
  287.  */