


Function to read in listed variables from a netCDF file
[M] = read_netcdf_vars(varargin)
DESCRIPTION:
Optionally select a dimension to select a range for
This should work for any netCDF, but was written with FCOM output files in mind
INPUT
Pass the variable names that you want to extract
[optional pair] filename, the netCDF filename
[optional triple] dimrange, the dimension name, the dimension range
the dimension range si of the form [start end
stride], where stride is optional (default 1).
EXAMPLE USAGE
Extract variables time, x, y
M = read_netcdf_vars('time', 'x', 'y');
Extract variables time, x, y from filename text.nc:
M = read_netcdf_vars('filename', 'test.nc', 'time', 'x', 'y');
Extract variables time, x, y from filename text.nc but only for time
indicies 0-99:
M = read_netcdf_vars('filename', 'test.nc', 'dimrange', 'time', [0 100], 'time', 'x', 'y');
Extract variables time, x, y from filename text.nc but only for time
indicies 0-99 and siglay index of 0:
M = read_netcdf_vars('filename', 'test.nc', 'dimrange', 'time', [0 100], ...
'dimrange', 'siglay', [0 1], 'time', 'x', 'y', 'u', 'v');
Author(s)
Rory O'Hara Murray, Marine Scotland Science
Revision history
v0 July 2013
2014-05-27 dimension ids are now added to attributes (ROM)
2014-06-02 added the ability to specify the stride/sample rate
==========================================================================

