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

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

import Roms_Agrif

File size: 5.1 KB
Line 
1function nc_cat_a ( input_ncfiles, output_ncfile, abscissa_var )
2% NC_CAT_A:  concatentates a set of netcdf files into ascending order
3%
4% The concatenation is done only along unlimited variable, which by
5% definition have an unlimited dimension.  Variables which do NOT have
6% an unlimited dimension are copied over from the first of the input
7% netcdf input files.
8%
9% This m-file is not meant as a replacement for ncrcat or any of Charles
10% Zender's terrific NCO tools.  If you need NCO functionality, you should
11% get NCO tools from http://nco.sourceforge.net
12%
13% USAGE:  nc_cat_a ( input_ncfiles, output_ncfile, abscissa_var )
14%
15% PARAMETERS:
16%   Input:
17%       input_ncfiles:
18%           This can be either a cell array of netcdf files, or a text
19%           file with one netcdf file per line
20%       output_ncfile:
21%           This file will be generated from scratch.
22%       abscissa_var:
23%           Name of an unlimited variable.  Supposing we are dealing
24%           with time series, then a good candidate for this would
25%           be a variable called, oh, I don't know, maybe "time". 
26%   Output:
27%       None.  An exception is thrown in case of an error.
28%
29% The best way to explain this is with simple examples.  Suppose that
30% the abscissa_var is "time" and that the other netcdf variable is "tsq".
31% Suppose that the first netcdf file has files for "time" and "tsq" of
32%
33%      time: 0 2  4
34%      tsq:  0 4 16
35%
36% Suppose the 2nd netcdf file has values of
37%
38%      time:  4  6  8
39%      tsq:  18 36 64
40%
41% Note that the 2nd time series has a different value of "tsq" for the
42% abscissa value of 4.
43%
44% Running nc_cat_asc will produce a single time series of
45%
46%      time:  0   2   4   6   8
47%      tsq:   0   4  18  36  64
48%
49% In other words, the 2nd netcdf file's abscissa/ordinate values take
50% precedence.  So the order of your netcdf files matter, and the output
51% netcdf file will have unique abscissa values.
52
53%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54%
55% $Id:$
56% $LastChangedDate:$
57% $LastChangedRevision:$
58% $LastChangedBy:$
59%
60%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
61
62
63
64error(nargchk(3,3,nargin,'struct'));
65error(nargoutchk(0,0,nargout,'struct'));
66
67
68%
69% If the first input is of type char and is a file, then read it in.
70% At the end of this process, the list of netcdf files to be
71% concatenated is in a cell array.
72if ischar(input_ncfiles) && exist(input_ncfiles,'file')
73
74    afid = fopen ( input_ncfiles, 'r' );
75    x = textscan ( afid, '%s' );
76    input_ncfiles = x{1};
77
78elseif iscell ( input_ncfiles )
79
80    %
81    % Do nothing
82
83else
84    error ( 'first input must be either a text file or a cell array\n' );
85end
86
87num_input_files = length(input_ncfiles);
88
89
90%
91% This is how close the abscissa variable values have to be before they
92% are considered to be the same value.
93tol = 10*eps;
94
95
96%
97% Now construct the empty output netcdf file.
98ncm = nc_info ( input_ncfiles{1} );
99mode = nc_clobber_mode;
100
101nc_create_empty(output_ncfile,mode);
102
103
104%
105% Add the dimensions.
106for d = 1:length(ncm.Dimension)
107    if ncm.Dimension(d).Unlimited
108        nc_add_dimension ( output_ncfile, ncm.Dimension(d).Name, 0 );
109    else
110        nc_add_dimension ( output_ncfile, ncm.Dimension(d).Name, ncm.Dimension(d).Length );
111    end
112end
113
114%
115% Add the variables
116for v = 1:length(ncm.Dataset)
117    nc_addvar ( output_ncfile, ncm.Dataset(v) );
118
119    %
120    % If the variable is NOT unlimited, then we can copy over
121    % its data now
122    if ~ncm.Dataset(v).Unlimited
123        vardata = nc_varget ( input_ncfiles{1}, ncm.Dataset(v).Name );
124        nc_varput ( output_ncfile, ncm.Dataset(v).Name, vardata );
125    end
126end
127
128
129%
130% Go thru and figure out how much data we are looking at,
131% then pre-allocate for speed.
132total_length = 0;
133for j = 1:num_input_files
134    sz = nc_varsize ( input_ncfiles{j}, abscissa_var );
135    total_length = total_length + sz;
136end
137
138abscissa_vardata = NaN*ones(total_length,1);
139file_index = NaN*ones(total_length,1);
140infile_abscissa_varindex = NaN*ones(total_length,1);
141
142
143
144%
145% Now read in the abscissa variable for each file.
146start_index = 1;
147for j = 1:num_input_files
148    v = nc_varget ( input_ncfiles{j}, abscissa_var );
149    nv = length(v);
150
151    end_index = start_index + nv - 1;
152    inds = start_index:end_index;
153
154    abscissa_vardata(inds) = v;
155    file_index(inds) = j*ones(nv,1);
156    infile_abscissa_varindex(inds) = (0:nv-1)';
157
158    start_index = start_index + nv;
159end
160
161
162%
163% Sort the ascissa_vardata into ascending order. 
164[abscissa_vardata,I] = sort ( abscissa_vardata );
165file_index = file_index(I);
166infile_abscissa_varindex = infile_abscissa_varindex(I);
167
168%
169% Are there any duplicates?
170ind = find ( diff(abscissa_vardata) < tol );
171if ~isempty(ind)
172    abscissa_vardata(ind) = [];
173    file_index(ind) = [];
174    infile_abscissa_varindex(ind) = [];
175end
176
177
178%
179% So now go thru each record and append it to the output file and we
180% are done.
181for j = 1:length(abscissa_vardata)
182    ncfile = input_ncfiles{file_index(j)};
183    start = infile_abscissa_varindex(j);
184    input_record = nc_getbuffer ( ncfile, start, 1 );
185    nc_addnewrecs ( output_ncfile, input_record, abscissa_var );
186end
187
Note: See TracBrowser for help on using the repository browser.