11#include "quetzal/coalescence/graph/network.hpp"
12#include "quetzal/io/newick/ast.hpp"
13#include "quetzal/io/newick/generator.hpp"
14#include "quetzal/io/newick/parser.hpp"
20template <
class Graph>
void regraft_cycles(Graph &graph,
auto root)
22 using graph_type = Graph;
23 using vertex_descriptor =
typename graph_type::vertex_descriptor;
24 using vertex_property =
typename Graph::vertex_property;
25 using dict_type = std::map<std::string, std::map<std::string, std::vector<vertex_descriptor>>>;
28 std::regex rgx(
"[a-zA-Z0-9_]*"
35 for (
auto vertex : graph.vertices())
39 if constexpr (std::is_same_v<vertex_property, std::string>)
40 label = graph[vertex];
42 label = graph[vertex].label();
45 if (std::regex_search(label, match, rgx))
48 const auto event_type = match.str(1);
49 const auto event_id = match.str(2);
50 records[event_type][event_id].push_back(vertex);
54 using namespace ranges;
57 for (
auto const &[event_type, val] : records)
59 for (
auto const &[event_id, duplicated_vertices] : val)
61 auto new_vertex = graph.add_vertex(
"#" + event_type + event_id);
64 duplicated_vertices | views::transform([&graph](
auto v) {
return graph.in_edges(v); }) |
66 views::transform([&graph](
auto &&range_of_e) {
return graph.source(*range_of_e.begin()); });
68 auto new_targets = duplicated_vertices | views::transform([&graph](
auto v) {
return graph.out_edges(v); }) |
69 views::join | views::transform([&graph](
auto e) {
return graph.target(e); });
71 ranges::for_each(duplicated_vertices, [&graph](
auto v) {
72 graph.clear_vertex(v);
73 graph.remove_vertex(v);
76 auto regraft = [&graph, new_vertex](
auto s,
auto t) {
77 graph.add_edge(s, new_vertex);
78 graph.add_edge(new_vertex, t);
81 auto todo = ranges::views::zip(new_sources, new_targets);
82 ranges::for_each(todo, [regraft](
auto &&z) { std::apply(regraft, z); });
91std::tuple<quetzal::coalescence::network<VertexProperty, EdgeProperty>,
96 using vertex_descriptor =
typename graph_type::vertex_descriptor;
99 auto root = graph.add_vertex(VertexProperty(ast_root.
name));
102 static const auto populate = [](graph_type &graph, vertex_descriptor parent,
const auto &ast) {
103 static auto recursive = [](graph_type &graph, vertex_descriptor parent,
const auto &ast,
104 auto &self)
mutable ->
void {
105 std::vector<std::tuple<vertex_descriptor, EdgeProperty>> children;
107 children.reserve(ast.children.size());
109 for (
const auto &ast_child : ast.children)
111 children.push_back(std::make_tuple(graph.add_vertex(VertexProperty(ast_child.name)),
112 EdgeProperty(ast_child.distance_to_parent)));
115 graph.add_edges(parent, children);
117 for (
int i = 0; i < children.size(); i++)
119 self(graph, std::get<0>(children[i]), ast.children[i], self);
122 recursive(graph, parent, ast, recursive);
125 populate(graph, root, ast_root);
126 detail::regraft_cycles(graph, root);
127 return {std::move(graph), root};
135std::tuple<quetzal::coalescence::network<VertexProperty, EdgeProperty>,
142 auto ok = quetzal::parse(begin(extended_newick), end(extended_newick), quetzal::format::newick::parser::tree, ast);
145 return to_network<VertexProperty, EdgeProperty>(ast);
Definition network.hpp:380