


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 options (in no particular order) includes:
params_opts={'time','data_dir','file_netcdf','varnames','nele_idx','node_idx','siglay_idx','siglev_idx'};
time time_interval = {'30/01/06 00:00:00','01/02/06 23:00:00'} or -1 to
extract all times in NC file
data_dir '/home_nfs/rito/models/FVCOM/...' directory where NC file is.
default value is ../fvcom_postproc/netcdf
file_netcdf 'filename.nc' default value is file_netcdf='*.nc', but it
only access the first file in alphabetical order in the directory
varnames {'Itime','Itime2','xc','yc','art1','art2','h','siglay','siglev','nv','zeta','ua','va'}
cell array of variable names to be read from NC file
the variables need to exist in the file but they are case insensitive. The complete list 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 and time_idx
default values cause the script to extract all available data for all
possible dimensions. time_idx is constructed from time_interval. All
other indices need to be zero referenced as is Netcdf standard.
No checks are done on the bounds of each dimension so make sure you
choose them right!
OUTPUT:
data = cell array with variables in the order they were requested
EXAMPLE USAGE
var_2_xtractFVCOM_0 = {'Itime','Itime2','xc','yc','art1','art2','h','siglay','siglev','nv','zeta','ua','va'};
date_range={'30/01/06 00:00:00','15/02/06 23:00:00'}; 1 if all available data wanted
node_idx=[10:30,40:50];% zero referenced!
FVCOM_data=read_netCDF_FVCOM_in_progress('time',date_range,'data_dir','/home_nfs/models/FVCOM/runCO2_leak/output/',...
'file_netcdf','co2_S1_0001.nc','siglev_idx',1,...
'node_idx',node_idx,'varnames',var_2_xtractFVCOM_0);
Author(s):
Ricardo Torres - Plymouth Marine Laboratory 2012
Revision history
v0 March 2012
==============================================================================
%
------------------------------------------------------------------------------
Parse input arguments
------------------------------------------------------------------------------

