![]() |
Quetzal-CoaTL
The Coalescence Template Library
|
Although graphs are ubiquitous in phylogeography and coalescence frameworks, they can represent quite different objects depending on the exact context. Consequently Quetzal had to make a number of design choices in their implementation.
As geneticists, we expect from a simple Kingman coalescent tree to exhibit certain characteristics (for example the guarantee of having either 0 or 2 children but never only 1) that we don't expect from a phylogenetic network (that would in contrast exhibit cycles and hybrid nodes).
In programming jargon, these expectations are called class invariants.
Rather than exposing a 1-fit-all type of graph and be prone to programming mistakes, Quetzal comes with more specialized classes that maintain their invariants.
A point common to all class of graphs is that vertices and edges have unique identifiers.
This identifier is implementation-dependent and not always of type int
. It is instead referred by a type nested in each graph class: vertex_descriptor
and edge_descriptor
.
Methods of a class that receive or return specific edges/vertices will manipulate objects of this type.
The quality of information attached to the vertices and edges of a graph also varies depending on the user problem.
For example, a spatial coalescent tree may need a way to store the geographic location of the visited locations, whereas a Kingman coalescent tree does not need to allocated storage for this. Similarly, Phylogenetic Networks will surely embed completely different types of information, like \(\gamma\), the inheritance probability.
To reflect this variability in the type of information, graphs can embed arbitrary information along edges and vertices through small user-defined classes called property classes.
The type of information a graph class embeds is referred by a nested type: vertex_property
and edge_property
.
DFS is a form of graph traversal referering to the process of visiting (e.g. retrieving, updating, or deleting) each node in a tree data structure, exactly once.
When the graph has the structure of a tree, there are only three operations that are worth worrying about:
pre-order
,in-order
,post-order
. When you perform a DFS on a tree with Quetzal you need to pass to the DFS method a starting vertex (probably the root of the tree) and a visitor object: you would write tree.depth_first_search(start, visitor)
. This visitor must be a cheap-to-copy instance of a class that implements the details of the DFS operations as decided by the user, for example:
You could also capture a reference to the tree graph instance if you need it: