Home > utilities > read_netCDF_FVCOM.m

read_netCDF_FVCOM

PURPOSE ^

Function to extract data from a Netcdf file output from FVCOM.

SYNOPSIS ^

function [data,selection] = read_netCDF_FVCOM(varargin)

DESCRIPTION ^

 Function to extract data from a Netcdf file output from FVCOM.

 data = read_netCDF_FVCOM(varargin)

 DESCRIPTION:
    Function to extract data from a netCDF file output from FVCOM. Outputs
    data in cell array.

 INPUT [keyword pairs]:
   Options are passed in pairs.

   The list of keywords is:
       - 'time'
       - 'data_dir'
       - 'file_netcdf'
       - 'varnames'
       - 'nele_idx'
       - 'node_idx'
       - 'siglay_idx'
       - 'siglev_idx'

   'time' - {'30/01/06 00:00:00', '01/02/06 23:00:00'} or -1 to extract
   all times.

   'data_dir' - '/home/fvcom/results/...' directory where netCDF file is.
   Default value is ../fvcom_postproc/netcdf

   'file_netcdf' - 'filename.nc'. Default value is '*.nc', but it only
   access the first file in alphabetical order in the directory.

   'varnames' - Cell array of variable names to read from the netCDF file.
   The variables need to exist in the file but they are case insensitive.
   Choose FVCOM output variable names. For example:
       - 'Itime'
       - 'Itime2'
       - 'xc'
       - 'yc'
       - 'art1'
       - 'art2'
       - 'h'
       - 'siglay'
       - 'siglev'
       - 'nv'
       - 'zeta'
       - 'ua'
       - 'va'
   The complete list for a given file is given by running this script with
   varnames set to [].

   The variables can be restricted in five possible dimensions:
       - 'node_idx'
       - 'nele_idx'
       - 'siglev_idx'
       - 'siglay_idx'
       - 'time_idx'
   Default values cause the script to extract all available data for all
   possible dimensions. No checks are done on the bounds of each dimension
   so make sure you choose them right!

 OUTPUT:
    data = struct with fields whose names match those from the list of
    input variables extracted ('varnames').

 EXAMPLE USAGE
   vars = {'Times', 'xc', 'yc', 'h', 'siglay', 'nv', 'zeta', 'ua', 'va'};
   date_range = {'30/01/06 00:00:00', '15/02/06 23:00:00'};
   node_idx = [10:30, 40:50]; % zero referenced!
   data_dir = '/home/fvcom/results/output/';
   FVCOM = read_netCDF_FVCOM('data_dir', data_dir, ...
       'file_netcdf', 'casename_0001.nc', ...
       'time', date_range, ...
       'siglev_idx', 1, ...
       'node_idx', node_idx, ...
       'varnames', vars);

 BUGS:
   - When loading all times with the argument pair:
       'time', -1
     the returned time series is nt - 1 (where nt is the number of time
     steps in the netCDF file). Not sure where this is broken, but
     probably around line 377.

 Author(s):
   Ricardo Torres - Plymouth Marine Laboratory 2012
   Hakeem Johnson - CH2M
   Pierre Cazenave - Plymouth Marine Laboratory

 Revision history:
   v0 March 2012
   2014-03-06 - Add the global verbose flag. Also tidy up the help a bit.
   Also change some verbose statements to use fprintf instead of disp for
   better control over formatting. Also fixed a bug where if a 2D array
   was requested after a 3D array, the 2D array would cause the function
   to crash (because it was using a 3D index for getVar).
   2014-08-20 - Complete the functionality to be able to slice the data
   along any dimension (siglay, time, node etc.).
   2014-10-17 - Fix ability to slice with any combination of space
   (horizontal and vertical) and time.

