Skip to content

Commit

Permalink
Merge pull request #509 from NeurodataWithoutBorders/508-remove-inter…
Browse files Browse the repository at this point in the history
…national-datestring-parsing

Remove international datestring parsing for version checks
  • Loading branch information
lawrence-mbf authored May 30, 2023
2 parents 43cdffb + af0db0a commit 92a65a3
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 99 deletions.
150 changes: 75 additions & 75 deletions +io/parseDataset.m
Original file line number Diff line number Diff line change
@@ -1,85 +1,85 @@
function parsed = parseDataset(filename, info, fullpath, Blacklist)
%typed and untyped being container maps containing type and untyped datasets
% the maps store information regarding information and stored data
% NOTE, dataset name is in path format so we need to parse that out.
name = info.Name;
%typed and untyped being container maps containing type and untyped datasets
% the maps store information regarding information and stored data
% NOTE, dataset name is in path format so we need to parse that out.
name = info.Name;

%check if typed and parse attributes
[attrargs, Type] = io.parseAttributes(filename, info.Attributes, fullpath, Blacklist);
%check if typed and parse attributes
[attrargs, Type] = io.parseAttributes(filename, info.Attributes, fullpath, Blacklist);

fid = H5F.open(filename, 'H5F_ACC_RDONLY', 'H5P_DEFAULT');
did = H5D.open(fid, fullpath);
props = attrargs;
datatype = info.Datatype;
dataspace = info.Dataspace;
fid = H5F.open(filename, 'H5F_ACC_RDONLY', 'H5P_DEFAULT');
did = H5D.open(fid, fullpath);
props = attrargs;
datatype = info.Datatype;
dataspace = info.Dataspace;

parsed = containers.Map;
afields = keys(attrargs);
if ~isempty(afields)
anames = strcat(name, '_', afields);
parsed = [parsed; containers.Map(anames, attrargs.values(afields))];
end
parsed = containers.Map;
afields = keys(attrargs);
if ~isempty(afields)
anames = strcat(name, '_', afields);
parsed = [parsed; containers.Map(anames, attrargs.values(afields))];
end

% loading h5t references are required
% unfortunately also a bottleneck
if strcmp(datatype.Class, 'H5T_REFERENCE')
tid = H5D.get_type(did);
data = io.parseReference(did, tid, H5D.read(did));
H5T.close(tid);
elseif ~strcmp(dataspace.Type, 'simple')
data = H5D.read(did);
% loading h5t references are required
% unfortunately also a bottleneck
if strcmp(datatype.Class, 'H5T_REFERENCE')
tid = H5D.get_type(did);
data = io.parseReference(did, tid, H5D.read(did));
H5T.close(tid);
elseif ~strcmp(dataspace.Type, 'simple')
data = H5D.read(did);

switch datatype.Class
case 'H5T_STRING'
if datetime(version('-date')) < datetime('25-Feb-2020')
% MATLAB 2020a fixed string support for HDF5, making
% reading strings "consistent" with regular use.
data = data .';
end
datadim = size(data);
if datadim(1) > 1
%multidimensional strings should become cellstr
data = strtrim(mat2cell(data, ones(datadim(1), 1), datadim(2)));
end
case 'H5T_ENUM'
if io.isBool(datatype.Type)
data = strcmp('TRUE', data);
else
warning('NWB:Dataset:UnknownEnum', ...
['Encountered unknown enum under field `%s` with %d members. ' ...
'Will be saved as cell array of characters.'], ...
info.Name, length(datatype.Type.Member));
end
end
else
sid = H5D.get_space(did);
pid = H5D.get_create_plist(did);
isChunked = H5P.get_layout(pid) == H5ML.get_constant_value('H5D_CHUNKED');

tid = H5D.get_type(did);
class_id = H5T.get_class(tid);
isNumeric = class_id == H5ML.get_constant_value('H5T_INTEGER')...
|| class_id == H5ML.get_constant_value('H5T_FLOAT');
if isChunked && isNumeric
data = types.untyped.DataPipe('filename', filename, 'path', fullpath);
elseif any(dataspace.Size == 0)
data = [];
switch datatype.Class
case 'H5T_STRING'
if verLessThan('MATLAB', '9.8')
% MATLAB 2020a fixed string support for HDF5, making
% reading strings "consistent" with regular use.
data = data .';
end
datadim = size(data);
if datadim(1) > 1
%multidimensional strings should become cellstr
data = strtrim(mat2cell(data, ones(datadim(1), 1), datadim(2)));
end
case 'H5T_ENUM'
if io.isBool(datatype.Type)
data = strcmp('TRUE', data);
else
warning('NWB:Dataset:UnknownEnum', ...
['Encountered unknown enum under field `%s` with %d members. ' ...
'Will be saved as cell array of characters.'], ...
info.Name, length(datatype.Type.Member));
end
end
else
data = types.untyped.DataStub(filename, fullpath);
sid = H5D.get_space(did);
pid = H5D.get_create_plist(did);
isChunked = H5P.get_layout(pid) == H5ML.get_constant_value('H5D_CHUNKED');

