; docformat = 'rst'
;+
; Dumps the structure of an HDF5 file to the output log. This routine does
; not read any data, it simply finds the names and datatypes of datasets,
; groups, types, and links.
;
; :Categories:
; file i/o, hdf5, sdf
;
; :Examples:
; See the attached main-level program for a simple example::
;
; IDL> .run mg_h5_dump
;-
;+
; Return a string representing an IDL declaration of the given item
; (attribute or dataset).
;
; :Returns:
; string
;
; :Params:
; typeId : in, required, type=long
; type identifier
; spaceId : in, required, type=long
; dataspace identifier
;-
function mg_h5_dump_typedecl, typeId, spaceId
compile_opt strictarr
idlType = h5t_idltype(typeId)
scalarDecl = ['undefined', 'byte', 'int', 'long', 'float', 'double', $
'complex', 'string', '', 'dcomplex', 'ptr', 'object', $
'uint', 'ulong', 'long64', 'ulong64']
arrayDecl = ['', 'bytarr', 'intarr', 'lonarr', 'fltarr', 'dblarr', $
'complexarr', 'strarr', '', 'dcomplexarr', 'ptrarr', $
'objarr', 'uintarr', 'ulonarr', 'lon64arr', 'ulon64arr']
dims = h5s_get_simple_extent_dims(spaceId)
if (dims[0] eq 0) then begin
decl = scalarDecl[idlType]
endif else begin
decl = arrayDecl[idlType] + '(' + strjoin(strtrim(dims, 2), ', ') + ')'
endelse
return, decl
end
;+
; Parse a dataset or group.
;
; :Params:
; groupId : in, required, type=long
; identifier of parent item to parse (group or dataset)
;
; :Keywords:
; level : in, required, type=long
; level from root (where root is level 0)
; cache : in, out, required, type=strarr
; cache of fileno and objno used to identify a hard link
; objects : in, optional, type=boolean
; set to parse objects (i.e. for groups)
; attributes : in, optional, type=boolean
; set to parse attributes (i.e. for datasets and non-top-level groups)
;-
pro mg_h5_dump_level, groupId, level=level, cache=cache, $
objects=objects, attributes=attributes
compile_opt strictarr
spaces = level eq 0 ? '' : string(replicate(32B, 2L * level))
format = '(%"%s%s (%s)")'
if (keyword_set(attributes)) then begin
nattrs = h5a_get_num_attrs(groupId)
for a = 0L, nattrs - 1L do begin
attrId = h5a_open_idx(groupId, a)
attrName = h5a_get_name(attrId)
attrTypeId = h5a_get_type(attrId)
attrSpaceId = h5a_get_space(attrId)
typeDecl = mg_h5_dump_typedecl(attrTypeId, attrSpaceId)
h5s_close, attrSpaceId
h5t_close, attrTypeId
h5a_close, attrId
print, format=format, spaces, attrName, 'attribute: ' + typeDecl
endfor
endif
if (keyword_set(objects)) then begin
nmembers = h5g_get_num_objs(groupId)
for g = 0L, nmembers - 1L do begin
objName = h5g_get_obj_name_by_idx(groupId, g)
objInfo = h5g_get_objinfo(groupId, objName)
strcache = STRJOIN([objInfo.fileno, objInfo.objno], ' ')
if (n_elements(cache) gt 0) then begin
if (total(cache eq strcache) gt 0) then begin
objInfo.type = 'LINK'
endif else begin
cache = [cache, strcache]
endelse
endif else begin
cache = strcache
endelse
switch objInfo.type of
'GROUP': begin
print, format=format, spaces, objName, strlowcase(objInfo.type)
objId = h5g_open(groupId, objName)
mg_h5_dump_level, objId, level=level + 1L, /attributes, /objects, cache=cache
h5g_close, objId
break
end
'DATASET': begin
datasetId = h5d_open(groupId, objName)
datasetTypeId = h5d_get_type(datasetId)
datasetSpaceId = h5d_get_space(datasetId)
typeDecl = mg_h5_dump_typedecl(datasetTypeId, datasetSpaceId)
h5s_close, datasetSpaceId
h5t_close, datasetTypeId
print, format=format, spaces, objName, 'dataset: ' + typeDecl
mg_h5_dump_level, datasetId, level=level + 1L, /attributes, cache=cache
h5d_close, datasetId
break
end
'LINK':
'TYPE':
'UNKNOWN': begin
print, format=format, spaces, objName, strlowcase(objInfo.type)
end
else:
endswitch
endfor
endif
end
;+
; Parse and display a simple hierarchy of contents of a HDF5 file.
;
; :Params:
; filename : in, required, type=string
; HDF5 file to parse
;-
pro mg_h5_dump, filename
compile_opt strictarr
fileId = h5f_open(filename)
rootGroupId = h5g_open(fileId, '/')
mg_h5_dump_level, rootGroupId, level=0, /objects
h5g_close, rootGroupId
h5f_close, fileId
end
; example of using mg_h5_dump
f = filepath('hdf5_test.h5', subdir=['examples', 'data'])
mg_h5_dump, f
end