Showing posts with label native function. Show all posts
Showing posts with label native function. Show all posts

Wednesday, December 22, 2010

read netcdf file using native matlab functions

UPDATED VERSION:  Here

function ncvardata=GetNcVarMatlab(ncfile,ncvar,RangeStr)
% to read data from the netcdf file using native matlab netcdf-functions
% Usage: vardata=GetNcVarMatlab(nc-filename,nc-varname,Dimension-Range)
% e.g.,
% mydata=GetNcVarMatlab('mask.nc','tmask','1:1,1:46,1:400,1:568');
% RangeStr here is similar to the output of ncdump
% copyright by http://scriptdemo.blogspot.com

IsDebug=0;
if ~exist(ncfile,'file')
   error([ncfile,' can not been found']);
   return
end

ncfid=netcdf.open(ncfile,'NC_NOWRITE');
% get dimension length
[numdims, numvars, numglobalatts, unlimdimID] = netcdf.inq(ncfid);
for NDim=1:numdims
      [dimname{NDim}, dimlen(NDim)] = netcdf.inqDim(ncfid,NDim-1);
end

%var infor
varid=netcdf.inqVarID(ncfid,ncvar);
[varname,varxtype,vardimids,varnumatts]=netcdf.inqVar(ncfid,varid);
numdims=length(vardimids); % some variables may have less dimensions

if ~exist('RangeStr','var')
   RangeStr=':';
   for nd=2:numdims
         RangeStr=[RangeStr,',:'];
   end
end

IndC=strfind(RangeStr,',');% index of commas
if length(IndC)~=numdims-1
   disp(['Input dimension range is not correct, should be: ',num2str(numdims),'-d']);
   return
end

startstr=''; countstr=''; stridestr='';
for nn=1:length(IndC)+1
      if nn==1
         tmpstr=RangeStr(1:IndC(1)-1);
      elseif nn<numdims
         tmpstr=RangeStr(IndC(nn-1)+1:IndC(nn)-1);
      else
         tmpstr=RangeStr(IndC(nn-1)+1:end);
      end

      [tmpstart,tmpcount,tmpstride]=GetIndFromStr(tmpstr,':',dimlen(vardimids(numdims-nn+1)+1));
     if nn==1
        startstr=[num2str(tmpstart),'],'];
        countstr=[num2str(tmpcount),'],'];
        stridestr=[num2str(tmpstride),']'];
     elseif nn==numdims
        startstr=[',[',num2str(tmpstart),',',startstr];
        countstr=['[',num2str(tmpcount),',',countstr];
        stridestr=['[',num2str(tmpstride),',',stridestr];
     else
        startstr=[num2str(tmpstart),',',startstr];
        countstr=[num2str(tmpcount),',',countstr];
        stridestr=[num2str(tmpstride),',',stridestr];
     end
end

if IsDebug
   disp(['ncvardata=netcdf.getVar(ncfid,varid',startstr,countstr,stridestr,');']);
end
eval(['ncvardata=netcdf.getVar(ncfid,varid',startstr,countstr,stridestr,');']);
netcdf.close(ncfid);
ncvardata=permute(ncvardata,length(size(ncvardata)):-1:1);

function [numstart,numcount,numstride]=GetIndFromStr(tmpstr,ctag,Ndim)
% Read the numbers from the special string
IsDebug=0;
IndC=strfind(tmpstr,ctag);
if isempty(IndC)
   numstart=str2double(tmpstr)-1;
   numcount=1;
   numstride=1;
else
  switch length(IndC)
    case {1}
        switch IndC
            case {1} % : and :num
                if strcmp(tmpstr,':')
                   numstart=0; numcount=Ndim; numstride=1;
                else
                   if strcmp(tmpstr(2:end),'end')
                      numstart=0; numcount=Ndim; numstride=1;
                   else
                      numstart=0; numcount=str2double(tmpstr(2:end))-1; numstride=1;
                   end
                end
            case {length(tmpstr)}
                if strcmp(tmpstr,':')
                    numstart=0; numcount=Ndim; numstride=1;
                    return
                else
                    numstart=str2double(tmpstr(1:IndC-1))-1;
                    numcount=Ndim-numstart;
                    numstride=1;
                end
           otherwise
                numstart=str2double(tmpstr(1:IndC-1))-1;
                if strcmp(tmpstr(IndC+1:end),'end')
                    numend=Ndim;
                else
                    numend=str2double(tmpstr(IndC+1:end));
                end
                numcount=numend-numstart;
                numstride=1;
            end
   case {2}
      % num0:stride:num1
      if IndC(1)==1
         numstart=0;
      else
         numstart=str2double(tmpstr(1:IndC(1)-1))-1;
      end
      if IndC(2)==IndC(1)+1
         numstride=1;
      else
         numstride=str2double(tmpstr(IndC(1)+1:IndC(2)-1));
      end
      if IndC(2)==length(tmpstr)
             numend=Ndim;
      else
         if strcmp(tmpstr(IndC(2)+1:end),'end')
            numend=Ndim;
         else
            numend=str2double(tmpstr(IndC(2)+1:end));
         end
      end
      numcount=numend-numstart;
   otherwise
       error('Not defined range type')
   end
end
if IsDebug
   disp(['tmpstr=',tmpstr])
   disp(['start:',num2str(numstart), ' stride:',num2str(numstride),' count:',num2str(numcount)])
end

ShowCalendar