Utopia 2
Framework for studying models of complex & adaptive systems.
Loading...
Searching...
No Matches
Functions
Graph Utilities

Provides functions which wrap common tasks for writing out data from graphs. More...

Collaboration diagram for Graph Utilities:

Functions

template<typename Graph >
std::shared_ptr< HDFGroupUtopia::DataIO::create_graph_group (const Graph &g, const std::shared_ptr< HDFGroup > &parent_grp, const std::string &name)
 
template<typename Graph >
void Utopia::DataIO::save_graph (const Graph &g, const std::shared_ptr< HDFGroup > &grp)
 Write function for a boost::Graph.
 
template<typename Graph , typename PropertyMap >
void Utopia::DataIO::save_graph (const Graph &g, const std::shared_ptr< HDFGroup > &grp, const PropertyMap vertex_ids)
 Write function for a boost::Graph.
 
template<IterateOver iterate_over, typename Graph , typename... Adaptors>
void Utopia::DataIO::save_graph_entity_properties (const Graph &g, const std::shared_ptr< HDFGroup > &nw_grp, const std::string &label, const std::tuple< Adaptors... > &adaptor_tuple)
 
template<typename Graph , typename... Adaptors>
void Utopia::DataIO::save_vertex_properties (Graph &&g, const std::shared_ptr< HDFGroup > &nw_grp, const std::string &label, const std::tuple< Adaptors... > &adaptor_tuple)
 
template<typename Graph , typename... Adaptors>
void Utopia::DataIO::save_edge_properties (Graph &&g, const std::shared_ptr< HDFGroup > &nw_grp, const std::string &label, const std::tuple< Adaptors... > &adaptor_tuple)
 

Detailed Description

Provides functions which wrap common tasks for writing out data from graphs.

Graph Utilities Module

Overview

This module implements functions which wrap common tasks people face when they wish to extract data from boost::graph objects.

Implementation

The provided functions can be separated into two groups, one which saves the entire graph, i.e., its edge-vertex structure, and a second one which allows to extract data associated with either edges or vertices via user supplied functions.

Function Documentation

◆ create_graph_group()

template<typename Graph >
std::shared_ptr< HDFGroup > Utopia::DataIO::create_graph_group ( const Graph &  g,
const std::shared_ptr< HDFGroup > &  parent_grp,
const std::string &  name 
)

This function opens a HDFGroup for graph data and adds attributes.

The attributes that are set mark the newly created group as containing network data and add some graph metadata like whether the graph is directed and/or allows parallel edges.

Template Parameters
Graph
Parameters
gThe graph to save
parent_grpThe parent HDFGroup the graph data should be stored in
nameThe name the newly created graph group should have
Returns
std::shared_ptr<HDFGroup> The newly created graph group
294{
295 // Create the group for the graph and store metadata in its attributes
296 auto grp = parent_grp->open_group(name);
297
298 grp->add_attribute("content", "graph");
299 // Store additional metadata in the group attributes
300 grp->add_attribute("is_directed", boost::is_directed(g));
301 grp->add_attribute("allows_parallel", boost::allows_parallel_edges(g));
302
303 // Store the information on the edge container shape
304 // NOTE Here, it is assumed that the edge data is written in shape (2,N).
305 // If this is not the case, the attribute must be overwritten.
306 grp->add_attribute("edge_container_is_transposed", true);
307
308 // Prevent the vertex and edge dimension from being squeezed when selecting
309 // graph data via the GraphGroup.
310 grp->add_attribute(
311 "keep_dim", std::vector<std::string>{"vertex_idx", "edge_idx"}
312 );
313
314 spdlog::get("data_io")->info("Opened graph group '{}'.", name);
315
316 return grp;
317}

◆ save_edge_properties()

template<typename Graph , typename... Adaptors>
void Utopia::DataIO::save_edge_properties ( Graph &&  g,
const std::shared_ptr< HDFGroup > &  nw_grp,
const std::string &  label,
const std::tuple< Adaptors... > &  adaptor_tuple 
)

This function writes the results of all functions in a named tuple, applied to all edges of a boost::graph into a HDFGroup.

This function calls the general save_graph_entity_properties method using IterateOver::edges. See Utopia::DataIO::save_graph_entity_properties for more detail.

