| 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 |
|---|