1 | function [data, attribute] = load_nc_struct(nc_file, names); |
---|
2 | % load_nc_struct -- Load NetCDF variables and attributes. |
---|
3 | % |
---|
4 | % [data, attribute] = load_nc_struct('nc_file') loads all variables of |
---|
5 | % 'nc_file' into structure 'data' and all attributes into structure |
---|
6 | % 'attribute', so variable 'X' could then be accessed using 'data.X' |
---|
7 | % and attribute 'long_name' of 'X' could be accessed with |
---|
8 | % 'attribute.X.long_name'. |
---|
9 | |
---|
10 | if nargin < 1, help(mfilename), return, end |
---|
11 | |
---|
12 | result = []; |
---|
13 | if nargout > 0, data = []; attribute = []; end |
---|
14 | |
---|
15 | ncid = netcdf.open(nc_file, 'nowrite'); |
---|
16 | if isempty(ncid), return, end |
---|
17 | disp(['Loading ' nc_file]); |
---|
18 | |
---|
19 | if nargin < 2 |
---|
20 | names = var_names(ncid); |
---|
21 | end |
---|
22 | |
---|
23 | allnames = var_names(ncid); |
---|
24 | |
---|
25 | disp(['Variables:']); |
---|
26 | for ii = 1:length(names) |
---|
27 | if any(strcmp(names{ii},allnames)) |
---|
28 | newname = names{ii}; |
---|
29 | newname(find(newname == '-')) = '_'; |
---|
30 | newname(find(newname == '.')) = '_'; |
---|
31 | newname(find(newname == '@')) = '_'; |
---|
32 | varid = netcdf.inqVarID(ncid, names{ii}); |
---|
33 | |
---|
34 | [varname, xtype,dimids,natts] = netcdf.inqVar(ncid, varid); |
---|
35 | |
---|
36 | [add_offset, scale_factor] = get_scaling(ncid, varid); |
---|
37 | |
---|
38 | if xtype == netcdf.getConstant('NC_FLOAT') | ~isempty(add_offset) | ~isempty(scale_factor) |
---|
39 | missing_value = double(get_missing_value(ncid, varid)); |
---|
40 | data.(newname) = double(netcdf.getVar(ncid, varid)); |
---|
41 | else |
---|
42 | missing_value = get_missing_value(ncid, varid); |
---|
43 | data.(newname) = netcdf.getVar(ncid, varid); |
---|
44 | end |
---|
45 | |
---|
46 | if ~isempty(missing_value) |
---|
47 | data.(newname)(find(data.(newname) == missing_value)) = NaN; |
---|
48 | end |
---|
49 | |
---|
50 | if ~isempty(scale_factor) |
---|
51 | data.(newname) = data.(newname) .* scale_factor; |
---|
52 | else |
---|
53 | scale_factor = 1.0; |
---|
54 | end |
---|
55 | if ~isempty(add_offset) |
---|
56 | data.(newname) = data.(newname) + add_offset; |
---|
57 | else |
---|
58 | add_offset = 0.0; |
---|
59 | end |
---|
60 | |
---|
61 | if nargout > 1 |
---|
62 | % Do attributes |
---|
63 | for jj = 1:natts |
---|
64 | % Check for underscore starting attribute name |
---|
65 | attname = netcdf.inqAttName(ncid, varid, jj-1); |
---|
66 | attname_mod = attname; |
---|
67 | if strcmp(attname,'_FillValue') |
---|
68 | attname_mod = 'FillValue_'; |
---|
69 | elseif attname(1) == '_' |
---|
70 | warning([newname '.' attname ' changed to ' names{ii} ':X' attname]); |
---|
71 | attname = ['X' attname]; |
---|
72 | end |
---|
73 | eval(['attribute.' names{ii} '.' attname_mod ' = netcdf.getAtt(ncid, varid, attname);']); |
---|
74 | end |
---|
75 | end |
---|
76 | |
---|
77 | the_size = size(data.(newname)); |
---|
78 | if the_size(end) == 1; |
---|
79 | the_size = the_size(1:end-1); |
---|
80 | end |
---|
81 | |
---|
82 | long_name = ''; |
---|
83 | try |
---|
84 | long_name = netcdf.getAtt(ncid, varid, 'long_name'); |
---|
85 | long_name = clean_up_string(long_name); |
---|
86 | long_name = ['"' long_name '"']; |
---|
87 | end |
---|
88 | units = ''; |
---|
89 | try |
---|
90 | units = netcdf.getAtt(ncid, varid, 'units'); |
---|
91 | units = clean_up_string(units); |
---|
92 | units = [' (' units ')']; |
---|
93 | end |
---|
94 | |
---|
95 | names{ii} = newname; |
---|
96 | |
---|
97 | |
---|
98 | size_str = num2str(the_size(1)); |
---|
99 | for ii = 2:length(the_size); |
---|
100 | size_str = [size_str ',' num2str(the_size(ii))]; |
---|
101 | end |
---|
102 | |
---|
103 | newname = [newname ' (' size_str ')']; |
---|
104 | |
---|
105 | namefill = blanks(max(0,30-length(newname))); |
---|
106 | |
---|
107 | |
---|
108 | if add_offset ~= 0.0 | scale_factor ~= 1.0 |
---|
109 | scale_str = ' scaled'; |
---|
110 | else |
---|
111 | scale_str = ''; |
---|
112 | end |
---|
113 | disp([namefill newname ': ' long_name units scale_str]); |
---|
114 | |
---|
115 | end |
---|
116 | end |
---|
117 | |
---|
118 | %if nargout > 1 |
---|
119 | % Do global attributes |
---|
120 | % disp('Global attributes:'); |
---|
121 | % attnames = ncnames(att(f)); |
---|
122 | %for ii = 1:length(attnames) |
---|
123 | % if isempty(find(attnames{ii} == '/' | attnames{ii} == '-' | attnames{ii} == '+' | attnames{ii} == ' ') > 0) |
---|
124 | % eval(['attr = f.' attnames{ii} '(:);']); |
---|
125 | % if ischar(attr) |
---|
126 | % attr = clean_up_string(attr); |
---|
127 | % end |
---|
128 | % eval(['attribute.global.' attnames{ii} ' = attr;']); |
---|
129 | % namefill = blanks(max(0,14-length(attnames{ii}))); |
---|
130 | % disp([namefill attnames{ii} ': ' num2str(attr)]); |
---|
131 | % else |
---|
132 | % disp(['Attribute name ' attnames{ii} ' incompatible with Matlab - not loaded.']) |
---|
133 | % end |
---|
134 | %end |
---|
135 | %end |
---|
136 | netcdf.close(ncid) |
---|
137 | |
---|
138 | function newstr = clean_up_string(oldstr) |
---|
139 | newstr = num2str(oldstr); |
---|
140 | if length(newstr) > 1 |
---|
141 | if newstr(end-1) == '\' & newstr(end) == '0' |
---|
142 | newstr = deblank(newstr(1:end-2)); |
---|
143 | end |
---|
144 | end |
---|
145 | |
---|
146 | function names = var_names(ncid) |
---|
147 | [ndims,nvars,ngatts,unlimdimid] = netcdf.inq(ncid); |
---|
148 | for ii = 0:nvars-1 |
---|
149 | names{ii+1} = netcdf.inqVar(ncid, ii); |
---|
150 | end |
---|
151 | |
---|
152 | function missing_value = get_missing_value(ncid, varid) |
---|
153 | missing_value = []; |
---|
154 | try |
---|
155 | missing_value = netcdf.getAtt(ncid, varid, 'missing_value'); |
---|
156 | catch exception |
---|
157 | try |
---|
158 | missing_value = netcdf.getAtt(ncid, varid, '_FillValue'); |
---|
159 | end |
---|
160 | end |
---|
161 | |
---|
162 | function [add_offset,scale_factor] = get_scaling(ncid, varid) |
---|
163 | add_offset = []; |
---|
164 | scale_factor = []; |
---|
165 | try |
---|
166 | add_offset = netcdf.getAtt(ncid, varid, 'add_offset'); |
---|
167 | end |
---|
168 | try |
---|
169 | scale_factor = netcdf.getAtt(ncid, varid, 'scale_factor'); |
---|
170 | end |
---|