Chapter 9.  Appending Data

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.