Home > utilities > read_netcdf_vars.m

read_netcdf_vars

PURPOSE ^

SYNOPSIS ^

function [M] = read_netcdf_vars(varargin)

DESCRIPTION ^

 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
==========================================================================

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

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

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