A library for working with phylogenetic and population genetic data.
v0.27.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
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:54
genesis::utils::almost_equal_relative
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:181
common.hpp
genesis::tree::equal_common_trees
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,...
Definition: tree/common_tree/operators.cpp:46
tree.hpp
Header of Tree class.
genesis::tree::BaseEdgeData
Base class for storing data on Edges of a Tree.
Definition: edge_data.hpp:66
genesis::tree::convert_to_common_tree
CommonTree convert_to_common_tree(Tree const &source_tree)
Convert a Tree to a CommonTree with CommonNodeData and CommonEdgeData.
Definition: tree/common_tree/operators.cpp:95
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:81
genesis::tree::CommonNodeData::clone
virtual std::unique_ptr< BaseNodeData > clone() const override
Polymorphically copy an instance of this class. Use instead of copy constructor.
Definition: tree/common_tree/tree.hpp:113
genesis::tree::Tree
Class for representing phylogenetic trees.
Definition: tree/tree.hpp:97
logging.hpp
Provides easy and fast logging functionality.
operators.hpp
genesis::tree::CommonNodeData::name
std::string name
Name of the node.
Definition: tree/common_tree/tree.hpp:127
genesis::tree::TreeEdge
Definition: edge.hpp:60
genesis::tree::TreeNode
Definition: tree/tree/node.hpp:58
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::BaseNodeData
Base class for storing data on Nodes of a Tree.
Definition: node_data.hpp:66
operators.hpp
Tree operator functions.
tree.hpp
genesis::tree::TreeEdge::data_ptr
BaseEdgeData * data_ptr()
Return a pointer to the data.
Definition: edge.hpp:246
genesis::tree::CommonEdgeData::clone
virtual std::unique_ptr< BaseEdgeData > clone() const override
Polymorphically copy an instance of this class. Use instead of copy constructor.
Definition: tree/common_tree/tree.hpp:178
genesis::tree::CommonEdgeData
Common class containing the commonly needed data for tree edges.
Definition: tree/common_tree/tree.hpp:144
genesis::tree::CommonNodeData
Common class containing the commonly needed data for tree nodes.
Definition: tree/common_tree/tree.hpp:79
genesis::tree::TreeNode::data_ptr
BaseNodeData * data_ptr()
Return a pointer to the data.
Definition: tree/tree/node.hpp:232