A toolkit for working with phylogenetic data.
v0.18.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
placement/formats/newick_reader.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_PLACEMENT_FORMATS_NEWICK_READER_H_
2 #define GENESIS_PLACEMENT_FORMATS_NEWICK_READER_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2017 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@h-its.org>
23  Exelixis Lab, Heidelberg Institute for Theoretical Studies
24  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
25 */
26 
34 #include <assert.h>
35 #include <stdexcept>
36 
39 
42 
44 
45 namespace genesis {
46 namespace placement {
47 
48 // =================================================================================================
49 // Placement Tree Newick Reader Plugin
50 // =================================================================================================
51 
56 {
57 public:
58 
59  // -------------------------------------------------------------------------
60  // Constructor and Rule of Five
61  // -------------------------------------------------------------------------
62 
64  virtual ~PlacementTreeNewickReaderPlugin() = default;
65 
68 
71 
72  // -------------------------------------------------------------------------
73  // Plugin Functions
74  // -------------------------------------------------------------------------
75 
76  void element_to_edge( tree::NewickBrokerElement const& element, tree::TreeEdge& edge ) const
77  {
78  auto& edge_data = edge.data<PlacementEdgeData>();
79 
80  // Process the edge num.
81  edge_data.reset_edge_num(-1);
82  if (element.tags.size() == 0) {
83  throw std::invalid_argument(
84  "Edge at node '" + element.name + "' does not contain a tag value like '{42}'" +
85  " for the placement edge_num of this edge."
86  );
87  }
88  if (element.tags.size() > 1) {
89  throw std::invalid_argument(
90  "Edge at node '" + element.name + "' contains more than one tag value like " +
91  "'{xyz}'. Expecting only one for the placement edge_num of this edge."
92  );
93  }
94  assert(element.tags.size() == 1);
95  edge_data.reset_edge_num( std::stoi( element.tags[0] ));
96  }
97 
98  void finish_reading( tree::NewickBroker const& broker, tree::Tree& tree ) const
99  {
100  (void) broker;
101  if( ! has_correct_edge_nums( tree )) {
102  LOG_INFO << "Placement Tree does not have edge_nums that are increasing with a "
103  << "post-order traversal of the tree, as is demanded by the jplace standard. "
104  << "Genesis can still work with this tree, but it might indicate an issue "
105  << "with the data.";
106  }
107  }
108 
109  void register_with( tree::NewickReader& reader ) const
110  {
111  // Set node data creation function.
112  reader.create_node_data_plugin = []( tree::TreeNode& node ){
113  node.reset_data( PlacementNodeData::create() );
114  };
115 
116  // Set edge data creation function.
117  reader.create_edge_data_plugin = []( tree::TreeEdge& edge ){
118  edge.reset_data( PlacementEdgeData::create() );
119  };
120 
121  // Add edge manipulation functions.
122  reader.element_to_edge_plugins.push_back(
123  [&]( tree::NewickBrokerElement const& element, tree::TreeEdge& edge ) {
124  element_to_edge( element, edge );
125  }
126  );
127 
128  // Add finish reading plugin.
129  reader.finish_reading_plugins.push_back(
130  [&]( tree::NewickBroker const& broker, tree::Tree& tree ) {
131  finish_reading( broker, tree );
132  }
133  );
134  }
135 
136 };
137 
138 // =================================================================================================
139 // Placement Tree Newick Reader
140 // =================================================================================================
141 
143  : public tree::NewickReader
146 {
147 public:
148 
149  // -------------------------------------------------------------------------
150  // Constructor and Rule of Five
151  // -------------------------------------------------------------------------
152 
154  {
155  // Jplace files use tags. Activate them!
156  enable_tags( true );
157 
158  // We first register the default reader, then the placement reader, because the latter
159  // overwrites the data creation functions.
160  DefaultTreeNewickReaderPlugin::register_with( *this );
162  }
163 };
164 
165 } // namespace placement
166 } // namespace genesis
167 
168 #endif // include guard
void finish_reading(tree::NewickBroker const &broker, tree::Tree &tree) const
Data class for PlacementTreeEdges. Stores the branch length of the edge, and the edge_num, as defined in the jplace standard.
bool enable_tags() const
Return whether currently Newick tags are enabled.
void reset_edge_num(int val)
Force to set the edge_num to a certain value.
PlacementTreeNewickReaderPlugin & operator=(PlacementTreeNewickReaderPlugin const &)=default
Stores a Newick tree in an intermediate format that can be further processed into a Tree...
Definition: broker.hpp:106
Class for representing phylogenetic trees.
Definition: tree/tree.hpp:95
create_edge_data_function create_edge_data_plugin
std::vector< std::string > tags
Arbitrary strings that can be attached to a node, e.g. in Newick format via "{}". ...
Definition: element.hpp:109
std::vector< finish_reading_function > finish_reading_plugins
Provides easy and fast logging functionality.
static std::unique_ptr< PlacementEdgeData > create()
std::vector< element_to_edge_function > element_to_edge_plugins
Provide a set of plugin functions for NewickReader to read a DefaultTree.
create_node_data_function create_node_data_plugin
static std::unique_ptr< PlacementNodeData > create()
std::string name
Name of the node.
Definition: element.hpp:96
EdgeDataType & data()
Definition: edge.hpp:118
bool has_correct_edge_nums(PlacementTree const &tree)
Verify that the tree has correctly set edge nums.
void element_to_edge(tree::NewickBrokerElement const &element, tree::TreeEdge &edge) const
Store the information for one element of a Newick tree.
Definition: element.hpp:60
#define LOG_INFO
Log an info message. See genesis::utils::LoggingLevel.
Definition: logging.hpp:98