Working with groups

Groups are the basic containers within an HDF5 file. The entry point to the HDF5 node hierarchy is the root group of a file. It can be accessed from the root() method of a hdf5::file::File instance.

using namespace hdf5;

file::File f = ....;
node::Group root_group = f.root();

Groups act like STL container in a very general sense. With an HDF5 group you can iterate either over the links directly attached to it or over the objects referenced by those links. You can access links via the publik hdf5::node::Group::links member or the objects via the hdf5::node::Group::nodes member. They are instances of hdf5::node::LinkView and hdf5::node::NodeView respectively.

Iterating over nodes

There are basically two ways how to iterate over the children of a group

  • simpel iteration over the immediate children of a group

  • or recursive iteration

The former one works like expected from an STL container either with the for-each construction

hdf5::node::Group group = ...;

for(auto node: group.nodes)
{
 ...
}

or with the standard iterator interface using begin() and end() member functions to obtain the iterators. In the following example we collect all the datasets immediately attached to a particular group

hdf5::node::Group group = ...;
std::vector<hdf5::node::Dataset> datasets;

std::copy_if(group.nodes.begin(),group.nodes.end(),
             std::back_inserter(datasets),
             [](const hdf5::node::Node &node)
             {
               return node.type()==hdf5::node::Type::DATASET;
             });

For recursive iteration we currently cannot use the for-each construction but we can definitely use the iterator interface. To extend the above example we look for all datasets below a particular group and its subgroups

hdf5::node::Group group = ...;
std::vector<hdf5::node::Dataset> datasets;

std::copy_if(hdf5::node::RecursiveNodeIterator::begin(group),
             hdf5::node::RecursiveNodeIterator::end(group),
             std::back_inserter(datasets),
             [](const hdf5::node::Node &node)
             {
               return node.type()==hdf5::node::Type::DATASET;
             });

the major difference here is to use RecursiveNodeIterator and its static factory functions begin() and end().

Iterators

Two iterator types are provided

  • group_iterator_t which iterates over the direct children of a group. Instances can be created with the begin() and end() methods of an instance of group_t.

  • recursive_group_iterator_t which iterates recursively over all children below the given group. Instances of this iterator are created by the rbegin and rend methods of an instance of group_t.

Both iterator types satisfy the C++ ForwardIterator concept. Thus they are both read only iterators (one cannot change an object stored in the file via the iterator interface). Of course it is possible to read and write data to an object referenced by an iterator.

std::vector<h5::dataset_t> datasets;
h5::group_t g = ....;

std::copy_if(g.begin(),g.end(),std::back_inserter(datasets),
             [](const auto &o) { return h5::is_dataset(o); });