Skip to content

Commit

Permalink
Further updates for waveform support in matlab
Browse files Browse the repository at this point in the history
  • Loading branch information
dchansen committed May 16, 2018
1 parent 635aba1 commit 9045e40
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 3 deletions.
30 changes: 30 additions & 0 deletions matlab/+ismrmrd/+util/hdf5_datatypes.m
Expand Up @@ -30,6 +30,8 @@
obj.T_EncodingCounters = ismrmrd.util.hdf5_datatypes.getType_EncodingCounters();
obj.T_AcquisitionHeader = ismrmrd.util.hdf5_datatypes.getType_AcquisitionHeader();
obj.T_Acquisition = ismrmrd.util.hdf5_datatypes.getType_Acquisition();
obj.T_Waveform = ismrmrd.util.hdf5_datatypes.getType_Waveform();
obj.T_WaveformHeader = ismrmrd.util.hdf5_datatypes.getType_WaveformHeader();
end

end
Expand Down Expand Up @@ -122,6 +124,34 @@
H5T.insert(b, 'data', 360, data);

end


function b = getType_WaveformHeader()
b = H5T.create('H5T_COMPOUND',36);
H5T.insert(b, 'version', 0, 'H5T_NATIVE_UINT16');
H5T.insert(b, 'flags', 8, 'H5T_NATIVE_UINT64');
H5T.insert(b, 'measurement_uid', 16, 'H5T_NATIVE_UINT32');
H5T.insert(b, 'scan_counter', 20, 'H5T_NATIVE_UINT32');
H5T.insert(b, 'time_stamp', 24, 'H5T_NATIVE_UINT32');
H5T.insert(b, 'number_of_samples', 28, 'H5T_NATIVE_UINT16');
H5T.insert(b, 'channels', 30, 'H5T_NATIVE_UINT16');
H5T.insert(b, 'sample_time_us', 32, 'H5T_NATIVE_UINT16');
H5T.insert(b, 'waveform_id', 34, 'H5T_NATIVE_UINT16');
end

function b = getType_Waveform()

head = H5T.copy(ismrmrd.util.hdf5_datatypes.getType_WaveformHeader());
data = H5T.vlen_create(H5T.copy('H5T_NATIVE_UINT32');

b = H5T.create ('H5T_COMPOUND', 56);
H5T.insert(b, 'head', 0, head);
H5T.insert(b, 'data', 40, data);

end



end % Methods (Static)

end
Expand Down
9 changes: 7 additions & 2 deletions matlab/+ismrmrd/+xml/deserialize.m
Expand Up @@ -175,7 +175,9 @@
'phase', ...
'repetition', ...
'set', ...
'segment'};
'segment', ...
'waveformInformation'
};

status = ismember(name, headerNodeNames);
end
Expand Down Expand Up @@ -230,7 +232,10 @@
'coilName', ...
'calibrationMode',...
'interleavingDimension',...
'sequence_type'};
'sequence_type',...
'waveformName',...
'waveformType'
};

status = ismember(name, headerStringTypes);
end
Expand Down
30 changes: 30 additions & 0 deletions matlab/+ismrmrd/+xml/serialize.m
Expand Up @@ -200,6 +200,36 @@

docRootNode.appendChild(n1);
end

if isfield(header,'waveformInformation')
n1 = docNode.createElement('waveformInformation')
waveformInformation = header.waveformInformation;

append_node(docNode,n1,waveformInformation,'waveformName');
append_node(docNode,n1,waveformInformation,'waveformType');

if isfield(waveformInformation,'userParameters')
n2 = n1.createElement('userParameters')
userParameters = waveformInformation.userParameters;

if isfield(userParameters,'userParameterLong')
append_user_parameter(docNode,n2,userParameters,'userParameterLong',@int2str);
end

if isfield(userParameters,'userParameterDouble')
append_user_parameter(docNode,n2,userParameters,'userParameterDouble',@num2str);
end
if isfield(userParameters,'userParameterString')
append_user_parameter(docNode,n2,userParameters,'userParameterString');
end
if isfield(userParameters,'userParameterBase64')
append_user_parameter(docNode,n2,userParameters,'userParameterBase64');
end
end
end



xml_doc = xmlwrite(docNode);


Expand Down
147 changes: 147 additions & 0 deletions matlab/+ismrmrd/Dataset.m
Expand Up @@ -4,6 +4,7 @@
fid = -1;
filename = '';
datapath = '';
waveformpath = '';
xmlpath = '';
htypes = [];
end
Expand Down Expand Up @@ -37,6 +38,7 @@
grouppath = ['/' groupname];
obj.xmlpath = ['/' groupname '/xml'];
obj.datapath = ['/' groupname '/data'];
obj.waveformpath= ['/' groupname '/waveforms'];

