Skip to content

Commit 015ed4a

Browse files
committed
h5write scalar variables to scalar dataset
1 parent 5d63511 commit 015ed4a

File tree

4 files changed

+81
-17
lines changed

4 files changed

+81
-17
lines changed

+stdlib/+hdf5nc/TestHDF5.m

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,10 @@ function test_get_variables(tc)
101101

102102
function test_exists(tc, vars)
103103
import stdlib.hdf5nc.h5exists
104-
import matlab.unittest.constraints.IsScalar
105104
basic = tc.TestData.basic;
106105

107106
e = h5exists(basic, "/" + vars);
108-
tc.verifyThat(e, IsScalar)
107+
tc.verifyTrue(isscalar(e))
109108
tc.verifyTrue(e)
110109

111110
% vector
@@ -124,15 +123,14 @@ function test_exists(tc, vars)
124123

125124
function test_size(tc)
126125
import stdlib.hdf5nc.h5size
127-
import matlab.unittest.constraints.IsScalar
128126
basic = tc.TestData.basic;
129127

130128
s = h5size(basic, '/A0');
131-
tc.verifyThat(s, IsScalar)
129+
tc.verifyTrue(isscalar(s))
132130
tc.verifyEqual(s, 1)
133131

134132
s = h5size(basic, '/A1');
135-
tc.verifyThat(s, IsScalar)
133+
tc.verifyTrue(isscalar(s))
136134
tc.verifyEqual(s, 2)
137135

138136
s = h5size(basic, '/A2');
@@ -155,11 +153,10 @@ function test_size(tc)
155153

156154

157155
function test_read(tc)
158-
import matlab.unittest.constraints.IsScalar
159156
basic = tc.TestData.basic;
160157

161158
s = h5read(basic, '/A0');
162-
tc.verifyThat(s, IsScalar)
159+
tc.verifyTrue(isscalar(s))
163160
tc.verifyEqual(s, 42)
164161

165162
s = h5read(basic, '/A1');
@@ -218,11 +215,11 @@ function test_string(tc, str)
218215

219216
function test_file_missing(tc)
220217

221-
tc.verifyError(@() stdlib.hdf5nc.h5exists(tempname,""), 'hdf5nc:h5variables:fileNotFound')
218+
tc.verifyError(@() stdlib.hdf5nc.h5exists(tempname,"/bad"), 'hdf5nc:h5variables:fileNotFound')
222219
tc.verifyError(@() stdlib.hdf5nc.h5variables(tempname), 'hdf5nc:h5variables:fileNotFound')
223-
tc.verifyError(@() stdlib.hdf5nc.h5size(tempname,""), 'hdf5nc:h5size:fileNotFound')
220+
tc.verifyError(@() stdlib.hdf5nc.h5size(tempname,"/bad"), 'hdf5nc:h5size:fileNotFound')
224221
[~,badname] = fileparts(tempname);
225-
tc.verifyError(@() stdlib.hdf5nc.h5save(badname,"",0), 'hdf5nc:h5save:fileNotFound')
222+
tc.verifyError(@() stdlib.hdf5nc.h5save(badname,"/bad",0), 'hdf5nc:h5save:fileNotFound')
226223
end
227224

228225
function test_real_only(tc)

+stdlib/+hdf5nc/h5save.m

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ function h5save(filename, varname, A, opts)
1414
import stdlib.fileio.expanduser
1515
import stdlib.hdf5nc.h5exists
1616

17+
if strlength(varname) < 2
18+
error("MATLAB:expectedNonempty", "variable name must start with / and be non-empty")
19+
end
20+
1721
if isnumeric(A)
1822
mustBeReal(A)
1923
end
@@ -77,6 +81,31 @@ function new_file(filename, varname, A, sizeA)
7781
error('hdf5nc:h5save:fileNotFound', '%s is not a folder, cannot create %s', folder, filename)
7882
end
7983

84+
if isscalar(A) && ~isstring(A) && ~isempty(varname)
85+
dcpl = 'H5P_DEFAULT';
86+
87+
if isfile(filename)
88+
fid = H5F.open(filename, 'H5F_ACC_RDWR', dcpl);
89+
else
90+
fid = H5F.create(filename);
91+
end
92+
93+
create_hdf5_group(fid, varname);
94+
95+
space_id = H5S.create('H5S_SCALAR');
96+
t = class2h5t(A);
97+
type_id = H5T.copy(t);
98+
dset_id = H5D.create(fid, varname, type_id, space_id, dcpl);
99+
H5D.write(dset_id,'H5ML_DEFAULT','H5S_ALL','H5S_ALL', dcpl, A);
100+
101+
H5S.close(space_id);
102+
H5T.close(type_id);
103+
H5D.close(dset_id);
104+
H5F.close(fid);
105+
106+
return
107+
end
108+
80109
if isvector(A)
81110
h5create(filename, varname, sizeA, 'DataType', class(A))
82111
else
@@ -91,7 +120,45 @@ function new_file(filename, varname, A, sizeA)
91120

92121
end % function
93122

94-
% Copyright 2020 Michael Hirsch, Ph.D.
123+
124+
function t = class2h5t(A)
125+
% gets HDF5 H5T of variable A
126+
127+
switch class(A)
128+
case 'double', t = 'H5T_NATIVE_DOUBLE';
129+
case 'single', t = 'H5T_NATIVE_FLOAT';
130+
case 'int32', t = 'H5T_STD_I32LE';
131+
case 'int64', t = 'H5T_STD_I64LE';
132+
otherwise, error('h5save:class2h5t: unknown data class %s', class(A))
133+
end
134+
135+
end
136+
137+
138+
function create_hdf5_group(fid, name)
139+
140+
grps = split(name, "/");
141+
if length(grps) < 3
142+
return
143+
end
144+
145+
plist = 'H5P_DEFAULT';
146+
groot = H5G.open(fid, "/");
147+
148+
for i = 0:length(grps) - 3
149+
n = join(grps(1:i+2), "/");
150+
151+
if ~H5L.exists(groot, n, plist)
152+
gid = H5G.create(fid, n, plist, plist, plist);
153+
H5G.close(gid)
154+
end
155+
end % for
156+
157+
H5G.close(groot)
158+
end % function
159+
160+
161+
% Copyright 2020 Michael Hirsch
95162

96163
% Licensed under the Apache License, Version 2.0 (the "License");
97164
% you may not use this file except in compliance with the License.

+stdlib/+hdf5nc/h5size.m

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@
2727
error("hdf5nc:h5size:fileNotFound", "%s not found.", file)
2828
end
2929

30-
fsize = h5info(file, variable).Dataspace.Size;
30+
dsi = h5info(file, variable).Dataspace;
31+
if dsi.Type == "scalar"
32+
fsize = 1;
33+
else
34+
fsize = dsi.Size;
35+
end
3136

3237
end

Readme.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ TestAll
3131
import stdlib.hdf5nc.*
3232
```
3333

34-
Matlab R2021a uses HDF5 1.8.12.
35-
3634
```matlab
3735
[major,minor,rel] = H5.get_libversion()
3836
```
@@ -68,9 +66,6 @@ h5variables(filename)
6866
import stdlib.hdf5nc.*
6967
```
7068

71-
72-
Matlab R2021a uses NetCDF4 4.7.3.
73-
7469
```matlab
7570
netcdf.inqLibVers
7671
```

0 commit comments

Comments
 (0)