The content of an H5M file can be accessed by any HDF5 compatible tool.
The following viewer is available from the HDF Group:
HDFView : https://www.hdfgroup.org/downloads/hdfview/
Please visit the general support page of the HDF Group for more information. |
% author: Y. Klinkenberg % file used in this example, replace this by your file: fileName = '<path to your file.h5m>'; % this contains all metadata information and can be used to extract data: fileInfo = h5info(fileName); % these groups (blocks of data with the same shape exist in the file): allGroups = {fileInfo.Groups.Name}; % loop over the groups to extract data: for iGroup = 1:length(allGroups) % identify signals per group: signalsPerGroup = {fileInfo.Groups(iGroup).Datasets.Name}; % used to plot the data figure hold on % loop over each signal, load data and plot for iSignal = 1:length(signalsPerGroup) % retrieve data per signal dataSetName = ['/' allGroups{iGroup} '/' signalsPerGroup{iSignal}]; if ismember('bases', {fileInfo.Groups(iGroup).Datasets(iSignal).Attributes.Name}) signalData = h5read(fileName, dataSetName); baseDataC = h5readatt(fileName, dataSetName, 'bases'); % show in plot plot(baseDataC{1}, signalData) end end end |
Code below shows how to read an h5m file and yield it's content as a data struct.
function [DataStruct] = read_h5m2struct(fileName,nameOption) % This file reads H5M files produced by Shark. % Input: fileName, (optional: nameOption) % fileName: complete path and filename to H5M-file % nameOption (optional): true or false [DEFAULT] (or 0 / 1). If true: signals in the output datastruture are created as fields with the name of the signal as fieldname; Otherwise, accessible by index. % The data is permuted such that the order of dimensions of the data match the sequence of bases listed for each signal % <PLEASE CHECK THIS CAREFULLY; IT HAS BEEN TESTED BUT MAY NOT BE 100% FOOLPROOF> % Note: The bases themselves (DataStruct.Bases) are not ordered based on the order used for the signals! They are ordered based on the sequence in the H5M-file. % Different signals can have a different sequence of bases. The correct order of each signal's bases is in the "Bases" field of the respective signal (DataStruct.Signals(#).Bases) % Modified by S van Essen (Jul 2020) % Modified by FH Lafeber (Aug 2020) if nargin < 2 nameOption = false; end % this contains all metadata information and can be used to extract data fileInfo = h5info(fileName); % these groups (blocks of data with the same shape exist in the file) allGroups = {fileInfo.Groups.Name}; % Initialise DataStruct = struct('Signals',[],'Bases',[],'GroupName',[],'StepSize',[]); % loop over the groups to extract data for iGroup = 1:length(allGroups) signalsPerGroup = {fileInfo.Groups(iGroup).Datasets.Name}; % Check how many signals there are in total (including the base signals) signalCounter = 0; baseCounter = 0; % loop over each signal, load data and plot for iSignal = 1:length(signalsPerGroup) % retrieve data per signal dataSetName = ['/' allGroups{iGroup} '/' signalsPerGroup{iSignal}]; if ismember('bases', {fileInfo.Groups(iGroup).Datasets(iSignal).Attributes.Name}) % Put all the Signals (i.e. signals that have a base) in an array signalCounter = signalCounter + 1; signalName = {fileInfo.Groups(iGroup).Datasets(iSignal).Name}; % And the signal name signalName = matlab.lang.makeValidName(strrep(signalName{1},' ','_')); for iattrib = 1:length(fileInfo.Groups(iGroup).Datasets(iSignal).Attributes) if strcmp(fileInfo.Groups(iGroup).Datasets(iSignal).Attributes(iattrib).Name,'unit') signalUnit = fileInfo.Groups(iGroup).Datasets(iSignal).Attributes(iattrib).Value; break end end for iattrib = 1:length(fileInfo.Groups(iGroup).Datasets(iSignal).Attributes) if strcmp(fileInfo.Groups(iGroup).Datasets(iSignal).Attributes(iattrib).Name,'baseNames') signalBases = fileInfo.Groups(iGroup).Datasets(iSignal).Attributes(iattrib).Value; break end end signalValues = h5read(fileName, dataSetName); signalSize = fileInfo.Groups(iGroup).Datasets(iSignal).Dataspace.Size; dimensionOrder = length(signalSize):-1:1; % I am assuming it is always the "wrong way around" % Check with the dimensions of the bases? Then I need to find the sequence of the bases for each signal and get the dimensions of each of the bases (but that's only once) if isstruct(signalValues) signalValueNames = fieldnames(signalValues); for ival = 1:length(signalValues) for iField = signalValueNames' signalValues(ival).(iField{1}) = permute(signalValues(ival).(iField{1}),dimensionOrder); end end elseif min(size(signalValues)) > 1 signalValues = permute(signalValues,dimensionOrder); end if ~nameOption DataStruct(iGroup).Signals(signalCounter).Bases = signalBases; DataStruct(iGroup).Signals(signalCounter).Value = signalValues; % Get all the data DataStruct(iGroup).Signals(signalCounter).Unit = signalUnit{1}; DataStruct(iGroup).Signals(signalCounter).Name = signalName; else DataStruct(iGroup).Signals.(signalName).Unit = signalUnit{1}; DataStruct(iGroup).Signals.(signalName).Value = signalValues; % Get all the data DataStruct(iGroup).Signals.(signalName).Base = signalBases; end else % If it doesn't have a base, it IS a base; put in a separate array baseCounter = baseCounter + 1; baseName = {fileInfo.Groups(iGroup).Datasets(iSignal).Name}; % Get the base name baseName = matlab.lang.makeValidName(strrep(baseName{1},' ','_')); for iattrib = 1:length(fileInfo.Groups(iGroup).Datasets(iSignal).Attributes) if strcmp(fileInfo.Groups(iGroup).Datasets(iSignal).Attributes(iattrib).Name,'unit') signalUnit = fileInfo.Groups(iGroup).Datasets(iSignal).Attributes(iattrib).Value; break end end if ~nameOption DataStruct(iGroup).Bases(baseCounter).Value = h5read(fileName, dataSetName); DataStruct(iGroup).Bases(baseCounter).Unit = signalUnit{1}; DataStruct(iGroup).Bases(baseCounter).Name = baseName; else DataStruct(iGroup).Bases.(baseName).Value = h5read(fileName, dataSetName); DataStruct(iGroup).Bases.(baseName).Unit = signalUnit{1}; end end end DataStruct(iGroup).GroupName = allGroups{iGroup}(2:end); % Add the name of the group to the structure for identification DataStruct(iGroup).StepSize = fileInfo.Groups(iGroup).Attributes(find(strcmp({fileInfo.Groups(iGroup).Attributes.Name},'stepSize'),1,'first')).Value; % Add the stepsize end end |
Code above can be tested using the code below and using the download test.h5m
% test H5M reader clear variables % For this file the reader works: path1 = cd; file0 = '\test.h5m'; fileName0 = [path1,file0]; TestSet = read_h5m2struct(fileName0); TestSet2 = read_h5m2struct(fileName0,'true'); % Now all signals have their own name as field in the structur % Explore and do as you please with either TestSet or TestSet2... :-) |
import h5py import numpy fid = h5py.File('myfile.h5m', 'r') # Get the name of the measurements/groups in the file: print(fid.keys) # Get the name of the signals in the measurement: print(fid['measurement'].keys()) # Get the data as numpy array: numpy.array(fid['name of the test']['name of the signal']) # Get the units of the signal: fid['name of the test']['name of the signal'].attrs['unit'] |
For more information regarding h5py, see https://docs.h5py.org/
import pymarin # Get the groups as list of pymarin.SignalSet: sets_list = pymarin.io.h5m.read(‘afile.h5m’) # Or rather get the groups as a dictionary: sets_dict = pymarin.io.h5m.read(‘afile.h5m’, returnAsDict=True) # Pick some measurement in the list/dict: aset = sets_list[0] another_set = sets_dict[‘100.00 Hz’] # Get a signal using its name: asignal = aset[‘signal_name’] # Or using its index: another_signal = aset[1] # Accessing some attributes of the signal: data = asignal.data name = asignal.key.name unit = asignal.key.unit |
For more help using pymarin, see PYMARIN.