A toolkit for working with phylogenetic data.
v0.24.0
tree/common_tree/operators.cpp
Go to the documentation of this file.
1 /*
2  Genesis - A toolkit for working with phylogenetic data.
3  Copyright (C) 2014-2018 Lucas Czech and HITS gGmbH
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  Contact:
19  Lucas Czech <lucas.czech@h-its.org>
20  Exelixis Lab, Heidelberg Institute for Theoretical Studies
21  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
22 */
23 
32 
35 #include "genesis/tree/tree.hpp"
38 
39 namespace genesis {
40 namespace tree {
41 
42 // =================================================================================================
43 // Comparison and Conversion
44 // =================================================================================================
45 
47  Tree const& lhs,
48  Tree const& rhs,
49  bool compare_node_names,
50  bool compare_branch_lengths
51 ) {
52  auto node_comparator = [&] (
53  CommonTreeNode const& node_l,
54  CommonTreeNode const& node_r
55  ) {
56  if( ! compare_node_names ) {
57  return true;
58  }
59 
60  auto l_ptr = dynamic_cast< CommonNodeData const* >( node_l.data_ptr() );
61  auto r_ptr = dynamic_cast< CommonNodeData const* >( node_r.data_ptr() );
62  if( l_ptr == nullptr || r_ptr == nullptr ) {
63  return false;
64  }
65  // if( l_ptr->name != r_ptr->name ) {
66  // LOG_DBG << "Differing names: " << l_ptr->name << " and " << r_ptr->name;
67  // }
68 
69  return l_ptr->name == r_ptr->name;
70  };
71 
72  auto edge_comparator = [&] (
73  CommonTreeEdge const& edge_l,
74  CommonTreeEdge const& edge_r
75  ) {
76  if( ! compare_branch_lengths ) {
77  return true;
78  }
79 
80  auto l_ptr = dynamic_cast< CommonEdgeData const* >( edge_l.data_ptr() );
81  auto r_ptr = dynamic_cast< CommonEdgeData const* >( edge_r.data_ptr() );
82  if( l_ptr == nullptr || r_ptr == nullptr ) {
83  return false;
84  }
85  // if( ! utils::almost_equal_relative( l_ptr->branch_length, r_ptr->branch_length ) ) {
86  // LOG_DBG << "Differing branch lengths: " << l_ptr->branch_length << " and " << r_ptr->branch_length;
87  // }
88 
89  return utils::almost_equal_relative( l_ptr->branch_length, r_ptr->branch_length );
90  };
91 
92  return tree::equal( lhs, rhs, node_comparator, edge_comparator );
93 }
94 
95 CommonTree convert_to_common_tree( Tree const& source_tree )
96 {
97  // In both converter functions, we first cast to common data, in order to make sure that we
98  // actually have data that is derived from common data. If not, those casts will throw.
99  // Then, we explicitly call functions of the common data classes, i.e., we break the virtual
100  // call on purpose, by calling `.CommonNodeData::...`. This makes sure that we actually get
101  // common data and not the most derived one.
102 
103  auto node_data_converter = [] ( tree::BaseNodeData const& source_node ) {
104  return dynamic_cast< CommonNodeData const& >( source_node ).CommonNodeData::clone();
105  };
106 
107  auto edge_data_converter = [] ( tree::BaseEdgeData const& source_edge ) {
108  return dynamic_cast< CommonEdgeData const& >( source_edge ).CommonEdgeData::clone();
109  };
110 
111  return tree::convert(
112  source_tree,
113  node_data_converter,
114  edge_data_converter
115  );
116 }
117 
118 } // namespace tree
119 } // namespace genesis
Base class for storing data on Nodes of a Tree.
Definition: node_data.hpp:66
Tree operator functions.
virtual std::unique_ptr< BaseNodeData > clone() const override
Polymorphically copy an instance of this class. Use instead of copy constructor.
bool equal_common_trees(Tree const &lhs, Tree const &rhs, bool compare_node_names, bool compare_branch_lengths)
Compare two CommonTrees, that is, check whether they have identical topology, node names...
Container namespace for all symbols of genesis in order to keep them separate when used as a library...
BaseEdgeData * data_ptr()
Return a pointer to the data.
Definition: edge.hpp:246
Class for representing phylogenetic trees.
Definition: tree/tree.hpp:97
CommonTree convert_to_common_tree(Tree const &source_tree)
Convert a Tree to a CommonTree with CommonNodeData and CommonEdgeData.
std::string name
Name of the node.
Provides easy and fast logging functionality.
virtual std::unique_ptr< BaseEdgeData > clone() const override
Polymorphically copy an instance of this class. Use instead of copy constructor.
Common class containing the commonly needed data for tree nodes.
Header of Tree class.
Base class for storing data on Edges of a Tree.
Definition: edge_data.hpp:66
Common class containing the commonly needed data for tree edges.
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...
BaseNodeData * data_ptr()
Return a pointer to the data.
Definition: node.hpp:232
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.
bool almost_equal_relative(double lhs, double rhs, double max_rel_diff=std::numeric_limits< double >::epsilon())
Check whether two doubles are almost equal, using a relative epsilon to compare them.
Definition: common.hpp:118