tid = H5D.get_type(did);
class_id = H5T.get_class(tid);
isNumeric = class_id == H5ML.get_constant_value('H5T_INTEGER')...
|| class_id == H5ML.get_constant_value('H5T_FLOAT');
if isChunked && isNumeric
data = types.untyped.DataPipe('filename', filename, 'path', fullpath);
elseif any(dataspace.Size == 0)
data = [];
else
data = types.untyped.DataStub(filename, fullpath);
end
H5T.close(tid);
H5P.close(pid);
H5S.close(sid);
end
H5T.close(tid);
H5P.close(pid);
H5S.close(sid);
end

if isempty(Type.typename)
%untyped group
parsed(name) = data;
else
props('data') = data;
kwargs = io.map2kwargs(props);
parsed = eval([Type.typename '(kwargs{:})']);
end
H5D.close(did);
H5F.close(fid);
if isempty(Type.typename)
%untyped group
parsed(name) = data;
else
props('data') = data;
kwargs = io.map2kwargs(props);
parsed = eval([Type.typename '(kwargs{:})']);
end
H5D.close(did);
H5F.close(fid);
end
48 changes: 24 additions & 24 deletions +tests/+unit/boolTest.m
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
function tests = boolTest()
tests = functiontests(localfunctions);
tests = functiontests(localfunctions);
end

function setupOnce(testCase)
rootPath = fullfile(fileparts(mfilename('fullpath')), '..', '..');
testCase.applyFixture(matlab.unittest.fixtures.PathFixture(rootPath));
rootPath = fullfile(fileparts(mfilename('fullpath')), '..', '..');
testCase.applyFixture(matlab.unittest.fixtures.PathFixture(rootPath));
end

function setup(testCase)
testCase.applyFixture(matlab.unittest.fixtures.WorkingFolderFixture);
generateCore('savedir', '.');
schemaPath = fullfile(misc.getMatnwbDir(),...
'+tests', '+unit', 'boolSchema', 'bool.namespace.yaml');
generateExtension(schemaPath, 'savedir', '.');
rehash();
testCase.applyFixture(matlab.unittest.fixtures.WorkingFolderFixture);
generateCore('savedir', '.');
schemaPath = fullfile(misc.getMatnwbDir(),...
'+tests', '+unit', 'boolSchema', 'bool.namespace.yaml');
generateExtension(schemaPath, 'savedir', '.');
rehash();
end

function testIo(testCase)
nwb = NwbFile(...
'identifier', 'BOOL',...
'session_description', 'test bool',...
'session_start_time', datetime());
boolContainer = types.bool.BoolContainer(...
'data', logical(randi([0,1], 100, 1)), ...
'attribute', false);
scalarBoolContainer = types.bool.BoolContainer(...
'data', false, ...
'attribute', true);
nwb.acquisition.set('bool', boolContainer);
nwb.acquisition.set('scalarbool', scalarBoolContainer);
nwb.export('test.nwb');
nwbActual = nwbRead('test.nwb', 'ignorecache');
tests.util.verifyContainerEqual(testCase, nwbActual, nwb);
nwb = NwbFile(...
'identifier', 'BOOL',...
'session_description', 'test bool',...
'session_start_time', datetime());
boolContainer = types.bool.BoolContainer(...
'data', logical(randi([0,1], 100, 1)), ...
'attribute', false);
scalarBoolContainer = types.bool.BoolContainer(...
'data', false, ...
'attribute', true);
nwb.acquisition.set('bool', boolContainer);
nwb.acquisition.set('scalarbool', scalarBoolContainer);
nwb.export('test.nwb');
nwbActual = nwbRead('test.nwb', 'ignorecache');
tests.util.verifyContainerEqual(testCase, nwbActual, nwb);
end

0 comments on commit 92a65a3

Please sign in to comment.