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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: bio_tree.hpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 18:04:29  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.10
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef ALGO_PHY_TREE___BIO_TREE__HPP
  10. #define ALGO_PHY_TREE___BIO_TREE__HPP
  11. /*  $Id: bio_tree.hpp,v 1000.1 2004/06/01 18:04:29 gouriano Exp $
  12.  * ===========================================================================
  13.  *
  14.  *                            PUBLIC DOMAIN NOTICE
  15.  *               National Center for Biotechnology Information
  16.  *
  17.  *  This software/database is a "United States Government Work" under the
  18.  *  terms of the United States Copyright Act.  It was written as part of
  19.  *  the author's official duties as a United States Government employee and
  20.  *  thus cannot be copyrighted.  This software/database is freely available
  21.  *  to the public for use. The National Library of Medicine and the U.S.
  22.  *  Government have not placed any restriction on its use or reproduction.
  23.  *
  24.  *  Although all reasonable efforts have been taken to ensure the accuracy
  25.  *  and reliability of the software and data, the NLM and the U.S.
  26.  *  Government do not and cannot warrant the performance or results that
  27.  *  may be obtained by using this software or data. The NLM and the U.S.
  28.  *  Government disclaim all warranties, express or implied, including
  29.  *  warranties of performance, merchantability or fitness for any particular
  30.  *  purpose.
  31.  *
  32.  *  Please cite the author in any work or product based on this material.
  33.  *
  34.  * ===========================================================================
  35.  *
  36.  * Authors:  Anatoliy Kuznetsov
  37.  *
  38.  * File Description:  Things for representing and manipulating bio trees
  39.  *
  40.  */
  41. /// @file bio_tree.hpp
  42. /// Things for representing and manipulating bio trees
  43. #include <corelib/ncbistd.hpp>
  44. #include <map>
  45. #include <string>
  46. #include <memory>
  47. #include <vector>
  48. #include <list>
  49. #include <corelib/ncbi_tree.hpp>
  50. BEGIN_NCBI_SCOPE
  51. /// Feature Id. All bio tree dynamic features are encoded by feature ids.
  52. /// Ids are shared among the tree nodes. Feature id to feature name map is 
  53. /// supported by the tree.
  54. typedef unsigned int TBioTreeFeatureId;
  55. /// Tree node id. Every node has its unique id in the tree.
  56. typedef unsigned int TBioTreeNodeId;
  57. /// Tree node feature pair (id to string)
  58. struct NCBI_XALGOPHYTREE_EXPORT CBioTreeFeaturePair
  59. {
  60.     TBioTreeFeatureId  id;
  61.     string             value;
  62.     CBioTreeFeaturePair(TBioTreeFeatureId fid, const string& fvalue)
  63.     : id(fid),
  64.       value(fvalue)
  65.     {}
  66.     CBioTreeFeaturePair(void)
  67.     : id(0)
  68.     {}
  69. };
  70. /// Features storage for the bio tree node
  71. ///
  72. /// Every node in the bio tree may have a list of attached features.
  73. /// Features are string attributes which may vary from node to node in the
  74. /// tree.
  75. ///
  76. /// Implementation note: This class may evolve into a specialized templates
  77. /// parameterizing different feature storage options (like vector, map, list)
  78. /// depending on what tree is used.
  79. class NCBI_XALGOPHYTREE_EXPORT CBioTreeFeatureList
  80. {
  81. public:
  82.     typedef  vector<CBioTreeFeaturePair>    TFeatureList;
  83.     CBioTreeFeatureList();
  84.     CBioTreeFeatureList(const CBioTreeFeatureList& flist);
  85.     CBioTreeFeatureList& operator=(const CBioTreeFeatureList& flist);
  86.     /// Set feature value, feature if exists replaced, if not added.
  87.     void SetFeature(TBioTreeFeatureId id, const string& value);
  88.     /// Get feature value by id
  89.     /// @return Feature value or empty string if feature does not exists
  90.     const string& GetFeatureValue(TBioTreeFeatureId id) const;
  91.     /// Remove feature from the list
  92.     void RemoveFeature(TBioTreeFeatureId id);
  93.     /// Get feature value by id (operator semantics)
  94.     const string& operator[](TBioTreeFeatureId id) const
  95.     {
  96.         return GetFeatureValue(id);
  97.     }
  98.     /// Return reference on the internal container
  99.     const TFeatureList& GetFeatureList() const { return m_FeatureList; }
  100. protected:
  101.     TFeatureList  m_FeatureList;
  102. };
  103. /// Basic node data structure used by BioTreeBaseNode.
  104. /// Strucure carries absolutely no info.
  105. struct CBioTreeEmptyNodeData
  106. {
  107. };
  108. /// Basic data contained in every bio-tree node
  109. ///
  110. /// Template parameter NodeData allows to extend list of 
  111. /// compile-time (non-dynamic attributes in the tree)
  112. /// NodeFeatures - extends node with dynamic list of node attributes
  113. ///
  114. ///
  115. template<class TNodeData     = CBioTreeEmptyNodeData, 
  116.          class TNodeFeatures = CBioTreeFeatureList>
  117. struct BioTreeBaseNode
  118. {
  119.     TBioTreeNodeId      uid;      ///< Unique node Id
  120.     TNodeData           data;     ///< additional node info
  121.     TNodeFeatures       features; ///< list of node features
  122.     typedef  TNodeData        TNodeDataType;
  123.     typedef  TNodeFeatures    TNodeFeaturesType;
  124.     BioTreeBaseNode(TBioTreeNodeId uid_value = 0)
  125.      : uid(uid_value)
  126.     {}
  127.     BioTreeBaseNode(const BioTreeBaseNode<TNodeData, TNodeFeatures>& node)
  128.      : uid(node.uid),
  129.       data(node.data),
  130.       features(node.features)
  131.     {}
  132.     BioTreeBaseNode<TNodeData, TNodeFeatures>& 
  133.     operator=(const BioTreeBaseNode<TNodeData, TNodeFeatures>& node)
  134.     {
  135.         uid = node.uid;
  136.         data = node.data;
  137.         features = node.features;
  138.         return *this;
  139.     }
  140.     TBioTreeNodeId GetId() const { return uid; }
  141.     void SetId(TBioTreeNodeId id) { uid = id; }
  142. };
  143. /// Feature dictionary. 
  144. /// Used for mapping between feature ids and feature names.
  145. ///
  146. class NCBI_XALGOPHYTREE_EXPORT CBioTreeFeatureDictionary
  147. {
  148. public:
  149.     /// Feature dictionary (feature id -> feature name map)
  150.     typedef map<TBioTreeFeatureId, string> TFeatureDict;
  151.     /// Feature reverse index (feature name -> id)
  152.     typedef map<string, TBioTreeFeatureId> TFeatureNameIdx;
  153. public:
  154.     CBioTreeFeatureDictionary();
  155.     CBioTreeFeatureDictionary(const CBioTreeFeatureDictionary& btr);
  156.     
  157.     CBioTreeFeatureDictionary& 
  158.        operator=(const CBioTreeFeatureDictionary& btr);
  159.     /// Check if feature is listed in the dictionary
  160.     bool HasFeature(const string& feature_name);
  161.     /// Check if feature is listed in the dictionary
  162.     bool HasFeature(TBioTreeFeatureId id);
  163.     /// Register new feature, return its id.
  164.     /// If feature is already registered just returns the id.
  165.     /// Feature ids are auto incremented variable managed by the class.
  166.     TBioTreeFeatureId Register(const string& feature_name);
  167. /// Register new feature.
  168. /// @note
  169. /// Feature counter remains unchanged.
  170. /// Please do not mix auto counted Regsiter and this method.
  171. void Register(TBioTreeFeatureId id, const string& feature_name);
  172.     /// If feature is already registered returns its id by name.
  173.     /// If feature does not exist returns 0.
  174.     TBioTreeFeatureId GetId(const string& feature_name) const;
  175.     /// Clear the dictionary
  176.     void Clear();
  177.     /// Get reference on the internal map
  178.     const TFeatureDict& GetFeatureDict() const { return m_Dict; }
  179. protected:
  180.     TFeatureDict     m_Dict;        ///< id -> feature name map
  181.     TFeatureNameIdx  m_Name2Id;     ///< id -> feature name map
  182.     unsigned int     m_IdCounter;   ///< Feature id counter
  183. };
  184. /// Basic tree structure for biological applications
  185. template<class TBioNode>
  186. class CBioTree
  187. {
  188. public:
  189.     /// Biotree node (forms the tree hierarchy)
  190.     typedef CTreeNode<TBioNode> TBioTreeNode;
  191.     typedef TBioNode            TBioNodeType;
  192. public:
  193.     CBioTree() 
  194.      : m_NodeIdCounter(0),
  195.        m_TreeNode(0)
  196.     {}
  197.     CBioTree(const CBioTree<TBioNode>& btr)
  198.     : m_FeatureDict(btr.m_FeatureDict),
  199.       m_NodeIdCounter(btr.m_NodeIdCounter),
  200.       m_TreeNode(new TBioTreeNode(*(btr.m_TreeNode)))
  201.     {
  202.     }
  203.     CBioTree<TBioNode>&
  204.         operator=(const CBioTree<TBioNode>& btr)
  205.     {
  206.         m_FeatureDict = btr.m_FeatureDict;
  207.         m_NodeIdCounter = btr.m_NodeIdCounter;
  208.         m_TreeNode = new TBioTreeNode(*(btr.m_TreeNode));
  209.     }
  210.     /// Finds node by id.
  211.     /// @return 
  212.     ///     Node pointer or NULL if requested node id is unknown
  213.     const TBioTreeNode* FindNode(TBioTreeNodeId node_id) const
  214.     {
  215.         TBioTreeNode* tree_node = 
  216.             const_cast<TBioTreeNode*>(m_TreeNode.get());
  217.         if (tree_node == 0) {
  218.             return 0;
  219.         }
  220.         CFindUidFunc func = 
  221.           TreeDepthFirstTraverse(*tree_node, CFindUidFunc(node_id));
  222.         return func.GetNode();
  223.     }
  224.     /// Add feature to the tree node
  225.     /// Function controls that the feature is registered in the 
  226.     /// feature dictionary of this tree.
  227.     void AddFeature(TBioTreeNode*      node, 
  228.                     TBioTreeFeatureId  feature_id,
  229.                     const string&      feature_value)
  230.     {
  231.         // Check if this id is in the dictionary
  232.         bool id_found = m_FeatureDict.HasFeature(feature_id);
  233.         if (id_found) {
  234.             node->GetValue().features.SetFeature(feature_id, feature_value);
  235.         } else {
  236.             // TODO:throw an exception here
  237.         }
  238.     }
  239.     /// Add feature to the tree node
  240.     /// Function controls that the feature is registered in the 
  241.     /// feature dictionary of this tree. If feature is not found
  242.     /// it is added to the dictionary
  243.     void AddFeature(TBioTreeNode*      node, 
  244.                     const string&      feature_name,
  245.                     const string&      feature_value)
  246.     {
  247.         // Check if this id is in the dictionary
  248.         TBioTreeFeatureId feature_id 
  249.             = m_FeatureDict.GetId(feature_name);
  250.         if (!feature_id) {
  251.             // Register the new feature type
  252.             feature_id = m_FeatureDict.Register(feature_name);
  253.         }
  254.         AddFeature(node, feature_id, feature_value);
  255.     }
  256.     /// Get new unique node id
  257.     virtual TBioTreeNodeId GetNodeId()
  258.     {
  259.         return m_NodeIdCounter++;
  260.     }
  261.     /// Get new unique node id 
  262.     /// (for cases when node id depends on the node's content
  263.     virtual TBioTreeNodeId GetNodeId(const TBioTreeNode& node)
  264.     {
  265.         return m_NodeIdCounter++;
  266.     }
  267.     /// Assign new unique node id to the node
  268.     void SetNodeId(TBioTreeNode* node)
  269.     {
  270.         TBioTreeNodeId uid = GetNodeId(*node);
  271.         node->uid = uid;
  272.     }
  273.     /// Assign new top level tree node
  274.     void SetTreeNode(TBioTreeNode* node)
  275.     {
  276.         _ASSERT(node->GetParent() == 0);
  277.         m_TreeNode.reset(node);
  278.     }
  279.     const TBioTreeNode* GetTreeNode() const { return m_TreeNode.get(); }
  280.     /// Add node to the tree (node location is defined by the parent id
  281.     TBioTreeNode* AddNode(const TBioNodeType& node_value, 
  282.                           TBioTreeNodeId      parent_id)
  283.     {
  284. TBioTreeNode* ret = 0;
  285.         const TBioTreeNode* pnode = FindNode(parent_id);
  286.         if (pnode) {
  287.             TBioTreeNode* parent_node = const_cast<TBioTreeNode*>(pnode);
  288.             ret = parent_node->AddNode(node_value);
  289.         }
  290. return ret;
  291.     }
  292.     /// Clear the bio tree
  293.     void Clear()
  294.     {
  295.         m_FeatureDict.Clear();
  296.         m_NodeIdCounter = 0;
  297.         m_TreeNode.reset(0);
  298.     }
  299.     CBioTreeFeatureDictionary& GetFeatureDict() { return m_FeatureDict; }
  300.     const CBioTreeFeatureDictionary& GetFeatureDict() const 
  301.     { return m_FeatureDict; }
  302. protected:
  303.     /// Find node by UID functor
  304.     class CFindUidFunc 
  305.     {
  306.     public:
  307.         CFindUidFunc(TBioTreeNodeId uid)
  308.          : m_Uid(uid), 
  309.            m_Node(0)
  310.         {}
  311.         const TBioTreeNode* GetNode() const { return m_Node; }
  312.         ETreeTraverseCode operator()(TBioTreeNode& tree_node, int delta)
  313.         {
  314.             if (delta == 0 || delta == 1) {
  315.                 if (tree_node.GetValue().GetId() == m_Uid) {
  316.                     m_Node = &tree_node;
  317.                     return eTreeTraverseStop;
  318.                 }
  319.             }
  320.             return eTreeTraverse;
  321.         }
  322.     private:
  323.         TBioTreeNodeId  m_Uid;    ///< Node uid to search for
  324.         TBioTreeNode*   m_Node;   ///< Search result
  325.     };
  326. protected:
  327.     CBioTreeFeatureDictionary  m_FeatureDict;
  328.     TBioTreeNodeId             m_NodeIdCounter;
  329.     auto_ptr<TBioTreeNode>     m_TreeNode;      ///< Top level node
  330. };
  331. /// Bio tree without static elements. Everything is stored as features.
  332. ///
  333. /// @internal
  334. typedef 
  335.   CBioTree<BioTreeBaseNode<CBioTreeEmptyNodeData, CBioTreeFeatureList> >
  336.   CBioTreeDynamic;
  337. END_NCBI_SCOPE // ALGO_PHY_TREE___BIO_TREE__HPP
  338. /*
  339.  * ===========================================================================
  340.  * $Log: bio_tree.hpp,v $
  341.  * Revision 1000.1  2004/06/01 18:04:29  gouriano
  342.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.10
  343.  *
  344.  * Revision 1.10  2004/06/01 15:20:04  kuznets
  345.  * Minor modifications
  346.  *
  347.  * Revision 1.9  2004/05/26 15:29:10  kuznets
  348.  * Removed dead code
  349.  *
  350.  * Revision 1.8  2004/05/26 15:14:33  kuznets
  351.  * Tree convertion algorithms migrated to bio_tree_conv.hpp, plus multiple
  352.  * minor changes.
  353.  *
  354.  * Revision 1.7  2004/05/19 14:37:03  ucko
  355.  * Remove extraneous "typename" that confused some compilers.
  356.  *
  357.  * Revision 1.6  2004/05/19 12:46:25  kuznets
  358.  * Added utilities to convert tree to a fully dynamic variant.
  359.  *
  360.  * Revision 1.5  2004/05/10 20:51:27  ucko
  361.  * Repoint m_TreeNode with .reset() rather than assignment, which not
  362.  * all auto_ptr<> implementations support.
  363.  *
  364.  * Revision 1.4  2004/05/10 15:45:46  kuznets
  365.  * Redesign. Added dynamic interface for UI viewer compatibility.
  366.  *
  367.  * Revision 1.3  2004/04/06 20:32:42  ucko
  368.  * +<memory> for auto_ptr<>
  369.  *
  370.  * Revision 1.2  2004/04/06 17:59:00  kuznets
  371.  * Work in progress
  372.  *
  373.  * Revision 1.1  2004/03/29 16:43:38  kuznets
  374.  * Initial revision
  375.  *
  376.  * ===========================================================================
  377.  */
  378. #endif