Changeset 27889
- Timestamp:
- 08/30/23 15:08:57 (19 months ago)
- Location:
- issm/trunk/src/m/contrib/musselman
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/m/contrib/musselman/README.txt
r27887 r27889 37 37 Verbose examples: 38 38 write_netCDF(md, adress_to_save/../filename.nc, verbose = true); 39 40 or: 41 42 write_netCDF(md, adress_to_save/../filename.nc, verbose); 39 43 md = read_netCDF(adress_to_file/../filename.nc, verbose = true); 40 44 -
issm/trunk/src/m/contrib/musselman/read_netCDF.m
r27884 r27889 16 16 17 17 18 function model_copy = read_netCDF(filename )18 function model_copy = read_netCDF(filename, varargin) 19 19 if nargin > 1 20 20 verbose = true; … … 27 27 end 28 28 % make a model framework to fill that is in the scope of this file 29 global model_copy;30 29 model_copy = model(); 31 30 … … 37 36 38 37 % Open the given netCDF4 file 39 global NCData;40 38 NCData = netcdf.open(filename, 'NOWRITE'); 41 39 % Remove masks from netCDF data for easy conversion: NOT WORKING … … 44 42 % see if results is in there, if it is we have to instantiate some classes 45 43 try 46 results_group_id = netcdf.inqNcid(NCData, "results" , verbose);47 m ake_results_subclasses(verbose);44 results_group_id = netcdf.inqNcid(NCData, "results"); 45 model_copy = make_results_subclasses(model_copy, NCData, verbose); 48 46 catch 49 47 end % 'results' group doesn't exist … … 52 50 try 53 51 inversion_group_id = netcdf.inqNcid(NCData, "inversion"); 54 check_inversion_class(verbose);52 model_copy = check_inversion_class(model_copy, NCData, verbose); 55 53 catch 56 54 end % 'inversion' group doesn't exist … … 61 59 %disp(netcdf.inqGrpNameFull(group_id)) 62 60 % hand off first level to recursive search 63 walk_nested_groups(group_id, verbose);61 model_copy = walk_nested_groups(group_id, model_copy, NCData, verbose); 64 62 end 65 63 … … 75 73 76 74 77 function make_results_subclasses(verbose) 78 global model_copy; 79 global NCData; 75 function model_copy = make_results_subclasses(model_copy, NCData, verbose) 80 76 resultsGroup = netcdf.inqNcid(NCData, "results"); 81 77 variables = netcdf.inqVarIDs(resultsGroup); … … 90 86 %model_copy.results = setfield(model_copy.results, class_instance, class_instance_name); 91 87 end 88 model_copy = model_copy; 92 89 if verbose 93 90 disp('Successfully recreated results structs:') … … 99 96 100 97 101 function check_inversion_class(verbose)98 function model_copy = check_inversion_class(model_copy, NCData, verbose) 102 99 % get the name of the inversion class: either inversion or m1qn3inversion or taoinversion 103 global model_copy;104 global NCData;105 100 inversionGroup = netcdf.inqNcid(NCData, "inversion"); 106 101 varid = netcdf.inqVarID(inversionGroup, 'inversion_class_name'); … … 121 116 end 122 117 end 123 end 124 125 126 function walk_nested_groups(group_location_in_file, verbose) 127 global model_copy; 128 global NCData; 118 model_copy = model_copy; 119 end 120 121 122 function model_copy = walk_nested_groups(group_location_in_file, model_copy, NCData, verbose) 129 123 % we search the current group level for variables by getting this struct 130 124 variables = netcdf.inqVarIDs(group_location_in_file); … … 137 131 if strcmp(varname, 'this_is_a_nested') 138 132 is_nested = true; 139 copy_nested_struct(group_location_in_file, verbose)133 model_copy = copy_nested_struct(group_location_in_file, model_copy, NCData, verbose); 140 134 elseif strcmp(varname, 'solution') 141 135 % band-aid pass.. 142 136 else 143 copy_variable_data_to_new_model(group_location_in_file, varname, xtype, verbose);137 model_copy = copy_variable_data_to_new_model(group_location_in_file, varname, xtype, model_copy, NCData, verbose); 144 138 end 145 139 end … … 157 151 group_id = netcdf.inqNcid(group_location_in_file, netcdf.inqGrpName(group)); 158 152 %disp(netcdf.inqGrpNameFull(group_id)) 159 walk_nested_groups(group, verbose);153 model_copy = walk_nested_groups(group, model_copy, NCData, verbose); 160 154 end 161 155 end … … 167 161 168 162 169 function copy_nested_struct(group_location_in_file, verbose) 170 global model_copy; 171 global NCData; 163 function model_copy = copy_nested_struct(group_location_in_file, model_copy, NCData, verbose) 172 164 %{ 173 165 A common multidimensional struct array is the 1xn md.results.TransientSolution struct. … … 235 227 model_copy.(address_in_model).(name_of_struct)(current_layer); 236 228 if verbose 237 fprintf("Successfully saved layer %s to multidimension struct array\n", num2str(current_layer)) 238 end 239 end 229 fprintf("Successfully loaded layer %s to multidimension struct array\n", num2str(current_layer)) 230 end 231 end 232 model_copy = model_copy; 240 233 if verbose 241 234 fprintf('Successfully recreated multidimensional structure array %s in md.%s\n', name_of_struct, address_in_model) … … 252 245 %} 253 246 254 function copy_variable_data_to_new_model(group_location_in_file, varname, xtype, verbose) 255 global model_copy; 256 global NCData; 247 function model_copy = copy_variable_data_to_new_model(group_location_in_file, varname, xtype, model_copy, NCData, verbose) 257 248 %disp(varname) 258 249 % this is an inversion band-aid … … 305 296 arg_to_eval = ['model_copy', address_to_attr, '.', varname, ' = ' , 'double(data);']; 306 297 eval(arg_to_eval); 307 %disp(' saved int64 as int16')298 %disp('Loaded int64 as int16') 308 299 else 309 300 arg_to_eval = ['model_copy', address_to_attr, '.', varname, ' = data;']; … … 315 306 %disp(xtype) 316 307 %class(data) 317 fprintf('Successfully saved %s to %s\n', varname, full_addy);308 fprintf('Successfully loaded %s to %s\n', varname, full_addy); 318 309 end 319 310 … … 332 323 end 333 324 end 334 end 325 model_copy = model_copy; 326 end -
issm/trunk/src/m/contrib/musselman/read_netCDF.py
r27884 r27889 34 34 35 35 # open the given netCDF4 file 36 global NCData37 36 NCData = Dataset(filename, 'r') 38 37 # remove masks from numpy arrays for easy conversion … … 45 44 try: 46 45 NCData.groups['results'] 47 make_results_subclasses( verbose)46 make_results_subclasses(NCData, verbose) 48 47 except: 49 48 pass … … 52 51 try: 53 52 NCData.groups['inversion'] 54 check_inversion_class( verbose)53 check_inversion_class(NCData, verbose) 55 54 except: 56 55 pass … … 63 62 # have to send a custom name to this function: filename.groups['group'] 64 63 name = "NCData.groups['" + str(group) + "']" 65 walk_nested_groups(name, verbose)64 walk_nested_groups(name, NCData, verbose) 66 65 67 66 if verbose: 68 print("Model Successfully Recreated.")67 print("Model Successfully Loaded.") 69 68 return model_copy 70 69 71 70 72 def make_results_subclasses( verbose = False):71 def make_results_subclasses(NCData, verbose = False): 73 72 ''' 74 73 There are 3 possible subclasses: solution, solutionstep, resultsdakota. … … 93 92 94 93 95 def check_inversion_class( verbose = False):94 def check_inversion_class(NCData, verbose = False): 96 95 # get the name of the inversion class: either inversion or m1qn3inversion or taoinversion 97 96 inversion_class_is = NCData.groups['inversion'].variables['inversion_class_name'][:][...].tobytes().decode() … … 109 108 110 109 111 def walk_nested_groups(group_location_in_file, verbose = False):110 def walk_nested_groups(group_location_in_file, NCData, verbose = False): 112 111 # first, we enter the group by: filename.groups['group_name'] 113 112 # second we search the current level for variables: filename.groups['group_name'].variables.keys() … … 123 122 matches = re.findall(pattern, group_location_in_file) 124 123 name_of_struct = matches[-1] #eval(group_location_in_file + ".variables['solution']") 125 copy_multidimensional_results_struct(group_location_in_file, name_of_struct )124 copy_multidimensional_results_struct(group_location_in_file, name_of_struct, NCData) 126 125 istruct = True 127 126 … … 145 144 variable_name = matches[-1] 146 145 location_of_variable_in_model = '.'.join(matches[:-1]) 147 copy_variable_data_to_new_model(location_of_variable_in_file, location_of_variable_in_model, variable_name, verbose=verbose)146 copy_variable_data_to_new_model(location_of_variable_in_file, location_of_variable_in_model, variable_name, NCData, verbose=verbose) 148 147 149 148 if 'istruct' in locals(): … … 152 151 for nested_group in eval(group_location_in_file + '.groups.keys()'): 153 152 new_nested_group = group_location_in_file + ".groups['" + str(nested_group) + "']" 154 walk_nested_groups(new_nested_group, verbose=verbose)153 walk_nested_groups(new_nested_group, NCData, verbose=verbose) 155 154 156 155 … … 163 162 ''' 164 163 165 def copy_multidimensional_results_struct(group_location_in_file, name_of_struct, verbose = False):164 def copy_multidimensional_results_struct(group_location_in_file, name_of_struct, NCData, verbose = False): 166 165 ''' 167 166 A common multidimensional array is the 1xn md.results.TransientSolution object. … … 195 194 steps.append(solutionstep_instance) 196 195 if verbose: 197 print('Succesfully saved layer ' + str(layer) + ' to results.' + str(class_instance_name) + ' struct.')196 print('Succesfully loaded layer ' + str(layer) + ' to results.' + str(class_instance_name) + ' struct.') 198 197 else: pass 199 198 layer += 1 … … 203 202 204 203 205 def copy_variable_data_to_new_model(location_of_variable_in_file, location_of_variable_in_model, variable_name, verbose = False):204 def copy_variable_data_to_new_model(location_of_variable_in_file, location_of_variable_in_model, variable_name, NCData, verbose = False): 206 205 # as simple as navigating to the location_of_variable_in_model and setting it equal to the location_of_variable_in_file 207 206 # NetCDF4 has a property called "_FillValue" that sometimes saves empty lists, so we have to catch those … … 245 244 setattr(eval('model_copy.' + location_of_variable_in_model), variable_name, eval(location_of_variable_in_file + '[:]')) 246 245 except AttributeError: 247 copy_variable_data_to_new_model_dict(location_of_variable_in_file, location_of_variable_in_model, verbose=verbose)246 copy_variable_data_to_new_model_dict(location_of_variable_in_file, location_of_variable_in_model, NCData, verbose=verbose) 248 247 249 248 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):249 print('Successfully loaded ' + location_of_variable_in_model + '.' + variable_name + ' into model.') 250 251 252 def copy_variable_data_to_new_model_dict(location_of_variable_in_file, location_of_variable_in_model, NCData, verbose = False): 254 253 # as simple as navigating to the location_of_variable_in_model and setting it equal to the location_of_variable_in_file 255 254 … … 300 299 dict_object.update({key: data}) 301 300 else: 302 print(f"Unrecognized object was saved and cannot be reconstructed: {location_of_variable_in_model}")301 print(f"Unrecognized object was saved to NetCDF file and cannot be reconstructed: {location_of_variable_in_model}") -
issm/trunk/src/m/contrib/musselman/write_netCDF.m
r27884 r27889 10 10 11 11 12 function write_netCDF(model_var, filename )12 function write_netCDF(model_var, filename, varargin) 13 13 if nargin > 2 14 14 verbose = true; … … 19 19 disp('MATLAB C2NetCDF4 v1.1.14'); 20 20 end 21 21 22 % model_var = class object to be saved 22 23 % filename = path and name to save file under 23 24 24 25 % Create a NetCDF file to write to 25 make_NetCDF(filename, verbose);26 NetCDF = make_NetCDF(filename, verbose); 26 27 27 28 % Create an instance of an empty model class to compare model_var against 28 global empty_model;29 29 empty_model = model(); 30 30 31 31 % Walk through the model_var class and compare subclass states to empty_model 32 walk_through_model(model_var, verbose);32 walk_through_model(model_var, empty_model, NetCDF, verbose); 33 33 34 34 % in order to handle some subclasses in the results class, we have to utilize this band-aid 35 35 % there will likely be more band-aids added unless a class name library is created with all class names that might be added to a model 36 global NetCDF;37 36 try 38 37 % if results had meaningful data, save the name of the subclass and class instance 39 38 netcdf.inqNcid(NetCDF,'results'); 40 results_subclasses_bandaid(model_var, verbose);39 results_subclasses_bandaid(model_var, NetCDF, verbose); 41 40 % otherwise, ignore 42 41 catch … … 51 50 52 51 53 function make_NetCDF(filename, verbose)52 function NetCDF = make_NetCDF(filename, verbose) 54 53 % matlab can't handle input in the jupyter interface, so we just yell at the user to rename 55 54 % their file if needed … … 71 70 else 72 71 % Otherwise create the file and define it globally so other functions can call it 73 global NetCDF;72 74 73 NetCDF = netcdf.create(filename, 'NETCDF4'); 75 74 netcdf.putAtt(NetCDF, netcdf.getConstant('NC_GLOBAL'), 'history', ['Created ', datestr(now)]); … … 81 80 fprintf('Successfully created %s\n', filename); 82 81 end 82 83 return 83 84 end 84 85 end … … 93 94 %} 94 95 95 function results_subclasses_bandaid(model_var, verbose)96 global NetCDF;96 function results_subclasses_bandaid(model_var, NetCDF, verbose) 97 97 98 % The results class may have nested fields within it, so we need to record the name of 98 99 % the nested field as it appears in the model that we're trying to save … … 120 121 quality_control{end+1} = 1; 121 122 solutionsteps{end+1} = class_instance_name; 122 %varname = ['solutionstep', num2str(i)]123 %write_string_to_netcdf(varname, class_instance_name, groupid);124 123 if verbose 125 124 disp('Successfully stored class python subclass instance: solutionstep') … … 131 130 quality_control{end+1} = 1; 132 131 solutions{end+1} = class_instance_name; 133 %varname = ['solution', num2str(i)]134 %write_string_to_netcdf(varname, class_instance_name, groupid);135 132 if verbose 136 133 disp('Successfully stored class python subclass instance: solution') … … 142 139 quality_control{end+1} = 1; 143 140 resultsdakotas{end+1} = class_instance_name; 144 %varname = ['resultsdakota', num2str(i)]145 %write_string_to_netcdf(varname, class_instance_name, groupid);146 141 if verbose 147 142 disp('Successfully stored class python subclass instance: resultsdakota') … … 150 145 end 151 146 if ~isempty(solutionsteps) 152 write_cell_with_strings('solutionstep', solutionsteps, groupid, verbose)147 write_cell_with_strings('solutionstep', solutionsteps, groupid, NetCDF, verbose) 153 148 end 154 149 if ~isempty(solutions) 155 write_cell_with_strings('solution', solutions, groupid, verbose)150 write_cell_with_strings('solution', solutions, groupid, NetCDF, verbose) 156 151 end 157 152 if ~isempty(resultsdakotas) 158 write_cell_with_strings('resultsdakota', resultsdakotas, groupid, verbose)153 write_cell_with_strings('resultsdakota', resultsdakotas, groupid, NetCDF, verbose) 159 154 end 160 155 … … 166 161 disp(class(results_var.(class_instance_name))); 167 162 else 168 disp('The results class was successfully stored on disk'); 169 end 170 end 171 172 173 174 function walk_through_model(model_var, verbose) 175 global empty_model; 163 if verbose 164 disp('The results class was successfully stored on disk'); 165 end 166 end 167 end 168 169 170 171 function walk_through_model(model_var, empty_model, NetCDF, verbose) 176 172 % Iterate over first layer of model_var attributes and assume this first layer is only classes fundamental to the model() class 177 173 % note that groups are the same as class instances/subfields in this context … … 183 179 % Now we can recursively walk through the remaining subclasses 184 180 list_of_layers = {groups{group}}; 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)181 walk_through_subclasses(model_subclass, empty_model_subclass, list_of_layers, empty_model, NetCDF, verbose); 182 end 183 end 184 185 186 function walk_through_subclasses(model_subclass, empty_model_subclass, given_list_of_layers, empty_model, NetCDF, verbose) 191 187 % Recursivley iterate over each subclass' attributes and look for more subclasses and variables with relevant data 192 188 % model_subclass is an object (ie, md.mesh.elements) … … 195 191 if numel(given_list_of_layers) == 1 196 192 if strcmp(given_list_of_layers{1}, 'inversion') 197 create_group(model_subclass, given_list_of_layers );198 check_inversion_class(model_subclass, verbose);193 create_group(model_subclass, given_list_of_layers, NetCDF, verbose); 194 check_inversion_class(model_subclass, NetCDF, verbose); 199 195 end 200 196 end … … 220 216 % if the current field is a nested struct assume it has valuable data that needs to be saved 221 217 if isstruct(location_of_child) && any(size(location_of_child) > 1) 222 create_group(location_of_child, list_of_layers, verbose);218 create_group(location_of_child, list_of_layers, NetCDF, verbose); 223 219 224 220 % this would mean that the layer above the layer we're interested in is a struct, so … … 230 226 % if the current attribute is a numerical array assume it has valuable data that needs to be saved 231 227 if isnumeric(location_of_child) && logical(numel(location_of_child) > 1) 232 create_group(location_of_child, list_of_layers, verbose);228 create_group(location_of_child, list_of_layers, NetCDF, verbose); 233 229 % if the attributes are identical we don't need to save anything 234 230 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)) 235 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers, verbose);231 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers, empty_model, NetCDF, verbose); 236 232 % if the attributes are not the same we need to save ours 237 233 else 238 234 % THE ORDER OF THESE LINES IS CRITICAL 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);235 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers, empty_model, NetCDF, verbose); 236 create_group(location_of_child, list_of_layers, NetCDF, verbose); 241 237 end 242 238 % this would mean that the layer we're interested in is not fundamental to the model architecture 243 239 % and thus needs to be saved to the netcdf 244 240 else 245 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, verbose);246 create_group(location_of_child, list_of_layers, verbose);241 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, empty_model, NetCDF, verbose); 242 create_group(location_of_child, list_of_layers, NetCDF, verbose); 247 243 end 248 244 % this would mean it's not a struct, and must be a class/subclass … … 255 251 % if the current attribute is a numerical array assume it has valuable data that needs to be saved 256 252 if isnumeric(location_of_child) && logical(numel(location_of_child) > 1) 257 create_group(location_of_child, list_of_layers, verbose);253 create_group(location_of_child, list_of_layers, NetCDF, verbose); 258 254 259 255 elseif iscell(location_of_child) … … 263 259 else 264 260 % otherwise we need to save 265 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, verbose);266 create_group(location_of_child, list_of_layers, verbose);261 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, empty_model, NetCDF, verbose); 262 create_group(location_of_child, list_of_layers, NetCDF, verbose); 267 263 end 268 264 elseif (all(isnan(location_of_child)) && all(isnan(location_of_child_in_empty_model))) 269 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers, verbose);265 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers, empty_model, NetCDF, verbose); 270 266 % if the attributes are not the same we need to save ours 271 267 else 272 268 % THE ORDER OF THESE LINES IS CRITICAL 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);269 walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers, empty_model, NetCDF, verbose); 270 create_group(location_of_child, list_of_layers, NetCDF, verbose); 275 271 end 276 272 else 277 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, verbose);278 create_group(location_of_child, list_of_layers, verbose);273 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, empty_model, NetCDF, verbose); 274 create_group(location_of_child, list_of_layers, NetCDF, verbose); 279 275 end 280 276 catch 281 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, verbose);282 create_group(location_of_child, list_of_layers, verbose);277 walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, empty_model, NetCDF, verbose); 278 create_group(location_of_child, list_of_layers, NetCDF, verbose); 283 279 end 284 280 end … … 290 286 % this is if we come accross instances/subfields in our model that are not fundamental to the model class (ie, taoinversion) 291 287 elseif strcmp(ME.identifier, 'MATLAB:UndefinedFunction') 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);288 walk_through_subclasses(location_of_child, empty_model_subclass, given_list_of_layers, empty_model, NetCDF, verbose); 289 create_group(location_of_child, list_of_layers, NetCDF, verbose); 294 290 % If it's a different error, rethrow it to MATLAB's default error handling 295 291 else … … 302 298 303 299 304 function create_group(location_of_child, list_of_layers, verbose) 305 global NetCDF; 300 function create_group(location_of_child, list_of_layers, NetCDF, verbose) 306 301 % location_of_child is an object 307 302 % list_of_layers is a list like {'inversion', 'StressbalanceSolution','cost_functions_coefficients'} … … 336 331 elseif isstruct(location_of_child) && any(size(location_of_child) > 1) 337 332 % we have a nested struct 338 copy_nested_struct(variable_name, location_of_child, group, verbose)333 copy_nested_struct(variable_name, location_of_child, group, NetCDF, verbose) 339 334 end 340 335 catch 341 336 % if that line doesn't work, it means we're dealing with raw data 342 337 % not a nested struct, so we can pass 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)338 create_var(variable_name, location_of_child, group, NetCDF, verbose); 339 end 340 end 341 342 343 344 function copy_nested_struct(parent_struct_name, address_of_struct, group, NetCDF, verbose) 350 345 %{ 351 346 This function takes a struct of structs and saves them to netcdf. … … 387 382 for variable_name = string(substruct_fields) 388 383 address_of_child = current_substruct.(variable_name); 389 create_var(variable_name, address_of_child, subgroup, verbose);384 create_var(variable_name, address_of_child, subgroup, NetCDF, verbose); 390 385 end 391 386 end … … 399 394 % ironically inversion does not have the same problem as results as inversion subfields 400 395 % are actually subclasses and not fields 401 function check_inversion_class(model_var, verbose)402 global NetCDF;396 function check_inversion_class(model_var, NetCDF, verbose) 397 403 398 % Define a persistent variable to ensure this function is only run once 404 399 persistent executed; … … 412 407 413 408 if isa(model_var, 'm1qn3inversion') 414 write_string_to_netcdf('inversion_class_name', 'm1qn3inversion', groupid, verbose);409 write_string_to_netcdf('inversion_class_name', 'm1qn3inversion', groupid, NetCDF, verbose); 415 410 if verbose 416 411 disp('Successfully saved inversion class instance m1qn3inversion') 417 412 end 418 413 elseif isa(model_var, 'taoinversion') 419 write_string_to_netcdf('inversion_class_name', 'taoinversion', groupid, verbose);414 write_string_to_netcdf('inversion_class_name', 'taoinversion', groupid, NetCDF, verbose); 420 415 if verbose 421 416 disp('Successfully saved inversion class instance taoinversion') 422 417 end 423 418 else 424 write_string_to_netcdf('inversion_class_name', 'inversion', groupid, verbose);419 write_string_to_netcdf('inversion_class_name', 'inversion', groupid, NetCDF, verbose); 425 420 if verbose 426 421 disp('Successfully saved inversion class instance inversion') … … 433 428 434 429 435 function create_var(variable_name, address_of_child, group, verbose) 436 global NetCDF; 430 function create_var(variable_name, address_of_child, group, NetCDF, verbose) 437 431 % There are lots of different variable types that we need to handle from the model class 438 432 … … 444 438 % This first conditional statement will catch numeric arrays (matrices) of any dimension and save them 445 439 if any(size(address_of_child)>1) && ~iscellstr(address_of_child) && ~ischar(address_of_child) 446 write_numeric_array_to_netcdf(variable_name, address_of_child, group, verbose);440 write_numeric_array_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose); 447 441 448 442 % check if it's a string 449 443 elseif ischar(address_of_child) 450 write_string_to_netcdf(variable_name, address_of_child, group, verbose);444 write_string_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose); 451 445 452 446 % or an empty variable … … 456 450 % or a list of strings 457 451 elseif iscellstr(address_of_child) || iscell(address_of_child) && ischar(address_of_child{1}) 458 write_cell_with_strings(variable_name, address_of_child, group, verbose)452 write_cell_with_strings(variable_name, address_of_child, group, NetCDF, verbose) 459 453 460 454 % or an empty list … … 503 497 504 498 505 function write_cell_with_strings(variable_name, address_of_child, group, verbose)499 function write_cell_with_strings(variable_name, address_of_child, group, NetCDF, verbose) 506 500 %{ 507 501 Write cell array (ie {'one' 'two' 'three'}) to netcdf 508 502 %} 509 global NetCDF510 503 511 504 if isempty(address_of_child) … … 542 535 543 536 544 function write_string_to_netcdf(variable_name, address_of_child, group, verbose)537 function write_string_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose) 545 538 % netcdf and strings don't get along.. we have to do it 'custom': 546 global NetCDF;547 539 548 540 the_string_to_save = address_of_child; … … 590 582 591 583 592 function write_numeric_array_to_netcdf(variable_name, address_of_child, group, verbose) 593 global NetCDF; 584 function write_numeric_array_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose) 594 585 % get the dimensions we'll need 595 586 intdim = netcdf.inqDimID(NetCDF,'int'); -
issm/trunk/src/m/contrib/musselman/write_netCDF.py
r27884 r27889 35 35 36 36 # Create a NetCDF file to write to 37 make_NetCDF(filename, verbose)37 NetCDF = make_NetCDF(filename, verbose) 38 38 39 39 # Create an instance of an empty md class to compare md_var against 40 global empty_model41 40 empty_model = model() 42 41 43 42 # Walk through the md class and compare subclass states to empty_model 44 walk_through_model(md, verbose)43 walk_through_model(md, empty_model, NetCDF, verbose) 45 44 46 45 # in order to handle some subclasses in the results class, we have to utilize this band-aid … … 49 48 # if results has meaningful data, save the name of the subclass and class instance 50 49 NetCDF.groups['results'] 51 results_subclasses_bandaid(md, verbose)50 results_subclasses_bandaid(md, NetCDF, verbose) 52 51 # otherwise, ignore 53 52 except KeyError: … … 60 59 61 60 62 def results_subclasses_bandaid(md, verbose = False):61 def results_subclasses_bandaid(md, NetCDF, verbose = False): 63 62 # since the results class may have nested classes within it, we need to record the name of the 64 63 # nested class instance variable as it appears in the md that we're trying to save … … 90 89 91 90 if solutionsteps != []: 92 write_string_to_netcdf(variable_name=str('solutionstep'), address_of_child=solutionsteps, group=NetCDF.groups['results'], list=True, verbose=verbose)91 write_string_to_netcdf(variable_name=str('solutionstep'), address_of_child=solutionsteps, group=NetCDF.groups['results'], list=True, NetCDF=NetCDF, verbose=verbose) 93 92 94 93 if solutions != []: 95 write_string_to_netcdf(variable_name=str('solution'), address_of_child=solutions, group=NetCDF.groups['results'], list=True, verbose=verbose)94 write_string_to_netcdf(variable_name=str('solution'), address_of_child=solutions, group=NetCDF.groups['results'], list=True, NetCDF=NetCDF, verbose=verbose) 96 95 97 96 if resultsdakotas != []: 98 write_string_to_netcdf(variable_name=str('resultsdakota'), address_of_child=resultsdakotas, group=NetCDF.groups['results'], list=True, verbose=verbose)97 write_string_to_netcdf(variable_name=str('resultsdakota'), address_of_child=resultsdakotas, group=NetCDF.groups['results'], list=True, NetCDF=NetCDF, verbose=verbose) 99 98 100 99 … … 123 122 else: 124 123 # Otherwise create the file and define it globally so other functions can call it 125 global NetCDF126 124 NetCDF = Dataset(filename, 'w', format='NETCDF4') 127 125 NetCDF.history = 'Created ' + time.ctime(time.time()) … … 133 131 print('Successfully created ' + filename) 134 132 135 136 def walk_through_model(md, verbose = False): 133 return NetCDF 134 135 136 def walk_through_model(md, empty_model, NetCDF, verbose= False): 137 137 # Iterate over first layer of md_var attributes and assume this first layer is only classes 138 138 for group in md.__dict__.keys(): … … 143 143 144 144 # Recursively walk through subclasses 145 walk_through_subclasses(address, empty_address, layers, verbose)146 147 148 def walk_through_subclasses(address, empty_address, layers: list, verbose = False):145 walk_through_subclasses(address, empty_address, layers, NetCDF, empty_model, verbose) 146 147 148 def walk_through_subclasses(address, empty_address, layers: list, NetCDF, empty_model, verbose = False): 149 149 # See if we have an object with keys or a not 150 150 try: … … 167 167 # if the current object is a results.<solution> object and has the steps attr it needs special treatment 168 168 if isinstance(address_of_child, solution) and len(address_of_child.steps) != 0: 169 create_group(address_of_child, current_layer, is_struct = True, verbose = verbose)169 create_group(address_of_child, current_layer, is_struct = True, NetCDF=NetCDF, verbose = verbose) 170 170 171 171 # if the variable is an array, assume it has relevant data (this is because the next line cannot evaluate "==" with an array) 172 172 elif isinstance(address_of_child, np.ndarray): 173 create_group(address_of_child, current_layer, is_struct = False, verbose = verbose)173 create_group(address_of_child, current_layer, is_struct = False, NetCDF=NetCDF, verbose = verbose) 174 174 175 175 # see if the child exists in the empty md. If not, record it in the netcdf … … 181 181 # if the attributes are identical we don't need to save anything 182 182 if address_of_child == address_of_child_in_empty_class: 183 walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer, verbose)183 walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer, NetCDF, empty_model, verbose) 184 184 185 185 # If it has been modified, record it in the NetCDF file 186 186 else: 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)187 create_group(address_of_child, current_layer, is_struct = False, NetCDF=NetCDF, verbose = verbose) 188 walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer, NetCDF, empty_model, verbose) 189 189 190 190 except KeyError: # record in netcdf and continue to walk thru md 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)191 walk_through_subclasses(address_of_child, empty_address, current_layer, NetCDF, empty_model, verbose) 192 create_group(address_of_child, current_layer, is_struct = False, NetCDF=NetCDF, verbose = verbose) 193 193 else: pass 194 194 195 195 196 def create_group(address_of_child, layers, is_struct = False, verbose = False):196 def create_group(address_of_child, layers, is_struct = False, NetCDF=None, verbose = False): 197 197 198 198 # Handle the first layer of the group(s) … … 205 205 # need to check if inversion or m1qn3inversion class 206 206 if group_name == 'inversion': 207 check_inversion_class(address_of_child, verbose)207 check_inversion_class(address_of_child, NetCDF, verbose) 208 208 else: pass 209 209 … … 220 220 if is_struct: 221 221 parent_struct_name = layers[-1] 222 copy_nested_results_struct(parent_struct_name, address_of_child, group, verbose)222 copy_nested_results_struct(parent_struct_name, address_of_child, group, NetCDF, verbose) 223 223 224 224 else: 225 225 variable_name = layers[-1] 226 create_var(variable_name, address_of_child, group, verbose)226 create_var(variable_name, address_of_child, group, NetCDF, verbose) 227 227 228 228 … … 242 242 243 243 @singleton 244 def check_inversion_class(address_of_child, verbose = False):244 def check_inversion_class(address_of_child, NetCDF, verbose = False): 245 245 # need to make sure that we have the right inversion class: inversion, m1qn3inversion, taoinversion 246 246 if isinstance(address_of_child, m1qn3inversion): 247 write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('m1qn3inversion'), group=NetCDF.groups['inversion'], verbose = verbose)247 write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('m1qn3inversion'), group=NetCDF.groups['inversion'], NetCDF=NetCDF, verbose = verbose) 248 248 if verbose: 249 249 print('Successfully saved inversion class instance ' + 'm1qn3inversion') 250 250 elif isinstance(address_of_child, taoinversion): 251 write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('taoinversion'), group=NetCDF.groups['inversion'], verbose = verbose)251 write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('taoinversion'), group=NetCDF.groups['inversion'], NetCDF=NetCDF, verbose = verbose) 252 252 if verbose: 253 253 print('Successfully saved inversion class instance ' + 'taoinversion') 254 254 else: 255 write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('inversion'), group=NetCDF.groups['inversion'], verbose = verbose)255 write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('inversion'), group=NetCDF.groups['inversion'], NetCDF=NetCDF, verbose = verbose) 256 256 if verbose: 257 257 print('Successfully saved inversion class instance ' + 'inversion') 258 258 259 259 260 def copy_nested_results_struct(parent_struct_name, address_of_struct, group, verbose = False):260 def copy_nested_results_struct(parent_struct_name, address_of_struct, group, NetCDF, verbose = False): 261 261 ''' 262 262 This function takes a solution class instance and saves the solutionstep instances from <solution>.steps to the netcdf. … … 274 274 275 275 # make sure other systems can flag the nested struct type 276 write_string_to_netcdf('this_is_a_nested', 'struct', group, list=False, verbose = verbose)276 write_string_to_netcdf('this_is_a_nested', 'struct', group, list=False, NetCDF=NetCDF, verbose = verbose) 277 277 278 278 # other systems know the name of the parent struct because it's covered by the results/qmu functions above … … 290 290 for variable in substruct_fields: 291 291 address_of_child = current_substruct.__dict__[variable] 292 create_var(variable, address_of_child, subgroup, verbose = verbose)292 create_var(variable, address_of_child, subgroup, NetCDF, verbose = verbose) 293 293 294 294 if verbose: … … 296 296 297 297 298 def create_var(variable_name, address_of_child, group, verbose = False):298 def create_var(variable_name, address_of_child, group, NetCDF, verbose = False): 299 299 # There are lots of different variable types that we need to handle from the md class 300 300 301 301 # This first conditional statement will catch numpy arrays of any dimension and save them 302 302 if isinstance(address_of_child, np.ndarray): 303 write_numpy_array_to_netcdf(variable_name, address_of_child, group, verbose=verbose)303 write_numpy_array_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose=verbose) 304 304 305 305 # check if it's an int … … 315 315 # or a string 316 316 elif isinstance(address_of_child, str): 317 write_string_to_netcdf(variable_name, address_of_child, group, verbose=verbose)317 write_string_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose=verbose) 318 318 319 319 #or a bool … … 331 331 elif isinstance(address_of_child,list) and isinstance(address_of_child[0],str): 332 332 for string in address_of_child: 333 write_string_to_netcdf(variable_name, string, group, list=True, verbose=verbose)333 write_string_to_netcdf(variable_name, string, group, list=True, NetCDF=NetCDF, verbose=verbose) 334 334 335 335 # or a regular list … … 355 355 356 356 357 def write_string_to_netcdf(variable_name, address_of_child, group, list=False, verbose = False):357 def write_string_to_netcdf(variable_name, address_of_child, group, list=False, NetCDF=None, verbose = False): 358 358 # netcdf and strings dont get along.. we have to do it 'custom': 359 359 # if we hand it an address we need to do it this way: … … 431 431 432 432 433 def write_numpy_array_to_netcdf(variable_name, address_of_child, group, verbose = False):433 def write_numpy_array_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose = False): 434 434 # to make a nested array in netCDF, we have to get the dimensions of the array, 435 435 # create corresponding dimensions in the netCDF file, then we can make a variable
Note:
See TracChangeset
for help on using the changeset viewer.