0001 function [varargout]=read_netCDF_FVCOM(varargin) 0002 % 0003 % Function to extract data from a Netcdf file output from FVCOM 0004 % 0005 % [data] = read_netCDF_FVCOM(varargin) 0006 % 0007 % DESCRIPTION: 0008 % Function to extract data from a Netcdf file output from FVCOM 0009 % Outputs data in cell array 0010 % 0011 % 0012 % INPUT [keyword pairs]: 0013 % Options are passed in pairs. 0014 % The list of options (in no particular order) includes: 0015 % params_opts={'time','data_dir','file_netcdf','varnames','nele_idx','node_idx','siglay_idx','siglev_idx'}; 0016 % 0017 % time time_interval = {'30/01/06 00:00:00','01/02/06 23:00:00'} or -1 to 0018 % extract all times in NC file 0019 % 0020 % data_dir '/home_nfs/rito/models/FVCOM/...' directory where NC file is. 0021 % default value is ../fvcom_postproc/netcdf 0022 % 0023 % file_netcdf 'filename.nc' default value is file_netcdf='*.nc', but it 0024 % only access the first file in alphabetical order in the directory 0025 % 0026 % varnames {'Itime','Itime2','xc','yc','art1','art2','h','siglay','siglev','nv','zeta','ua','va'} 0027 % cell array of variable names to be read from NC file 0028 % the variables need to exist in the file but they are case insensitive. The complete list is given by 0029 % running this script with varnames set to []; 0030 % 0031 % The variables can be restricted in five possible dimensions 0032 % node_idx, nele_idx, siglev_idx, siglay_idx and time_idx 0033 % default values cause the script to extract all available data for all 0034 % possible dimensions. time_idx is constructed from time_interval. All 0035 % other indices need to be zero referenced as is Netcdf standard. 0036 % No checks are done on the bounds of each dimension so make sure you 0037 % choose them right! 0038 % 0039 % 0040 % OUTPUT: 0041 % data = cell array with variables in the order they were requested 0042 % 0043 % EXAMPLE USAGE 0044 % var_2_xtractFVCOM_0 = {'Itime','Itime2','xc','yc','art1','art2','h','siglay','siglev','nv','zeta','ua','va'}; 0045 % date_range={'30/01/06 00:00:00','15/02/06 23:00:00'}; 1 if all available data wanted 0046 % node_idx=[10:30,40:50];% zero referenced! 0047 % FVCOM_data=read_netCDF_FVCOM_in_progress('time',date_range,'data_dir','/home_nfs/models/FVCOM/runCO2_leak/output/',... 0048 % 'file_netcdf','co2_S1_0001.nc','siglev_idx',1,... 0049 % 'node_idx',node_idx,'varnames',var_2_xtractFVCOM_0); 0050 % 0051 % 0052 % Author(s): 0053 % Ricardo Torres - Plymouth Marine Laboratory 2012 0054 % 0055 % Revision history 0056 % v0 March 2012 0057 %============================================================================== 0058 %% 0059 %------------------------------------------------------------------------------ 0060 % Parse input arguments 0061 %------------------------------------------------------------------------------ 0062 CD=pwd; 0063 disp('Using date conversion of +678942 to go from FVCOM time to matlab time') 0064 time_offset = 678942; 0065 params_opts={'time','data_dir','file_netcdf','varnames','nele_idx','node_idx','siglay_idx','siglev_idx'}; 0066 0067 disp('Parameters being used are ...') 0068 var_in_list = {'all_data','netfile_dir','file_netcdf','varnames','nele_idx','node_idx','siglay_idx','siglev_idx'}; 0069 all_data = 1; 0070 netfile_dir = '../fvcom_postproc/netcdf'; 0071 file_netcdf='*.nc'; 0072 siglay_idx=-1; 0073 siglev_idx=-1; 0074 nele_idx=-1;node_idx=-1; 0075 time_idx=-1; 0076 varnames={}; 0077 for aa=1:2:nargin 0078 res=strcmp(varargin(aa),params_opts); 0079 if ~isempty(res), 0080 eval([var_in_list{res},' = varargin{aa+1};']) 0081 disp([params_opts{res}]) 0082 end 0083 end 0084 %------------------------------------------------------------------------------ 0085 % sort and remove repeats all indices elements, nodes or layers to increasing values 0086 %------------------------------------------------------------------------------ 0087 nele_idx=unique(nele_idx); 0088 node_idx=unique(node_idx); 0089 siglay_idx=unique(siglay_idx); 0090 siglev_idx=unique(siglev_idx); 0091 % 0092 RestrictDims.Name={'node' 'nele' 'siglay' 'siglev' 'time'}; 0093 RestrictDims.idx={node_idx, nele_idx, siglay_idx, siglev_idx, time_idx}; 0094 % 0095 if ~isempty(varnames) 0096 nvarnames = length(varnames); 0097 for nn=1:nvarnames 0098 data{nn} = []; 0099 end 0100 end 0101 %% 0102 %------------------------------------------------------------------------------ 0103 % Open netcdf file 0104 %------------------------------------------------------------------------------ 0105 file_netcdf=[netfile_dir file_netcdf]; 0106 filesINdir=dir(file_netcdf); 0107 file_netcdf= fullfile(netfile_dir,filesINdir(1).name); 0108 nc = netcdf.open(file_netcdf, 'NC_NOWRITE'); 0109 disp(['NetCDF file ', file_netcdf,' opened successfully.']) 0110 % Get information from netcdf file 0111 info=ncinfo(file_netcdf); 0112 % Extract all possible dimensions in file 0113 DimsAll=info.Dimensions; 0114 % Extract variable names in nc file 0115 Vars=struct2cell(info.Variables); 0116 vars = squeeze(Vars(1,:,:)); 0117 %% 0118 %------------------------------------------------------------------------------ 0119 % find variable Itime 0120 %------------------------------------------------------------------------------ 0121 Itime.idx=find(strcmpi(vars,'Itime')); 0122 Itime.ID=netcdf.inqVarID(nc,'Itime'); 0123 Itime.Data = netcdf.getVar(nc,Itime.ID,'int32'); 0124 Itime2.Data = netcdf.getVar(nc,Itime.ID+1,'int32'); 0125 % 0126 [start_d(1),end_d(1)] = deal(double(Itime.Data(1))+time_offset,double(Itime.Data(end))+time_offset); 0127 [start_d(2),end_d(2)] = deal(double(Itime2.Data(1)),double(Itime2.Data(end))); 0128 % 0129 var_time = double(Itime.Data)+time_offset+double(Itime2.Data)./(24*600*6000); 0130 start_date=sum(start_d.*[1 1/(24*60*60)]); 0131 end_date = sum(end_d.*[1 1/(24*60*60)]); 0132 if (length(all_data)==2) 0133 req_st = datenum(all_data{1},'dd/mm/yy HH:MM:SS'); 0134 req_end = datenum(all_data{2},'dd/mm/yy HH:MM:SS'); 0135 else 0136 req_st =start_date; 0137 req_end =end_date; 0138 end 0139 time_idx = find(req_st <= var_time & var_time <= req_end ); 0140 % add correct time_idx to RestrictDims 0141 RestrictDims.idx{end}=time_idx; 0142 disp(['Start and end of file, ', datestr(start_date),' ',datestr(end_date)]) 0143 %% 0144 %------------------------------------------------------------------------------ 0145 % Return information about file to the screen 0146 %------------------------------------------------------------------------------ 0147 0148 disp(['Possible variables to extract are: ']) 0149 for ii = 1 : length(vars) 0150 fprintf('%s\n ',vars{ii}) 0151 end 0152 if isempty(varnames) 0153 disp(['Stopping, Choose a variable from the list above : ']) 0154 varargout{1} = 0; 0155 netcdf.close(nc) 0156 return 0157 end 0158 %% 0159 %------------------------------------------------------------------------------ 0160 % re-organise RestrictDims to follow order of dimensions in nc file from FVCOM 0161 %------------------------------------------------------------------------------ 0162 cc=1; 0163 for dd=1:length(DimsAll) 0164 idx=find(strcmpi(RestrictDims.Name,DimsAll(dd).Name)); 0165 if ~isempty(idx) 0166 TEMP{cc}=RestrictDims.Name{idx}; 0167 TEMPidx{cc}=RestrictDims.idx{idx}; 0168 cc=cc+1; 0169 end 0170 end 0171 RestrictDims.Name=TEMP; 0172 RestrictDims.idx=TEMPidx;clear TEMP TEMPidx 0173 %% 0174 %------------------------------------------------------------------------------ 0175 % Start Processing extraction of data from NC file 0176 %------------------------------------------------------------------------------ 0177 disp(['NetCDF file ', file_netcdf,' opened successfully.']) 0178 nvars=length(info.Variables); 0179 for aa=1:length(varnames) 0180 %------------------------------------------------------------------------------ 0181 % Extract number of dimensions, lengths and names of all variables 0182 %------------------------------------------------------------------------------ 0183 TF = strcmpi(varnames{aa},vars); 0184 if ~isempty(find(TF)); 0185 varidx(aa) = find(TF);TF = sum(TF); 0186 dimens=ndims(aa); 0187 disp(['Variable ',vars{varidx(aa)},' found in file']) 0188 else 0189 disp(['Variable ',varnames{aa},' NOT found in file Stopping. Check variable names.']) 0190 netcdf.close(nc) 0191 varargout{1} = 0; 0192 return 0193 end 0194 varID=netcdf.inqVarID(nc,vars{varidx(aa)}); 0195 0196 [name,xtype,dimids,natts] = netcdf.inqVar(nc,varID); 0197 dimens=length(dimids); 0198 0199 for dd=1:length(dimids) 0200 [dimName{dd},dimLength(dd)] = netcdf.inqDim(nc,dimids(dd)); 0201 disp(['Variable ',name,' has ',num2str(dimens),' dimensions: ',dimName{dd}]) 0202 end 0203 %------------------------------------------------------------------------------ 0204 % Get the data! 0205 %------------------------------------------------------------------------------ 0206 0207 start=zeros(size(dimLength)); 0208 count=dimLength; 0209 switch dimens 0210 case 1 0211 % only one dimension present in variable 0212 switch dimName{1} 0213 case 'time' 0214 if time_idx>=0 0215 % only restrict data on access if dimension is TIME 0216 eval([varnames{aa},'=netcdf.getVar(nc,varID,time_idx(1),length(time_idx));']) 0217 end 0218 case 'nele' 0219 eval([varnames{aa},'=netcdf.getVar(nc,varID);']) 0220 if nele_idx>=0 0221 eval([varnames{aa},' = ',varnames{aa},'(nele_idx);']) 0222 end 0223 case 'node' 0224 eval([varnames{aa},'=netcdf.getVar(nc,varID);']) 0225 if node_idx>=0 0226 eval([varnames{aa},' = ',varnames{aa},'(node_idx);']) 0227 end 0228 otherwise 0229 disp('Unkown dimension for variable ',name,' Skipping to next one function call'); 0230 end 0231 otherwise 0232 % identified dimensions to restrict 0233 do_restrict=zeros(size(dimName)); 0234 dimidx=nan*ones(size(dimName)); 0235 for dd=1:length(dimName) 0236 test=find(strcmpi(RestrictDims.Name,dimName{dd})); 0237 if ~isempty(test); dimidx(dd)=test; end 0238 end 0239 % create start index for dimensions of the variable to 0240 % access 0241 if (sum(isfinite(dimidx))==length(dimidx)) 0242 % we have two valid dimension indices, proceed 0243 for dd=1:length(dimidx) 0244 % if restriction is not -1 then select specified 0245 % indices otherwise read all 0246 if RestrictDims.idx{dimidx(dd)}(1)>=0 0247 start(dd)=RestrictDims.idx{dimidx(dd)}(1); 0248 count(dd)=length(start(dd):RestrictDims.idx{dimidx(dd)}(end)); 0249 do_restrict(dd)=1; 0250 end 0251 end 0252 else 0253 fprintf('Wrong selection of dimensions to extract, \n Extracting all values in current variable \n'); 0254 end 0255 eval([varnames{aa},'=netcdf.getVar(nc,varID,start,count);']) 0256 % only restrict if required... 0257 if sum(do_restrict) 0258 for dd=1:length(do_restrict) 0259 sd=dd-1; 0260 % calculate indices to extract (might not have been 0261 % consecutive numbers) 0262 idx=RestrictDims.idx{dimidx(dd)}-start(dd)+1; 0263 if ( do_restrict(dd) & ~(count(dd)==length(idx)) ) 0264 [~,idx]=setdiff(start(dd):RestrictDims.idx{dimidx(dd)}(end),RestrictDims.idx{dimidx(dd)}); 0265 eval([varnames{aa},' = shiftdim(',varnames{aa},',sd);']) 0266 switch dimens 0267 case 2 0268 eval([varnames{aa},'(idx, :) = [];']) 0269 case 3 0270 eval([varnames{aa},'(idx, :,:) = [];']) 0271 0272 case 4 0273 eval([varnames{aa},'(idx, :,:,:) = [];']) 0274 end 0275 eval([varnames{aa},' = shiftdim(',varnames{aa},',dimens-sd);']) 0276 end 0277 end 0278 end 0279 end 0280 eval(['data(aa) = {[data{aa};',varnames{aa},']};']) 0281 eval(['clear ',varnames{aa}]) 0282 end 0283 %% 0284 %------------------------------------------------------------------------------ 0285 % Tidy up, finish and return data 0286 %------------------------------------------------------------------------------ 0287 0288 netcdf.close(nc) 0289 cd(CD) 0290 varargout{1} = data; 0291 return