function [out] = ncload(fname, varargin)
% ncload -- Load NetCDF variables.  This was designed to work for
%  NetCDF4, but it should also work for NetCDF3 (Classic) since they
%  are supposed to the backwards compatible.
% 
%  ncload(fname, 'var1', 'var2', ...) loads the
%   specified variables of the NetCDF file, fname, into the 
%   workspace or into a structure if an output is given
%   If no attributes are given, the function loads the whole file
%   Global attributes are also loaded into a structure called GlobAtts.
%   If saved to a structure, variable attributes are loaded.
%
% EXAMPLES:
%   % read everything in a file and save into the workspace
%   ncload('base_file.nc');  
%
%   % read everything in file, save to a structure
%   ncstruct=ncload('base_file.nc')
%
%   % read two variables and save in a structure
%   ncstruct=ncload('base_file.nc', 'ta19v', 'ta19h')

%   Written by Matt Sapiano, May 2011


if nargin < 1, help(mfilename), return, end;
if nargout > 1, help(mfilename), return, end;
clear out; out={}; out.GlobAtts={}; out.atts={}; out.dimlens={};


% open file in read only format
ncid = netcdf.open(fname,'NOWRITE');
if isempty(ncid), return, end



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Read global attributes
[numdims,numvars,numglobalatts,unlimdimid] = netcdf.inq(ncid);

%save them to the output structure
clear GlobAtts;
for i=0:(numglobalatts-1),
  attname = netcdf.inqAttName(ncid,netcdf.getConstant('NC_GLOBAL'),i);
  eval(['GlobAtts.' attname '=netcdf.getAtt(ncid,netcdf.getConstant(' ...
          '''NC_GLOBAL''),''' attname ''');']);
end;

% store the global attributes structure
if nargout==1,
  out.GlobAtts=GlobAtts;
else,
  assignin('caller','GlobAtts',GlobAtts);
end;



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% if not specified, get variables
if isempty(varargin), tmp={};
  [ndims,nvars,ngatts,unlimdimid] = netcdf.inq(ncid);
  for varid=0:(nvars-1), 
    tmp{varid+1}=netcdf.inqVar(ncid,varid); 
  end; varargin=tmp;
end;



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Get information on variables
[ndims,nvars,ngatts,unlimdimid] = netcdf.inq(ncid);

% read each variable, including attributes
for i = 1:length(varargin),
  try, % just in case a variable doesn't load...

    % get varid
    varid=netcdf.inqVarID(ncid,varargin{i});

    % get variable and atribute info
    [vname,xtype,dimids,natts]=netcdf.inqVar(ncid,varid);
    if strcmp(vname(1),'_'), vname=vname(2:end); end;

    % get actual data and save
    if nargout==1,
      eval(['out.' vname '=netcdf.getVar(ncid,varid,''double'');'])
    else,
      assignin('caller',vname,netcdf.getVar(ncid,varid,'double'));
    end;

    % get dimension info for each variable
    if nargout==1,
      try, for dimid=dimids,
        [dimname, dimlen] = netcdf.inqDim(ncid,dimid);
        if strcmp(dimname(1),'_'), dimname=dimname(2:end); end;
        eval(['out.dimlens.' vname '.' dimname '=dimlen;']);
      end; end;
    end;

    % get attributes for each variable
    if nargout==1,
      try, for attid=0:(natts-1),
        attname=netcdf.inqAttName(ncid,varid,attid); attname1=attname;
        if strcmp(attname1(1),'_'), attname1=attname1(2:end); end;
        eval(['out.atts.' vname '.' attname1 '=netcdf.getAtt(ncid,varid,attname);']);
      end; end;
    end;

  catch,
    disp(['Variable ' char(varargin{i}) ' not found; skipping to next']);
  end;
end;


% close NetCDF file
netcdf.close(ncid);







