Changeset 27884
- Timestamp:
- 08/22/23 17:37:20 (19 months ago)
- Location:
- issm/trunk/src/m/contrib/musselman
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified issm/trunk/src/m/contrib/musselman/read_netCDF.m ¶
r27877 r27884 17 17 18 18 function model_copy = read_netCDF(filename) 19 fprintf('NetCDF42C v1.1.14\n'); 20 19 if nargin > 1 20 verbose = true; 21 else 22 verbose = false; 23 end 24 25 if verbose 26 fprintf('NetCDF42C v1.1.14\n'); 27 end 21 28 % make a model framework to fill that is in the scope of this file 22 29 global model_copy; … … 25 32 % Check if path exists 26 33 if exist(filename, 'file') 27 fprintf('Opening %s for reading\n', filename); 34 if verbose 35 fprintf('Opening %s for reading\n', filename); 36 end 28 37 29 38 % Open the given netCDF4 file … … 35 44 % see if results is in there, if it is we have to instantiate some classes 36 45 try 37 results_group_id = netcdf.inqNcid(NCData, "results" );38 make_results_subclasses( );46 results_group_id = netcdf.inqNcid(NCData, "results", verbose); 47 make_results_subclasses(verbose); 39 48 catch 40 49 end % 'results' group doesn't exist … … 43 52 try 44 53 inversion_group_id = netcdf.inqNcid(NCData, "inversion"); 45 check_inversion_class( );54 check_inversion_class(verbose); 46 55 catch 47 56 end % 'inversion' group doesn't exist … … 52 61 %disp(netcdf.inqGrpNameFull(group_id)) 53 62 % hand off first level to recursive search 54 walk_nested_groups(group_id );63 walk_nested_groups(group_id, verbose); 55 64 end 56 65 57 66 % Close the netCDF file 58 67 netcdf.close(NCData); 59 disp('Model Successfully Copied') 68 if verbose 69 disp('Model Successfully Copied') 70 end 60 71 else 61 72 fprintf('File %s does not exist.\n', filename); … … 64 75 65 76 66 function make_results_subclasses( )77 function make_results_subclasses(verbose) 67 78 global model_copy; 68 79 global NCData; … … 79 90 %model_copy.results = setfield(model_copy.results, class_instance, class_instance_name); 80 91 end 81 disp('Successfully recreated results structs:') 82 for fieldname = string(fieldnames(model_copy.results)) 83 disp(fieldname) 84 end 85 end 86 87 88 function check_inversion_class() 92 if verbose 93 disp('Successfully recreated results structs:') 94 for fieldname = string(fieldnames(model_copy.results)) 95 disp(fieldname) 96 end 97 end 98 end 99 100 101 function check_inversion_class(verbose) 89 102 % get the name of the inversion class: either inversion or m1qn3inversion or taoinversion 90 103 global model_copy; … … 95 108 if strcmp(inversion_class, 'm1qn3inversion') 96 109 model_copy.inversion = m1qn3inversion(); 97 disp('Successfully created inversion class instance: m1qn3inversion') 110 if verbose 111 disp('Successfully created inversion class instance: m1qn3inversion') 112 end 98 113 elseif strcmp(inversion_class, 'taoinversion') 99 114 model_copy.inversion = taoinversion(); 100 disp('Successfully created inversion class instance: taoinversion') 101 else 102 disp('No inversion class was found') 103 end 104 end 105 106 107 108 function walk_nested_groups(group_location_in_file) 115 if verbose 116 disp('Successfully created inversion class instance: taoinversion') 117 end 118 else 119 if verbose 120 disp('No inversion class was found') 121 end 122 end 123 end 124 125 126 function walk_nested_groups(group_location_in_file, verbose) 109 127 global model_copy; 110 128 global NCData; … … 119 137 if strcmp(varname, 'this_is_a_nested') 120 138 is_nested = true; 121 copy_nested_struct(group_location_in_file )139 copy_nested_struct(group_location_in_file, verbose) 122 140 elseif strcmp(varname, 'solution') 123 141 % band-aid pass.. 124 142 else 125 copy_variable_data_to_new_model(group_location_in_file, varname, xtype );143 copy_variable_data_to_new_model(group_location_in_file, varname, xtype, verbose); 126 144 end 127 145 end … … 139 157 group_id = netcdf.inqNcid(group_location_in_file, netcdf.inqGrpName(group)); 140 158 %disp(netcdf.inqGrpNameFull(group_id)) 141 walk_nested_groups(group );159 walk_nested_groups(group, verbose); 142 160 end 143 161 end … … 149 167 150 168 151 function copy_nested_struct(group_location_in_file )169 function copy_nested_struct(group_location_in_file, verbose) 152 170 global model_copy; 153 171 global NCData; … … 216 234 end 217 235 model_copy.(address_in_model).(name_of_struct)(current_layer); 218 fprintf("Successfully saved layer %s to multidimension struct array\n", num2str(current_layer)) 219 end 220 fprintf('Successfully recreated multidimensional structure array %s in md.%s\n', name_of_struct, address_in_model) 236 if verbose 237 fprintf("Successfully saved layer %s to multidimension struct array\n", num2str(current_layer)) 238 end 239 end 240 if verbose 241 fprintf('Successfully recreated multidimensional structure array %s in md.%s\n', name_of_struct, address_in_model) 242 end 221 243 end 222 244 … … 230 252 %} 231 253 232 function copy_variable_data_to_new_model(group_location_in_file, varname, xtype )254 function copy_variable_data_to_new_model(group_location_in_file, varname, xtype, verbose) 233 255 global model_copy; 234 256 global NCData; … … 289 311 end 290 312 291 full_addy = netcdf.inqGrpNameFull(group_location_in_file); 292 %disp(xtype) 293 %class(data) 294 fprintf('Successfully saved %s to %s\n', varname, full_addy); 295 296 catch Me %e is an MException struct 313 if verbose 314 full_addy = netcdf.inqGrpNameFull(group_location_in_file); 315 %disp(xtype) 316 %class(data) 317 fprintf('Successfully saved %s to %s\n', varname, full_addy); 318 end 319 320 catch ME %ME is an MException struct 297 321 % Some error occurred if you get here. 298 322 fprintf(1,'There was an error with %s! \n', varname) … … 300 324 fprintf(1, '%s\n', errorMessage); 301 325 uiwait(warndlg(errorMessage)); 302 %line = M e.stack.line326 %line = ME.stack.line 303 327 %fprintf(1,'There was an error with %s! \n', varname) 304 %fprintf('The message was:\n%s\n',M e.message);305 %fprintf(1,'The identifier was:\n%s\n',M e.identifier);328 %fprintf('The message was:\n%s\n',ME.message); 329 %fprintf(1,'The identifier was:\n%s\n',ME.identifier); 306 330 307 331 % more error handling... … … 309 333 end 310 334 end 311 312 313 -
TabularUnified issm/trunk/src/m/contrib/musselman/read_netCDF.py ¶
r27882 r27884 12 12 13 13 14 15 14 ''' 16 15 Given a NetCDF4 file, this set of functions will perform the following: … … 24 23 model_copy = model() 25 24 26 27 def read_netCDF(filename):28 print('NetCDF42C v1.1.13')25 def read_netCDF(filename, verbose = False): 26 if verbose: 27 print('NetCDF42C v1.1.13') 29 28 30 29 # check if path exists 31 30 if path.exists(filename): 32 print('Opening {} for reading'.format(filename)) 31 if verbose: 32 print('Opening {} for reading'.format(filename)) 33 else: pass 33 34 34 35 # open the given netCDF4 file … … 39 40 else: 40 41 print('The file you entered does not exist or cannot be found in the current directory') 42 return print() 41 43 42 44 # continuation of band-aid for results class 43 45 try: 44 46 NCData.groups['results'] 45 make_results_subclasses( )47 make_results_subclasses(verbose) 46 48 except: 47 49 pass … … 50 52 try: 51 53 NCData.groups['inversion'] 52 check_inversion_class( )54 check_inversion_class(verbose) 53 55 except: 54 56 pass … … 61 63 # have to send a custom name to this function: filename.groups['group'] 62 64 name = "NCData.groups['" + str(group) + "']" 63 walk_nested_groups(name) 64 65 print("Model Successfully Recreated.") 65 walk_nested_groups(name, verbose) 66 67 if verbose: 68 print("Model Successfully Recreated.") 66 69 return model_copy 67 70 68 71 69 def make_results_subclasses( ):72 def make_results_subclasses(verbose = False): 70 73 ''' 71 74 There are 3 possible subclasses: solution, solutionstep, resultsdakota. … … 86 89 # from here we can make new subclasses named as they were in the model saved 87 90 setattr(model_copy.results, class_instance_name, eval(class_instance)) 88 print(f'Successfully created results subclass instance {class_instance} named {class_instance_name}.') 89 90 91 def check_inversion_class(): 91 if verbose: 92 print(f'Successfully created results subclass instance {class_instance} named {class_instance_name}.') 93 94 95 def check_inversion_class(verbose = False): 92 96 # get the name of the inversion class: either inversion or m1qn3inversion or taoinversion 93 97 inversion_class_is = NCData.groups['inversion'].variables['inversion_class_name'][:][...].tobytes().decode() … … 95 99 # if it is m1qn3inversion we need to instantiate that class since it's not native to model() 96 100 model_copy.inversion = m1qn3inversion(model_copy.inversion) 97 print('Conversion successful') 101 if verbose: 102 print('Conversion successful') 98 103 elif inversion_class_is == 'taoinversion': 99 104 # if it is taoinversion we need to instantiate that class since it's not native to model() 100 105 model_copy.inversion = taoinverion() 101 print('Conversion successful') 106 if verbose: 107 print('Conversion successful') 102 108 else: pass 103 109 104 110 105 106 def walk_nested_groups(group_location_in_file): 111 def walk_nested_groups(group_location_in_file, verbose = False): 107 112 # first, we enter the group by: filename.groups['group_name'] 108 113 # second we search the current level for variables: filename.groups['group_name'].variables.keys() … … 140 145 variable_name = matches[-1] 141 146 location_of_variable_in_model = '.'.join(matches[:-1]) 142 copy_variable_data_to_new_model(location_of_variable_in_file, location_of_variable_in_model, variable_name )147 copy_variable_data_to_new_model(location_of_variable_in_file, location_of_variable_in_model, variable_name, verbose=verbose) 143 148 144 149 if 'istruct' in locals(): … … 147 152 for nested_group in eval(group_location_in_file + '.groups.keys()'): 148 153 new_nested_group = group_location_in_file + ".groups['" + str(nested_group) + "']" 149 walk_nested_groups(new_nested_group )154 walk_nested_groups(new_nested_group, verbose=verbose) 150 155 151 156 … … 158 163 ''' 159 164 160 def copy_multidimensional_results_struct(group_location_in_file, name_of_struct ):165 def copy_multidimensional_results_struct(group_location_in_file, name_of_struct, verbose = False): 161 166 ''' 162 167 A common multidimensional array is the 1xn md.results.TransientSolution object. … … 189 194 # step 2b 190 195 steps.append(solutionstep_instance) 191 print('Succesfully saved layer ' + str(layer) + ' to results.' + str(class_instance_name) + ' struct.') 196 if verbose: 197 print('Succesfully saved layer ' + str(layer) + ' to results.' + str(class_instance_name) + ' struct.') 198 else: pass 192 199 layer += 1 193 200 194 print('Successfully recreated results structure ' + str(class_instance_name))195 196 197 198 def copy_variable_data_to_new_model(location_of_variable_in_file, location_of_variable_in_model, variable_name ):201 if verbose: 202 print('Successfully recreated results structure ' + str(class_instance_name)) 203 204 205 def copy_variable_data_to_new_model(location_of_variable_in_file, location_of_variable_in_model, variable_name, verbose = False): 199 206 # as simple as navigating to the location_of_variable_in_model and setting it equal to the location_of_variable_in_file 200 207 # NetCDF4 has a property called "_FillValue" that sometimes saves empty lists, so we have to catch those … … 236 243 setattr(eval('model_copy.' + location_of_variable_in_model), variable_name, var_to_save.item()) 237 244 except: 238 setattr(eval('model_copy.' + location_of_variable_in_model), variable_name, eval(location_of_variable_in_file + '[:] .item()'))245 setattr(eval('model_copy.' + location_of_variable_in_model), variable_name, eval(location_of_variable_in_file + '[:]')) 239 246 except AttributeError: 240 copy_variable_data_to_new_model_dict(location_of_variable_in_file, location_of_variable_in_model) 241 242 print('Successfully saved ' + location_of_variable_in_model + '.' + variable_name + ' to model.') 243 244 245 246 247 248 249 def copy_variable_data_to_new_model_dict(location_of_variable_in_file, location_of_variable_in_model): 247 copy_variable_data_to_new_model_dict(location_of_variable_in_file, location_of_variable_in_model, verbose=verbose) 248 249 if verbose: 250 print('Successfully saved ' + location_of_variable_in_model + '.' + variable_name + ' to model.') 251 252 253 def copy_variable_data_to_new_model_dict(location_of_variable_in_file, location_of_variable_in_model, verbose = False): 250 254 # as simple as navigating to the location_of_variable_in_model and setting it equal to the location_of_variable_in_file 251 255 … … 297 301 else: 298 302 print(f"Unrecognized object was saved and cannot be reconstructed: {location_of_variable_in_model}") 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 -
TabularUnified issm/trunk/src/m/contrib/musselman/write_netCDF.m ¶
r27877 r27884 11 11 12 12 function write_netCDF(model_var, filename) 13 disp('MATLAB C2NetCDF4 v1.1.14'); 13 if nargin > 2 14 verbose = true; 15 else 16 verbose = false; 17 end 18 if verbose 19 disp('MATLAB C2NetCDF4 v1.1.14'); 20 end 14 21 % model_var = class object to be saved 15 22 % filename = path and name to save file under 16 23 17 24 % Create a NetCDF file to write to 18 make_NetCDF(filename );25 make_NetCDF(filename, verbose); 19 26 20 27 % Create an instance of an empty model class to compare model_var against … … 23 30 24 31 % Walk through the model_var class and compare subclass states to empty_model 25 walk_through_model(model_var );32 walk_through_model(model_var, verbose); 26 33 27 34 % in order to handle some subclasses in the results class, we have to utilize this band-aid … … 31 38 % if results had meaningful data, save the name of the subclass and class instance 32 39 netcdf.inqNcid(NetCDF,'results'); 33 results_subclasses_bandaid(model_var );40 results_subclasses_bandaid(model_var, verbose); 34 41 % otherwise, ignore 35 42 catch … … 37 44 38 45 netcdf.close(NetCDF); 39 disp('Model successfully saved as NetCDF4'); 40 end 41 42 43 44 function make_NetCDF(filename) 46 if verbose 47 disp('Model successfully saved as NetCDF4'); 48 end 49 end 50 51 52 53 function make_NetCDF(filename, verbose) 45 54 % matlab can't handle input in the jupyter interface, so we just yell at the user to rename 46 55 % their file if needed … … 68 77 netcdf.defDim(NetCDF, 'float', 1); % single integer dimension 69 78 netcdf.defDim(NetCDF, 'int', 1); % single float dimension 70 71 fprintf('Successfully created %s\n', filename); 79 80 if verbose 81 fprintf('Successfully created %s\n', filename); 82 end 72 83 end 73 84 end … … 82 93 %} 83 94 84 function results_subclasses_bandaid(model_var )95 function results_subclasses_bandaid(model_var, verbose) 85 96 global NetCDF; 86 97 % The results class may have nested fields within it, so we need to record the name of … … 95 106 96 107 % Loop through each class instance in results 97 class_instance_names = fieldnames(results_var) 108 class_instance_names = fieldnames(results_var); 98 109 99 110 % we save lists of instances to the netcdf 100 solutions = {} 101 solutionsteps = {} 102 resultsdakotas = {} 111 solutions = {}; 112 solutionsteps = {}; 113 resultsdakotas = {}; 103 114 104 115 for i = 1:numel(class_instance_names) … … 108 119 if contains(class_instance_name, 'solutionstep',IgnoreCase=true) 109 120 quality_control{end+1} = 1; 110 solutionsteps{end+1} = class_instance_name 121 solutionsteps{end+1} = class_instance_name; 111 122 %varname = ['solutionstep', num2str(i)] 112 123 %write_string_to_netcdf(varname, class_instance_name, groupid); 113 disp('Successfully stored class python subclass instance: solutionstep') 124 if verbose 125 disp('Successfully stored class python subclass instance: solutionstep') 126 end 114 127 end 115 128 … … 117 130 if contains(class_instance_name, 'solution',IgnoreCase=true) 118 131 quality_control{end+1} = 1; 119 solutions{end+1} = class_instance_name 132 solutions{end+1} = class_instance_name; 120 133 %varname = ['solution', num2str(i)] 121 134 %write_string_to_netcdf(varname, class_instance_name, groupid); 122 disp('Successfully stored class python subclass instance: solution') 135 if verbose 136 disp('Successfully stored class python subclass instance: solution') 137 end 123 138 end 124 139 … … 126 141 if contains(class_instance_name, 'resultsdakota',IgnoreCase=true) 127 142 quality_control{end+1} = 1; 128 resultsdakotas{end+1} = class_instance_name 143 resultsdakotas{end+1} = class_instance_name; 129 144 %varname = ['resultsdakota', num2str(i)] 130 145 %write_string_to_netcdf(varname, class_instance_name, groupid); 131 disp('Successfully stored class python subclass instance: resultsdakota') 146 if verbose 147 disp('Successfully stored class python subclass instance: resultsdakota') 148 end 132 149 end 133 150 end 134 151 if ~isempty(solutionsteps) 135 write_cell_with_strings('solutionstep', solutionsteps, groupid )152 write_cell_with_strings('solutionstep', solutionsteps, groupid, verbose) 136 153 end 137 154 if ~isempty(solutions) 138 write_cell_with_strings('solution', solutions, groupid )155 write_cell_with_strings('solution', solutions, groupid, verbose) 139 156 end 140 157 if ~isempty(resultsdakotas) 141 write_cell_with_strings('resultsdakota', resultsdakotas, groupid )158 write_cell_with_strings('resultsdakota', resultsdakotas, groupid, verbose) 142 159 end 143 160 … … 155 172 156 173 157 function walk_through_model(model_var )174 function walk_through_model(model_var, verbose) 158 175 global empty_model; 159 176 % Iterate over first layer of model_var attributes and assume this first layer is only classes fundamental to the model() class … … 166 183 % Now we can recursively walk through the remaining subclasses 167 184 list_of_layers = {groups{group}}; 168 walk_through_subclasses(model_subclass, empty_model_subclass, list_of_layers );169 end 170 end 171 172 173 function walk_through_subclasses(model_subclass, empty_model_subclass, given_list_of_layers )185 walk_through_subclasses(model_subclass, empty_model_subclass, list_of_layers, verbose); 186 end 187 end 188 189 190 function walk_through_subclasses(model_subclass, empty_model_subclass, given_list_of_layers, verbose) 174 191 % Recursivley iterate over each subclass' attributes and look for more subclasses and variables with relevant data 175 192 % model_subclass is an object (ie, md.mesh.elements) … … 179 196 if strcmp(given_list_of_layers{1}, 'inversion') 180 197 create_group(model_subclass, given_list_of_layers); 181 check_inversion_class(model_subclass );198 check_inversion_class(model_subclass, verbose); 182 199 end 183 200 end … … 203 220 % if the current field is a nested struct assume it has valuable data that needs to be saved 204 221 if isstruct(location_of_child) && any(size(location_of_child) > 1) 205 create_group(location_of_child, list_of_layers );222 create_group(location_of_child, list_of_layers, verbose); 206 223 207 224 % this would mean that the layer above the layer we're interested in is a struct, so … … 213 230 % if the current attribute is a numerical array assume it has valuable data that needs to be saved 214 231 if isnumeric(location_of_child) && logical(numel(location_of_child) > 1) 215 create_group(location_of_child, list_of_layers );232 create_group(location_of_child, list_of_layers, verbose); 216 233 % if the attributes are identical we don't need to save anything 217 234 elseif (all(isnan(location_of_child)) && all(isnan(location_of_child_in_empty_model))) || isempty(setxor(location_of_child, location_of_child_in_empty_model)) 218 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers );235 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers, verbose); 219 236 % if the attributes are not the same we need to save ours 220 237 else 221 238 % THE ORDER OF THESE LINES IS CRITICAL 222 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers );223 create_group(location_of_child, list_of_layers );239 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers, verbose); 240 create_group(location_of_child, list_of_layers, verbose); 224 241 end 225 242 % this would mean that the layer we're interested in is not fundamental to the model architecture 226 243 % and thus needs to be saved to the netcdf 227 244 else 228 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers );229 create_group(location_of_child, list_of_layers );245 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, verbose); 246 create_group(location_of_child, list_of_layers, verbose); 230 247 end 231 248 % this would mean it's not a struct, and must be a class/subclass … … 238 255 % if the current attribute is a numerical array assume it has valuable data that needs to be saved 239 256 if isnumeric(location_of_child) && logical(numel(location_of_child) > 1) 240 create_group(location_of_child, list_of_layers );257 create_group(location_of_child, list_of_layers, verbose); 241 258 242 259 elseif iscell(location_of_child) … … 246 263 else 247 264 % otherwise we need to save 248 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers );249 create_group(location_of_child, list_of_layers );265 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, verbose); 266 create_group(location_of_child, list_of_layers, verbose); 250 267 end 251 268 elseif (all(isnan(location_of_child)) && all(isnan(location_of_child_in_empty_model))) 252 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers );269 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers, verbose); 253 270 % if the attributes are not the same we need to save ours 254 271 else 255 272 % THE ORDER OF THESE LINES IS CRITICAL 256 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers );257 create_group(location_of_child, list_of_layers );273 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers, verbose); 274 create_group(location_of_child, list_of_layers, verbose); 258 275 end 259 276 else 260 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers );261 create_group(location_of_child, list_of_layers );277 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, verbose); 278 create_group(location_of_child, list_of_layers, verbose); 262 279 end 263 280 catch 264 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers );265 create_group(location_of_child, list_of_layers );281 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, verbose); 282 create_group(location_of_child, list_of_layers, verbose); 266 283 end 267 284 end … … 273 290 % this is if we come accross instances/subfields in our model that are not fundamental to the model class (ie, taoinversion) 274 291 elseif strcmp(ME.identifier, 'MATLAB:UndefinedFunction') 275 walk_through_subclasses(location_of_child, empty_model_subclass, given_list_of_layers );276 create_group(location_of_child, list_of_layers );292 walk_through_subclasses(location_of_child, empty_model_subclass, given_list_of_layers, verbose); 293 create_group(location_of_child, list_of_layers, verbose); 277 294 % If it's a different error, rethrow it to MATLAB's default error handling 278 295 else … … 285 302 286 303 287 function create_group(location_of_child, list_of_layers )304 function create_group(location_of_child, list_of_layers, verbose) 288 305 global NetCDF; 289 306 % location_of_child is an object … … 319 336 elseif isstruct(location_of_child) && any(size(location_of_child) > 1) 320 337 % we have a nested struct 321 copy_nested_struct(variable_name, location_of_child, group )338 copy_nested_struct(variable_name, location_of_child, group, verbose) 322 339 end 323 340 catch 324 341 % if that line doesn't work, it means we're dealing with raw data 325 342 % not a nested struct, so we can pass 326 create_var(variable_name, location_of_child, group );327 end 328 end 329 330 331 332 function copy_nested_struct(parent_struct_name, address_of_struct, group )343 create_var(variable_name, location_of_child, group, verbose); 344 end 345 end 346 347 348 349 function copy_nested_struct(parent_struct_name, address_of_struct, group, verbose) 333 350 %{ 334 351 This function takes a struct of structs and saves them to netcdf. … … 340 357 %} 341 358 342 disp("Beginning transfer of nested MATLAB struct to the NetCDF") 359 if verbose 360 disp("Beginning transfer of nested MATLAB struct to the NetCDF") 361 end 343 362 % make a new subgroup to contain all the others: 344 363 group = netcdf.defGrp(group, parent_struct_name); … … 368 387 for variable_name = string(substruct_fields) 369 388 address_of_child = current_substruct.(variable_name); 370 create_var(variable_name, address_of_child, subgroup); 371 end 372 end 373 fprintf('Succesfully transferred nested MATLAB struct %s to the NetCDF\n', parent_struct_name) 389 create_var(variable_name, address_of_child, subgroup, verbose); 390 end 391 end 392 if verbose 393 fprintf('Succesfully transferred nested MATLAB struct %s to the NetCDF\n', parent_struct_name) 394 end 374 395 end 375 396 … … 378 399 % ironically inversion does not have the same problem as results as inversion subfields 379 400 % are actually subclasses and not fields 380 function check_inversion_class(model_var )401 function check_inversion_class(model_var, verbose) 381 402 global NetCDF; 382 403 % Define a persistent variable to ensure this function is only run once … … 384 405 % Check if the function has already been executed 385 406 if isempty(executed) 386 disp('Deconstructing Inversion class instance') 407 if verbose 408 disp('Deconstructing Inversion class instance') 409 end 387 410 % Need to make sure that we have the right inversion class: inversion, m1qn3inversion, taoinversion 388 411 groupid = netcdf.inqNcid(NetCDF,'inversion'); 389 412 390 413 if isa(model_var, 'm1qn3inversion') 391 write_string_to_netcdf('inversion_class_name', 'm1qn3inversion', groupid); 392 disp('Successfully saved inversion class instance m1qn3inversion') 414 write_string_to_netcdf('inversion_class_name', 'm1qn3inversion', groupid, verbose); 415 if verbose 416 disp('Successfully saved inversion class instance m1qn3inversion') 417 end 393 418 elseif isa(model_var, 'taoinversion') 394 write_string_to_netcdf('inversion_class_name', 'taoinversion', groupid); 395 disp('Successfully saved inversion class instance taoinversion') 419 write_string_to_netcdf('inversion_class_name', 'taoinversion', groupid, verbose); 420 if verbose 421 disp('Successfully saved inversion class instance taoinversion') 422 end 396 423 else 397 write_string_to_netcdf('inversion_class_name', 'inversion', groupid); 398 disp('Successfully saved inversion class instance inversion') 424 write_string_to_netcdf('inversion_class_name', 'inversion', groupid, verbose); 425 if verbose 426 disp('Successfully saved inversion class instance inversion') 427 end 399 428 end 400 429 % Set the persistent variable to indicate that the function has been executed … … 404 433 405 434 406 407 function create_var(variable_name, address_of_child, group) 435 function create_var(variable_name, address_of_child, group, verbose) 408 436 global NetCDF; 409 437 % There are lots of different variable types that we need to handle from the model class … … 416 444 % This first conditional statement will catch numeric arrays (matrices) of any dimension and save them 417 445 if any(size(address_of_child)>1) && ~iscellstr(address_of_child) && ~ischar(address_of_child) 418 write_numeric_array_to_netcdf(variable_name, address_of_child, group );446 write_numeric_array_to_netcdf(variable_name, address_of_child, group, verbose); 419 447 420 448 % check if it's a string 421 449 elseif ischar(address_of_child) 422 write_string_to_netcdf(variable_name, address_of_child, group );450 write_string_to_netcdf(variable_name, address_of_child, group, verbose); 423 451 424 452 % or an empty variable … … 428 456 % or a list of strings 429 457 elseif iscellstr(address_of_child) || iscell(address_of_child) && ischar(address_of_child{1}) 430 write_cell_with_strings(variable_name, address_of_child, group )458 write_cell_with_strings(variable_name, address_of_child, group, verbose) 431 459 432 460 % or an empty list … … 464 492 variable = netcdf.defVar(group, variable_name, "NC_DOUBLE", unlimdim); 465 493 netcdf.putVar(group,variable,address_of_child); 466 disp('Used Unlim Dim');467 494 catch ME 468 495 disp(ME.message); … … 470 497 end 471 498 end 472 473 fprintf('Successfully transferred data from %s to the NetCDF\n', variable_name); 474 end 475 476 477 function write_cell_with_strings(variable_name, address_of_child, group) 499 if verbose 500 fprintf('Successfully transferred data from %s to the NetCDF\n', variable_name); 501 end 502 end 503 504 505 function write_cell_with_strings(variable_name, address_of_child, group, verbose) 478 506 %{ 479 507 Write cell array (ie {'one' 'two' 'three'}) to netcdf … … 514 542 515 543 516 function write_string_to_netcdf(variable_name, address_of_child, group )544 function write_string_to_netcdf(variable_name, address_of_child, group, verbose) 517 545 % netcdf and strings don't get along.. we have to do it 'custom': 518 546 global NetCDF; … … 556 584 end 557 585 558 disp(['Successfully transferred data from ', variable_name, ' to the NetCDF']); 559 end 560 561 562 563 function write_numeric_array_to_netcdf(variable_name, address_of_child, group) 586 if verbose 587 disp(['Successfully transferred data from ', variable_name, ' to the NetCDF']); 588 end 589 end 590 591 592 function write_numeric_array_to_netcdf(variable_name, address_of_child, group, verbose) 564 593 global NetCDF; 565 594 % get the dimensions we'll need -
TabularUnified issm/trunk/src/m/contrib/musselman/write_netCDF.py ¶
r27882 r27884 24 24 25 25 26 def write_netCDF(md, filename: str): 27 print('Python C2NetCDF4 v1.1.14') 26 def write_netCDF(md, filename: str, verbose = False): 27 if verbose: 28 print('Python C2NetCDF4 v1.1.14') 29 else: pass 28 30 ''' 29 31 md = model() class instance to be saved 30 32 filename = path and name to save file under 33 verbose = T/F muted or show log statements. Naturally muted 31 34 ''' 32 35 33 36 # Create a NetCDF file to write to 34 make_NetCDF(filename )37 make_NetCDF(filename, verbose) 35 38 36 39 # Create an instance of an empty md class to compare md_var against … … 39 42 40 43 # Walk through the md class and compare subclass states to empty_model 41 walk_through_model(md )44 walk_through_model(md, verbose) 42 45 43 46 # in order to handle some subclasses in the results class, we have to utilize this band-aid … … 46 49 # if results has meaningful data, save the name of the subclass and class instance 47 50 NetCDF.groups['results'] 48 results_subclasses_bandaid(md )51 results_subclasses_bandaid(md, verbose) 49 52 # otherwise, ignore 50 53 except KeyError: … … 52 55 53 56 NetCDF.close() 54 print('Model successfully saved as NetCDF4') 55 56 57 def results_subclasses_bandaid(md): 57 if verbose: 58 print('Model successfully saved as NetCDF4') 59 else: pass 60 61 62 def results_subclasses_bandaid(md, verbose = False): 58 63 # since the results class may have nested classes within it, we need to record the name of the 59 64 # nested class instance variable as it appears in the md that we're trying to save … … 66 71 67 72 for class_instance_name in md.results.__dict__.keys(): 68 print(class_instance_name) 73 if verbose: 74 print(class_instance_name) 69 75 # for each class instance in results, see which class its from and record that info in the netcdf to recreate structure later 70 76 # check to see if there is a solutionstep class instance … … 84 90 85 91 if solutionsteps != []: 86 write_string_to_netcdf(variable_name=str('solutionstep'), address_of_child=solutionsteps, group=NetCDF.groups['results'], list=True )92 write_string_to_netcdf(variable_name=str('solutionstep'), address_of_child=solutionsteps, group=NetCDF.groups['results'], list=True, verbose=verbose) 87 93 88 94 if solutions != []: 89 write_string_to_netcdf(variable_name=str('solution'), address_of_child=solutions, group=NetCDF.groups['results'], list=True )95 write_string_to_netcdf(variable_name=str('solution'), address_of_child=solutions, group=NetCDF.groups['results'], list=True, verbose=verbose) 90 96 91 97 if resultsdakotas != []: 92 write_string_to_netcdf(variable_name=str('resultsdakota'), address_of_child=resultsdakotas, group=NetCDF.groups['results'], list=True )98 write_string_to_netcdf(variable_name=str('resultsdakota'), address_of_child=resultsdakotas, group=NetCDF.groups['results'], list=True, verbose=verbose) 93 99 94 100 … … 97 103 print(type(md.results.__dict__[class_instance_name])) 98 104 else: 99 print('The results class was successfully stored on disk') 100 101 102 def make_NetCDF(filename: str): 105 if verbose: 106 print('The results class was successfully stored on disk') 107 else: pass 108 109 110 def make_NetCDF(filename: str, verbose = False): 103 111 # If file already exists delete / rename it 104 112 if os.path.exists(filename): … … 122 130 NetCDF.createDimension('int', 1) # single float dimension 123 131 124 print('Successfully created ' + filename) 125 126 127 def walk_through_model(md): 132 if verbose: 133 print('Successfully created ' + filename) 134 135 136 def walk_through_model(md, verbose = False): 128 137 # Iterate over first layer of md_var attributes and assume this first layer is only classes 129 138 for group in md.__dict__.keys(): … … 134 143 135 144 # Recursively walk through subclasses 136 walk_through_subclasses(address, empty_address, layers )137 138 139 def walk_through_subclasses(address, empty_address, layers: list ):145 walk_through_subclasses(address, empty_address, layers, verbose) 146 147 148 def walk_through_subclasses(address, empty_address, layers: list, verbose = False): 140 149 # See if we have an object with keys or a not 141 150 try: … … 158 167 # if the current object is a results.<solution> object and has the steps attr it needs special treatment 159 168 if isinstance(address_of_child, solution) and len(address_of_child.steps) != 0: 160 create_group(address_of_child, current_layer, is_struct = True )169 create_group(address_of_child, current_layer, is_struct = True, verbose = verbose) 161 170 162 171 # if the variable is an array, assume it has relevant data (this is because the next line cannot evaluate "==" with an array) 163 172 elif isinstance(address_of_child, np.ndarray): 164 create_group(address_of_child, current_layer )173 create_group(address_of_child, current_layer, is_struct = False, verbose = verbose) 165 174 166 175 # see if the child exists in the empty md. If not, record it in the netcdf … … 172 181 # if the attributes are identical we don't need to save anything 173 182 if address_of_child == address_of_child_in_empty_class: 174 walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer )183 walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer, verbose) 175 184 176 185 # If it has been modified, record it in the NetCDF file 177 186 else: 178 create_group(address_of_child, current_layer )179 walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer )187 create_group(address_of_child, current_layer, is_struct = False, verbose = verbose) 188 walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer, verbose) 180 189 181 190 except KeyError: # record in netcdf and continue to walk thru md 182 walk_through_subclasses(address_of_child, empty_address, current_layer )183 create_group(address_of_child, current_layer )191 walk_through_subclasses(address_of_child, empty_address, current_layer, verbose) 192 create_group(address_of_child, current_layer, is_struct = False, verbose = verbose) 184 193 else: pass 185 194 186 195 187 def create_group(address_of_child, layers, is_struct = False ):196 def create_group(address_of_child, layers, is_struct = False, verbose = False): 188 197 189 198 # Handle the first layer of the group(s) … … 196 205 # need to check if inversion or m1qn3inversion class 197 206 if group_name == 'inversion': 198 check_inversion_class(address_of_child )207 check_inversion_class(address_of_child, verbose) 199 208 else: pass 200 209 … … 211 220 if is_struct: 212 221 parent_struct_name = layers[-1] 213 copy_nested_results_struct(parent_struct_name, address_of_child, group )222 copy_nested_results_struct(parent_struct_name, address_of_child, group, verbose) 214 223 215 224 else: 216 225 variable_name = layers[-1] 217 create_var(variable_name, address_of_child, group )226 create_var(variable_name, address_of_child, group, verbose) 218 227 219 220 228 221 229 def singleton(func): … … 234 242 235 243 @singleton 236 def check_inversion_class(address_of_child): 237 print('inversion ... ') 244 def check_inversion_class(address_of_child, verbose = False): 238 245 # need to make sure that we have the right inversion class: inversion, m1qn3inversion, taoinversion 239 246 if isinstance(address_of_child, m1qn3inversion): 240 write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('m1qn3inversion'), group=NetCDF.groups['inversion']) 241 print('Successfully saved inversion class instance ' + 'm1qn3inversion') 247 write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('m1qn3inversion'), group=NetCDF.groups['inversion'], verbose = verbose) 248 if verbose: 249 print('Successfully saved inversion class instance ' + 'm1qn3inversion') 242 250 elif isinstance(address_of_child, taoinversion): 243 write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('taoinversion'), group=NetCDF.groups['inversion']) 244 print('Successfully saved inversion class instance ' + 'taoinversion') 245 else: 246 write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('inversion'), group=NetCDF.groups['inversion']) 247 print('Successfully saved inversion class instance ' + 'inversion') 248 249 250 251 def copy_nested_results_struct(parent_struct_name, address_of_struct, group): 251 write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('taoinversion'), group=NetCDF.groups['inversion'], verbose = verbose) 252 if verbose: 253 print('Successfully saved inversion class instance ' + 'taoinversion') 254 else: 255 write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('inversion'), group=NetCDF.groups['inversion'], verbose = verbose) 256 if verbose: 257 print('Successfully saved inversion class instance ' + 'inversion') 258 259 260 def copy_nested_results_struct(parent_struct_name, address_of_struct, group, verbose = False): 252 261 ''' 253 262 This function takes a solution class instance and saves the solutionstep instances from <solution>.steps to the netcdf. … … 258 267 For each variable, we create dimensions that are assigned to each subgroup uniquely. 259 268 ''' 260 print("Beginning transfer of nested MATLAB struct to the NetCDF") 269 if verbose: 270 print("Beginning transfer of nested MATLAB struct to the NetCDF") 261 271 262 272 # make a new subgroup to contain all the others: … … 264 274 265 275 # make sure other systems can flag the nested struct type 266 write_string_to_netcdf('this_is_a_nested', 'struct', group, list=False )276 write_string_to_netcdf('this_is_a_nested', 'struct', group, list=False, verbose = verbose) 267 277 268 278 # other systems know the name of the parent struct because it's covered by the results/qmu functions above … … 280 290 for variable in substruct_fields: 281 291 address_of_child = current_substruct.__dict__[variable] 282 create_var(variable, address_of_child, subgroup) 283 284 print(f'Successfully transferred struct {parent_struct_name} to the NetCDF\n') 292 create_var(variable, address_of_child, subgroup, verbose = verbose) 293 294 if verbose: 295 print(f'Successfully transferred struct {parent_struct_name} to the NetCDF\n') 285 296 286 297 287 def create_var(variable_name, address_of_child, group ):298 def create_var(variable_name, address_of_child, group, verbose = False): 288 299 # There are lots of different variable types that we need to handle from the md class 289 300 290 301 # This first conditional statement will catch numpy arrays of any dimension and save them 291 302 if isinstance(address_of_child, np.ndarray): 292 write_numpy_array_to_netcdf(variable_name, address_of_child, group )303 write_numpy_array_to_netcdf(variable_name, address_of_child, group, verbose=verbose) 293 304 294 305 # check if it's an int … … 304 315 # or a string 305 316 elif isinstance(address_of_child, str): 306 write_string_to_netcdf(variable_name, address_of_child, group )317 write_string_to_netcdf(variable_name, address_of_child, group, verbose=verbose) 307 318 308 319 #or a bool … … 320 331 elif isinstance(address_of_child,list) and isinstance(address_of_child[0],str): 321 332 for string in address_of_child: 322 write_string_to_netcdf(variable_name, string, group, list=True )333 write_string_to_netcdf(variable_name, string, group, list=True, verbose=verbose) 323 334 324 335 # or a regular list 325 336 elif isinstance(address_of_child, list): 326 print('made list w/ unlim dim')327 337 variable = group.createVariable(variable_name, type(address_of_child[0]), ('Unlim',)) 328 338 variable[:] = address_of_child … … 333 343 variable = group.createVariable(variable_name, type(address_of_child), ('Unlim',)) 334 344 variable[:] = address_of_child 335 print( 'Used Unlim Dim')345 print(f'Unrecognized variable was saved {variable_name}') 336 346 except TypeError: pass # this would mean that we have an object, so we just let this continue to feed thru the recursive function above 337 347 except Exception as e: … … 340 350 print(e) 341 351 print('Datatype given: ' + str(type(address_of_child))) 342 343 print(f'Successfully transferred data from {variable_name} to the NetCDF') 344 345 346 def write_string_to_netcdf(variable_name, address_of_child, group, list=False): 352 353 if verbose: 354 print(f'Successfully transferred data from {variable_name} to the NetCDF') 355 356 357 def write_string_to_netcdf(variable_name, address_of_child, group, list=False, verbose = False): 347 358 # netcdf and strings dont get along.. we have to do it 'custom': 348 359 # if we hand it an address we need to do it this way: … … 390 401 # save array to netcdf file 391 402 string_var[:] = arr 392 393 print(f'Saved {len(modded_strings)} strings to {variable_name}') 403 404 if verbose: 405 print(f'Saved {len(modded_strings)} strings to {variable_name}') 394 406 395 407 except Exception as e: … … 419 431 420 432 421 422 def write_numpy_array_to_netcdf(variable_name, address_of_child, group): 433 def write_numpy_array_to_netcdf(variable_name, address_of_child, group, verbose = False): 423 434 # to make a nested array in netCDF, we have to get the dimensions of the array, 424 435 # create corresponding dimensions in the netCDF file, then we can make a variable … … 462 473 variable[:] = address_of_child[0] 463 474 else: 464 print( 'Encountered single datatypethat was not float64 or int64, saving under unlimited dimension, may cause errors.')475 print(f'Encountered single datatype from {variable_name} that was not float64 or int64, saving under unlimited dimension, may cause errors.') 465 476 variable = group.createVariable(variable_name, typeis, ('Unlim',)) 466 477 variable[:] = address_of_child[0] … … 482 493 # write the variable: 483 494 variable[:] = address_of_child 495 496
Note:
See TracChangeset
for help on using the changeset viewer.