Template Parameters
Graph
Adaptors
Parameters
gThe graph from which to save edge properties.
nw_grpThe HDFGroup the data should be written to.
labelUnder which label the results of the adaptors should be stored.
adaptor_tupleWhich edge-associated properties to write.
Returns
void
577{
578 save_graph_entity_properties<IterateOver::edges>(std::forward<Graph>(g),
579 nw_grp,
580 label,
581 adaptor_tuple);
582}

◆ save_graph() [1/2]

template<typename Graph >
void Utopia::DataIO::save_graph ( const Graph &  g,
const std::shared_ptr< HDFGroup > &  grp 
)

Write function for a boost::Graph.

This function writes a boost::graph into a HDFGroup. It assumes that the vertices and edges of the graph already supply indices.

Template Parameters
Graph
Parameters
gThe graph to save
grpThe HDFGroup the graph should be stored in
Returns
void
333{
334 // Create and prepare the datasets for vertices and edges
335 auto [dset_vertices,
336 dset_edges] = GraphUtilsHelper::setup_graph_containers(g, grp);
337
338 // Save vertex list
339 auto [v, v_end] = boost::vertices(g);
340 dset_vertices->write(v, v_end, [&](auto vd) {
341 return boost::get(boost::vertex_index_t(), g, vd);
342 });
343
344 // Save edges
345 // NOTE Need to call write twice to achieve the desired data shape.
346 auto [e, e_end] = boost::edges(g);
347 dset_edges->write(e, e_end, [&](auto ed) {
348 return boost::get(boost::vertex_index_t(), g, boost::source(ed, g));
349 });
350
351 dset_edges->write(e, e_end, [&](auto ed) {
352 return boost::get(boost::vertex_index_t(), g, boost::target(ed, g));
353 });
354
355 spdlog::get("data_io")->debug("Graph saved.");
356}

◆ save_graph() [2/2]

template<typename Graph , typename PropertyMap >
void Utopia::DataIO::save_graph ( const Graph &  g,
const std::shared_ptr< HDFGroup > &  grp,
const PropertyMap  vertex_ids 
)

Write function for a boost::Graph.

This function writes a boost::graph into a HDFGroup. By supplying custom vertex IDs, they need not be part of the graph in order for this function to operate.

Template Parameters
Graph
PropertyMapThe property map of the vertex ids
Parameters
gThe graph to save
grpThe HDFGroup the graph should be stored in
vertex_idsA custom property map of vertex IDs to use
Returns
void
377{
378 // Create and prepare the datasets for vertices and edges
379 auto [dset_vertices,
380 dset_edges] = GraphUtilsHelper::setup_graph_containers(g, grp);
381
382 // Save vertex list
383 auto [v, v_end] = boost::vertices(g);
384 dset_vertices->write(
385 v, v_end, [&](auto vd) { return boost::get(vertex_ids, vd); });
386
387 // Save edges
388 // NOTE Need to call write twice to achieve the desired data shape.
389 auto [e, e_end] = boost::edges(g);
390 dset_edges->write(e, e_end, [&](auto ed) {
391 return boost::get(vertex_ids, boost::source(ed, g));
392 });
393
394 dset_edges->write(e, e_end, [&](auto ed) {
395 return boost::get(vertex_ids, boost::target(ed, g));
396 });
397
398 spdlog::get("data_io")->debug("Graph saved.");
399}

◆ save_graph_entity_properties()

template<IterateOver iterate_over, typename Graph , typename... Adaptors>
void Utopia::DataIO::save_graph_entity_properties ( const Graph &  g,
const std::shared_ptr< HDFGroup > &  nw_grp,
const std::string &  label,
const std::tuple< Adaptors... > &  adaptor_tuple 
)

This function writes the results of all functions in a named tuple, applied to all vertices/edges of a boost::graph into a HDFGroup.

For each adaptor, the data written by this function is available at the path nw_grp/adaptor_name/label, where label is a dataset of size {num_edges/vertices} in the 1d case or {num_adaptors, num_edges/vertices} if data from more than one adaptor is to be written.

Attributes are added to the datasets that determine the dimension names and the coordinates. The name of dimension -1 is set to vertex_idx/edge_idx. The respective coordinates are the trivial ones. In the case of 2d data custom dimension name and coordinates for dimension need to be given. Note that the former has to be string-like and the latter have to be of the same type.

