A toolkit for working with phylogenetic data.
v0.20.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tree/default/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  DefaultTreeNode const& node_l,
54  DefaultTreeNode const& node_r
55  ) {
56  if( ! compare_node_names ) {
57  return true;
58  }
59 
60  auto l_ptr = dynamic_cast< DefaultNodeData const* >( node_l.data_ptr() );
61  auto r_ptr = dynamic_cast< DefaultNodeData 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  DefaultTreeEdge const& edge_l,
74  DefaultTreeEdge const& edge_r
75  ) {
76  if( ! compare_branch_lengths ) {
77  return true;
78  }
79 
80  auto l_ptr = dynamic_cast< DefaultEdgeData const* >( edge_l.data_ptr() );
81  auto r_ptr = dynamic_cast< DefaultEdgeData 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 
96 {
97  // In both converter functions, we first cast to default data, in order to make sure that we
98  // actually have data that is derived from default data. If not, those casts will throw.
99  // Then, we explicitly call functions of the default data classes, i.e., we break the virtual
100  // call on purpose, by calling `.DefaultNodeData::...`. This makes sure that we actually get
101  // default data and not the most derived one.
102 
103  auto node_data_converter = [] ( tree::BaseNodeData const& source_node ) {
104  return dynamic_cast< DefaultNodeData const& >( source_node ).DefaultNodeData::clone();
105  };
106 
107  auto edge_data_converter = [] ( tree::BaseEdgeData const& source_edge ) {
108  return dynamic_cast< DefaultEdgeData const& >( source_edge ).DefaultEdgeData::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
virtual std::unique_ptr< BaseEdgeData > clone() const override
Polymorphically copy an instance of this class. Use instead of copy constructor.
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.
DefaultTree convert_to_default_tree(Tree const &source_tree)
Convert a Tree to a DefaultTree with DefaultNodeData and DefaultEdgeData.
Base class for storing data on Nodes of a Tree.
Definition: node_data.hpp:66
Tree operator functions.
Default class containing the commonly needed data for tree nodes.
Default class containing the commonly needed data for tree edges.
virtual std::unique_ptr< BaseNodeData > clone() const override
Polymorphically copy an instance of this class. Use instead of copy constructor.
BaseEdgeData * data_ptr()
Return a pointer to the data.
Definition: edge.hpp:212
Class for representing phylogenetic trees.
Definition: tree/tree.hpp:95
Provides easy and fast logging functionality.
std::string name
Name of the node.
Header of Tree class.
Base class for storing data on Edges of a Tree.
Definition: edge_data.hpp:66
bool equal_default_trees(Tree const &lhs, Tree const &rhs, bool compare_node_names, bool compare_branch_lengths)
Compare two DefaultTrees, that is, check whether they have identical topology, node names...
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)
Compares 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:181
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:108