Skip to content

Commit

Permalink
fix: preserve logical datatype (#2)
Browse files Browse the repository at this point in the history
Found that variable declared as `logical` were being read back in as `uint8`. It turns out that MATLAB manages the datatype with more than one dataset attribute. This PR copies over all dataset attributes in a loop, which solves the problem.

* Tests that reading logical from MAT-file yields logical, which fails

* Copy over all dataset attributes, not just MATLAB_class...

This change preserves logical datatype on read

* Bump version
  • Loading branch information
keithfma authored Feb 24, 2020
1 parent 336cdb9 commit f5f653c
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 12 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.2.0
0.2.1
27 changes: 16 additions & 11 deletions newmatic.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
out_fcpl = H5P.copy(ref_fcpl);
out_fid = H5F.create(out_file, 'H5F_ACC_EXCL', out_fcpl, 'H5P_DEFAULT');

% copy over datasets (a.k.a., variables), applying chunking as needed
% copy datasets (a.k.a., variables), applying chunking as needed
for ii = 1:length(varargin)
var = varargin{ii};

Expand All @@ -53,18 +53,23 @@
H5D.get_space(ref_ds_id), ...
out_ds_cpl);

% note: assume that only this one attribute exists (cribbed from manual inspection of files
% created by matfile function)
ref_attr_id = H5A.open(ref_ds_id, 'MATLAB_class');
% copy dataset attributes
ref_ds_info = H5O.get_info(ref_ds_id);

out_attr_id = H5A.create(...
out_ds_id, ...
'MATLAB_class', ...
H5A.get_type(ref_attr_id), ...
H5A.get_space(ref_attr_id), ...
'H5P_DEFAULT');
H5A.write(out_attr_id, 'H5ML_DEFAULT', H5A.read(ref_attr_id));
for ref_attr_idx = 0:ref_ds_info.num_attrs - 1

ref_attr_id = H5A.open_by_idx(...
ref_fid, var.name, 'H5_INDEX_NAME', 'H5_ITER_DEC', ref_attr_idx);

out_attr_id = H5A.create(...
out_ds_id, ...
H5A.get_name(ref_attr_id), ...
H5A.get_type(ref_attr_id), ...
H5A.get_space(ref_attr_id), ...
'H5P_DEFAULT');
H5A.write(out_attr_id, 'H5ML_DEFAULT', H5A.read(ref_attr_id));
end

H5A.close(ref_attr_id);
H5A.close(out_attr_id);

Expand Down
11 changes: 11 additions & 0 deletions test_newmatic.m
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,14 @@ function test_input_validation(testCase)
fclose(fopen(fname, 'w')); % create file by touching it
assertError(testCase, @() newmatic(fname, a_var), 'newmatic:OverwriteError');
end


function test_preserve_logical_dtype(testCase)
fname = testCase.TestData.filename;
mat = newmatic(fname, newmatic_variable('x', 'logical', [100, 200], [50, 100]));
mat.x(:, :) = false(100, 200);

% data read back from file should still be logical
assertClass(testCase, mat.x, 'logical');
end

0 comments on commit f5f653c

Please sign in to comment.