function S_res = grasdir(file, varargin) % GRASDIR read directory of gras data % % This is a reading routine for the Global Navigation Satellite System % (GNSS) Receiver for Atmospheric Sounding (GRAS) data directories. % In GRAS measurements, a single measurement is stored in a single % NetCDF-file. In the framework of the collocation toolkit, this is % impractical and inefficient. Therefore, the reading is done for a % whole directory, which still contains only ~20 MiB of data. % % For calling format, see Contents.m. Note that you should pass a % directory, not a file! % % For info on the common format, see SatDataset/reader. % $Id$ % WARNING: functionality relies on consistent no. and order of data % files within directory! assert(isdir(file), ['atmlab:' mfilename ':notadirectory'], ... 'function ''grasdir'' wants a directory, which %s is not', file); core_fields = {'lat','lon'}; extra_fields = optargs(varargin, {{}}); all_fields = [core_fields(:); extra_fields(:)]; cont = dir(file); fullpaths = cellfun(@(x) fullfile(file, x), {cont.name}, 'UniformOutput', false); % read data into a cell array of structures path_is_gran = cellfun(@any, strfind(fullpaths, 'nc')); alldata = cellfun(@(f) loadncvar(f, all_fields), ... fullpaths(path_is_gran), ... 'UniformOutput', false); % convert cell array of structures into structure with matrices % NB: this would be the direct output from cellfun with 'UniformOutput' % set to true, but I cannot assume this if some fields have non-constant % data sizes S = horzcat(alldata{:}); if isempty(alldata) S_res = cell2struct(repmat({[]}, size(all_fields)), all_fields); S_res.epoch = 0; S_res.time = []; S_res.version = '?'; return; end flds = fieldnames(S(1)); varying_size = cellfun(@(fn) length(unique(cellfun(@length, {S.(fn)}))), flds)>1; vals = cellfun(@(f) [S.(f)].', flds(~varying_size), 'UniformOutput', false); S_res = cell2struct(vals.', flds(~varying_size).', 2); if length(find(varying_size)) > 0 logtext(atmlab('ERR'), 'Cannot concatenate fields: %s\n', ... strjoin(flds(varying_size))); end % add time info from filenames % hardcode regular expression here; this is about files inside the % 'granule' directory, not the 'granule' directory itself f_re = 'wet(?\d{4})(?\d{2})(?\d{2})_(?\d{2})(?\d{2})(?\d{2})_M.._\d*_N\d*_X*\.nc'; info = regexp({cont(path_is_gran).name}, f_re, 'names'); % str to double and cell array to struct array info = cellfun(@(S) structfun(@str2double, S, 'UniformOutput', false), info, 'UniformOutput', false); info = horzcat(info{:}); S_res.time = vec2col([info.hour] * 3600 + [info.minute] * 60 + [info.second]); S_res.epoch = date2unixsecs(info(1).year, info(1).month, info(1).day); assert(length(unique([info.day]))==1, ['atmlab:' mfilename ':multi-day'], ... 'Data appear to span multiple days, I did not expect that'); S_res.version = '?'; end