-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathread_wrf_vars.m
170 lines (147 loc) · 5.76 KB
/
read_wrf_vars.m
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
function [ varargout ] = read_wrf_vars( filepath, filenames, varnames, force_dims, DEBUG_LEVEL )
%READ_WRF_VARS Reads WRF_BEHR .nc files
% This function will read in arbitrary variables from WRF_BEHR .nc files
% (the result of processing raw wrfout files using
% (slurm)run_wrf_output.sh in this folder). Requires 3 arguments:
%
% FILEPATH - a path to the netCDF files. Alternatively, pass an empty
% string to indicate that the full path is contained in each file
% name.
%
% FILENAMES - this can either be a structure output from the dir()
% function (i.e. each file is an entry in the structure, and has its
% filename in the "name" field) or a cell array of filenames.
%
% VARNAMES - a cell array of variable names to read in, i.e. the name
% you would pass as the second argument to ncread.
%
% There is an optional argument, force_dims, that controls how the output
% dimensions of the variables are set up. By default, each variable will
% be concatenated along a new dimension, i.e. if U is a 4-D variable in
% the files, then the various files will be concatenated along the 5th
% dimension, whereas if time is a 1-D variable, it will be concatenated
% along the 2nd dimension. However, if force_dims is set to true, all
% variables will be concatenated along the same dimension. So in the
% example above, both U and time will be concatenated along the 5th
% dimension.
%
% This will return the variables in the same order they are named.
%
% Josh Laughner <[email protected]> 28 Aug 2015
E = JLLErrors;
%%%%%%%%%%%%%%%%%%%%%%%
%%%% INPUT PARSING %%%%
%%%%%%%%%%%%%%%%%%%%%%%
if ~ischar(filepath)
E.badinput('filepath must be a string')
elseif ~exist(filepath, 'dir') && ~isempty(filepath)
E.badinput('%s is an invalid directory', filepath)
end
filenames = files_input(filenames);
if ischar(varnames)
varnames = {varnames};
end
if ~iscell(varnames) || any(~iscellcontents(varnames,'ischar'))
E.badinput('varnames must be a cell array of strings or a single string')
elseif ~isvector(varnames)
E.badinput('varnames should be a vector cell array')
end
if ~exist('force_dims','var')
force_dims = false;
elseif ~isscalar(force_dims) || (~isnumeric(force_dims) && ~islogical(force_dims))
E.badinput('force_dims, if given, must be a scalar logical or number than can be converted to a logical')
end
waitbar_bool = false;
if ~exist('DEBUG_LEVEL','var')
DEBUG_LEVEL = 1;
elseif ischar(DEBUG_LEVEL) && strcmpi('visual',DEBUG_LEVEL)
if isDisplay
waitbar_bool = true;
DEBUG_LEVEL = 0;
else
warning('Cannot use waitbar when running in non-GUI mode, defaulting to DEBUG_LEVEL = 1')
DEBUG_LEVEL = 1;
end
elseif ~isscalar(DEBUG_LEVEL) || ~isnumeric(DEBUG_LEVEL)
E.badinput('DEBUG_LEVEL must be a scalar or the string ''visual''')
end
%%%%%%%%%%%%%%%%%%%%%%%
%%%% MAIN FUNCTION %%%%
%%%%%%%%%%%%%%%%%%%%%%%
% Prepare varargout to hold the variables requested
varargout = cell(size(varnames));
n_days = numel(filenames);
wrfi = ncinfo(fullfile(filepath, filenames{1}));
wrf_vars = {wrfi.Variables.Name};
var_dims = zeros(1,numel(varnames)); % used for concatenation
var_sizes = cell(1,numel(varnames)); % used to check each file's variables
% First figure out how many dimensions each variable has; we'll need this
% whether or not force_dims is set to determine which dimension to
% concatenate along.
for a=1:numel(varnames)
vv = strcmp(varnames{a}, wrf_vars);
if sum(vv) < 1
E.callError('var_not_found','Variable %s cannot be found in the first WRF file',varnames{a})
elseif sum(vv) > 1
E.callError('too_many_var','Multiple instances of %s found in the first WRF file',varnames{a})
end
var_dims(a) = numel(wrfi.Variables(vv).Size)+1;
var_sizes{a} = wrfi.Variables(vv).Size;
end
max_dims = max(var_dims);
if force_dims
% Make all concatenate along the same dimension
var_dims(:) = max_dims;
end
% for a=1:numel(varnames)
% vv = strcmp(varnames{a}, wrf_vars);
% if sum(vv) < 1
% E.callError('var_not_found','Variable %s cannot be found in the first WRF file',varnames{a})
% elseif sum(vv) > 1
% E.callError('too_many_var','Multiple instances of %s found in the first WRF file',varnames{a})
% end
%
% if ~force_dims
% sz = [wrfi.Variables(vv).Size, n_days];
% varargout{a} = nan(sz);
% else
% % This will create a matrix with singleton dimensions in any
% % dimensions between its last one and the concatenation dimension.
% sz = wrfi.Variables(vv).Size;
% sz(max_dims) = n_days;
% sz(sz==0) = 1;
% varargout{a} = nan(sz);
% end
% end
% Now go through each file and import each variable into the correct cell
% in varargout, concatenating as we go.
if waitbar_bool
wb = waitbar(0, 'Reading WRF files');
end
for d=1:n_days
if waitbar_bool
waitbar(d/n_days)
end
if DEBUG_LEVEL > 0
fprintf('Reading day %d of %d: ', d, n_days);
end
for a=1:numel(varnames)
if DEBUG_LEVEL > 0
fprintf('%s ', varnames{a});
end
var = ncread(fullfile(filepath, filenames{d}),varnames{a});
% Check that the variables have the same dimensions as the first
% day.
%if (ndims(var) ~= numel(var_sizes{a}) && var_sizes{a}(end) > 1) || (var_sizes{a}(end) > 1 && any(size(var) ~= var_sizes{a}))
% E.callError('import','%s in the file %s is not the same size as in the first .nc file (%s vs. %s in the first)', varnames{a}, filenames{a}, mat2str(size(var)), mat2str(var_sizes{a}));
%end
varargout{a} = cat(var_dims(a), varargout{a}, var);
end
if DEBUG_LEVEL > 0
fprintf('\n');
end
end
if waitbar_bool
close(wb)
end
end