Creating C++ HDF5 viewer using QtCreator


#1

Hi,

I want to use Qt to build a gui that can read HDF5 files in C++.

Currently I have an empty qstandardtablemodel, with a qdatastream, that I want to populate with attributes and their sub-attributes.

I am not very experiece with HDF5, so any advice/tutorials would be greatly appreciated!


#2

Hello,

you might find H5CPP an easy to use header only library useful. Most functionality of CAPI implemented; in addition to all handles/descriptors can be passed between CAPI and H5CPP calls, making your work easy by providing RAII for h5::fd_t, h5::ds_t, h5::dt_t … . Its pythonic syntax let’s you start to work with HDF5 right away, yet you have the option to use CAPI where and whenever you see fit.
here is an example:

#include <armadillo>
#include <h5cpp/all>
...
auto fd = h5::open("some_file.h5", H5F_ACC_RDWR);
/* the RVO arma::Mat<double> object will have the size 10x5 filled*/
try {
    /* will drop extents of unit dimension returns a 2D object */
    auto M = h5::read<arma::mat>(fd,"path/to/object", 
            h5::offset{3,4,1}, h5::count{10,1,5}, h5::stride{3,1,1} ,h5::block{2,1,1} );
} catch (const std::runtime_error& ex ){
    ...
}
// fd closes underlying resource (raii idiom)

The HDF5 attribute calls in H5CPP are prefixed with ‘a’ such h5::awrite h5::aread.
best wishes: steven


#3

I wrote a Qt HDF5 reader a couple of years ago

It uses a QAbstractTableModel derived class to show datasets/attributes in a table

here is a screenshot

http://www.space-research.org/explorer/explorer.htm


#4

Wow, these are both great, I will check them out! Thank you both so much!


#5

Hi Pedro, so I checked out the hdf_explorer_qt, it’s very nice! I just wondered if you could summarise the purpose of the iterate and visit implementation files? I see this is where the HDF5 heavy lifting is happening.


#6

Hi Steven, indeed this looks very nice! I think this approach is very intuitive, so I will try to implement it. Basically, I have comboboxes in a model I want to fill with all HDF5 attributes inside all groups classes, that the user will be able to select a subset of (via comboboxes) and then create a new HDF5 file only containing that subset. Any ideas would be amazing!


#7

Currently I am adding full STL support to H5CPP what would look good in your design if you abstracted out data model from view. The latter has GUI specifics so you may need some shim to implicit/explicit convert STL containers to that specific view’s data container.
As STL doesn’t support linear algebra, I suggest you to use armadillo linear algebra templates. When properly set up it has no dependencies: supports vectors, matrices and cubes. Of course you can choose eigen3 as well or any supported linalg systems. When accessing data cells these linalg systems need no linking against BLAS/LAPACK, do take an advantage if this.

Currently attributes can be manipulated with aread( ...) or awrite( ... ), from rank 0 to 3 most known objects are supported – higher ranks can be subset-ed thrugh partial IO to 0-3. In January will get a nice syntactic sugar to blend it to C++ and H5CPP easy to use philosophy.

Because GUI requires iterating through datasets in H5Ialgorithm.hpp you find stubs for such iterators. In a bright day I can add a visitor pattern which you can use with lambda function to fill your data structures with content.

Does this help you?


#8

Hi Steven,

so I wanted to give things a run, and I added H5CPP to my local headers (i.e. #include “/home/user/Project/h5cpp/attribute/attribute_manager.hpp”), but there is an error appearing that says

/home/user/Project/h5cpp/attribute/attribute_manager.hpp:59: error: redefinition of ‘class hdf5::attribute::AttributeManager’
class AttributeManager
^~~~~~~~~~~~~~~~

any ideas why and how I can fix it? I haven’t defined anything called AttributeManager anywhere else, but I see it appears inside namespace attribute as a class, but also in a template starting

template
Attribute AttributeManager

etc.?

I’m sure theres a very basic reason for it, I am just unsure what :slight_smile:


#9

Yes, it must be a basic reason: Did you make sure you checked out the right project? There is no attribute_manager.hpp in the code base AFAIK. Here is the link to the source files, and my github page which hosts the project.

Also, as outlined in the documentation, this is a stand alone header library, which has linking requirements to HDF5 CAPI only. In other words this is a replacement for the C++ API, and no dependency on the high level API either.

best
steven


#10

Brilliant, I did indeed checkout the wrong project (whoops!)

OK, will try to implement it this week and get back to you; as a first hint, I wonder if there is a method in the header library which can read a &filename, and if it does not find a dataset under this filename, it creates a dataset? I saw some examples of people defining such a function, but perhaps it is already in your project?

Thanks again for all your amazing help!


#11

Can you ask this in a separate question, so others can find it?
The right way is using CAPI H5Fis_hdf5 then act on outcome:
Returns a positive value if the file name is an HDF5 file. Returns 0 if the file name is not an HDF5 file. Returns a negative value when the function fails. This includes the case where the file does not exist.

And the alternative method:

h5::fd_t fd{H5I_UNINIT};
h5::mute(); // hush error messages printed by CAPI
// probe with h5::open
try{
    fd = h5::open("some_file.h5",H5F_ACC_RDWR);
} catch( const h5::error::io::file::open& err ){
    fd = h5::create("some_file.h5", H5F_ACC_TRUNC);
}
h5::unmute();