-
Notifications
You must be signed in to change notification settings - Fork 53
/
hdf5write_safe.m
158 lines (128 loc) · 3.86 KB
/
hdf5write_safe.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
function err = hdf5write_safe(fileobj, name, val, options)
err = -1;
if isempty(val)
return;
end
if ~exist('options','var')
options = '';
end
force_scalar = false;
force_array = false;
if any(strcmp(options, 'array'))
force_array = true;
elseif any(strcmp(options, 'scalar'))
force_scalar = true;
end
% Identify type of val and use SNIRF v1.1-compliant write function
fid = HDF5_GetFileDescriptor(fileobj);
if fid < 0
err = -1;
return;
end
% Create group where dataset is located
group = filesepStandard(fileparts(name), 'nameonly');
gid = HDF5_CreateGroup(fid, group);
if gid < 0
err = -1;
return;
end
% Create dataset
if iscell(val) || isstring(val)
if length(val) > 1 && ~force_scalar || force_array % Returns true for single strings, believe it or not
write_string_array(fid, name, val);
else
write_string(fid, name, val);
end
elseif ischar(val)
write_string(fid, name, val);
elseif isfloat(val)
if length(val) > 1 && ~force_scalar || force_array
write_numeric_array(fid, name, val);
else
write_numeric(fid, name, val);
end
elseif isinteger(val)
if length(val) > 1 && ~force_scalar || force_array
write_numeric_array(fid, name, val); % As of now, no integer arrays exist
else
write_integer(fid, name, val);
end
else
warning(['An unrecognized variable was saved to ', name])
end
% -----------------------------------------------------------------
function err = write_string(fid, name, val)
sid = H5S.create('H5S_SCALAR');
tid = H5T.copy('H5T_C_S1');
H5T.set_size(tid, 'H5T_VARIABLE');
did = H5D.create(fid, name, tid, sid, 'H5P_DEFAULT');
H5D.write(did, tid, 'H5S_ALL', 'H5S_ALL', 'H5P_DEFAULT', {val});
err = 0;
% -----------------------------------------------------------------
function err = write_string_array(fid, name, val)
val = HDF5_Transpose(val);
sid = H5S.create_simple(1, numel(val), H5ML.get_constant_value('H5S_UNLIMITED'));
tid = H5T.copy('H5T_C_S1');
H5T.set_size(tid, 'H5T_VARIABLE');
pid = H5P.create('H5P_DATASET_CREATE');
H5P.set_chunk(pid, 2);
dsid = H5D.create(fid, name, tid, sid, pid);
H5D.write(dsid, tid, 'H5S_ALL', 'H5S_ALL', 'H5P_DEFAULT', val);
err = 0;
% -----------------------------------------------------------------
function err = write_numeric(fid, name, val)
tid = H5T.copy('H5T_NATIVE_DOUBLE');
sid = H5S.create('H5S_SCALAR');
dsid = H5D.create(fid, name, tid, sid, 'H5P_DEFAULT');
H5D.write(dsid, tid, 'H5S_ALL', 'H5S_ALL', 'H5P_DEFAULT', val);
err = 0;
% -----------------------------------------------------------------
function err = write_integer(fid, name, val)
warning off; % Suppress the int truncation warning
tid = H5T.copy('H5T_NATIVE_ULONG');
sid = H5S.create('H5S_SCALAR');
dsid = H5D.create(fid, name, tid, sid, 'H5P_DEFAULT');
H5D.write(dsid, tid, 'H5S_ALL', 'H5S_ALL', 'H5P_DEFAULT', int32(val));
err = 0;
warning on;
% -----------------------------------------------------------------
function err = write_numeric_array(fid, name, data)
err = 0;
data = HDF5_Transpose(data);
sizedata = size(data);
if sizedata(1) == 1 || sizedata(2) == 1
n = length(data);
else
n = sizedata;
end
tid = -1;
sid = -1;
gid = -1;
dsid = -1;
maxdims = n;
try
sid = H5S.create_simple(numel(n), fliplr(n), fliplr(maxdims));
gid = HDF5_CreateGroup(fid, fileparts(name));
dsid = H5D.create(gid, name, 'H5T_NATIVE_DOUBLE', sid, 'H5P_DEFAULT');
H5D.write(dsid, 'H5ML_DEFAULT', 'H5S_ALL', 'H5S_ALL', 'H5P_DEFAULT', data);
catch
% Clean up; Close everything
cleanUp(tid, sid, gid, dsid);
err = -1;
return;
end
cleanUp(tid, sid, gid, dsid);
% ------------------------------------------------------
function cleanUp(tid, sid, gid, dsid)
if ~isnumeric(tid)
H5T.close(tid);
end
if ~isnumeric(sid)
H5S.close(sid);
end
if ~isnumeric(gid)
H5G.close(gid);
end
if ~isnumeric(dsid)
H5D.close(dsid);
end