Now we consider what we need to do to start adding
time series data to the myvar
variable. We could use nc_varput
,
but that requires us to give the correct (and changing) indices every time, since
the time dimension increases each time you add data to it.
>> nc_dump ( 'test.nc', 'myvar' ) netcdf test.nc { dimensions: latitude = 20 ; longitude = 30 ; time = UNLIMITED ; (0 currently) variables: float myvar(time,latitude,longitude), shape = [0 20 30] }
So the time dimension currently has a length of zero... how should we call
nc_varput
to write our first timestep of data?
Let's try the obvious.
>> data = rand(20,30); >> nc_varput ( 'test.nc', 'myvar', data ); ??? Error using ==> nc_varput nc_varput: rank of input data (2) does not match rank of netcdf variable (3).
The rank of the input data must, therefore be three. Let's try again.
>> data = rand(1,20,30); >> nc_varput ( 'test.nc', 'myvar', data ); ??? Error using ==> nc_varput nc_varput: total number of input datums was 600, but the netcdf variable size is 0 elements.
What's going on here? The problem is that myvar
is an unlimited
variable that currently has no data in it, and you just tried to cram 600 elements into
it without telling it how to do so. For unlimited variables, you must supply the
start
and count
parameters.
>> data = rand(1,20,30); >> start = [0 0 0]; >> count = [1 20 30]; >> nc_varput ( 'test.nc', 'myvar', data, start, count );
If we have to add more data, we would have to modify the start
parameter appropriately.
>> data = rand(1,20,30); >> start = [1 0 0]; >> count = [1 20 30]; >> nc_varput ( 'test.nc', 'myvar', data, start, count );
This seems to work, but there are two little problems. The first is that it
requires you to constantly keep track of the time index in order to properly
append the data, and, if you notice, the time
variable now
has two datums in it that we never initialized.
>> nc_dump ( 'test.nc' ) netcdf test.nc { dimensions: latitude = 20 ; longitude = 30 ; time = UNLIMITED ; (2 currently) variables: float myvar(time,latitude,longitude), shape = [0 20 30] double longitude(longitude), shape = [30] double time(time), shape = [2] double latitude(latitude), shape = [20] } >> nc_varget ( 'test.nc', 'time' ) ans = 1.0e+36 * 9.9692 9.9692
These values happen to correspond to the default fill value, which is a story for another day. Let's fix those two time values.
>> time_data = [0; 1]; >> nc_varput ( 'test.nc', 'time', time_data );
Back to the matter at hand, it would be nice
to be able to append to all the variables in an unlimited file all
at once without having to keep track of the time index. The m-file
nc_addnewrecs
was written with this in mind (so long
as you are working with monotonically increasing data, i.e. time series)
and
figures out how to correctly call
nc_varput
,
and will even handle the special case of leading singleton dimensions
for you, i.e.
>> new_record.time = [2]; >> new_record.myvar = rand(20,30); >> new_record new_record = time: 2 data: [20x30 double] >> nc_addnewrecs ( 'test.nc', new_record ); >> nc_dump ( 'test.nc' ) netcdf test.nc { dimensions: latitude = 20 ; longitude = 30 ; time = UNLIMITED ; (3 currently) variables: float data(time,latitude,longitude), shape = [3 20 30] double longitude(longitude), shape = [30] double latitude(latitude), shape = [20] double time(time), shape = [3] }
Let's add a 4th and 5th observation at once.
>> new_record.time = [3; 4]; >> new_record.data = rand(2,20,30); >> new_record new_record = time: [2x1 double] data: [2x20x30 double] >> nc_addnewrecs ( 'test.nc', new_record ); >> nc_dump ( 'test.nc' ) netcdf test.nc { dimensions: latitude = 20 ; longitude = 30 ; time = UNLIMITED ; (4 currently) variables: float data(time,latitude,longitude), shape = [4 20 30] double longitude(longitude), shape = [30] double latitude(latitude), shape = [20] double time(time), shape = [4] }
Be aware that
nc_addnewrecs
is only suitable for
writing data to netCDF variables with an unlimited dimension. If your
variables don't have an unlimited dimension, then you should stick with
nc_varput
.