0001 function [M] = read_netcdf_vars(varargin) 0002 % 0003 % Function to read in listed variables from a netCDF file 0004 % 0005 % [M] = read_netcdf_vars(varargin) 0006 % 0007 % DESCRIPTION: 0008 % Optionally select a dimension to select a range for 0009 % This should work for any netCDF, but was written with FCOM output files in mind 0010 % 0011 % INPUT 0012 % Pass the variable names that you want to extract 0013 % [optional pair] filename, the netCDF filename 0014 % [optional triple] dimrange, the dimension name, the dimension range 0015 % the dimension range si of the form [start end 0016 % stride], where stride is optional (default 1). 0017 % 0018 % EXAMPLE USAGE 0019 % Extract variables time, x, y 0020 % M = read_netcdf_vars('time', 'x', 'y'); 0021 % 0022 % Extract variables time, x, y from filename text.nc: 0023 % M = read_netcdf_vars('filename', 'test.nc', 'time', 'x', 'y'); 0024 % 0025 % Extract variables time, x, y from filename text.nc but only for time 0026 % indicies 0-99: 0027 % M = read_netcdf_vars('filename', 'test.nc', 'dimrange', 'time', [0 100], 'time', 'x', 'y'); 0028 % 0029 % Extract variables time, x, y from filename text.nc but only for time 0030 % indicies 0-99 and siglay index of 0: 0031 % M = read_netcdf_vars('filename', 'test.nc', 'dimrange', 'time', [0 100], ... 0032 % 'dimrange', 'siglay', [0 1], 'time', 'x', 'y', 'u', 'v'); 0033 % Author(s) 0034 % Rory O'Hara Murray, Marine Scotland Science 0035 % 0036 % Revision history 0037 % v0 July 2013 0038 % 2014-05-27 dimension ids are now added to attributes (ROM) 0039 % 2014-06-02 added the ability to specify the stride/sample rate 0040 %========================================================================== 0041 0042 dimrange = false; 0043 extract_all_flag = false; 0044 0045 % look for some keywords with some setting after them and remember which 0046 % index of varargin are 'taken' in freeI. 0047 freeI = ones(size(varargin)); 0048 subsample_num = 0; 0049 for ii=1:1:length(varargin) 0050 keyword = lower(varargin{ii}); 0051 if length(keyword)<8, continue; end 0052 switch(keyword(1:8)) 0053 case 'filename' 0054 netcdf_filename = varargin{ii+1}; 0055 freeI([ii ii+1]) = 0; 0056 case 'dimrange' 0057 dimrange = true; 0058 subsample_num = subsample_num + 1; 0059 subsample_dim(subsample_num) = {varargin{ii+1}}; 0060 range_tmp = varargin{ii+2}; 0061 subsample_ran(1:2,subsample_num) = range_tmp(1:2); 0062 if length(range_tmp)>2 0063 subsample_ran(3,subsample_num) = range_tmp(3); 0064 else 0065 subsample_ran(3,subsample_num) = 1; 0066 end 0067 freeI([ii ii+1 ii+2]) = 0; 0068 case 'all_vars' 0069 freeI([ii]) = 0; 0070 extract_all_flag = true; 0071 end 0072 end 0073 0074 % save all the non 'taken' values of varargin as a list 0075 % of varables to look for and extract 0076 varnames = varargin(find(freeI)); 0077 0078 % if there isn't a netCDF filename defined, ask the user for one 0079 if exist('netcdf_filename')==0 0080 [FileName,PathName] = uigetfile('*.nc', 'Select FVCOM netCDF file to read'); 0081 netcdf_filename = [PathName FileName]; 0082 end 0083 0084 % open netCDF file for reading 0085 ncid = netcdf.open(netcdf_filename, 'NC_NOWRITE'); 0086 0087 [ndims,nvars,ngatts,unlimdimid] = netcdf.inq(ncid); 0088 0089 % get a list of the variables avaliable and check the inputs 0090 variable_names_avaliable = {}; 0091 for ii=0:nvars-1 0092 variable_names_avaliable{ii+1} = netcdf.inqVar(ncid, ii); 0093 end 0094 test = []; 0095 for ii=1:size(varnames,2); 0096 test1 = strmatch(varnames{ii}, variable_names_avaliable, 'exact'); 0097 if size(test1,1)==0 test = [test ii]; end 0098 end 0099 0100 if extract_all_flag 0101 varnames = variable_names_avaliable; 0102 elseif sum(test)>0 0103 disp([varnames(test) ' could not be found']); 0104 disp(['variables avaliable are: ' variable_names_avaliable]); 0105 M = 0; netcdf.close(ncid); 0106 return 0107 end 0108 0109 % Get global attributes 0110 for ii=1:ngatts 0111 M.gattname{ii} = netcdf.inqAttName(ncid,netcdf.getConstant('NC_GLOBAL'),ii-1); 0112 M.gattval{ii} = netcdf.getAtt(ncid,netcdf.getConstant('NC_GLOBAL'),M.gattname{ii}); 0113 end 0114 0115 % get dimension lengths 0116 for jj=1:ndims 0117 [dimname{jj} dimsize(jj)] = netcdf.inqDim(ncid, jj-1); 0118 end 0119 0120 if dimrange 0121 %get ID for sub_var dimension 0122 for ii=1:size(dimname,2) 0123 for jj=1:subsample_num 0124 if findstr(dimname{ii},subsample_dim{jj}) sDID(jj) = ii-1; end 0125 end 0126 end 0127 end 0128 0129 % Loop through all the variables to extract 0130 for ii=1:size(varnames,2) 0131 varid(ii) = netcdf.inqVarID(ncid,varnames{ii}); 0132 0133 % Get the attributes of the variables listed 0134 [varname,tmp,tmp,natts] = netcdf.inqVar(ncid, varid(ii)); 0135 for jj=0:natts-1 0136 attname = netcdf.inqAttName(ncid, varid(ii), jj); 0137 if attname(1)=='_' 0138 attname2 = attname(2:end); 0139 else 0140 attname2 = attname; 0141 end 0142 aI = strfind(attname2, '-'); 0143 attname2(aI) = '_'; 0144 0145 eval(['M.' varnames{ii} '_att.' attname2 ' = netcdf.getAtt(ncid, varid(ii), attname);']); 0146 end 0147 0148 % get info about the variable in question 0149 [varname xtype dimids atts] = netcdf.inqVar(ncid,varid(ii)); 0150 0151 % add dimids to the attributes 0152 eval(['M.' varnames{ii} '_att.dimids = dimids;']); 0153 0154 % Take a subset if variable is dependent on the subsample variable 0155 if dimrange 0156 0157 % work out which dimensions this variable has that should be 0158 % subsampled, assuming it has any... 0159 clear I 0160 for jj=1:length(dimids) 0161 tmp = find(dimids(jj)==sDID); 0162 if tmp I(jj) = tmp; end 0163 end 0164 end 0165 0166 % 'I' only exists if this variable has dimensions that should be sub 0167 % sampled 0168 if dimrange & exist('I') 0169 clear dim_range 0170 % get all the dimension lengths and make a starts one (zeros) 0171 dim_range(2,:) = dimsize(dimids+1); % the sizes 0172 dim_range(1,:) = zeros(1, size(dim_range,2)); % the start positions, i.e. zeros 0173 dim_range(3,:) = ones(1, size(dim_range,2)); % default stride of 1 0174 0175 % redefine the dim_starts and dim array 0176 for jj=1:length(I) 0177 if I(jj) 0178 dim_range(:,jj) = [subsample_ran(1,I(jj)); ... 0179 round([subsample_ran(2,I(jj))-subsample_ran(1,I(jj))]./subsample_ran(3,I(jj))); ... 0180 subsample_ran(3,I(jj))]; 0181 end 0182 end 0183 0184 %M.(varnames{ii}) = double(netcdf.getVar(ncid, varid(ii), dim_range(1,:), dim_range(2,:), dim_range(3,:))); 0185 M.(varnames{ii}) = (netcdf.getVar(ncid, varid(ii), dim_range(1,:), dim_range(2,:), dim_range(3,:))); 0186 else 0187 % Do not subsample if 'I' doens't exist or we are not subsampling 0188 %M.(varnames{ii}) = double(netcdf.getVar(ncid, varid(ii))); 0189 M.(varnames{ii}) = (netcdf.getVar(ncid, varid(ii))); 0190 end 0191 end 0192 0193 % close netCDF file 0194 netcdf.close(ncid) 0195 0196 return