read_ERA_wind.m 4.13 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
function era = read_ERA_wind(year, datadir, varlist)
% Reads in ERA Interim files and outputs a struct containing the requested
% variables for a given year. 
% 
% ERA = read_ERA_wind(YEAR, DATADIR, VARLIST)
% 
% DESCRIPTION:
%   For the given YEAR, find all the ERA Interim NetCDF files and aggregate
%   them into a single MATLAB struct, which contains the variables
%   specified in VARLIST. In addition to the specified variables, time and
%   longitude and latitude will also be extracted. 
% 
% INPUT:
%   YEAR - year to extract
%   DATADIR - path to the directory which contains the ERA NetCDF files
%   VARLIST - list of the particular variables to extract from the NetCDF
%   files.
% 
% OUTPUT:
%   era - struct containing the variables specified in VARLIST.
% 
% Author(s)
%   Pierre Cazenave (Plymouth Marine Laboratory)
% 
% Revision history:
%   2012-10-19 First version based loosely on read_NCEP_wind.m in the
%   fvcom-toolbox.
% 
%==========================================================================

% year = 2006;
% % datadir = '/data/modellers/to_archive/momm-ERA40-interim/';
% datadir = '/users/modellers/pica/Data/ECMWF/2006';
% varlist = {'u10', 'v10'};

warning off

if nargin ~= 3
    error('Incorrect number of arguments')
end

subname = 'read_ERA_wind';

global ftbverbose;
if(ftbverbose);
  fprintf('\n')
  fprintf(['begin : ' subname '\n'])
end;

if exist(datadir, 'dir') ~= 7
   error(['file: ' datadir ' does not exist']);
end

%--------------------------------------------------------------------------
% Open ERA Interim data and check for time range
%--------------------------------------------------------------------------

% Get the time. 
ncERA = netcdf.open(fullfile(datadir, [num2str(year), '_U10V10.nc']), 'NOWRITE');
time_varid = netcdf.inqVarID(ncERA, 'time');
eratimehours = netcdf.getVar(ncERA, time_varid);

% ERA Interim times are stored as hours since 1900-01-01 00:00:0.0.
% MATLAB's dates days since 0000/00/00 00:00:00. 
eratimehours = datevec((double(eratimehours)/24) + datenum('1900-01-01 00:00:0.0'));
% Convert the ERA times to Modified Julian Date.
era.time = greg2mjulian(eratimehours(:,1), eratimehours(:,2),...
    eratimehours(:,3), eratimehours(:,4), eratimehours(:,5),...
69
    eratimehours(:,6));
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

if(ftbverbose);
    fprintf('beg time of ERA Interim data %04i/%02i/%02i %02i:%02i:%02i\n', eratimehours(1,:));
    fprintf('end time of ERA Interim data %04i/%02i/%02i %02i:%02i:%02i\n', eratimehours(end,:));
end

% Get the geographical information from the ERA Interim data. Again, use
% the U10 file only (we're assuming they're both global).
lat_varid = netcdf.inqVarID(ncERA, 'latitude');
lon_varid = netcdf.inqVarID(ncERA, 'longitude');
eralatvector = netcdf.getVar(ncERA, lat_varid);
eralonvector = netcdf.getVar(ncERA, lon_varid);
[era.lon, era.lat] = meshgrid(eralonvector, eralatvector);

% Find the necessary variables
for var=1:numel(varlist)

    getVar = varlist{var};
88
    varid_ERA = netcdf.inqVarID(ncERA, getVar);
89 90 91 92 93 94 95 96 97 98

    % Get the data
    data = netcdf.getVar(ncERA, varid_ERA, 'single');
    
    if strcmpi(getVar, 'u10') || strcmpi(getVar, 'v10')
        % The ERA Interim wind component data are packed as integers. The
        % following equation describes how to unpack them:
        %     unpacked value = add_offset + ((packed value)*scale_factor)
        % (from
        % http://www.ecmwf.int/products/data/archive/data_faq.html#netcdfintegers).
99 100
        % ERA wind scale_factor and add_offset are doubles (the NCEP ones
        % are singles).
101 102
        scale_factor = netcdf.getAtt(ncERA,varid_ERA,'scale_factor','double');
        add_offset = netcdf.getAtt(ncERA,varid_ERA,'add_offset','double');
103 104 105 106

        % Unpack the values. In general, the data for U10 and V10 should be
        % doubles for griddata to work. Fix the order of the dimensions to
        % match the coordinates in eralon and eralat.
107
        era.(getVar) = permute(double(add_offset + (data.*scale_factor)), [2,1,3]);
108 109 110 111 112 113 114
    else
        % We're assuming they're not packed and so we just return the data
        % as is (but as doubles).
        era.(getVar) = double(data);
    end
end

115 116 117 118 119
netcdf.close(ncERA)

if ftbverbose;
    fprintf(['end   : ' subname '\n'])
end