59 if( ladderize_tree ) {
62 init_tree_( orig_tree );
93 for(
size_t i = 0; i < tree_.
edge_count(); ++i ) {
101 if( strokes.empty() ) {
108 throw std::runtime_error(
"Edge stroke vector has wrong size." );
110 for(
size_t i = 0; i < tree_.
edge_count(); ++i ) {
117 for(
size_t i = 0; i < tree_.
edge_count(); ++i ) {
125 if( strokes.empty() ) {
132 throw std::runtime_error(
"Edge stroke vector has wrong size." );
134 for(
size_t i = 0; i < tree_.
edge_count(); ++i ) {
141 for(
size_t i = 0; i < tree_.
node_count(); ++i ) {
157 if( strokes.empty() ) {
168 for(
size_t i = 0; i < tree_.
node_count(); ++i ) {
171 }
else if( strokes.size() == tree_.
node_count() -1 ) {
174 for(
size_t i = 0; i < tree_.
node_count(); ++i ) {
184 for(
size_t i = 0; i < tree_.
node_count(); ++i ) {
192 throw std::runtime_error(
193 "Edge stroke vector has wrong size. Has to be either tree.node_count(), " 194 "tree.node_count() - 1, or leaf_edge_count( tree )." 205 for(
size_t i = 0; i < tree_.
edge_count(); ++i ) {
213 if( shapes.empty() ) {
220 throw std::runtime_error(
"Edge shape vector has wrong size." );
222 for(
size_t i = 0; i < tree_.
edge_count(); ++i ) {
229 for(
size_t i = 0; i < tree_.
node_count(); ++i ) {
237 if( shapes.empty() ) {
244 throw std::runtime_error(
"Node shape vector has wrong size." );
246 for(
size_t i = 0; i < tree_.
node_count(); ++i ) {
255 void LayoutBase::init_tree_(
Tree const& orig_tree )
260 auto const& orig_node = orig_tree.
node_at(i);
263 assert( node.index() == i && orig_node.index() == i );
270 if( orig_node_data_ptr ) {
278 auto const& orig_edge = orig_tree.
edge_at(i);
281 assert( edge.index() == i && orig_edge.index() == i );
288 if( orig_edge_data_ptr ) {
297 void LayoutBase::init_layout_()
299 if(
tree().empty() ) {
306 auto& node_data =
tree().
node_at( it.node().index() ).data<LayoutNodeData>();
307 if( node_data.parent_index == -1 ) {
308 node_data.parent_index = parent;
310 parent = it.node().
index();
315 set_node_distances_cladogram_();
317 set_node_distances_phylogram_();
319 throw std::runtime_error(
"Invalid LayoutType value." );
324 set_node_spreadings_leaves_();
326 set_node_spreadings_all_( inner_node_spreading_ );
330 void LayoutBase::set_node_spreadings_leaves_()
337 size_t leaf_count = 0;
339 auto& node_data =
tree().
node_at( it.node().index() ).data<LayoutNodeData>();
341 auto const lcd =
static_cast<double>( leaf_count );
342 auto const nld =
static_cast<double>( num_leaves );
343 node_data.spreading = lcd / nld;
347 assert( leaf_count == num_leaves + 1 );
351 auto chrn_min_s = std::vector<double>(
tree().
node_count(), -1.0 );
352 auto chrn_max_s = std::vector<double>(
tree().
node_count(), -1.0 );
356 auto const node_index = it.node().index();
360 if( node_data.spreading < 0.0 ) {
362 assert( chrn_min_s[ node_index ] > -1.0 );
363 assert( chrn_max_s[ node_index ] > -1.0 );
365 auto min_max_diff = chrn_max_s[ node_index ] - chrn_min_s[ node_index ];
366 node_data.spreading = chrn_min_s[ node_index ] + min_max_diff / 2.0;
369 if( chrn_min_s[ prnt_index ] < 0.0 || chrn_min_s[ prnt_index ] > node_data.spreading ) {
370 chrn_min_s[ prnt_index ] = node_data.spreading;
372 if( chrn_max_s[ prnt_index ] < 0.0 || chrn_max_s[ prnt_index ] < node_data.spreading ) {
373 chrn_max_s[ prnt_index ] = node_data.spreading;
380 assert( ! tree_.
empty() );
382 throw std::invalid_argument(
383 "Tree is not bifurcating. Cannot draw with inner node spreading." 398 auto visits = std::vector<size_t>( tree_.
node_count(), 0 );
399 size_t node_counter = 0;
403 auto const node_index = it.node().index();
407 ++visits[ node_index ];
408 assert( visits[ node_index ] <= 3 );
412 }
else if(
is_leaf( it.node() ) || visits[ node_index ] == 2 ) {
413 auto const ncd =
static_cast<double>( node_counter );
414 auto const nnd =
static_cast<double>( num_nodes );
415 node_data.spreading = ncd / nnd;
419 assert( node_counter == num_nodes + 1 );
427 auto const degr =
degree( root );
431 auto const& l_data = root.link().outer().node().data<
LayoutNodeData>();
432 auto const& r_data = root.link().next().outer().node().data<
LayoutNodeData>();
436 auto const& l_data = root.link().outer().node().data<
LayoutNodeData>();
437 auto const& r_data = root.link().next().next().outer().node().data<
LayoutNodeData>();
446 void LayoutBase::set_node_distances_phylogram_()
452 assert( ! node_dists.empty() );
453 auto const max_d = *std::max_element( node_dists.begin(), node_dists.end() );
455 for(
size_t i = 0; i < node_dists.size(); ++i ) {
460 void LayoutBase::set_node_distances_cladogram_()
469 auto const root_height =
static_cast<double>( heights[
tree().
root_node().
index() ] );
474 if( it.is_first_iteration() ) {
479 auto const height =
static_cast<double>( heights[ it.node().index() ]);
480 assert(
height <= root_height );
483 auto const distance = ( root_height -
height ) / root_height;
484 tree().
node_at( it.node().index() ).data<LayoutNodeData>().distance = distance;
494 type_ = drawing_type;
495 if( ! tree_.
empty() ) {
507 inner_node_spreading_ = value;
508 if( ! tree_.
empty() ) {
515 return inner_node_spreading_;
520 align_labels_ = value;
525 return align_labels_;
530 extra_spacer_ = value;
535 return extra_spacer_;
545 return text_template_;
550 return text_template_;
void set_node_shapes(utils::SvgGroup const &shape)
bool align_labels() const
void ladderize(Tree &tree, LadderizeOrder order)
Ladderize a Tree, that is, order its subtrees by size.
bool is_root(TreeLink const &link)
Return whether the link belongs to the root node of its Tree.
static std::unique_ptr< LayoutNodeData > create()
Header of CommonTree distance methods.
double extra_spacer() const
bool empty() const
Return whether the Tree is empty (i.e., has no nodes, edges and links).
static std::unique_ptr< LayoutEdgeData > create()
size_t edge_count() const
Return the number of TreeEdges of the Tree.
bool is_bifurcating(Tree const &tree, bool loose)
Return whether the Tree is bifurcating.
TreeEdge & reset_data(std::unique_ptr< BaseEdgeData > data)
Reset the data pointer of this TreeEdge.
Container namespace for all symbols of genesis in order to keep them separate when used as a library...
LayoutSpreading inner_node_spreading() const
utils::Range< IteratorEulertour< true > > eulertour(ElementType const &element)
void set_edge_shapes(utils::SvgGroup const &shape)
Data class for LayoutTreeEdges.
utils::Range< IteratorPostorder< true > > postorder(ElementType const &element)
Tree clone_topology() const
Return a Tree with the same topology, but without any data.
void set_edge_distance_strokes(utils::SvgStroke const &stroke)
size_t leaf_node_count(Tree const &tree)
Count the number of leaf Nodes of a Tree.
Class for representing phylogenetic trees.
std::vector< double > node_branch_length_distance_vector(Tree const &tree, TreeNode const *node)
Return a vector containing the distance of all nodes with respect to the given start node...
double height(Tree const &tree)
Get the height of the tree, i.e., the longest distance from the root to a leaf, measured using the br...
TreeNode & node_at(size_t index)
Return the TreeNode at a certain index.
Tree const & tree() const
std::vector< size_t > subtree_max_path_heights(Tree const &tree, TreeNode const &node)
void set_label_spacer_strokes(utils::SvgStroke const &stroke, LayoutSpreading spreading=LayoutSpreading::kLeafNodesOnly)
TreeEdge & edge_at(size_t index)
Return the TreeEdge at a certain index.
std::string name
Name of the node.
LayoutSpreading
Spreading of the nodes of a tree for drawing.
void set_edge_strokes(utils::SvgStroke const &stroke)
size_t node_count() const
Return the number of TreeNodes of the Tree.
double branch_length
Branch length of the edge.
utils::Range< IteratorPreorder< true > > preorder(ElementType const &element)
LayoutType
Type of tree for drawing, either phylogram or cladogram.
double spreading
Position of the node along the second axis.
Common class containing the commonly needed data for tree nodes.
TreeNode & root_node()
Return the TreeNode at the current root of the Tree.
Data class for LayoutTreeNodes.
Header of Tree distance methods.
size_t index() const
Return the index of this Node.
TreeNode & reset_data(std::unique_ptr< BaseNodeData > data)
Reset the data pointer of this TreeNode.
Common class containing the commonly needed data for tree edges.
size_t degree(TreeLink const &link)
Return the degree of the node for a given TreeLink, i.e. how many neighbouring nodes it has...
void set_edge_spreading_strokes(utils::SvgStroke const &stroke)
EdgeDataType * data_cast()
bool is_leaf(TreeLink const &link)
Return true iff the node of the given link is a leaf node.
utils::SvgText & text_template()
NodeDataType * data_cast()