Warning
The coordinate type is deduced from the first coordinate. All other coordinates have to be of the same type.
Template Parameters
IterateOverThe type of iterator that is used to access the graph. The entity properties can be accessed either via edge-descriptors (IterateOver::edges) or via vertex-descriptors (IterateOver::vertices).
Graph
Adaptors
Parameters
gThe graph from which to save vertex or edge properties.
nw_grpThe HDFGroup the data should be written to. This should be the previously created network group. For each tuple entry, a new group will be created, which has the name specified as first element of that tuple.
labelUnder which label the results of the adaptors should be stored. This will be the name of the dataset to which the adaptors write data. If time-varying data is to be written, this can be used to specify the time step.
adaptor_tupleWhich vertex- or edge-associated properties to write. This should be a tuple of tuples, where the latter are of one of the following forms: If (adaptor_name, adaptor) then 1d data is written. If (adaptor_name, dim0_name, (coord1, adaptor1), (coord2, adaptor2), ...) then 2d data is written.
Returns
void
454{
455
456 static_assert(
457 // assert stringlike-ness of first thing
458 std::conjunction_v<Utils::is_string<
459 std::tuple_element_t<0, std::decay_t<Adaptors>>>...>,
460 "Error, the first entry of each entry of 'adaptor_tuple' has to be "
461 "string like, to name the adaptor");
462
463 static_assert(
464 iterate_over == IterateOver::vertices or
465 iterate_over == IterateOver::edges, "Error, unknown iterator type! "
466 "Has to be either 'IterateOver::vertices' or 'IterateOver::edges'"
467 );
468
469 // NOTE Consider a check for literal types, which is more capable than
470 // the (now removed) std::is_literal_type ...
471
472 // Get a logger
473 auto log = spdlog::get("data_io");
474
475 using GraphUtilsHelper::EntityKind;
476 using GraphUtilsHelper::generate_write_function;
477
478 // ... vertex_iterator ...
479 if constexpr (iterate_over == IterateOver::vertices)
480 {
481 // Collect some information on the graph
482 const auto num_vertices = boost::num_vertices(g);
483
484 // Make vertex iterator pair
485 auto it_pair = GraphUtils::iterator_pair<IterateOver::vertices>(g);
486
487 // Get write function that saves data given by the adaptor(s) to new
488 // dataset(s), fire-and-forget
489 auto write_f = generate_write_function<EntityKind::vertex>(
490 g, nw_grp,
491 label,
492 it_pair,
493 num_vertices);
494
495 boost::hana::for_each(adaptor_tuple, write_f);
496
497 log->debug("Graph vertex properties saved with label '{}'.", label);
498 }
499
500 // ... and edge_iterator
501 else {
502 // Collect some information on the graph
503 const auto num_edges = boost::num_edges(g);
504
505 // Make edge iterator pair
506 auto it_pair = GraphUtils::iterator_pair<IterateOver::edges>(g);
507
508 // Get write function that saves data given by the adaptor(s) to new
509 // dataset(s), fire-and-forget
510 auto write_f = generate_write_function<EntityKind::edge>(
511 g, nw_grp,
512 label,
513 it_pair,
514 num_edges);
515
516 boost::hana::for_each(adaptor_tuple, write_f);
517
518 log->debug("Graph edge properties saved with label '{}'.", label);
519 }
520}

◆ save_vertex_properties()

template<typename Graph , typename... Adaptors>
void Utopia::DataIO::save_vertex_properties ( Graph &&  g,
const std::shared_ptr< HDFGroup > &  nw_grp,
const std::string &  label,
const std::tuple< Adaptors... > &  adaptor_tuple 
)

This function writes the results of all functions in a named tuple, applied to all vertices of a boost::graph into a HDFGroup.

This function calls the general save_graph_entity_properties method using IterateOver::vertices. See Utopia::DataIO::save_graph_entity_properties for more detail.

Template Parameters
Graph
Adaptors
Parameters
gThe graph from which to save vertex properties.
nw_grpThe HDFGroup the data should be written to.
labelUnder which label the results of the adaptors should be stored.
adaptor_tupleWhich vertex–associated properties to write.
Returns
void
546{
547 save_graph_entity_properties<IterateOver::vertices>(std::forward<Graph>(g),
548 nw_grp,
549 label,
550 adaptor_tuple);
551}