source: Roms_tools/mexcdf/snctools/nc_add_recs.m @ 1

Last change on this file since 1 was 1, checked in by cholod, 13 years ago

import Roms_Agrif

File size: 11.3 KB
Line 
1function nc_add_recs ( ncfile, new_data, varargin )
2% NC_ADD_RECS:  add records onto the end of a netcdf file
3%
4% USAGE:  nc_add_recs ( ncfile, new_data, unlimited_dimension );
5%
6% INPUT:
7%   ncfile:  netcdf file
8%   new_data:  Matlab structure.  Each field is a data array
9%      to be written to the netcdf file.  Each array had
10%      better be the same length.  All arrays are written
11%      in the same fashion.
12%   unlimited_dimension:
13%      Optional.  Name of the unlimited dimension along which the data
14%      is written.  If not provided, we query for the first unlimited
15%      dimension (looking ahead to HDF5/NetCDF4).
16%     
17% OUTPUT:
18%   None.  In case of an error, an exception is thrown.
19%
20% AUTHOR:
21%   johnevans@acm.org
22%
23%
24
25%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
26%
27% $Id: nc_add_recs.m 2659 2009-04-01 17:38:36Z johnevans007 $
28% $LastChangedDate: 2009-04-01 13:38:36 -0400 (Wed, 01 Apr 2009) $
29% $LastChangedRevision: 2659 $
30% $LastChangedBy: johnevans007 $
31%
32%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33
34
35error(nargchk(2,3,nargin,'struct'));
36
37
38%
39% Check that we were given good inputs.
40if ~isstruct ( new_data )
41    err_id = 'SNCTOOLS:NC_ADD_RECS:badStruct';
42    error ( err_id, '2nd input argument must be a structure .\n' );
43end
44
45%
46% Check that each field of the structure has the same length.
47varnames = fieldnames ( new_data );
48num_fields = length(varnames);
49if ( num_fields <= 0 )
50    err_id = 'SNCTOOLS:NC_ADD_RECS:badRecord';
51    error ( err_id, 'data record cannot be empty' );
52end
53field_length = zeros(num_fields,1);
54for j = 1:num_fields
55
56    v = nc_getvarinfo(ncfile,varnames{j});
57
58    if getpref('SNCTOOLS','PRESERVE_FVD',false)
59
60        if numel(v.Size) == 1
61            % netCDF variable is 1D
62            field_length(j) = numel(new_data.(varnames{j}));
63        elseif (numel(v.Size) == 2)
64            % netCDF variable is 2D
65            field_length(j) = size(new_data.(varnames{j}),2);
66        elseif (numel(v.Size) > 2) && (numel(v.Size) == (ndims(new_data.(varnames{j})) + 1))
67            % netCDF variable is more than 2D, but we're given just one record.
68            field_length(j) = 1;
69        else
70            % netCDF variable is n-D
71            n = ndims(new_data.(varnames{j}));
72            command = sprintf ( 'field_length(j) = size(new_data.%s,%d);', ...
73                varnames{j}, n );
74            eval(command);
75        end
76
77    else
78        if numel(v.Size) == 1
79            % netCDF variable is 1D
80            field_length(j) = numel(new_data.(varnames{j}));
81        elseif (numel(v.Size) == 2)
82            % netCDF variable is 2D
83            field_length(j) = size(new_data.(varnames{j}),1);
84        elseif (numel(v.Size) > 2) && (numel(v.Size) == (ndims(new_data.(varnames{j})) + 1))
85            % netCDF variable is more than 2D, but we're given just one record.
86            field_length(j) = 1;
87        else
88            % netCDF variable is n-D
89            command = sprintf ( 'field_length(j) = size(new_data.%s,1);', varnames{j} );
90            eval(command);
91        end
92
93    end
94end
95if any(diff(field_length))
96    err_id = 'SNCTOOLS:NC_ADD_RECS:badFieldLengths';
97    error ( err_id, 'Some of the fields do not have the same length.\n' );
98end
99
100%
101% So we have this many records to write.
102record_count = field_length(1);
103
104
105[unlim_dimname, unlim_dimlen, unlim_dimid] = get_unlimdim_info ( ncfile, varargin{:} );
106
107varsize = get_all_varsizes ( ncfile, new_data, unlim_dimid );
108
109
110%
111% So we start writing here.
112record_corner = unlim_dimlen;
113
114
115
116%
117% write out each data field, as well as the minimum and maximum
118input_variable = fieldnames ( new_data );
119num_vars = length(input_variable);
120for i = 1:num_vars
121
122    current_var = input_variable{i};
123    %fprintf ( 1, '%s:  processing %s...\n', mfilename, current_var );
124
125    current_var_data = new_data.(current_var);
126
127    netcdf_var_size = varsize.(current_var);
128
129    corner = zeros( 1, length(netcdf_var_size) );
130    count = netcdf_var_size;
131
132    if getpref('SNCTOOLS','PRESERVE_FVD',false)
133        % record dimension is last.
134        corner(end) = record_corner;
135        count(end) = record_count;
136    else
137        % Old school
138        corner(1) = record_corner;
139        count(1) = record_count;
140    end
141
142
143
144    %
145    % Ok, we are finally ready to write some data.
146    nc_varput ( ncfile, current_var, current_var_data, corner, count );
147   
148
149end
150
151
152return
153
154
155
156
157
158
159
160
161
162%--------------------------------------------------------------------------
163function varsize = get_all_varsizes ( ncfile, new_data,unlimited_dimension_dimid )
164
165switch ( version('-release') )
166case { '11', '12', '13', '14', '2006a', '2006b', '2007a', '2007b', '2008a' }
167    varsize = get_all_varsizes_mexnc(ncfile, new_data,unlimited_dimension_dimid);
168otherwise
169    varsize = get_all_varsizes_tmw(ncfile, new_data,unlimited_dimension_dimid);
170end
171
172
173
174
175%--------------------------------------------------------------------------
176function varsize = get_all_varsizes_tmw ( ncfile, new_data,unlimited_dimension_dimid )
177
178ncid=netcdf.open(ncfile, nc_nowrite_mode );
179
180
181%
182% For each field of "new_data" buffer, inquire as to the dimensions in the
183% NetCDF file.  We need this data to properly tell nc_varput how to write
184% the data
185input_variable = fieldnames ( new_data );
186num_vars = length(input_variable);
187varsize = [];
188for j = 1:num_vars
189
190    varid = netcdf.inqVarID(ncid, input_variable{j} );
191    [dud,dud,dimids] = netcdf.inqVar(ncid, varid);
192    ndims = length(dimids);
193    dimsize = zeros(1,ndims);
194
195
196    %
197    % make sure that this variable is defined along the unlimited dimension.
198    if ~any(find(dimids==unlimited_dimension_dimid))
199        netcdf.close(ncid);
200        format = 'variable %s must be defined along unlimited dimension %s.\n';
201        error ( 'SNCTOOLS:NC_ADD_RECS:missingUnlimitedDimension', ...
202                format, input_variable{j}, unlimited_dimension_name );
203    end
204
205    for k = 1:ndims
206        [dud,dim_length] = netcdf.inqDim(ncid, dimids(k) );
207        dimsize(k) = dim_length;
208    end
209
210    % R2008b reports in opposite order of C API
211    if ~getpref('SNCTOOLS','PRESERVE_FVD',false)
212        dimsize = fliplr(dimsize);
213    end
214    varsize.(input_variable{j}) = dimsize;
215
216
217end
218
219netcdf.close(ncid);
220
221
222%--------------------------------------------------------------------------
223function varsize = get_all_varsizes_mexnc ( ncfile, new_data,unlimited_dimension_dimid )
224[ncid,status ]=mexnc( 'open', ncfile, nc_nowrite_mode );
225if status ~= 0
226    ncerr = mexnc ( 'strerror', status );
227    error_id = 'SNCTOOLS:NC_ADD_RECS:openFailed';
228    error ( error_id, ncerr );
229end
230
231
232
233%
234% For each field of "new_data" buffer, inquire as to the dimensions in the
235% NetCDF file.  We need this data to properly tell nc_varput how to write
236% the data
237input_variable = fieldnames ( new_data );
238num_vars = length(input_variable);
239varsize = [];
240for j = 1:num_vars
241
242    [varid, status] = mexnc('INQ_VARID', ncid, input_variable{j} );
243    if ( status ~= 0 )
244        mexnc('close',ncid);
245        ncerr = mexnc ( 'strerror', status );
246        error_id = 'SNCTOOLS:NC_ADD_RECS:inq_varidFailed';
247        error ( error_id, ncerr );
248    end
249
250    [dimids, status] = mexnc('INQ_VARDIMID', ncid, varid);
251    if ( status ~= 0 )
252        mexnc('close',ncid);
253        ncerr = mexnc ( 'strerror', status );
254        error_id = 'SNCTOOLS:NC_ADD_RECS:inq_vardimidFailed';
255        error ( error_id, ncerr );
256    end
257    ndims = length(dimids);
258    dimsize = zeros(1,ndims);
259
260
261    %
262    % make sure that this variable is defined along the unlimited dimension.
263    if ~any(find(dimids==unlimited_dimension_dimid))
264        mexnc('close',ncid);
265        format = 'variable %s must be defined along unlimited dimension %s.\n';
266        error ( 'SNCTOOLS:NC_ADD_RECS:missingUnlimitedDimension', ...
267                format, input_variable{j}, unlimited_dimension_name );
268    end
269
270    for k = 1:ndims
271        [dim_length, status] = mexnc('INQ_DIMLEN', ncid, dimids(k) );
272        if ( status ~= 0 )
273            mexnc('close',ncid);
274            ncerr = mexnc ( 'strerror', status );
275            error_id = 'SNCTOOLS:NC_ADD_RECS:inq_dimlenFailed';
276            error ( error_id, ncerr );
277        end
278        dimsize(k) = dim_length;
279    end
280
281    % If we want to preserve the fastest varying dimension, then we
282        % have to flip the dimensions.
283    if getpref('SNCTOOLS','PRESERVE_FVD',false)
284        dimsize = fliplr(dimsize);
285    end
286    varsize.(input_variable{j}) = dimsize;
287    varsize.(input_variable{j}) = dimsize;
288
289end
290
291status = mexnc('close',ncid);
292if status ~= 0
293    ncerr = mexnc ( 'strerror', status );
294    error_id = 'SNCTOOLS:NC_ADD_RECS:closeFailed';
295    error ( error_id, ncerr );
296end
297   
298
299
300
301
302
303
304%--------------------------------------------------------------------------
305function [dimname, dimlen, dimid] = get_unlimdim_info ( ncfile, varargin )
306
307switch ( version('-release') )
308case { '11', '12', '13', '14', '2006a', '2006b', '2007a', '2007b', '2008a' }
309    [dimname, dimlen, dimid] = get_unlimdim_info_mexnc ( ncfile, varargin{:} );
310otherwise
311    [dimname, dimlen, dimid] = get_unlimdim_info_tmw ( ncfile, varargin{:} );
312end
313
314
315
316%--------------------------------------------------------------------------
317function [dimname, dimlen, dimid] = get_unlimdim_info_tmw ( ncfile, varargin )
318ncid=netcdf.open(ncfile, nc_nowrite_mode );
319
320
321%
322% If we were not given the name of an unlimited dimension, get it now
323if nargin < 2
324    [dud,dud,dud,dimid] = netcdf.inq(ncid );
325
326    dimname = netcdf.inqDim(ncid, dimid );
327
328    if dimid == -1
329        error_id = 'SNCTOOLS:NC_ADD_RECS:noUnlimitedDimension';
330        error ( error_id, '%s is missing an unlimited dimension, %s requires it', ncfile, mfilename );
331    end
332
333else
334   
335    dimname = varargin{1};
336    dimid = netcdf.inqDimID(ncid, dimname );
337   
338end
339   
340[dud,dimlen] = netcdf.inqDim(ncid, dimid );
341netcdf.close(ncid);
342
343   
344%--------------------------------------------------------------------------
345function [dimname, dimlen, dimid] = get_unlimdim_info_mexnc ( ncfile, varargin )
346[ncid,status ]=mexnc( 'open', ncfile, nc_nowrite_mode );
347if status ~= 0
348    mexnc('close',ncid);
349    ncerr = mexnc ( 'strerror', status );
350    error ( 'SNCTOOLS:NC_ADD_RECS:openFailed', ncerr );
351end
352
353
354
355%
356% If we were not given the name of an unlimited dimension, get it now
357if nargin < 2
358    [dimid, status] = mexnc ( 'inq_unlimdim', ncid );
359    if status ~= 0
360        mexnc('close',ncid);
361        ncerr = mexnc ( 'strerror', status );
362        error ( 'SNCTOOLS:NC_ADD_RECS:inq_unlimdimFailed', ncerr );
363    end
364
365    [dimname, status] = mexnc ( 'INQ_DIMNAME', ncid, dimid );
366    if status ~= 0
367        mexnc('close',ncid);
368        ncerr = mexnc ( 'strerror', status );
369        error ( 'SNCTOOLS:NC_ADD_RECS:inq_dimnameFailed', ncerr );
370    end
371
372    if dimid == -1
373        error_id = 'SNCTOOLS:NC_ADD_RECS:noUnlimitedDimension';
374        error ( error_id, '%s is missing an unlimited dimension, %s requires it', ncfile, mfilename );
375    end
376
377
378else
379   
380    dimname = varargin{1};
381    [dimid, status] = mexnc ( 'inq_dimid', ncid, dimname );
382    if status ~= 0
383        mexnc('close',ncid);
384        ncerr = mexnc ( 'strerror', status );
385        error ( 'SNCTOOLS:NC_ADD_RECS:inq_dimid', ncerr );
386    end
387   
388end
389   
390[dimlen, status] = mexnc ( 'INQ_DIMLEN', ncid, dimid );
391if status ~= 0
392    mexnc('close',ncid);
393    ncerr = mexnc ( 'strerror', status );
394    error ( 'SNCTOOLS:NC_ADD_RECS:inq_dimlenFailed', ncerr );
395end
396
397status = mexnc('close',ncid);
398if status ~= 0
399    ncerr = mexnc ( 'strerror', status );
400    error ( 'SNCTOOLS:NC_ADD_RECS:closeFailed', ncerr );
401end
402
403
404return
405
406
407
Note: See TracBrowser for help on using the repository browser.