Home > database >  Determine the object type of a HDF5 path
Determine the object type of a HDF5 path

Time:04-29

I have a path name (a string) and an open HDF5 file. I have used H5Lexists to ensure an object with that name exists. How do I determine what the object type is? e.g. dataset, group, etc.

// open the file
hid_t fapl = H5Pcreate(H5P_FILE_ACCESS);  
H5Pset_fclose_degree(fapl, H5F_CLOSE_STRONG);
hid_t hid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, fapl);

// ensure the object exists
const string path = "/some/path/to/an/object";
if (H5Lexists(m_hid, path.c_str(), H5P_DEFAULT) < 0) throw runtime_error();

// determine the object type
// TODO
if (dataset) {
    hid_t dataset = H5Dopen(hid, path.c_str(), H5P_DEFAULT);
    // do something
}
else if (group) {
    hid_t group = H5Gopen(hid, path.c_str(), H5P_DEFAULT);
    // do something
}
H5Fclose(hid);

I am trying not to use the C class based interface because this is being added to legacy code. I tried just opening the dataset to see if dataset < 0 to determine if it is a dataset, however, the HDF5 library throws a ton of warnings to stderr, so I'd like to do it the correct way.

CodePudding user response:

Use H5Oopen if you don't know the type in advance and use H5Iget_type to determine it.

hid_t object = H5Dopen(hid, path.c_str(), H5P_DEFAULT);
H5I_type_t h5type = H5Iget_type(object);

if (h5type == H5I_BADID) {
    ... // error handling stuff
} else if (h5type == H5I_DATASET) {
    ... // dataset stuff
} else if (h5type == H5I_GROUP) {
    ... // group stuff
} else { // other stuff maybe
}

H5Oclose(hid);

CodePudding user response:

If you are not bound to a particular library, you may want to have a look at HDFql as it greatly alleviates you from the low-level details of HDF5. Using HDFql, your use-case can be solved as follows in C (and, in principle, no error messages will be generated):

int type;

if (hdfql_execute("SHOW TYPE /some/path/to/an/object") == HDFQL_SUCCESS)
{
    hdfql_cursor_next(NULL);
    type = *hdfql_cursor_get_int(NULL);
    if (type == HDFQL_GROUP)
    {
        printf("Object is a group\n");
    }
    else if (type == HDFQL_DATASET)
    {
        printf("Object is a dataset\n");
    }
    else if (type == HDFQL_ATTRIBUTE)
    {
        printf("Object is an attribute\n");
    }
    else if (type == HDFQL_SOFT_LINK)
    {
        printf("Object is a soft link\n");
    }
    else if (type == HDFQL_EXTERNAL_LINK)
    {
        printf("Object is an external link\n");
    }
    else if (type == HDFQL_SOFT_LINK | HDFQL_GROUP)
    {
        printf("Object is a soft link pointing to a group\n");
    }
    else if (type == HDFQL_SOFT_LINK | HDFQL_DATASET)
    {
        printf("Object is a soft link pointing to a dataset\n");
    }
    else if (type == HDFQL_EXTERNAL_LINK | HDFQL_GROUP)
    {
        printf("Object is an external link pointing to a group\n");
    }
    else if (type == HDFQL_EXTERNAL_LINK | HDFQL_DATASET)
    {
        printf("Object is an external link pointing to a dataset\n");
    }
    else
    {
        printf("Object is of unknown type!\n");
    }
}
else
{
    printf("Object was not found!");
}

CodePudding user response:

The H5O portion of the library was the answer. Also, H5Lexists is not the correct way to determine if an object exists either, so I updated that as well.

// open the file
hid_t fapl = H5Pcreate(H5P_FILE_ACCESS);  
H5Pset_fclose_degree(fapl, H5F_CLOSE_STRONG);
hid_t hid = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, fapl);

// ensure the object exists
const string path = "/some/path/to/an/object";
if (H5Oexists_by_name(hid, path.c_str(), H5P_DEFAULT) <= 0) throw runtime_error();

// determine the object type
H5O_info_t info;
H5Oget_info_by_name(m_hid, parent.c_str(), &info, H5P_DEFAULT);
if (info.type == H5O_TYPE_DATASET) {
    hid_t dataset = H5Dopen(hid, path.c_str(), H5P_DEFAULT);
    // do something
}
else if (info.type == H5O_TYPE_GROUP) {
    hid_t group = H5Gopen(hid, path.c_str(), H5P_DEFAULT);
    // do something
}
H5Fclose(hid);
  • Related