A library for working with phylogenetic and population genetic data.
v0.32.0
tree/function/operators.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_TREE_FUNCTION_OPERATORS_H_
2 #define GENESIS_TREE_FUNCTION_OPERATORS_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2024 Lucas Czech
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21  Contact:
22  Lucas Czech <lucas.czech@sund.ku.dk>
23  University of Copenhagen, Globe Institute, Section for GeoGenetics
24  Oster Voldgade 5-7, 1350 Copenhagen K, Denmark
25 */
26 
34 #include "genesis/tree/tree.hpp"
35 
36 #include <cassert>
37 #include <functional>
38 #include <iosfwd>
39 #include <memory>
40 #include <typeinfo>
41 
42 namespace genesis {
43 namespace tree {
44 
45 // =================================================================================================
46 // Forward Declarations
47 // =================================================================================================
48 
49 class BaseNodeData;
50 class BaseEdgeData;
51 class Subtree;
52 
53 // =================================================================================================
54 // Data Type Checks
55 // =================================================================================================
56 
65 template< class NodeDataType, class EdgeDataType >
66 bool tree_data_is( Tree const& tree, bool allow_null = false )
67 {
68  // Check node data types.
69  for( auto const& node : tree.nodes() ) {
70  if( ! node.has_data() ) {
71  if( allow_null ) {
72  continue;
73  } else {
74  return false;
75  }
76  }
77  assert( node.data_ptr() );
78  auto const& ref = *node.data_ptr();
79  if( typeid( ref ) != typeid( NodeDataType )) {
80  return false;
81  }
82  }
83 
84  // Check edge data types.
85  for( auto const& edge : tree.edges() ) {
86  if( ! edge.has_data() ) {
87  if( allow_null ) {
88  continue;
89  } else {
90  return false;
91  }
92  }
93  assert( edge.data_ptr() );
94  auto const& ref = *edge.data_ptr();
95  if( typeid( ref ) != typeid( EdgeDataType )) {
96  return false;
97  }
98  }
99 
100  return true;
101 }
102 
111 template< class NodeDataType, class EdgeDataType >
112 bool tree_data_is_derived_from( Tree const& tree, bool allow_null = false )
113 {
114  // Check node data types.
115  for( auto const& node : tree.nodes() ) {
116  if( ! node.has_data() ) {
117  if( allow_null ) {
118  continue;
119  } else {
120  return false;
121  }
122  }
123  assert( node.data_ptr() );
124  if( dynamic_cast< NodeDataType const* >( node.data_ptr() ) == nullptr ) {
125  return false;
126  }
127  }
128 
129  // Check edge data types.
130  for( auto const& edge : tree.edges() ) {
131  if( ! edge.has_data() ) {
132  if( allow_null ) {
133  continue;
134  } else {
135  return false;
136  }
137  }
138  assert( edge.data_ptr() );
139  if( dynamic_cast< EdgeDataType const* >( edge.data_ptr() ) == nullptr ) {
140  return false;
141  }
142  }
143 
144  return true;
145 }
146 
147 // =================================================================================================
148 // Conversion
149 // =================================================================================================
150 
163 Tree convert(
164  Tree const& source,
165  std::function< std::unique_ptr<BaseNodeData>( BaseNodeData const& node_data )> node_data_converter,
166  std::function< std::unique_ptr<BaseEdgeData>( BaseEdgeData const& edge_data )> edge_data_converter
167 );
168 
169 // =================================================================================================
170 // Equality and Identity
171 // =================================================================================================
172 
189 bool equal(
190  Tree const& lhs,
191  Tree const& rhs,
192  std::function<bool ( TreeNode const&, TreeNode const&) > node_comparator,
193  std::function<bool ( TreeEdge const&, TreeEdge const&) > edge_comparator
194 );
195 
202 bool equal(
203  std::vector<Tree> const& trees,
204  std::function<bool ( TreeNode const&, TreeNode const&) > node_comparator,
205  std::function<bool ( TreeEdge const&, TreeEdge const&) > edge_comparator
206 );
207 
208 // bool equal( Tree const& lhs, Tree const& rhs);
209 
223 bool identical_topology( Tree const& lhs, Tree const& rhs, bool identical_indices = true );
224 
230 bool identical_topology( std::vector<Tree> const& trees, bool identical_indices = true );
231 
232 // =================================================================================================
233 // Element Ownership Checks
234 // =================================================================================================
235 
239 bool belongs_to( Tree const& tree, TreeNode const& node );
240 
244 bool belongs_to( TreeNode const& node, Tree const& tree );
245 
249 bool belongs_to( Tree const& tree, TreeEdge const& edge );
250 
254 bool belongs_to( TreeEdge const& edge, Tree const& tree );
255 
259 bool belongs_to( Tree const& tree, TreeLink const& link );
260 
264 bool belongs_to( TreeLink const& link, Tree const& tree );
265 
269 bool belongs_to( Tree const& tree, Subtree const& subt );
270 
274 bool belongs_to( Subtree const& subt, Tree const& tree );
275 
279 TreeEdge* edge_between( TreeNode& lhs, TreeNode& rhs );
280 
284 TreeEdge const* edge_between( TreeNode const& lhs, TreeNode const& rhs );
285 
286 // =================================================================================================
287 // Output
288 // =================================================================================================
289 
290 std::string print_info( Tree const& tree );
291 std::string print_info( TreeEdge const& edge );
292 std::string print_info( TreeLink const& link );
293 std::string print_info( TreeNode const& node );
294 
295 std::string print_gist( Tree const& tree, long items = 10 );
296 
297 // =================================================================================================
298 // Validate
299 // =================================================================================================
300 
307 bool validate_topology( Tree const& tree );
308 
309 } // namespace tree
310 } // namespace genesis
311 
312 #endif // include guard
genesis::tree::convert
Tree convert(Tree const &source, std::function< std::unique_ptr< BaseNodeData >(BaseNodeData const &node_data)> node_data_converter, std::function< std::unique_ptr< BaseEdgeData >(BaseEdgeData const &edge_data)> edge_data_converter)
Create a tree with the same topology as the source tree, while converting its data.
Definition: tree/function/operators.cpp:53
genesis::tree::print_gist
std::string print_gist(Tree const &tree, long items)
Definition: tree/function/operators.cpp:321
tree.hpp
Header of Tree class.
genesis::tree::print_info
std::string print_info(Tree const &tree)
Definition: tree/function/operators.cpp:288
genesis::tree::tree_data_is
bool tree_data_is(Tree const &tree, bool allow_null=false)
Check whether the data of the nodes and edges of the Tree are exactly of the specified data types.
Definition: tree/function/operators.hpp:66
genesis::tree::belongs_to
bool belongs_to(Tree const &tree, TreeNode const &node)
Return whether the TreeNode belongs to the Tree, i.e., whether it is owned by the Tree.
Definition: tree/function/operators.cpp:220
genesis::tree::identical_topology
bool identical_topology(Tree const &lhs, Tree const &rhs, bool identical_indices)
Return whether both trees have an identical topology.
Definition: tree/function/operators.cpp:169
genesis::tree::equal
bool equal(Tree const &lhs, Tree const &rhs, std::function< bool(TreeNode const &, TreeNode const &) > node_comparator, std::function< bool(TreeEdge const &, TreeEdge const &) > edge_comparator)
Compare two trees for equality given binary comparator functionals for their nodes and edges.
Definition: tree/function/operators.cpp:80
genesis::tree::tree_data_is_derived_from
bool tree_data_is_derived_from(Tree const &tree, bool allow_null=false)
Check whether the data of the nodes and edges of the Tree are derived from the specified data types.
Definition: tree/function/operators.hpp:112
genesis::tree::edge_between
TreeEdge * edge_between(TreeNode &lhs, TreeNode &rhs)
Return the TreeEdge between two TreeNode&s, if they are neighbours, or nullptr otherwise.
Definition: tree/function/operators.cpp:260
genesis::tree::Tree
Class for representing phylogenetic trees.
Definition: tree/tree.hpp:97
genesis
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
Definition: placement/formats/edge_color.cpp:42
genesis::tree::Tree::nodes
utils::Range< IteratorNodes > nodes()
Definition: tree/tree.hpp:418
genesis::tree::Tree::edges
utils::Range< IteratorEdges > edges()
Definition: tree/tree.hpp:452
genesis::tree::validate_topology
bool validate_topology(Tree const &tree)
Validate that all internal pointers of the Tree elements (TreeLinks, TreeNodes, TreeEdges) to each ot...
Definition: tree/function/operators.cpp:332