Changeset 27898 for issm/trunk
- Timestamp:
- 09/06/23 14:41:22 (19 months ago)
- Location:
- issm/trunk/src/m/contrib/musselman
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/m/contrib/musselman/read_netCDF.py
r27896 r27898 30 30 print('NetCDF42C v1.1.13') 31 31 32 # check if path exists 33 if path.exists(filename): 32 # this is a precaution so that data is not lost 33 try: 34 # check if path exists 35 if path.exists(filename): 36 if verbose: 37 print('Opening {} for reading'.format(filename)) 38 else: pass 39 40 # open the given netCDF4 file 41 NCData = Dataset(filename, 'r') 42 # remove masks from numpy arrays for easy conversion 43 NCData.set_auto_mask(False) 44 else: 45 print('The file you entered does not exist or cannot be found in the current directory') 46 return print() 47 48 # continuation of band-aid for results class 49 try: 50 NCData.groups['results'] 51 make_results_subclasses(NCData, verbose) 52 except: 53 pass 54 55 # similarly, we need to check and see if we have an m1qn3inversion class instance 56 try: 57 NCData.groups['inversion'] 58 check_inversion_class(NCData, verbose) 59 except: 60 pass 61 62 # walk through each group looking for subgroups and variables 63 for group in NCData.groups.keys(): 64 if 'debris' in group: 65 pass 66 else: 67 # have to send a custom name to this function: filename.groups['group'] 68 name = "NCData.groups['" + str(group) + "']" 69 walk_nested_groups(name, NCData, verbose) 70 34 71 if verbose: 35 print('Opening {} for reading'.format(filename)) 36 else: pass 37 38 # open the given netCDF4 file 39 NCData = Dataset(filename, 'r') 40 # remove masks from numpy arrays for easy conversion 41 NCData.set_auto_mask(False) 42 else: 43 print('The file you entered does not exist or cannot be found in the current directory') 44 return print() 45 46 # continuation of band-aid for results class 47 try: 48 NCData.groups['results'] 49 make_results_subclasses(NCData, verbose) 50 except: 51 pass 52 53 # similarly, we need to check and see if we have an m1qn3inversion class instance 54 try: 55 NCData.groups['inversion'] 56 check_inversion_class(NCData, verbose) 57 except: 58 pass 59 60 # walk through each group looking for subgroups and variables 61 for group in NCData.groups.keys(): 62 if 'debris' in group: 63 pass 64 else: 65 # have to send a custom name to this function: filename.groups['group'] 66 name = "NCData.groups['" + str(group) + "']" 67 walk_nested_groups(name, NCData, verbose) 68 69 if verbose: 70 print("Model Successfully Loaded.") 71 return model_copy 72 print("Model Successfully Loaded.") 73 74 NCData.close() 75 76 return model_copy 77 78 except Error: 79 NCData.close() 80 return Error 72 81 73 82 … … 126 135 matches = re.findall(pattern, group_location_in_file) 127 136 name_of_struct = matches[-1] #eval(group_location_in_file + ".variables['solution']") 128 copy_multidimensional_results_struct(group_location_in_file, name_of_struct, NCData)137 deserialize_nested_results_struct(group_location_in_file, name_of_struct, NCData) 129 138 is_object = True 130 139 131 140 elif variable == 'name_of_cell_array': 132 141 # reconstruct an array of elements 133 copy_cell_array_of_objects(group_location_in_file, model_copy, NCData, verbose)142 deserialize_array_of_objects(group_location_in_file, model_copy, NCData, verbose) 134 143 is_object = True 135 144 … … 150 159 variable_name = matches[-1] 151 160 location_of_variable_in_model = '.'.join(matches[:-1]) 152 copy_variable_data_to_new_model(location_of_variable_in_file, location_of_variable_in_model, variable_name, NCData, verbose=verbose)161 deserialize_data(location_of_variable_in_file, location_of_variable_in_model, variable_name, NCData, verbose=verbose) 153 162 154 163 # if one of the variables above was an object, further subclasses will be taken care of when reconstructing it … … 161 170 162 171 163 def copy_cell_array_of_objects(group_location_in_file, model_copy, NCData, verbose):172 def deserialize_array_of_objects(group_location_in_file, model_copy, NCData, verbose): 164 173 ''' 165 174 The structure in netcdf for groups with the name_of_cell_array variable is like: … … 336 345 ''' 337 346 338 def copy_multidimensional_results_struct(group_location_in_file, name_of_struct, NCData, verbose = False):347 def deserialize_nested_results_struct(group_location_in_file, name_of_struct, NCData, verbose = False): 339 348 ''' 340 349 A common multidimensional array is the 1xn md.results.TransientSolution object. … … 376 385 377 386 378 def copy_variable_data_to_new_model(location_of_variable_in_file, location_of_variable_in_model, variable_name, NCData, verbose = False):387 def deserialize_data(location_of_variable_in_file, location_of_variable_in_model, variable_name, NCData, verbose = False): 379 388 # as simple as navigating to the location_of_variable_in_model and setting it equal to the location_of_variable_in_file 380 389 # NetCDF4 has a property called "_FillValue" that sometimes saves empty lists, so we have to catch those … … 417 426 setattr(eval('model_copy.' + location_of_variable_in_model), variable_name, eval(location_of_variable_in_file + '[:]')) 418 427 except AttributeError: 419 copy_variable_data_to_new_model_dict(location_of_variable_in_file, location_of_variable_in_model, NCData, verbose=verbose)428 deserialize_dict(location_of_variable_in_file, location_of_variable_in_model, NCData, verbose=verbose) 420 429 421 430 if verbose: … … 424 433 425 434 426 def copy_variable_data_to_new_model_dict(location_of_variable_in_file, location_of_variable_in_model, NCData, verbose = False):435 def deserialize_dict(location_of_variable_in_file, location_of_variable_in_model, NCData, verbose = False): 427 436 # as simple as navigating to the location_of_variable_in_model and setting it equal to the location_of_variable_in_file 428 437 -
issm/trunk/src/m/contrib/musselman/write_netCDF.py
r27889 r27898 1 1 # imports 2 import netCDF43 from netCDF4 import Dataset2 import NCData4 3 from NCData4 import Dataset 4 4 import numpy as np 5 5 import numpy.ma as ma … … 15 15 ''' 16 16 Given a md, this set of functions will perform the following: 17 1. Enter each nested class of the md. 18 2. View each attribute of each nested class. 19 3. Compare state of attribute in the model to an empty model class. 20 4. If states are identical, pass. 21 5. Otherwise, create nested groups named after class structure. 22 6. Create variable named after class attribute and assign value to it. 17 1. View each attribute of each nested class. 18 2. Compare state of attribute in the model to an empty model. 19 3. If states are identical, pass. (except for np arrays which will always be saved) 20 4. Otherwise, create nested groups named after class structure. 21 5. Create variable named after class attribute and assign value to it. 23 22 ''' 24 23 25 24 26 def write_ netCDF(md, filename: str, verbose = False):25 def write_NCData(md, filename: str, verbose = False): 27 26 if verbose: 28 print('Python C2N etCDF4 v1.1.14')27 print('Python C2NCData4 v1.1.14') 29 28 else: pass 30 29 ''' … … 33 32 verbose = T/F muted or show log statements. Naturally muted 34 33 ''' 35 36 # Create a NetCDF file to write to 37 NetCDF = make_NetCDF(filename, verbose) 38 39 # Create an instance of an empty md class to compare md_var against 40 empty_model = model() 41 42 # Walk through the md class and compare subclass states to empty_model 43 walk_through_model(md, empty_model, NetCDF, verbose) 44 45 # in order to handle some subclasses in the results class, we have to utilize this band-aid 46 # 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 md 34 # this is a precaution so that data is not lost 47 35 try: 48 # if results has meaningful data, save the name of the subclass and class instance 49 NetCDF.groups['results'] 50 results_subclasses_bandaid(md, NetCDF, verbose) 51 # otherwise, ignore 52 except KeyError: 53 pass 36 # Create a NCData file to write to 37 NCData = create_NCData(filename, verbose) 54 38 55 NetCDF.close() 56 if verbose: 57 print('Model successfully saved as NetCDF4') 58 else: pass 59 60 61 def results_subclasses_bandaid(md, NetCDF, verbose = False): 39 # Create an instance of an empty md class to compare md_var against 40 empty_model = model() 41 42 # Walk through the md class and compare subclass states to empty_model 43 walk_through_model(md, empty_model, NCData, verbose) 44 45 # in order to handle some subclasses in the results class, we have to utilize this band-aid 46 # 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 md 47 try: 48 # if results has meaningful data, save the name of the subclass and class instance 49 NCData.groups['results'] 50 results_subclasses_bandaid(md, NCData, verbose) 51 # otherwise, ignore 52 except KeyError: 53 pass 54 55 NCData.close() 56 if verbose: 57 print('Model successfully saved as NCData4') 58 else: pass 59 60 except Error: 61 NCData.close() 62 return Error 63 64 65 def results_subclasses_bandaid(md, NCData, verbose = False): 62 66 # since the results class may have nested classes within it, we need to record the name of the 63 67 # nested class instance variable as it appears in the md that we're trying to save 64 68 quality_control = [] 65 69 66 # we save lists of instances to the netcdf70 # we save lists of instances to the NCData 67 71 solutions = [] 68 72 solutionsteps = [] … … 72 76 if verbose: 73 77 print(class_instance_name) 74 # for each class instance in results, see which class its from and record that info in the netcdfto recreate structure later78 # for each class instance in results, see which class its from and record that info in the NCData to recreate structure later 75 79 # check to see if there is a solutionstep class instance 76 80 if isinstance(md.results.__dict__[class_instance_name],solutionstep): … … 89 93 90 94 if solutionsteps != []: 91 write_string_to_netcdf(variable_name=str('solutionstep'), address_of_child=solutionsteps, group=NetCDF.groups['results'], list=True, NetCDF=NetCDF, verbose=verbose)95 serialize_string(variable_name=str('solutionstep'), address_of_child=solutionsteps, group=NCData.groups['results'], list=True, NCData=NCData, verbose=verbose) 92 96 93 97 if solutions != []: 94 write_string_to_netcdf(variable_name=str('solution'), address_of_child=solutions, group=NetCDF.groups['results'], list=True, NetCDF=NetCDF, verbose=verbose)98 serialize_string(variable_name=str('solution'), address_of_child=solutions, group=NCData.groups['results'], list=True, NCData=NCData, verbose=verbose) 95 99 96 100 if resultsdakotas != []: 97 write_string_to_netcdf(variable_name=str('resultsdakota'), address_of_child=resultsdakotas, group=NetCDF.groups['results'], list=True, NetCDF=NetCDF, verbose=verbose)101 serialize_string(variable_name=str('resultsdakota'), address_of_child=resultsdakotas, group=NCData.groups['results'], list=True, NCData=NCData, verbose=verbose) 98 102 99 103 … … 107 111 108 112 109 def make_NetCDF(filename: str, verbose = False):113 def create_NCData(filename: str, verbose = False): 110 114 # If file already exists delete / rename it 111 115 if os.path.exists(filename): … … 122 126 else: 123 127 # Otherwise create the file and define it globally so other functions can call it 124 N etCDF = Dataset(filename, 'w', format='NETCDF4')125 N etCDF.history = 'Created ' + time.ctime(time.time())126 N etCDF.createDimension('Unlim', None) # unlimited dimension127 N etCDF.createDimension('float', 1) # single integer dimension128 N etCDF.createDimension('int', 1) # single float dimension128 NCData = Dataset(filename, 'w', format='NCData4') 129 NCData.history = 'Created ' + time.ctime(time.time()) 130 NCData.createDimension('Unlim', None) # unlimited dimension 131 NCData.createDimension('float', 1) # single integer dimension 132 NCData.createDimension('int', 1) # single float dimension 129 133 130 134 if verbose: 131 135 print('Successfully created ' + filename) 132 136 133 return N etCDF134 135 136 def walk_through_model(md, empty_model, N etCDF, verbose= False):137 # Iterate over first layer of md _varattributes and assume this first layer is only classes137 return NCData 138 139 140 def walk_through_model(md, empty_model, NCData, verbose= False): 141 # Iterate over first layer of md attributes and assume this first layer is only classes 138 142 for group in md.__dict__.keys(): 139 143 address = md.__dict__[group] 140 144 empty_address = empty_model.__dict__[group] 141 # we need to record the layers of the md so we can save them to the netcdffile145 # we need to record the layers of the md so we can save them to the NCData file 142 146 layers = [group] 143 147 144 148 # Recursively walk through subclasses 145 walk_through_subclasses(address, empty_address, layers, N etCDF, empty_model, verbose)146 147 148 def walk_through_subclasses(address, empty_address, layers: list, N etCDF, empty_model, verbose = False):149 walk_through_subclasses(address, empty_address, layers, NCData, empty_model, verbose) 150 151 152 def walk_through_subclasses(address, empty_address, layers: list, NCData, empty_model, verbose = False): 149 153 # See if we have an object with keys or a not 150 154 try: … … 155 159 if is_object: 156 160 # enter the subclass, see if it has nested classes and/or attributes 157 # then compare attributes between mds and write to netCDFif they differ161 # then compare attributes between mds and write to NCData if they differ 158 162 # if subclass found, walk through it and repeat 159 163 for child in address.__dict__.keys(): … … 165 169 address_of_child = address.__dict__[child] 166 170 167 # if the current object is a results.<solution> object and has thesteps attr it needs special treatment171 # if the current object is a results.<solution> object and has nonzero steps attr it needs special treatment 168 172 if isinstance(address_of_child, solution) and len(address_of_child.steps) != 0: 169 create_group(address_of_child, current_layer, is_struct = True, NetCDF=NetCDF, verbose = verbose) 173 create_group(address_of_child, current_layer, is_struct = True, is_special_list = False, NCData=NCData, verbose = verbose) 174 175 # if the current object is a list of objects (currently only filters for lists/arrays of classes) 176 elif isinstance(address_of_child, list) and len(address_of_child) > 0 and hasattr(address_of_child[0], '__dict__'): 177 create_group(address_of_child, current_layer, is_struct = False, is_special_list = True, NCData=NCData, verbose = verbose) 170 178 171 179 # if the variable is an array, assume it has relevant data (this is because the next line cannot evaluate "==" with an array) 172 180 elif isinstance(address_of_child, np.ndarray): 173 create_group(address_of_child, current_layer, is_struct = False, NetCDF=NetCDF, verbose = verbose)174 175 # see if the child exists in the empty md. If not, record it in the netcdf181 create_group(address_of_child, current_layer, is_struct = False, is_special_list = False, NCData=NCData, verbose = verbose) 182 183 # see if the child exists in the empty md. If not, record it in the NCData 176 184 else: 177 185 try: … … 181 189 # if the attributes are identical we don't need to save anything 182 190 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, N etCDF, empty_model, verbose)184 185 # If it has been modified, record it in the N etCDFfile191 walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer, NCData, empty_model, verbose) 192 193 # If it has been modified, record it in the NCData file 186 194 else: 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, N etCDF, empty_model, verbose)189 190 except KeyError: # record in netcdfand continue to walk thru md191 walk_through_subclasses(address_of_child, empty_address, current_layer, N etCDF, empty_model, verbose)192 create_group(address_of_child, current_layer, is_struct = False, NetCDF=NetCDF, verbose = verbose)195 create_group(address_of_child, current_layer, is_struct = False, is_special_list = False, NCData=NCData, verbose = verbose) 196 walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer, NCData, empty_model, verbose) 197 198 except KeyError: # record in NCData and continue to walk thru md 199 walk_through_subclasses(address_of_child, empty_address, current_layer, NCData, empty_model, verbose) 200 create_group(address_of_child, current_layer, is_struct = False, is_special_list = False, NCData=NCData, verbose = verbose) 193 201 else: pass 194 202 195 203 196 def create_group(address_of_child, layers, is_struct = False, NetCDF=None, verbose = False):204 def create_group(address_of_child, layers, is_struct = False, is_special_list = False, NCData=None, verbose = False): 197 205 198 206 # Handle the first layer of the group(s) 199 207 group_name = layers[0] 208 209 # try to make a group unless the group is already made 200 210 try: 201 group = N etCDF.createGroup(str(group_name))211 group = NCData.createGroup(str(group_name)) 202 212 except: 203 group = N etCDF.groups[str(group_name)]213 group = NCData.groups[str(group_name)] 204 214 205 215 # need to check if inversion or m1qn3inversion class 206 216 if group_name == 'inversion': 207 check_inversion_class(address_of_child, N etCDF, verbose)217 check_inversion_class(address_of_child, NCData, verbose) 208 218 else: pass 209 219 210 # if the data is nested , create nested groups to match class structure220 # if the data is nested in md, create nested groups to match class structure 211 221 if len(layers) > 2: 212 222 for name in layers[1:-1]: … … 214 224 group = group.createGroup(str(name)) 215 225 except: 216 group = N etCDF.groups[str(name)]226 group = NCData.groups[str(name)] 217 227 else: pass 218 228 … … 220 230 if is_struct: 221 231 parent_struct_name = layers[-1] 222 copy_nested_results_struct(parent_struct_name, address_of_child, group, NetCDF, verbose) 232 serialize_nested_results_struct(parent_struct_name, address_of_child, group, NCData, verbose) 233 234 elif is_special_list: 235 list_name = layers[-1] 236 serialize_array_of_objects(list_name, address_of_child, group, NCData, verbose) 223 237 224 238 else: 225 239 variable_name = layers[-1] 226 create_var(variable_name, address_of_child, group, NetCDF, verbose)240 serialize_var(variable_name, address_of_child, group, NCData, verbose) 227 241 228 242 … … 242 256 243 257 @singleton 244 def check_inversion_class(address_of_child, N etCDF, verbose = False):258 def check_inversion_class(address_of_child, NCData, verbose = False): 245 259 # need to make sure that we have the right inversion class: inversion, m1qn3inversion, taoinversion 246 260 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'], NetCDF=NetCDF, verbose = verbose)261 serialize_string(variable_name=str('inversion_class_name'), address_of_child=str('m1qn3inversion'), group=NCData.groups['inversion'], NCData=NCData, verbose = verbose) 248 262 if verbose: 249 263 print('Successfully saved inversion class instance ' + 'm1qn3inversion') 250 264 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'], NetCDF=NetCDF, verbose = verbose)265 serialize_string(variable_name=str('inversion_class_name'), address_of_child=str('taoinversion'), group=NCData.groups['inversion'], NCData=NCData, verbose = verbose) 252 266 if verbose: 253 267 print('Successfully saved inversion class instance ' + 'taoinversion') 254 268 else: 255 write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('inversion'), group=NetCDF.groups['inversion'], NetCDF=NetCDF, verbose = verbose)269 serialize_string(variable_name=str('inversion_class_name'), address_of_child=str('inversion'), group=NCData.groups['inversion'], NCData=NCData, verbose = verbose) 256 270 if verbose: 257 271 print('Successfully saved inversion class instance ' + 'inversion') 258 272 259 273 260 def copy_nested_results_struct(parent_struct_name, address_of_struct, group, NetCDF, verbose = False):274 def (parent_struct_name, address_of_struct, group, NCData, verbose = False): 261 275 ''' 262 This function takes a solution class instance and saves the solutionstep instances from <solution>.steps to the netcdf.276 This function takes a solution class instance and saves the solutionstep instances from <solution>.steps to the NCData. 263 277 264 278 To do this, we get the number of dimensions (substructs) of the parent struct. … … 268 282 ''' 269 283 if verbose: 270 print("Beginning transfer of nested MATLAB struct to the N etCDF")284 print("Beginning transfer of nested MATLAB struct to the NCData") 271 285 272 286 # make a new subgroup to contain all the others: … … 274 288 275 289 # make sure other systems can flag the nested struct type 276 write_string_to_netcdf('this_is_a_nested', 'struct', group, list=False, NetCDF=NetCDF, verbose = verbose)290 serialize_string('this_is_a_nested', 'struct', group, list=False, NCData=NCData, verbose = verbose) 277 291 278 292 # other systems know the name of the parent struct because it's covered by the results/qmu functions above … … 290 304 for variable in substruct_fields: 291 305 address_of_child = current_substruct.__dict__[variable] 292 create_var(variable, address_of_child, subgroup, NetCDF, verbose = verbose)306 serialize_var(variable, address_of_child, subgroup, NCData, verbose = verbose) 293 307 294 308 if verbose: 295 print(f'Successfully transferred struct {parent_struct_name} to the NetCDF\n') 296 309 print(f'Successfully transferred struct {parent_struct_name} to the NCData\n') 310 311 312 313 314 def serialize_array_of_objects(list_name, address_of_child, group, NCData, verbose): 315 # Get the dimensions of the cell array 316 if len(np.shape(address_of_child)) > 1: 317 rows, cols = np.shape(address_of_child) 318 else: rows, cols = 1, np.shape(address_of_child)[0] 319 320 # Make subgroup to represent the array 321 name_of_subgroup = f"{str(rows)}x{str(cols)}_cell_array_of_objects" 322 subgroup = group.createGroup(name_of_subgroup) 323 324 # Save the name of the cell array 325 serialize_string('name_of_cell_array', list_name, subgroup, NCData, verbose) 326 327 # Save the dimensions of the cell array 328 rowsID = subgroup.createVariable('rows', int, ('int',)) 329 colsID = subgroup.createVariable('cols', int, ('int',)) 330 rowsID[:] = rows 331 colsID[:] = cols 332 333 334 # If this is a multidimensional cell array, iterate over rows here and cols in serialize_objects 335 if rows > 1: 336 for row in range(rows): 337 # Make a subgroup for each row 338 name_of_subgroup = f"Row_{row+1}_of_{rows}" 339 subgroup = group.createGroup(name_of_subgroup) 340 serialize_objects(address_of_child, subgroup, NCData, cols, verbose) 341 else: 342 serialize_objects(address_of_child, subgroup, NCData, cols, verbose) 343 344 345 346 def serialize_objects(address_of_child, group, NCData, cols, verbose): 347 for col in range(cols): 348 # Make subgroup to contain each col of array 349 name_of_subgroup = f'Col_{col+1}_of_{cols}' 350 subgroup = group.createGroup(name_of_subgroup) 351 352 # index the current item 353 variable = address_of_child[col] 354 355 # Get the kind of object we're working with: 356 # see if it's a solution instance 357 if isinstance(variable, solution) and len(variable.steps) != 0: 358 pass 359 # this needs more work... 360 #name_raw = list(address_of_child[col - 1].keys())[0] 361 #variable_name = name_raw 362 #serialize_nested_struct(variable_name, variable, subgroup, NCData, verbose) 297 363 298 def create_var(variable_name, address_of_child, group, NetCDF, verbose = False): 364 # see if it's a general class -- assume ISSM classes all have __dict__ 365 elif hasattr(variable, '__dict__'): 366 # Handle class instances 367 serialize_class_instance(variable, subgroup, NCData, verbose) 368 else: 369 print('ERROR: Cell arrays of mixed types are not yet supported in read_NCData!') 370 print('Deserialization will not be able to complete!') 371 # Handle regular data structures that are already supported 372 serialize_var(variable_name, variable, subgroup, NCData, verbose) 373 374 375 376 377 def serialize_class_instance(instance, group, NCData, verbose): 378 # get parent class name: 379 name = instance.__class__.__name__ 380 381 # save the name of the class 382 serialize_string(variable_name='class_is_a', address_of_child=name, group=group, NCData=NCData, verbose = verbose) 383 384 # make subgroup to contain attributes 385 name_of_subgroup = 'Properties_of_' + name 386 subgroup = group.createGroup(name_of_subgroup) 387 388 # get attributes 389 keys = instance.__dict__.keys() 390 391 for name in keys: 392 serialize_var(name, instance.__dict__[name], subgroup, NCData, verbose) 393 394 395 396 397 def serialize_var(variable_name, address_of_child, group, NCData, verbose = False): 299 398 # There are lots of different variable types that we need to handle from the md class 300 399 301 400 # This first conditional statement will catch numpy arrays of any dimension and save them 302 401 if isinstance(address_of_child, np.ndarray): 303 write_numpy_array_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose=verbose)402 serialize_numpy_array(variable_name, address_of_child, group, NCData, verbose=verbose) 304 403 305 404 # check if it's an int … … 315 414 # or a string 316 415 elif isinstance(address_of_child, str): 317 write_string_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose=verbose)416 serialize_string(variable_name, address_of_child, group, NCData, verbose=verbose) 318 417 319 418 #or a bool 320 419 elif isinstance(address_of_child, bool) or isinstance(address_of_child, np.bool_): 321 # netcdf4 can't handle bool types like True/False so we convert all to int 1/0 and add an attribute named units with value 'bool'420 # NCData4 can't handle bool types like True/False so we convert all to int 1/0 and add an attribute named units with value 'bool' 322 421 variable = group.createVariable(variable_name, int, ('int',)) 323 422 variable[:] = int(address_of_child) … … 331 430 elif isinstance(address_of_child,list) and isinstance(address_of_child[0],str): 332 431 for string in address_of_child: 333 write_string_to_netcdf(variable_name, string, group, list=True, NetCDF=NetCDF, verbose=verbose)432 serialize_string(variable_name, string, group, list=True, NCData=NCData, verbose=verbose) 334 433 335 434 # or a regular list … … 352 451 353 452 if verbose: 354 print(f'Successfully transferred data from {variable_name} to the N etCDF')355 356 357 def write_string_to_netcdf(variable_name, address_of_child, group, list=False, NetCDF=None, verbose = False):358 # netcdfand strings dont get along.. we have to do it 'custom':453 print(f'Successfully transferred data from {variable_name} to the NCData') 454 455 456 def serialize_string(variable_name, address_of_child, group, list=False, NCData=None, verbose = False): 457 # NCData and strings dont get along.. we have to do it 'custom': 359 458 # if we hand it an address we need to do it this way: 360 459 if list == True: 361 460 """ 362 Save a list of strings to a N etCDFfile.461 Save a list of strings to a NCData file. 363 462 364 463 Convert a list of strings to a numpy.char_array with utf-8 encoded elements 365 and size rows x cols with each row the same # of cols and save to N etCDF464 and size rows x cols with each row the same # of cols and save to NCData 366 465 as char array. 367 466 """ … … 399 498 arr[i] = new_list[i] 400 499 401 # save array to netcdffile500 # save array to NCData file 402 501 string_var[:] = arr 403 502 … … 412 511 length_of_the_string = len(the_string_to_save) 413 512 numpy_datatype = 'S' + str(length_of_the_string) 414 str_out = netCDF4.stringtochar(np.array([the_string_to_save], dtype=numpy_datatype))513 str_out = NCData4.stringtochar(np.array([the_string_to_save], dtype=numpy_datatype)) 415 514 416 515 # we'll need to make a new dimension for the string if it doesn't already exist … … 431 530 432 531 433 def write_numpy_array_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose = False):434 # to make a nested array in netCDF, we have to get the dimensions of the array,435 # create corresponding dimensions in the netCDFfile, then we can make a variable436 # in the netCDFwith dimensions identical to those in the original array532 def serialize_numpy_array(variable_name, address_of_child, group, NCData, verbose = False): 533 # to make a nested array in NCData, we have to get the dimensions of the array, 534 # create corresponding dimensions in the NCData file, then we can make a variable 535 # in the NCData with dimensions identical to those in the original array 437 536 438 537 # start by getting the data type at the lowest level in the array:
Note:
See TracChangeset
for help on using the changeset viewer.