Skip to content

Commit 6b9b1c6

Browse files
committed
ncsave: require dimensions for non-scalar
1 parent 8481622 commit 6b9b1c6

File tree

4 files changed

+30
-41
lines changed

4 files changed

+30
-41
lines changed

+stdlib/+hdf5nc/ncsave.m

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ function ncsave(filename, varname, A, opts)
44
filename (1,1) string {mustBeNonzeroLengthText}
55
varname (1,1) string {mustBeNonzeroLengthText}
66
A {mustBeNonempty}
7-
opts.dims cell = {}
7+
opts.dims cell
88
opts.type string {mustBeScalarOrEmpty} = string.empty
99
end
1010

@@ -15,42 +15,28 @@ function ncsave(filename, varname, A, opts)
1515
% avoid creating confusing file ./~/foo.nc
1616
filename = stdlib.fileio.expanduser(filename);
1717

18-
if isempty(opts.dims)
19-
if isscalar(A)
20-
sizeA = 1;
21-
ncdims = [];
22-
elseif isvector(A)
23-
sizeA = length(A);
24-
ncdims = {'x', sizeA};
25-
elseif ismatrix(A)
26-
sizeA = size(A);
27-
ncdims = {'x', sizeA(1), 'y', sizeA(2)};
28-
else
29-
sizeA = size(A);
30-
switch length(sizeA)
31-
case 3, ncdims = {'x', sizeA(1), 'y', sizeA(2), 'z', sizeA(3)};
32-
case 4, ncdims = {'x', sizeA(1), 'y', sizeA(2), 'z', sizeA(3), 'w', sizeA(4)};
33-
otherwise, error('ncsave currently does scalar through 4D')
34-
end
35-
end % if
36-
else
37-
ncdims = opts.dims;
18+
% coerce if needed
19+
A = coerce_ds(A, opts.type);
3820

21+
if isscalar(A)
22+
sizeA = 1;
23+
else
24+
if isempty(opts.dims)
25+
error("For non-scalar NetCDF variables, the dimenions must be defined as a cell array")
26+
end
3927
for i = 2:2:length(opts.dims)
4028
sizeA(i/2) = opts.dims{i}; %#ok<AGROW>
4129
end
4230
end
43-
% coerce if needed
44-
A = coerce_ds(A, opts.type);
4531

4632
if isfile(filename)
4733
if stdlib.hdf5nc.ncexists(filename, varname)
4834
nc_exist_file(filename, varname, A, sizeA)
4935
else
50-
nc_new_file(filename, varname, A, sizeA, ncdims)
36+
nc_new_file(filename, varname, A, sizeA, opts.dims)
5137
end
5238
else
53-
nc_new_file(filename, varname, A, sizeA, ncdims)
39+
nc_new_file(filename, varname, A, sizeA, opts.dims)
5440
end
5541

5642
end

+stdlib/+hdf5nc/private/nc_new_file.m

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,22 @@ function nc_new_file(filename, varname, A, sizeA, ncdims)
22

33
if isscalar(A)
44
nccreate(filename, varname, ...
5-
"Datatype", class(A), ...
6-
"Format", 'netcdf4')
5+
Datatype=class(A), ...
6+
Format='netcdf4')
77
elseif isvector(A) || ischar(A) || isstring(A)
88
nccreate(filename, varname, ...
9-
"Dimensions", ncdims, ...
10-
"Datatype", class(A), ...
11-
"Format", 'netcdf4')
9+
Dimensions=ncdims, ...
10+
Datatype=class(A), ...
11+
Format='netcdf4')
1212
else
1313
% enable Gzip compression--remember Matlab's dim order is flipped from
1414
% C / Python
1515
nccreate(filename, varname, ...
16-
"Dimensions", ncdims, ...
17-
"Datatype", class(A), ...
18-
"DeflateLevel", 1, "Shuffle", true, ...
19-
"ChunkSize", stdlib.hdf5nc.auto_chunk_size(sizeA), ...
20-
"Format", 'netcdf4')
16+
Dimensions=ncdims, ...
17+
Datatype=class(A), ...
18+
DeflateLevel=1, Shuffle=true, ...
19+
ChunkSize=stdlib.hdf5nc.auto_chunk_size(sizeA), ...
20+
Format='netcdf4')
2121
end
2222

2323
ncwrite(filename, varname, A)

+stdlib/ncsave.m

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,5 @@ function ncsave(filename, varname, A, opts)
88
opts.type string {mustBeScalarOrEmpty} = string.empty
99
end
1010

11-
stdlib.hdf5nc.ncsave(filename, varname, A, ...
12-
'dims', opts.dims, 'type', opts.type)
11+
stdlib.hdf5nc.ncsave(filename, varname, A, dims=opts.dims, type=opts.type)
1312
end

test/TestNetCDF.m

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ function setup_path(tc)
1515
function setup_file(tc)
1616
import matlab.unittest.constraints.IsFile
1717
import matlab.unittest.fixtures.TemporaryFolderFixture
18+
19+
tc.assumeFalse(isMATLABReleaseOlderThan('R2021a'), "NetCDF requires Matlab >= R2021a")
20+
1821
fixture = tc.applyFixture(TemporaryFolderFixture);
1922

2023
A0 = 42.;
@@ -41,15 +44,15 @@ function setup_file(tc)
4144

4245
% create test data first, so that parallel tests works
4346
stdlib.ncsave(basic, 'A0', A0)
44-
stdlib.ncsave(basic, 'A1', A1)
47+
stdlib.ncsave(basic, 'A1', A1, "dims", {'x1', size(A1,1)})
4548
stdlib.ncsave(basic, 'A2', A2, "dims", {'x2', size(A2,1), 'y2', size(A2,2)})
4649
stdlib.ncsave(basic, 'A3', A3, "dims", {'x3', size(A3,1), 'y3', size(A3,2), 'z3', size(A3,3)})
4750
stdlib.ncsave(basic, 'A4', A4, "dims", {'x4', size(A4,1), 'y4', size(A4,2), 'z4', size(A4,3), 'w4', size(A4,4)})
4851

4952
if ~isMATLABReleaseOlderThan('R2021b')
5053
stdlib.ncsave(basic, "utf0", utf0)
51-
stdlib.ncsave(basic, "utf1", utf1)
52-
stdlib.ncsave(basic, "utf2", utf2)
54+
stdlib.ncsave(basic, "utf1", utf1, "dims", {'s1', size(utf1, 1)})
55+
stdlib.ncsave(basic, "utf2", utf2, "dims", {'s1', size(utf2, 1), 't1', size(utf2, 2)})
5356
end
5457

5558
stdlib.ncsave(basic, '/t/x', 12)
@@ -226,7 +229,8 @@ function test_rewrite(tc)
226229
import matlab.unittest.constraints.IsFile
227230
basic = tc.TestData.basic;
228231

229-
stdlib.ncsave(basic, "A2", 3*magic(4))
232+
A2 = 3*magic(4);
233+
stdlib.ncsave(basic, "A2", A2, "dims", {'x2', size(A2,1), 'y2', size(A2,2)})
230234

231235
tc.assumeThat(basic, IsFile)
232236
tc.verifyEqual(ncread(basic, 'A2'), 3*magic(4))

0 commit comments

Comments
 (0)