The rdkit library provides a molecule class ROMol
that provides a member function getTopology
that returns a BGL graph of type adjacency_list<vecS, vecS, undirectedS, Atom *, Bond *>
. I understand that the rdkit type Bond
defines the edge properties of the graph. I know that Bond
provides a member function getIdx
that returns a unique integer identifying the bond, so the graph must have a notion of edge numbering.
To make use of the BGL algorithm for biconnected_components
one requires a component property map that maps objects of the edge descriptor type of the graph (I understand this type is Bond
?) to component identifying integers. As rdkit does not deal in biconnected components, I conclude this property map must be exterior to the graph. In this case, the BGL documentation suggests to use the iterator_property_map
adaptor class (see section "Exterior Properties"). I struggle to determine the correct template arguments for iterator_property_map
to get the required property map. If this is the correct approach what are the missing template arguments?
Unfortunately I did not get very far with my code before getting lost in the BGL documentation:
void my_function(const RDKit::ROMol& molecule) {
const RDKit::MolGraph& molecule_graph{molecule.getTopology()};
using EdgesSize =
boost::graph_traits<RDKit::MolGraph>::edges_size_type; // map value type
using Edge =
boost::graph_traits<RDKit::MolGraph>::edge_descriptor; // map key type
std::vector<EdgesSize> component_map(boost::num_edges(molecule_graph)
); // range, begin() yields random access iterator
// boost::iterator_property_map<?>;
// boost::biconnected_components(molecule_graph, ?);
}
Edge descriptors are internal descriptors, sort of like stable iterators. E.g.
Edge properties are entirely separate notions. You get the edge properties from an edge descriptor like so:
Unsurprisingly the same goes for vertex descriptors vs. properties:
The Complication
A notable difference between the two descriptor types is that - only because the graph type is using
vecS
as the vertex container selector - the vertex descriptor is guaranteed to be integral, where edge descriptor is opaque (similar to avoid*
).Hence, the edge-decriptor cannot be the key type to a vector-based property map (because it would require an integral indexer).
Instead make an associative property-map:
Sample
Live On Coliru
Prints
Advanced Example
You can force a vector as mapping storage, but that requires you to map the edges (bonds) to a contiguous integral range [0..num_edges(g)).
I couldn't assume that
getIdx()
satisfies the criterion, but if it did:Let's apply it to the graph from the documentation:
Live On Coliru
Which prints prints the expected mapping
In fact, if we add a little bit of bonus wizardry, we can render that: