function vardata = nc_varget(ncfile , varname , varargin ) % % version of nc_varget for mexec to replace snctools version % the aim is to replace snctools nc_ calls with faster versions that make % simple native matlab netcdf calls. % % rather than changing every mexec program, the snctools library can be % replaced with this library % % varargin can be % start, count, stride % start begins at zero, so if start = [2 3] it will retrieve data from % row 3, column 4; % if start is defined and count is empty, the data are retrieved from % the point denoted by the start offset, to the end of each row and column. % % When I tried it, the -1 notation for count in the snctools version did % not work as intended. % % This version handles _FillValue but not missing values or scaling or % offset. % % The old snctools description was % % % DATA = NC_VARGET(NCFILE,VARNAME) retrieves all the data from the % % variable VARNAME in the netCDF file NCFILE. % % % % DATA = NC_VARGET(NCFILE,VARNAME,START,COUNT) retrieves the contiguous % % portion of the variable specified by the index vectors START and % % COUNT. Remember that SNCTOOLS indexing is zero-based, not % % one-based. Specifying a -1 in COUNT means to retrieve everything % % along that dimension from the START coordinate. % % % % DATA = NC_VARGET(NCFILE,VARNAME,START,COUNT,STRIDE) retrieves % % a non-contiguous portion of the dataset. The amount of % % skipping along each dimension is given through the STRIDE vector. % % % % NCFILE can also be an OPeNDAP URL if the proper java SNCTOOLS % % backend is installed. See the README for details. % % % % NC_VARGET tries to be intelligent about retrieving the data. % % Since most general matlab operations are done in double precision, % % retrieved numeric data will be cast to double precision, while % % character data remains just character data. % % % % bak jc191 6 Feb 2020 % args = varargin(:); start = []; count = []; stride = []; switch length(args) case 1 start = args{1}; case 2 start = args{1}; count = args{2}; case 3 start = args{1}; count = args{2}; stride = args{3}; otherwise end ncid = netcdf.open(ncfile,'NOWRITE'); varid = netcdf.inqVarID(ncid,varname); % is there is start but no count, then calculate count to retrieve from % start to the end of each dimension [varname,xtype,dimids,natts] = netcdf.inqVar(ncid, varid); if isempty(count) & ~isempty(start) % we seem to need to flip the dimids to get the same effect as the snctools % nc_addvar dimids = fliplr(dimids); ndimsv = length(dimids); clear dimsize for kd = 1:ndimsv [dimname, dimlength] = netcdf.inqDim(ncid, dimids(kd)); dimsize(kd) = dimlength; end count = dimsize(:)'-start; end % the snctools version seems to retrieve every element if there is start but no count. % % I couldn't see anywhere where mexec calls nc_varget with start but no % count, so the above difference should not matter. start = fliplr(start); count = fliplr(count); stride = fliplr(stride); if isempty(start) vardata = netcdf.getVar(ncid, varid ); elseif isempty(count) fprintf(2,'\n%s\n','Warning, nc_varget has been called with start but no count'); fprintf(2,'%s\n','The bahaviour of this version is different than the behaviour of the snctools version'); fprintf(2,'%s\n\n','Suggest the code be rewritten to state exactly what ''count'' should be'); error('error in nc_varget'); % if you reinstate the line of code below you will get precisely one data % value, at location given by 'start' vardata = netcdf.getVar(ncid, varid, start ); elseif isempty(stride) vardata = netcdf.getVar(ncid, varid, start, count ); else vardata = netcdf.getVar(ncid, varid, start, count, stride); end if length(dimids) == 1 vardata = vardata(:); % techsas files have one dimension which is time; snctools nc_varget makes this a column vector else vardata = vardata'; % this is necessary to mimic the action of the old nc_varget; % the above line will only work on 2-D vars, ie 1xN, Mx1, MxN. % mexec is not presently set up to handle more than 2-D vars. % mexec files have at least three dimension parameters: n_unity, nrows1, ncols1. % mexec variables are always 2-D. MxN 1xN or Mx1. end % now handle _FillValue switch ( xtype ) case { 6 } % 6 is double try fillvalue = netcdf.getAtt(ncid, varid, '_FillValue'); vardata(vardata == fillvalue) = NaN; catch % If there is no fillvalue defined, take no action end otherwise end netcdf.close(ncid); return