% Check if the group exists
lapl_id=H5P.create('H5P_LINK_ACCESS');
Expand Down Expand Up @@ -267,6 +269,151 @@ function appendAcquisition(obj, acq)
H5D.close(data_id);
end


function nacq = getNumberOfWaveforms(obj)

% Check if the Data exists
lapl_id=H5P.create('H5P_LINK_ACCESS');
if (H5L.exists(obj.fid, obj.waveformpath, lapl_id) == 0)
error([obj.datapath ' does not exist in the HDF5 dataset.']);
end
dset = H5D.open(obj.fid, obj.waveformpath);
space = H5D.get_space(dset);
H5S.get_simple_extent_dims(space);
[~,dims,~] = H5S.get_simple_extent_dims(space);
nacq = dims(1);
H5S.close(space);
H5D.close(dset);

end

function block = readWaveform(obj, start, stop)
if nargin == 1
% Read all the acquisitions
start = 1;
stop = -1;
elseif nargin == 2
% Read a single acquisition
stop = start;
end

% Check if the Data exists
lapl=H5P.create('H5P_LINK_ACCESS');
if (H5L.exists(obj.fid, obj.waveformpath, lapl) == 0)
error([obj.waveformpath ' does not exist in the HDF5 dataset.']);
end

% Open the data
dset = H5D.open(obj.fid, obj.waveformpath);

% Open the data space
space = H5D.get_space(dset);

% Get the size
[~,dims,~] = H5S.get_simple_extent_dims(space);
nacq = dims(1);

% Create a mem_space for reading
if (stop >= start)
offset = [start-1];
dims = [stop-start+1];
mem_space = H5S.create_simple(1,dims,[]);
else
offset = [0];
dims = [nacq];
mem_space = H5S.create_simple(1,dims,[]);
end

% Read the desired acquisitions
H5S.select_hyperslab(space,'H5S_SELECT_SET',offset,[1],[1],dims);
d = H5D.read(dset, obj.htypes.T_Waveform, ...
mem_space, space, 'H5P_DEFAULT');

% Pack'em
block = ismrmrd.Waveform(d.head, d.data);

% Clean up
H5S.close(mem_space);
H5S.close(space);
H5D.close(dset);
end

function appendWaveform(obj, wav)
% Append an acquisition

% TODO: Check the type of the input

% The number of acquisitions that we are going to append
N = wav.getNumber();

% Check if the Data exists
% if it does not exist, create it
% if it does exist increase it's size
lapl_id=H5P.create('H5P_LINK_ACCESS');
if (H5L.exists(obj.fid, obj.waveformpath, lapl_id) == 0)
% Data does not exist
% create with rank 1, unlimited, and set the chunk size
dims = [N];
maxdims = [H5ML.get_constant_value('H5S_UNLIMITED')];
file_space_id = H5S.create_simple(1, dims, maxdims);

dcpl = H5P.create('H5P_DATASET_CREATE');
chunk = [1];
H5P.set_chunk (dcpl, chunk);
data_id = H5D.create(obj.fid, obj.waveformpath, ...
obj.htypes.T_Waveform, ...
file_space_id, dcpl);
H5P.close(dcpl);
H5S.close(file_space_id);

else
% Open the data
data_id = H5D.open(obj.fid, obj.waveformpath);

% Open the data space
file_space_id = H5D.get_space(data_id);

% Get the size, increment by N
H5S.get_simple_extent_dims(file_space_id);
[~,dims,~] = H5S.get_simple_extent_dims(file_space_id);
dims = [dims(1)+N];
H5D.set_extent (data_id, dims);
H5S.close(file_space_id);

end
H5P.close(lapl_id);

% Get the file space
file_space_id = H5D.get_space(data_id);
[~,dims,~] = H5S.get_simple_extent_dims(file_space_id);

% Select the last N block
offset = [dims(1)-N];
H5S.select_hyperslab(file_space_id,'H5S_SELECT_SET',offset,[1],[1],[N]);

% Mem space
mem_space_id = H5S.create_simple(1,[N],[]);

% Check and fix the acquisition header types
wav.head.check();
% TODO: Error checking on the sizes of the data and trajectories.

% Pack the acquisition into the correct struct for writing
d = struct();
d.head = wav.head.toStruct();
d.data = cast(wav.data,'uin32');

% Write
H5D.write(data_id, obj.htypes.T_Waveform, ...
mem_space_id, file_space_id, 'H5P_DEFAULT', d);

% Clean up
H5S.close(mem_space_id);
H5S.close(file_space_id);
H5D.close(data_id);
end


end

end
2 changes: 1 addition & 1 deletion matlab/+ismrmrd/Waveform.m
Expand Up @@ -81,7 +81,7 @@ function extend(obj,N)
end
obj.data{M} = [];
end

end

end

0 comments on commit 9045e40

Please sign in to comment.