Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove international datestring parsing for version checks #509

Merged
merged 4 commits into from
May 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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