Changeset 27875 for issm/trunk/src/m/contrib/musselman/read_netCDF.m
- Timestamp:
- 08/10/23 18:34:53 (20 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/m/contrib/musselman/read_netCDF.m
r27874 r27875 17 17 18 18 function model_copy = read_netCDF(filename) 19 fprintf('NetCDF42C v1.1.1 3\n');19 fprintf('NetCDF42C v1.1.14\n'); 20 20 21 21 % make a model framework to fill that is in the scope of this file … … 109 109 for variable = variables 110 110 [varname, xtype, dimids, numatts] = netcdf.inqVar(group_location_in_file, variable); 111 copy_variable_data_to_new_model(group_location_in_file,varname, xtype); 111 112 % keep an eye out for nested structs: 113 if strcmp(varname, 'this_is_a_nested') 114 is_nested = true; 115 copy_nested_struct(group_location_in_file) 116 else 117 is_nested = false; 118 copy_variable_data_to_new_model(group_location_in_file,varname, xtype); 119 end 112 120 end 113 121 catch ME … … 117 125 % try to find groups in current level, if it doesn't work it's because there is nothing there 118 126 try 119 % search for nested groups in the current level to feed back to this function 120 groups = netcdf.inqGrps(group_location_in_file); 121 if not(isempty(groups)) 122 for group = groups 123 %disp('found nested group!!') 124 group_id = netcdf.inqNcid(group_location_in_file, netcdf.inqGrpName(group)); 125 %disp(netcdf.inqGrpNameFull(group_id)) 126 walk_nested_groups(group); 127 end 128 end 129 catch 130 end 131 end 127 % if it's not a nested struct, keep searching for subgroups 128 if isnested 129 % do nothing 130 else 131 % search for nested groups in the current level to feed back to this function 132 groups = netcdf.inqGrps(group_location_in_file); 133 if not(isempty(groups)) 134 for group = groups 135 %disp('found nested group!!') 136 group_id = netcdf.inqNcid(group_location_in_file, netcdf.inqGrpName(group)); 137 %disp(netcdf.inqGrpNameFull(group_id)) 138 walk_nested_groups(group); 139 end 140 end 141 end 142 catch % no nested groups here 143 end 144 end 145 146 147 148 function copy_nested_struct(group_location_in_file) 149 global model_copy; 150 global NCData; 151 %{ 152 A common multidimensional struct array is the 1xn md.results.TransientSolution struct. 153 The process to recreate is as follows: 154 1. Get the name of the struct from group variable name_of_struct 155 2. Get the fieldnames from the subgroups 156 3. Recreate the struct with fieldnames 157 4. Populate the fields with their respective values 158 %} 159 160 % step 1 161 varid = netcdf.inqVarID(group_location_in_file, 'name_of_struct'); 162 name_of_struct = netcdf.getVar(group_location_in_file, varid)'; 163 164 % step 2 165 subgroups = netcdf.inqGrps(group_location_in_file); % numerical cell array with ID's of subgroups 166 % get single subgroup's data 167 single_subgroup_ID = subgroups(1); 168 subgroup_varids = netcdf.inqVarIDs(single_subgroup_ID); 169 fieldnames = {}; 170 for variable = subgroup_varids 171 [varname, xtype, dimids, numatts] = netcdf.inqVar(single_subgroup_ID, variable); 172 fieldnames{end+1} = varname; 173 end 174 175 % step 3 176 address_in_model = strrep(netcdf.inqGrpNameFull(group_location_in_file), '/', ''); 177 % we cannot assign a variable to represent this object as MATLAB treats all variables as copies 178 % and not pointers to the same memory address 179 % this means that if address_in_model is more than 1 item, we need to modify the code. For now, 180 % we just hope this will do 181 182 model_copy.(address_in_model).(name_of_struct) = struct(); 183 184 % for every fieldname in the subgroup, create an empty field 185 for fieldname = string(fieldnames) 186 model_copy.(address_in_model).(name_of_struct).(fieldname) = {}; 187 end 188 189 % use repmat to make the struct array multidimensional along the fields axis 190 number_of_dimensions = numel(subgroups); 191 model_copy.(address_in_model).(name_of_struct) = repmat(model_copy.(address_in_model).(name_of_struct), 1, number_of_dimensions); 192 193 % step 4 194 % for every layer of the multidimensional struct array, populate the fields 195 for current_layer = 1:number_of_dimensions 196 % choose subgroup 197 current_layer_subgroup_ID = subgroups(current_layer); 198 % get all vars 199 current_layer_subgroup_varids = netcdf.inqVarIDs(current_layer_subgroup_ID); 200 % get individual vars and set fields at layer current_layer 201 for varid = current_layer_subgroup_varids 202 [varname, xtype, dimids, numatts] = netcdf.inqVar(current_layer_subgroup_ID, varid); 203 data = netcdf.getVar(current_layer_subgroup_ID, varid); 204 205 % netcdf uses Row Major Order but MATLAB uses Column Major Order so we need to transpose all arrays w/ more than 1 dim 206 if all(size(data)~=1) || xtype == 2 207 data = data.'; 208 end 209 210 % set the field 211 model_copy.(address_in_model).(name_of_struct)(current_layer).(varname) = data; 212 %address_to_struct_in_model = setfield(address_to_struct_in_model(current_layer), varname, data) 213 end 214 model_copy.(address_in_model).(name_of_struct)(current_layer); 215 fprintf("Successfully saved layer %s to multidimension struct array\n", num2str(current_layer)) 216 end 217 fprintf('Successfully recreated multidimensional structure array %s in md.%s\n', name_of_struct, address_in_model) 218 end 219 220 221 132 222 133 223 %{ … … 142 232 %disp(varname) 143 233 % this is an inversion band-aid 144 if strcmp(varname, 'inversion_class_name') 234 if strcmp(varname, 'inversion_class_name') || strcmp(varname, 'name_of_struct') || strcmp(varname, 'solution') 145 235 % we don't need this 146 236 else … … 149 239 %disp(netcdf.inqGrpNameFull(group_location_in_file)) 150 240 %disp(class(netcdf.inqGrpNameFull(group_location_in_file))) 151 ad ress_to_attr = strrep(netcdf.inqGrpNameFull(group_location_in_file), '/', '.');152 153 data = netcdf.getVar(group_location_in_file, netcdf.inqVarID(group_location_in_file, varname));154 155 156 % matlab needs to know that ' ' = char()241 address_to_attr = strrep(netcdf.inqGrpNameFull(group_location_in_file), '/', '.'); 242 varid = netcdf.inqVarID(group_location_in_file, varname); 243 data = netcdf.getVar(group_location_in_file, varid); 244 245 246 % if we have an empty string 157 247 if xtype == 2 && isempty(all(data)) 158 248 data = cell(char()); 249 % if we have an empty cell-char array 159 250 elseif numel(data) == 1 && xtype == 3 && data == -32767 160 251 data = cell(char()); 161 252 end 162 % band-aid for cell-char-arrays:253 % band-aid for some cell-char-arrays: 163 254 if xtype == 2 && strcmp(data, 'default') 164 255 data = {'default'}; … … 168 259 if all(size(data)~=1) || xtype == 2 169 260 data = data.'; 261 end 262 263 % if we have a list of strings 264 if xtype == 2 265 try 266 if strcmp(netcdf.getAtt(group, varid, "type_is"), 'cell_array_of_strings') 267 data = cellstr(data) 268 end 269 catch 270 % no attr found so we pass 271 end 170 272 end 171 273 … … 174 276 %xtype 175 277 if xtype == 10 176 arg_to_eval = ['model_copy', ad ress_to_attr, '.', varname, ' = ' , 'double(data);'];278 arg_to_eval = ['model_copy', address_to_attr, '.', varname, ' = ' , 'double(data);']; 177 279 eval(arg_to_eval); 178 280 %disp('saved int64 as int16') 179 281 else 180 arg_to_eval = ['model_copy', ad ress_to_attr, '.', varname, ' = ' , 'data;'];282 arg_to_eval = ['model_copy', address_to_attr, '.', varname, ' = ' , 'data;']; 181 283 eval(arg_to_eval); 182 284 end
Note:
See TracChangeset
for help on using the changeset viewer.