==========================================================================

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [data,selection] = read_netCDF_FVCOM(varargin)
0002 % Function to extract data from a Netcdf file output from FVCOM.
0003 %
0004 % data = read_netCDF_FVCOM(varargin)
0005 %
0006 % DESCRIPTION:
0007 %    Function to extract data from a netCDF file output from FVCOM. Outputs
0008 %    data in cell array.
0009 %
0010 % INPUT [keyword pairs]:
0011 %   Options are passed in pairs.
0012 %
0013 %   The list of keywords is:
0014 %       - 'time'
0015 %       - 'data_dir'
0016 %       - 'file_netcdf'
0017 %       - 'varnames'
0018 %       - 'nele_idx'
0019 %       - 'node_idx'
0020 %       - 'siglay_idx'
0021 %       - 'siglev_idx'
0022 %
0023 %   'time' - {'30/01/06 00:00:00', '01/02/06 23:00:00'} or -1 to extract
0024 %   all times.
0025 %
0026 %   'data_dir' - '/home/fvcom/results/...' directory where netCDF file is.
0027 %   Default value is ../fvcom_postproc/netcdf
0028 %
0029 %   'file_netcdf' - 'filename.nc'. Default value is '*.nc', but it only
0030 %   access the first file in alphabetical order in the directory.
0031 %
0032 %   'varnames' - Cell array of variable names to read from the netCDF file.
0033 %   The variables need to exist in the file but they are case insensitive.
0034 %   Choose FVCOM output variable names. For example:
0035 %       - 'Itime'
0036 %       - 'Itime2'
0037 %       - 'xc'
0038 %       - 'yc'
0039 %       - 'art1'
0040 %       - 'art2'
0041 %       - 'h'
0042 %       - 'siglay'
0043 %       - 'siglev'
0044 %       - 'nv'
0045 %       - 'zeta'
0046 %       - 'ua'
0047 %       - 'va'
0048 %   The complete list for a given file is given by running this script with
0049 %   varnames set to [].
0050 %
0051 %   The variables can be restricted in five possible dimensions:
0052 %       - 'node_idx'
0053 %       - 'nele_idx'
0054 %       - 'siglev_idx'
0055 %       - 'siglay_idx'
0056 %       - 'time_idx'
0057 %   Default values cause the script to extract all available data for all
0058 %   possible dimensions. No checks are done on the bounds of each dimension
0059 %   so make sure you choose them right!
0060 %
0061 % OUTPUT:
0062 %    data = struct with fields whose names match those from the list of
0063 %    input variables extracted ('varnames').
0064 %
0065 % EXAMPLE USAGE
0066 %   vars = {'Times', 'xc', 'yc', 'h', 'siglay', 'nv', 'zeta', 'ua', 'va'};
0067 %   date_range = {'30/01/06 00:00:00', '15/02/06 23:00:00'};
0068 %   node_idx = [10:30, 40:50]; % zero referenced!
0069 %   data_dir = '/home/fvcom/results/output/';
0070 %   FVCOM = read_netCDF_FVCOM('data_dir', data_dir, ...
0071 %       'file_netcdf', 'casename_0001.nc', ...
0072 %       'time', date_range, ...
0073 %       'siglev_idx', 1, ...
0074 %       'node_idx', node_idx, ...
0075 %       'varnames', vars);
0076 %
0077 % BUGS:
0078 %   - When loading all times with the argument pair:
0079 %       'time', -1
0080 %     the returned time series is nt - 1 (where nt is the number of time
0081 %     steps in the netCDF file). Not sure where this is broken, but
0082 %     probably around line 377.
0083 %
0084 % Author(s):
0085 %   Ricardo Torres - Plymouth Marine Laboratory 2012
0086 %   Hakeem Johnson - CH2M
0087 %   Pierre Cazenave - Plymouth Marine Laboratory
0088 %
0089 % Revision history:
0090 %   v0 March 2012
0091 %   2014-03-06 - Add the global verbose flag. Also tidy up the help a bit.
0092 %   Also change some verbose statements to use fprintf instead of disp for
0093 %   better control over formatting. Also fixed a bug where if a 2D array
0094 %   was requested after a 3D array, the 2D array would cause the function
0095 %   to crash (because it was using a 3D index for getVar).
0096 %   2014-08-20 - Complete the functionality to be able to slice the data
0097 %   along any dimension (siglay, time, node etc.).
0098 %   2014-10-17 - Fix ability to slice with any combination of space
0099 %   (horizontal and vertical) and time.
0100 %
0101 %==========================================================================
0102 
0103 global ftbverbose
0104 subname = 'read_netCDF_FVCOM';
0105 
0106 if ftbverbose
0107     fprintf('\nbegin : %s \n', subname)
0108 end
0109 
0110 %--------------------------------------------------------------------------
0111 %  Parse input arguments
0112 %--------------------------------------------------------------------------
0113 
0114 params_opts = {'time', 'data_dir', 'file_netcdf', 'varnames', 'nele_idx', ...
0115     'node_idx', 'siglay_idx', 'siglev_idx', 'timestride'};
0116 
0117 if ftbverbose
0118     fprintf('Input parameters being used are:\n')
0119 end
0120 var_in_list = {'all_data', 'netfile_dir', 'file_netcdf', 'varnames', ...
0121     'nele_idx', 'node_idx', 'siglay_idx', 'siglev_idx', 'timestrd'};
0122 all_data = 1;
0123 netfile_dir = '../fvcom_postproc/netcdf';
0124 file_netcdf='*.nc';
0125 siglay_idx=-1;
0126 siglev_idx=-1;
0127 nele_idx=-1;
0128 node_idx=-1;
0129 time_idx=-1;
0130 varnames={};
0131 timestrd=1;
0132 for aa=1:2:nargin
0133     res=strcmp(varargin(aa),params_opts);
0134     if sum(res)
0135         eval([var_in_list{res},' = varargin{aa+1};'])
0136         if ftbverbose
0137             fprintf(' %s\n', params_opts{res})
0138         end
0139     end
0140 end
0141 
0142 %--------------------------------------------------------------------------
0143 % Sort (and remove repeats) for all indices elements, nodes or layers
0144 %--------------------------------------------------------------------------
0145 nele_idx=unique(nele_idx);
0146 node_idx=unique(node_idx);
0147 siglay_idx=unique(siglay_idx);
0148 siglev_idx=unique(siglev_idx);
0149 
0150 RestrictDims.Name={'node' 'nele' 'siglay' 'siglev' 'time'};
0151 RestrictDims.idx={node_idx, nele_idx, siglay_idx, siglev_idx, time_idx};
0152 
0153 if ~isempty(varnames)
0154     nvarnames = length(varnames);
0155     for nn=1:nvarnames
0156         data.(varnames{nn}) = [];
0157     end
0158 end
0159 
0160 %--------------------------------------------------------------------------
0161 % Open netcdf file
0162 %--------------------------------------------------------------------------
0163 file_netcdf=fullfile(netfile_dir, file_netcdf);
0164 filesINdir=dir(file_netcdf);
0165 file_netcdf= fullfile(netfile_dir,filesINdir(1).name);
0166 nc = netcdf.open(file_netcdf, 'NC_NOWRITE');
0167 [PATHSTR,NAME,EXT] = fileparts(file_netcdf)
0168 
0169 if ftbverbose
0170         fprintf('NetCDF file %s opened successfully.\n', NAME)
0171 end
0172 % Get information from netcdf file
0173 info=ncinfo(file_netcdf);
0174 % Extract all possible dimensions in file
0175 DimsAll=info.Dimensions;
0176 % Extract variable names in  nc file
0177 Vars=struct2cell(info.Variables);
0178 vars = squeeze(Vars(1,:,:));
0179 
0180 %--------------------------------------------------------------------------
0181 % Find variable Itime
0182 %--------------------------------------------------------------------------
0183 if ftbverbose
0184     fprintf('Using date conversion of +678942 days to go from FVCOM time (Modified Julian Day) to MATLAB time.\n')
0185 end
0186 time_offset = 678942;
0187 idx=find(strcmpi(cat(1,{DimsAll.Name}),'time'));
0188 last_entry=DimsAll(idx).Length;
0189 Itime=[];Itime2=[];
0190 % tic
0191 try
0192     % use character time instead
0193   
0194 
0195     Itime.idx=find(strcmpi(vars,'Times'));
0196     Itime.ID=netcdf.inqVarID(nc,'Times');
0197     Itime.sData=ncread(file_netcdf,'Times')
0198     Itime.Data(1) = datenum(Itime.sData(:,1)','yyyy-mm-ddTHH:MM:SS');
0199 %     Itime.Data(2) = datenum(Itime.sData(:,end-1)','yyyy-mm-ddTHH:MM:SS');
0200     Itime.Data(2) = datenum(Itime.sData(:,end)','yyyy-mm-ddTHH:MM:SS');
0201     start_date= Itime.Data(1);
0202     end_date = Itime.Data(2);
0203 %     var_time = datenum(Itime.sData(:,1:end-1)','yyyy-mm-ddTHH:MM:SS');
0204     var_time = datenum(Itime.sData(:,1:end)','yyyy-mm-ddTHH:MM:SS');
0205 %     Itime.idx=find(strcmpi(vars,'Itime'));
0206 %     Itime.ID=netcdf.inqVarID(nc,'Itime');
0207 %     Itime.Data(1)  = netcdf.getVar(nc,Itime.ID,0,1,'int32');
0208 %     Itime.Data(2)  = netcdf.getVar(nc,Itime.ID,last_entry-1,1,'int32');
0209 %     Itime2.Data(1)  = netcdf.getVar(nc,Itime.ID+1,0,1,'int32');
0210 %     Itime2.Data(2)  = netcdf.getVar(nc,Itime.ID+1,last_entry-1,1,'int32');
0211 %
0212 %     [start_d(1),end_d(1)] = deal(double(Itime.Data(1))+time_offset,double(Itime.Data(end))+time_offset);
0213 %     [start_d(2),end_d(2)] = deal(double(Itime2.Data(1)),double(Itime2.Data(end)));
0214 %
0215 %     start_date=sum(start_d.*[1 1/(24*60*60*1000)]);     %hkj missing 1000 inserted
0216 %     end_date = sum(end_d.*[1 1/(24*60*60*1000)]);       %hkj missing 1000 inserted
0217 %     var_time =  netcdf.getVar(nc,Itime.ID,[0],[min(last_entry,10)],'double')+time_offset+...
0218 %         netcdf.getVar(nc,Itime.ID+1,0,min(last_entry,10),'double')./(24*600*6000) ;
0219 %
0220 %     DeltaT=median(diff(var_time));
0221 %     var_time = start_date:DeltaT:(end_date-DeltaT);
0222 
0223 catch me
0224     if ftbverbose
0225         warning('No ''Itime'' and/or ''Itime2'' variables, using less precise ''time'' instead.\n(%s)\n', me.message)
0226     end
0227     Itime.idx=find(strcmpi(vars,'time'));
0228     Itime.ID=netcdf.inqVarID(nc,'time');
0229     Itime.Data(1)  = netcdf.getVar(nc,Itime.ID,0,1,'double');
0230 %     Itime.Data(2)  = netcdf.getVar(nc,Itime.ID,last_entry-1,1,'double');
0231     Itime.Data(2)  = netcdf.getVar(nc,Itime.ID,last_entry,1,'double');
0232     [start_date,end_date] = deal(Itime.Data(1)+time_offset,Itime.Data(end)+time_offset);
0233     DeltaT=(end_date-start_date)./last_entry;
0234     var_time = start_date:DeltaT:(end_date-DeltaT);
0235 end
0236 % toc
0237 if length(all_data) == 2
0238     req_st = datenum(all_data{1},'dd/mm/yy HH:MM:SS');
0239     req_end = datenum(all_data{2},'dd/mm/yy HH:MM:SS');
0240 else
0241     req_st = start_date;
0242     req_end =end_date;
0243 end
0244 time_idx = find(req_st <= var_time &   var_time <= req_end );
0245 time_idx = time_idx(1:timestrd:end);
0246 % Add correct time_idx to RestrictDims
0247 RestrictDims.idx{end}=time_idx;
0248 if ftbverbose
0249     fprintf('Start and end of file: %s - %s\n', datestr(start_date), datestr(end_date))
0250 end
0251 
0252 %--------------------------------------------------------------------------
0253 % Return information about file to the screen
0254 %--------------------------------------------------------------------------
0255 
0256 if ftbverbose
0257     fprintf('Possible variables to extract are:\n')
0258 end
0259 for ii = 1:length(vars)
0260     if ftbverbose
0261         fprintf(' %s\n', vars{ii})
0262     end
0263 end
0264 if isempty(varnames)
0265     data = 0;
0266     netcdf.close(nc)
0267     error('Stopping. Choose a variable from the list above.')
0268 end
0269 
0270 %--------------------------------------------------------------------------
0271 % Re-organise RestrictDims to follow order of dimensions in nc file from
0272 % FVCOM
0273 %--------------------------------------------------------------------------
0274 cc=1;
0275 for dd=1:length(DimsAll)
0276     idx=find(strcmpi(RestrictDims.Name,DimsAll(dd).Name));
0277     if ~isempty(idx)
0278         TEMP{cc}=RestrictDims.Name{idx};
0279         TEMPidx{cc}=RestrictDims.idx{idx};
0280         cc=cc+1;
0281     end
0282 end
0283 RestrictDims.Name = TEMP;
0284 RestrictDims.idx = TEMPidx;
0285 clear TEMP TEMPidx
0286 
0287 %--------------------------------------------------------------------------
0288 % Start Processing extraction of data from NC file
0289 %--------------------------------------------------------------------------
0290 selection=[];
0291 for aa=1:length(varnames)
0292     selection.(varnames{aa}).start=-1;
0293     selection.(varnames{aa}).count=-1;
0294     %----------------------------------------------------------------------
0295     % Extract number of dimensions, lengths and names of all variables
0296     %----------------------------------------------------------------------
0297 % tic
0298     if ftbverbose
0299         fprintf('Processing variable %s: ', varnames{aa})
0300     end
0301     % Tidy up the previous iteration's variables so we don't get confused.
0302     clear dimName dimLength
0303 
0304     TF = strcmpi(varnames{aa},vars);
0305     if ~isempty(find(TF));
0306         varidx(aa) = find(TF);
0307         TF = sum(TF);
0308         dimens=ndims(aa);
0309     else
0310         netcdf.close(nc)
0311         varargout{1} = 0;
0312         if ftbverbose; fprintf('\n'); end
0313         error('Variable %s NOT found in file. Stopping. Check input variable names.', varnames{aa})
0314     end
0315     varID=netcdf.inqVarID(nc,vars{varidx(aa)});
0316 
0317     [name,xtype,dimids,natts] = netcdf.inqVar(nc,varID);
0318     dimens=length(dimids);
0319 
0320     for dd=1:length(dimids)
0321         [dimName{dd}, dimLength(dd)] = netcdf.inqDim(nc,dimids(dd));
0322         if ftbverbose
0323             if dd == 1
0324                 if length(dimids) == 1
0325                     if ftbverbose
0326                         fprintf('%i dimension: %s ', dimens, dimName{dd})
0327                     end
0328                 else
0329                     if ftbverbose
0330                         fprintf('%i dimensions: %s ', dimens, dimName{dd})
0331                     end
0332                 end
0333             else
0334                 if ftbverbose
0335                     fprintf('%s ', dimName{dd})
0336                 end
0337             end
0338         end
0339     end
0340     if ftbverbose; fprintf('\n'); end
0341 
0342     %----------------------------------------------------------------------
0343     % Get the data!
0344     %----------------------------------------------------------------------
0345 
0346     switch dimens
0347         case 1
0348             % only one dimension present in variable
0349             switch dimName{1}
0350                 case 'time'
0351                     if time_idx>=0
0352                         % Only restrict data on access if dimension is TIME
0353 
0354                         % hkj it appears the first value in matlab netcdf
0355                         % interface is 0.
0356                         % hkj time_idx(1) CORRECTED TO time_idx(1)-1.
0357                         eval([varnames{aa},'=netcdf.getVar(nc,varID,time_idx(1)-1,length(time_idx),timestrd,''double'');'])
0358                     end
0359                 case 'nele'
0360                     eval([varnames{aa},'=netcdf.getVar(nc,varID,''double'');'])
0361                     if nele_idx>=0
0362                         eval([varnames{aa},' = ',varnames{aa},'(nele_idx);'])
0363                     end
0364                 case 'node'
0365                     eval([varnames{aa},'=netcdf.getVar(nc,varID,''double'');'])
0366                     if node_idx>=0
0367                         eval([varnames{aa},' = ',varnames{aa},'(node_idx);'])
0368                     end
0369                 otherwise
0370                     if ftbverbose
0371                         fprintf('Unkown dimension for variable %s. Skipping to next one in function call.\n', name);
0372                     end
0373             end
0374         otherwise
0375             % identified dimensions to restrict
0376             do_restrict=zeros(size(dimName));
0377             dimidx=nan(size(dimName));
0378             clear start count stride
0379             for dd=1:length(dimName)
0380                 start.(dimName{dd})=[];
0381                 count.(dimName{dd})=[];
0382                 stride.(dimName{dd})=[];
0383                 test=find(strcmpi(RestrictDims.Name,dimName{dd}));
0384                 if ~isempty(test); dimidx(dd)=test; end
0385             end
0386             % create start index for dimensions of the variable to
0387             % access
0388             if any(isfinite(dimidx))
0389                 % we have at least two valid dimension indices, proceed
0390                 for dd=1:length(dimidx)
0391                     % restrict time as range but node and nele dims are
0392                     % considered as stations rather than ranges.
0393                     % if restriction is not -1 then select specified
0394                     % indices otherwise read all
0395                     if ~isnan(dimidx(dd)) && RestrictDims.idx{dimidx(dd)}(1)>=0
0396                         if (strcmpi(dimName(dd),'time'))
0397                             start.(dimName{dd})=RestrictDims.idx{dimidx(dd)}(1)-1;
0398                             count.(dimName{dd})=length(RestrictDims.idx{dimidx(dd)});
0399                             stride.(dimName{dd})=timestrd;
0400 
0401                         else
0402                             for ss=1:length(RestrictDims.idx{dimidx(dd)})
0403                                 start.(dimName{dd})(ss)=RestrictDims.idx{dimidx(dd)}(ss)-1;
0404                                 count.(dimName{dd})(ss)=1;
0405                                 stride.(dimName{dd})=1;
0406                             end
0407                         end
0408                         do_restrict(dd)=1;
0409                     else
0410                         start.(dimName{dd})=0;
0411                         count.(dimName{dd})=dimLength(dd);
0412                         stride.(dimName{dd})=1;
0413                     end
0414                 end
0415             else
0416                 if ftbverbose
0417                     fprintf('Wrong selection of dimensions to extract.\nExtracting all values in current variable.\n');
0418                 end
0419             end
0420             %
0421             %             eval([varnames{aa},'=netcdf.getVar(nc,varID,start,count,''double'');'])
0422             cc_names=fieldnames(count);
0423             clear read_start read_count read_stride
0424             switch sum(do_restrict) % there are dimensions to restrict
0425                 case 1 % only one dimension to restrict
0426                     switch find(do_restrict) % find position of restrictive variable
0427                         case 1 % restrict the first variable
0428                             % but the variable can have more than 2 dimensions
0429                             switch dimens
0430                                 % initialise variable
0431                                 case 2
0432                                     rr=[min(sum(count.(cc_names{1})),dimLength(1)) min(sum(count.(cc_names{2})),dimLength(2))];
0433                                 case 3
0434                                     rr=[min(sum(count.(cc_names{1})),dimLength(1)),...
0435                                         min(sum(count.(cc_names{2})),dimLength(2)),...
0436                                         min(sum(count.(cc_names{3})),dimLength(3))];
0437                             end
0438 
0439                             eval([varnames{aa},'=nan(rr);'])
0440                             % reorganize start and count arrays
0441                             read_start(find(~do_restrict))=start.(cc_names{find(~do_restrict)});
0442                             read_count(find(~do_restrict))=count.(cc_names{find(~do_restrict)});
0443                             read_stride(find(~do_restrict))=stride.(cc_names{find(~do_restrict)});
0444 
0445                             for cc=1:length(start.(cc_names{find(do_restrict)}))
0446                                 read_start(find(do_restrict))=start.(cc_names{find(do_restrict)})(cc);
0447                                 read_count(find(do_restrict))=count.(cc_names{find(do_restrict)})(cc);
0448                                 read_stride(find(do_restrict))=stride.(cc_names{find(do_restrict)});
0449 
0450                                 var_dump=netcdf.getVar(nc,varID,read_start,read_count,read_stride,'double');
0451 
0452                                 eval([varnames{aa},'(cc,:)=var_dump;'])
0453                                 clear var_dump
0454                             end
0455                         case 2 % restrict the second variable (ie depth)
0456                             % but the variable can have more than 2 dimensions
0457                             switch dimens
0458                                 % initialise variable
0459                                 case 2
0460                                     rr=[min(sum(count.(cc_names{1})),dimLength(1)) min(sum(count.(cc_names{2})),dimLength(2))];
0461                                 case 3
0462                                     rr=[min(sum(count.(cc_names{1})),dimLength(1)),...
0463                                         min(sum(count.(cc_names{2})),dimLength(2)),...
0464                                         min(sum(count.(cc_names{3})),dimLength(3))];
0465                             end
0466 
0467                             eval([varnames{aa},'=nan(rr);'])
0468                             % reorganize start and count arrays
0469                             read_start(find(~do_restrict))=start.(cc_names{find(~do_restrict)});
0470                             read_count(find(~do_restrict))=count.(cc_names{find(~do_restrict)});
0471                             read_stride(find(~do_restrict))=stride.(cc_names{find(~do_restrict)});
0472 
0473                             for cc=1:length(start.(cc_names{logical(do_restrict)}))
0474                                 read_start(find(do_restrict))=start.(cc_names{find(do_restrict)})(cc);
0475                                 read_count(find(do_restrict))=count.(cc_names{find(do_restrict)})(cc);
0476                                 read_stride(find(do_restrict))=stride.(cc_names{find(do_restrict)});
0477                                 var_dump=netcdf.getVar(nc,varID,read_start,read_count,read_stride,'double');
0478                                 try
0479                                     eval([varnames{aa},'(:,cc)=var_dump;'])
0480                                 catch
0481                                     eval([varnames{aa},'(:,:,cc)=var_dump;'])
0482 
0483                                 end
0484                                 clear var_dump
0485                             end
0486                         case 3 % restrict the second variable (ie depth)
0487                             % but the variable needs to have at least 3 dimensions
0488                             rr=[min(sum(count.(cc_names{1})),dimLength(1)),...
0489                                 min(sum(count.(cc_names{2})),dimLength(2)),...
0490                                 min(sum(count.(cc_names{3})),dimLength(3))];
0491 
0492                             eval([varnames{aa},'=nan(rr);'])
0493                             % reorganize start and count arrays
0494                             % There are now 2 unrestricted dimensions
0495                             for tt=find(~do_restrict)
0496                                 read_start(tt)=start.(cc_names{tt});
0497                                 read_count(tt)=count.(cc_names{tt});
0498                                 read_stride(tt)=stride.(cc_names{tt});
0499 
0500                             end
0501 
0502                             % check if time is one of them
0503                             if ~isempty(find(dimidx==5))
0504                                 do_time = find(dimidx==5); % 5 is the index for time
0505                                 % reorganize start and count arrays
0506                                 read_start(do_time)=start.(cc_names{do_time});
0507                                 read_count(do_time)=count.(cc_names{do_time});
0508                                 read_stride(do_time)=stride.(cc_names{do_time});
0509                                 eval([varnames{aa},'=netcdf.getVar(nc,varID,read_start,read_count,read_stride,''double'');'])
0510                             else % we are looking at stations or depth layers
0511                                 for cc=1:length(start.(cc_names{find(do_restrict)}))
0512                                     read_start(find(do_restrict))=start.(cc_names{find(do_restrict)})(cc);
0513                                     read_count(find(do_restrict))=count.(cc_names{find(do_restrict)})(cc);
0514                                     read_stride(find(do_restrict))=stride.(cc_names{find(do_restrict)});
0515                                     var_dump=netcdf.getVar(nc,varID,read_start,read_count,read_stride,'double');
0516 
0517                                     switch dimName{find(do_restrict)}
0518                                         case 'node' | 'nele'
0519                                             eval([varnames{aa},'(cc,:,:)=var_dump;'])
0520                                         case 'siglay' | 'siglev'
0521                                             eval([varnames{aa},'(:,cc,:)=var_dump;'])
0522                                         case 'time' % this only happens if we only have one timestamp
0523                                             eval([varnames{aa},'=var_dump;'])
0524 
0525                                     end
0526                                     clear var_dump
0527                                 end
0528 
0529                             end
0530                     end
0531                     eval(['selection.',varnames{aa},'.start=start;'])
0532                     eval(['selection.',varnames{aa},'.count=count;'])
0533 
0534                 case 2 % Two dimension to restrict!
0535                     % but the variable can have more than 2 dimensions
0536                     switch dimens
0537                         % initialise variable
0538                         case 2
0539                             rr=[min(sum(count.(cc_names{1})),dimLength(1)) min(sum(count.(cc_names{2})),dimLength(2))];
0540                         case 3
0541                             rr=[min(sum(count.(cc_names{1})),dimLength(1)),...
0542                                 min(sum(count.(cc_names{2})),dimLength(2)),...
0543                                 min(sum(count.(cc_names{3})),dimLength(3))];
0544                     end
0545 
0546                     eval([varnames{aa},'=nan(rr);'])
0547                     % check if time is one of them
0548                     if ~isempty(find(dimidx==5))
0549                         do_time = find(dimidx==5); % 5 is the index for time
0550                         % reorganize start and count arrays
0551                         read_start(do_time)=start.(cc_names{do_time});
0552                         read_count(do_time)=count.(cc_names{do_time});
0553                         read_stride(do_time)=stride.(cc_names{do_time});
0554                         % search for the non_restrictive variable
0555                         %                         cc=1
0556                         %                         while ~(length( start.(cc_names{cc}))==1);cc=cc+1;end
0557                         % esto esta mal.... tengo que incluir otra opcion por si tenemos una
0558                         % variable de dos dimensiones donde los dos son restrictivas....
0559                         cc=find(~do_restrict);
0560                         if isempty(cc);cc=length(cc_names);end
0561                         read_start(cc)=start.(cc_names{cc});
0562                         read_count(cc)=count.(cc_names{cc});
0563                         read_stride(cc)=stride.(cc_names{cc});
0564                         do_other = setdiff(dimidx,[dimidx(cc),5]) ; % one of these is also restrictive...
0565                         do_other=find(dimidx==do_other);
0566 
0567                         for cc=1:length(start.(cc_names{do_other}))
0568                             read_start(do_other)=start.(cc_names{do_other})(cc);
0569                             read_count(do_other)=count.(cc_names{do_other})(cc);
0570                             read_stride(do_other)=stride.(cc_names{do_other});
0571                             var_dump=netcdf.getVar(nc,varID,read_start,read_count,read_stride,'double');
0572                             switch do_other
0573                                 case 1
0574                                     eval([varnames{aa},'(cc,:,:)=var_dump;'])
0575                                 case 2
0576                                     eval([varnames{aa},'(:,cc,:)=var_dump;'])
0577                                 case 3
0578                                     eval([varnames{aa},'(:,:,cc)=var_dump;'])
0579                             end
0580                             clear var_dump
0581                         end
0582                     else % time is not one of them so we need to restrict both variables...
0583                         % in this case it doesn't really matter
0584                         % which one we restrict firts...
0585 
0586                         for kk=1:length(start.(cc_names{1}))
0587                             % reorganize start and count arrays
0588                             read_start(1)=start.(cc_names{1})(kk);
0589                             read_count(1)=count.(cc_names{1})(kk);
0590                             read_stride(1)=stride.(cc_names{1});
0591                             for cc=1:length(start.(cc_names{2}))
0592                                 read_start(2)=start.(cc_names{2})(cc);
0593                                 read_count(2)=count.(cc_names{2})(cc);
0594                                 read_stride(2)=stride.(cc_names{2});
0595                                 var_dump=netcdf.getVar(nc,varID,read_start,read_count,read_stride,'double');
0596 
0597                                 eval([varnames{aa},'(kk,cc)=var_dump;'])
0598                                 clear var_dump
0599                             end
0600 
0601                         end
0602 
0603                     end
0604 
0605                     eval(['selection.',varnames{aa},'.start=start;'])
0606                     eval(['selection.',varnames{aa},'.count=count;'])
0607 
0608                 case 3 % three dimension to restrict!
0609                     % but the variable can have more than 2 dimensions
0610                     switch dimens
0611                         % initialise variable
0612                         case 2
0613                             rr=[min(sum(count.(cc_names{1})),dimLength(1)) min(sum(count.(cc_names{2})),dimLength(2))];
0614                         case 3
0615                             rr=[min(sum(count.(cc_names{1})),dimLength(1)),...
0616                                 min(sum(count.(cc_names{2})),dimLength(2)),...
0617                                 min(sum(count.(cc_names{3})),dimLength(3))];
0618                     end
0619 
0620                     eval([varnames{aa},'=nan(rr);'])
0621                     % check if time is one of them
0622                     if isempty(find(dimidx==5));disp('This won''t work, try again');return;end
0623                     do_time = find(dimidx==5); % 5 is the index for time
0624                     % reorganize start and count arrays
0625                     read_start(do_time)=start.(cc_names{do_time});
0626                     read_count(do_time)=count.(cc_names{do_time});
0627                     read_stride(do_time)=stride.(cc_names{do_time});
0628 
0629                     % search for the non_restrictive variable
0630                     %                         cc=1
0631                     %                         while ~(length( start.(cc_names{cc}))==1);cc=cc+1;end
0632                     % esto esta mal.... tengo que incluir otra opcion por si tenemos una
0633                     % variable de dos dimensiones donde los dos son restrictivas....
0634                     [~,do_other] = setdiff(dimidx,[dimidx(do_time)]) ; % these are also restrictive and are not time...
0635                     if length(count.(cc_names{do_other(1)})) <length(count.(cc_names{do_other(2)}))
0636                         do_one=do_other(1);do_two=do_other(2);
0637                     else
0638                         do_one=do_other(2);do_two=do_other(1);
0639                     end
0640 
0641                     for cc=1:length(start.(cc_names{do_one}))
0642                         read_start(do_one)=start.(cc_names{do_one})(cc);
0643                         read_count(do_one)=count.(cc_names{do_one})(cc);
0644                         read_stride(do_one)=stride.(cc_names{do_one});
0645 
0646                         for pp=1:length(start.(cc_names{do_two}))
0647                             read_start(do_two)=start.(cc_names{do_two})(pp);
0648                             read_count(do_two)=count.(cc_names{do_two})(pp);
0649                             read_stride(do_two)=stride.(cc_names{do_two});
0650 
0651                             var_dump=netcdf.getVar(nc,varID,read_start,read_count,read_stride,'double');
0652                             eval([varnames{aa},'(pp,cc,:)=var_dump;'])
0653                         end
0654                         clear var_dump
0655                     end
0656                     eval(['selection.',varnames{aa},'.start=start;'])
0657                     eval(['selection.',varnames{aa},'.count=count;'])
0658                 case 0 % there are NO dimensions to restrict and 3 dimensions haven't been coded yet!!
0659 
0660                     for nn=1:length(cc_names)
0661                         read_start(nn)=start.(cc_names{nn});
0662                         read_count(nn)=count.(cc_names{nn});
0663                          read_stride(nn)=stride.(cc_names{nn});
0664                     end
0665                     eval([varnames{aa},'=netcdf.getVar(nc,varID,read_start,read_count,read_stride,''double'');'])
0666                     eval(['selection.',varnames{aa},'.start=start;'])
0667                     eval(['selection.',varnames{aa},'.count=count;'])
0668 
0669             end
0670     end
0671     eval(['data.(varnames{aa}) = ',varnames{aa},';'])
0672     eval(['clear ',varnames{aa}])
0673 %     toc
0674 end
0675 
0676 %--------------------------------------------------------------------------
0677 % Tidy up, finish and return data
0678 %--------------------------------------------------------------------------
0679 
0680 netcdf.close(nc)
0681 
0682 if ftbverbose
0683     fprintf('end   : %s \n', subname)
0684 end

Generated on Wed 20-Feb-2019 16:06:01 by m2html © 2005