Index: /issm/trunk/src/m/contrib/musselman/read_netCDF.py
===================================================================
--- /issm/trunk/src/m/contrib/musselman/read_netCDF.py	(revision 27897)
+++ /issm/trunk/src/m/contrib/musselman/read_netCDF.py	(revision 27898)
@@ -30,44 +30,53 @@
         print('NetCDF42C v1.1.13')
 
-    # check if path exists
-    if path.exists(filename):
+    # this is a precaution so that data is not lost
+    try:
+        # check if path exists
+        if path.exists(filename):
+            if verbose:
+                print('Opening {} for reading'.format(filename))
+            else: pass
+    
+            # open the given netCDF4 file
+            NCData = Dataset(filename, 'r')
+            # remove masks from numpy arrays for easy conversion
+            NCData.set_auto_mask(False)
+        else:
+            print('The file you entered does not exist or cannot be found in the current directory')
+            return print()
+        
+        # continuation of band-aid for results class
+        try:
+            NCData.groups['results']
+            make_results_subclasses(NCData, verbose)
+        except:
+            pass
+    
+        # similarly, we need to check and see if we have an m1qn3inversion class instance
+        try:
+            NCData.groups['inversion']
+            check_inversion_class(NCData, verbose)
+        except:
+            pass
+        
+        # walk through each group looking for subgroups and variables
+        for group in NCData.groups.keys():
+            if 'debris' in group:
+                pass
+            else:
+                # have to send a custom name to this function: filename.groups['group']
+                name = "NCData.groups['" + str(group) + "']"
+                walk_nested_groups(name, NCData, verbose)
+        
         if verbose:
-            print('Opening {} for reading'.format(filename))
-        else: pass
-
-        # open the given netCDF4 file
-        NCData = Dataset(filename, 'r')
-        # remove masks from numpy arrays for easy conversion
-        NCData.set_auto_mask(False)
-    else:
-        print('The file you entered does not exist or cannot be found in the current directory')
-        return print()
-    
-    # continuation of band-aid for results class
-    try:
-        NCData.groups['results']
-        make_results_subclasses(NCData, verbose)
-    except:
-        pass
-
-    # similarly, we need to check and see if we have an m1qn3inversion class instance
-    try:
-        NCData.groups['inversion']
-        check_inversion_class(NCData, verbose)
-    except:
-        pass
-    
-    # walk through each group looking for subgroups and variables
-    for group in NCData.groups.keys():
-        if 'debris' in group:
-            pass
-        else:
-            # have to send a custom name to this function: filename.groups['group']
-            name = "NCData.groups['" + str(group) + "']"
-            walk_nested_groups(name, NCData, verbose)
-    
-    if verbose:
-        print("Model Successfully Loaded.")
-    return model_copy
+            print("Model Successfully Loaded.")
+            
+        NCData.close()
+        
+        return model_copy
+
+    except Error:
+        NCData.close()
+        return Error
 
 
@@ -126,10 +135,10 @@
                 matches = re.findall(pattern, group_location_in_file)
                 name_of_struct = matches[-1] #eval(group_location_in_file + ".variables['solution']") 
-                copy_multidimensional_results_struct(group_location_in_file, name_of_struct, NCData)
+                deserialize_nested_results_struct(group_location_in_file, name_of_struct, NCData)
                 is_object = True
     
             elif variable == 'name_of_cell_array':
                 # reconstruct an array of elements
-                copy_cell_array_of_objects(group_location_in_file, model_copy, NCData, verbose)
+                deserialize_array_of_objects(group_location_in_file, model_copy, NCData, verbose)
                 is_object = True
     
@@ -150,5 +159,5 @@
                 variable_name = matches[-1]
                 location_of_variable_in_model = '.'.join(matches[:-1])
-                copy_variable_data_to_new_model(location_of_variable_in_file, location_of_variable_in_model, variable_name, NCData, verbose=verbose)
+                deserialize_data(location_of_variable_in_file, location_of_variable_in_model, variable_name, NCData, verbose=verbose)
 
     # if one of the variables above was an object, further subclasses will be taken care of when reconstructing it
@@ -161,5 +170,5 @@
 
 
-def copy_cell_array_of_objects(group_location_in_file, model_copy, NCData, verbose):
+def deserialize_array_of_objects(group_location_in_file, model_copy, NCData, verbose):
     '''
         The structure in netcdf for groups with the name_of_cell_array variable is like:
@@ -336,5 +345,5 @@
 '''
 
-def copy_multidimensional_results_struct(group_location_in_file, name_of_struct, NCData, verbose = False):
+def deserialize_nested_results_struct(group_location_in_file, name_of_struct, NCData, verbose = False):
     '''
     A common multidimensional array is the 1xn md.results.TransientSolution object.
@@ -376,5 +385,5 @@
 
 
-def copy_variable_data_to_new_model(location_of_variable_in_file, location_of_variable_in_model, variable_name, NCData, verbose = False):
+def deserialize_data(location_of_variable_in_file, location_of_variable_in_model, variable_name, NCData, verbose = False):
     # as simple as navigating to the location_of_variable_in_model and setting it equal to the location_of_variable_in_file
     # NetCDF4 has a property called "_FillValue" that sometimes saves empty lists, so we have to catch those
@@ -417,5 +426,5 @@
                 setattr(eval('model_copy.' + location_of_variable_in_model), variable_name, eval(location_of_variable_in_file + '[:]'))
     except AttributeError:
-        copy_variable_data_to_new_model_dict(location_of_variable_in_file, location_of_variable_in_model, NCData, verbose=verbose)
+        deserialize_dict(location_of_variable_in_file, location_of_variable_in_model, NCData, verbose=verbose)
 
     if verbose:
@@ -424,5 +433,5 @@
 
 
-def copy_variable_data_to_new_model_dict(location_of_variable_in_file, location_of_variable_in_model, NCData, verbose = False):
+def deserialize_dict(location_of_variable_in_file, location_of_variable_in_model, NCData, verbose = False):
     # as simple as navigating to the location_of_variable_in_model and setting it equal to the location_of_variable_in_file
 
Index: /issm/trunk/src/m/contrib/musselman/write_netCDF.py
===================================================================
--- /issm/trunk/src/m/contrib/musselman/write_netCDF.py	(revision 27897)
+++ /issm/trunk/src/m/contrib/musselman/write_netCDF.py	(revision 27898)
@@ -1,5 +1,5 @@
 # imports
-import netCDF4
-from netCDF4 import Dataset
+import NCData4
+from NCData4 import Dataset
 import numpy as np
 import numpy.ma as ma
@@ -15,16 +15,15 @@
 '''
 Given a md, this set of functions will perform the following:
-    1. Enter each nested class of the md.
-    2. View each attribute of each nested class.
-    3. Compare state of attribute in the model to an empty model class.
-    4. If states are identical, pass.
-    5. Otherwise, create nested groups named after class structure.
-    6. Create variable named after class attribute and assign value to it.
+    1. View each attribute of each nested class.
+    2. Compare state of attribute in the model to an empty model.
+    3. If states are identical, pass. (except for np arrays which will always be saved)
+    4. Otherwise, create nested groups named after class structure.
+    5. Create variable named after class attribute and assign value to it.
 '''
 
 
-def write_netCDF(md, filename: str, verbose = False):
+def write_NCData(md, filename: str, verbose = False):
     if verbose:
-        print('Python C2NetCDF4 v1.1.14')
+        print('Python C2NCData4 v1.1.14')
     else: pass
     '''
@@ -33,36 +32,41 @@
     verbose = T/F muted or show log statements. Naturally muted
     '''
-    
-    # Create a NetCDF file to write to
-    NetCDF = make_NetCDF(filename, verbose)
-    
-    # Create an instance of an empty md class to compare md_var against
-    empty_model = model()
-
-    # Walk through the md class and compare subclass states to empty_model
-    walk_through_model(md, empty_model, NetCDF, verbose)
-
-    # in order to handle some subclasses in the results class, we have to utilize this band-aid
-    # 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
+    # this is a precaution so that data is not lost
     try:
-        # if results has meaningful data, save the name of the subclass and class instance
-        NetCDF.groups['results']
-        results_subclasses_bandaid(md, NetCDF, verbose)
-        # otherwise, ignore
-    except KeyError:
-        pass
+        # Create a NCData file to write to
+        NCData = create_NCData(filename, verbose)
         
-    NetCDF.close()
-    if verbose:
-        print('Model successfully saved as NetCDF4')
-    else: pass
-    
-
-def results_subclasses_bandaid(md, NetCDF, verbose = False):
+        # Create an instance of an empty md class to compare md_var against
+        empty_model = model()
+    
+        # Walk through the md class and compare subclass states to empty_model
+        walk_through_model(md, empty_model, NCData, verbose)
+    
+        # in order to handle some subclasses in the results class, we have to utilize this band-aid
+        # 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
+        try:
+            # if results has meaningful data, save the name of the subclass and class instance
+            NCData.groups['results']
+            results_subclasses_bandaid(md, NCData, verbose)
+            # otherwise, ignore
+        except KeyError:
+            pass
+            
+        NCData.close()
+        if verbose:
+            print('Model successfully saved as NCData4')
+        else: pass
+            
+    except Error:
+        NCData.close()
+        return Error
+    
+
+def results_subclasses_bandaid(md, NCData, verbose = False):
     # since the results class may have nested classes within it, we need to record the name of the 
     # nested class instance variable as it appears in the md that we're trying to save
     quality_control = []
 
-    # we save lists of instances to the netcdf
+    # we save lists of instances to the NCData
     solutions = []
     solutionsteps = []
@@ -72,5 +76,5 @@
         if verbose:
             print(class_instance_name)
-        # for each class instance in results, see which class its from and record that info in the netcdf to recreate structure later
+        # for each class instance in results, see which class its from and record that info in the NCData to recreate structure later
         # check to see if there is a solutionstep class instance
         if isinstance(md.results.__dict__[class_instance_name],solutionstep):
@@ -89,11 +93,11 @@
 
     if solutionsteps != []:
-        write_string_to_netcdf(variable_name=str('solutionstep'), address_of_child=solutionsteps, group=NetCDF.groups['results'], list=True, NetCDF=NetCDF, verbose=verbose)
+        serialize_string(variable_name=str('solutionstep'), address_of_child=solutionsteps, group=NCData.groups['results'], list=True, NCData=NCData, verbose=verbose)
 
     if solutions != []:
-        write_string_to_netcdf(variable_name=str('solution'), address_of_child=solutions, group=NetCDF.groups['results'], list=True, NetCDF=NetCDF, verbose=verbose)
+        serialize_string(variable_name=str('solution'), address_of_child=solutions, group=NCData.groups['results'], list=True, NCData=NCData, verbose=verbose)
 
     if resultsdakotas != []:
-        write_string_to_netcdf(variable_name=str('resultsdakota'), address_of_child=resultsdakotas, group=NetCDF.groups['results'], list=True, NetCDF=NetCDF, verbose=verbose)
+        serialize_string(variable_name=str('resultsdakota'), address_of_child=resultsdakotas, group=NCData.groups['results'], list=True, NCData=NCData, verbose=verbose)
 
     
@@ -107,5 +111,5 @@
 
 
-def make_NetCDF(filename: str, verbose = False):
+def create_NCData(filename: str, verbose = False):
     # If file already exists delete / rename it
     if os.path.exists(filename):
@@ -122,29 +126,29 @@
     else:
         # Otherwise create the file and define it globally so other functions can call it
-        NetCDF = Dataset(filename, 'w', format='NETCDF4')
-        NetCDF.history = 'Created ' + time.ctime(time.time())
-        NetCDF.createDimension('Unlim', None)  # unlimited dimension
-        NetCDF.createDimension('float', 1)     # single integer dimension
-        NetCDF.createDimension('int', 1)       # single float dimension
+        NCData = Dataset(filename, 'w', format='NCData4')
+        NCData.history = 'Created ' + time.ctime(time.time())
+        NCData.createDimension('Unlim', None)  # unlimited dimension
+        NCData.createDimension('float', 1)     # single integer dimension
+        NCData.createDimension('int', 1)       # single float dimension
     
     if verbose:
         print('Successfully created ' + filename)
 
-    return NetCDF
-
-
-def walk_through_model(md, empty_model, NetCDF, verbose= False):
-    # Iterate over first layer of md_var attributes and assume this first layer is only classes
+    return NCData
+
+
+def walk_through_model(md, empty_model, NCData, verbose= False):
+    # Iterate over first layer of md attributes and assume this first layer is only classes
     for group in md.__dict__.keys():
         address = md.__dict__[group]
         empty_address = empty_model.__dict__[group]
-        # we need to record the layers of the md so we can save them to the netcdf file
+        # we need to record the layers of the md so we can save them to the NCData file
         layers = [group]
 
         # Recursively walk through subclasses
-        walk_through_subclasses(address, empty_address, layers, NetCDF, empty_model, verbose)       
-
-
-def walk_through_subclasses(address, empty_address, layers: list, NetCDF, empty_model, verbose = False):
+        walk_through_subclasses(address, empty_address, layers, NCData, empty_model, verbose)       
+
+
+def walk_through_subclasses(address, empty_address, layers: list, NCData, empty_model, verbose = False):
     # See if we have an object with keys or a not
     try:
@@ -155,5 +159,5 @@
     if is_object:
         # enter the subclass, see if it has nested classes and/or attributes
-        # then compare attributes between mds and write to netCDF if they differ
+        # then compare attributes between mds and write to NCData if they differ
         # if subclass found, walk through it and repeat
         for child in address.__dict__.keys():
@@ -165,13 +169,17 @@
             address_of_child = address.__dict__[child]
             
-            # if the current object is a results.<solution> object and has the steps attr it needs special treatment
+            # if the current object is a results.<solution> object and has nonzero steps attr it needs special treatment
             if isinstance(address_of_child, solution) and len(address_of_child.steps) != 0:
-                create_group(address_of_child, current_layer, is_struct = True, NetCDF=NetCDF, verbose = verbose)
+                create_group(address_of_child, current_layer, is_struct = True, is_special_list = False,  NCData=NCData, verbose = verbose)
+
+            # if the current object is a list of objects (currently only filters for lists/arrays of classes)
+            elif isinstance(address_of_child, list) and len(address_of_child) > 0 and hasattr(address_of_child[0], '__dict__'):
+                create_group(address_of_child, current_layer, is_struct = False, is_special_list = True, NCData=NCData, verbose = verbose)
 
             # if the variable is an array, assume it has relevant data (this is because the next line cannot evaluate "==" with an array)
             elif isinstance(address_of_child, np.ndarray):
-                create_group(address_of_child, current_layer, is_struct = False, NetCDF=NetCDF, verbose = verbose)
-            
-            # see if the child exists in the empty md. If not, record it in the netcdf
+                create_group(address_of_child, current_layer, is_struct = False, is_special_list = False,  NCData=NCData, verbose = verbose)
+            
+            # see if the child exists in the empty md. If not, record it in the NCData
             else:
                 try: 
@@ -181,32 +189,34 @@
                     # if the attributes are identical we don't need to save anything
                     if address_of_child == address_of_child_in_empty_class:
-                        walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer, NetCDF, empty_model, verbose)
-    
-                    # If it has been modified, record it in the NetCDF file
+                        walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer, NCData, empty_model, verbose)
+    
+                    # If it has been modified, record it in the NCData file
                     else:
-                        create_group(address_of_child, current_layer, is_struct = False, NetCDF=NetCDF, verbose = verbose)
-                        walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer, NetCDF, empty_model, verbose)
-    
-                except KeyError: # record in netcdf and continue to walk thru md
-                    walk_through_subclasses(address_of_child, empty_address, current_layer, NetCDF, empty_model, verbose)
-                    create_group(address_of_child, current_layer, is_struct = False, NetCDF=NetCDF, verbose = verbose)
+                        create_group(address_of_child, current_layer, is_struct = False, is_special_list = False,  NCData=NCData, verbose = verbose)
+                        walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer, NCData, empty_model, verbose)
+    
+                except KeyError: # record in NCData and continue to walk thru md
+                    walk_through_subclasses(address_of_child, empty_address, current_layer, NCData, empty_model, verbose)
+                    create_group(address_of_child, current_layer, is_struct = False, is_special_list = False,  NCData=NCData, verbose = verbose)
     else: pass
 
 
-def create_group(address_of_child, layers, is_struct = False, NetCDF=None, verbose = False):
+def create_group(address_of_child, layers, is_struct = False, is_special_list = False,  NCData=None, verbose = False):
 
     # Handle the first layer of the group(s)
     group_name = layers[0]
+    
+    # try to make a group unless the group is already made
     try:
-        group = NetCDF.createGroup(str(group_name))
+        group = NCData.createGroup(str(group_name))
     except:
-        group = NetCDF.groups[str(group_name)]
+        group = NCData.groups[str(group_name)]
 
     # need to check if inversion or m1qn3inversion class
     if group_name == 'inversion':
-        check_inversion_class(address_of_child, NetCDF, verbose)
+        check_inversion_class(address_of_child, NCData, verbose)
     else: pass
 
-    # if the data is nested, create nested groups to match class structure
+    # if the data is nested in md, create nested groups to match class structure
     if len(layers) > 2:
         for name in layers[1:-1]:
@@ -214,5 +224,5 @@
                 group = group.createGroup(str(name))
             except:
-                group = NetCDF.groups[str(name)]
+                group = NCData.groups[str(name)]
     else: pass
 
@@ -220,9 +230,13 @@
     if is_struct:
         parent_struct_name = layers[-1]
-        copy_nested_results_struct(parent_struct_name, address_of_child, group, NetCDF, verbose)
+        serialize_nested_results_struct(parent_struct_name, address_of_child, group, NCData, verbose)
+
+    elif is_special_list:
+        list_name = layers[-1]
+        serialize_array_of_objects(list_name, address_of_child, group, NCData, verbose)
     
     else:
         variable_name = layers[-1]
-        create_var(variable_name, address_of_child, group, NetCDF, verbose)
+        serialize_var(variable_name, address_of_child, group, NCData, verbose)
             
 
@@ -242,23 +256,23 @@
 
 @singleton
-def check_inversion_class(address_of_child, NetCDF, verbose = False):
+def check_inversion_class(address_of_child, NCData, verbose = False):
     # need to make sure that we have the right inversion class: inversion, m1qn3inversion, taoinversion
     if isinstance(address_of_child, m1qn3inversion):
-        write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('m1qn3inversion'), group=NetCDF.groups['inversion'], NetCDF=NetCDF, verbose = verbose)
+        serialize_string(variable_name=str('inversion_class_name'), address_of_child=str('m1qn3inversion'), group=NCData.groups['inversion'], NCData=NCData, verbose = verbose)
         if verbose:
             print('Successfully saved inversion class instance ' + 'm1qn3inversion')
     elif isinstance(address_of_child, taoinversion):
-        write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('taoinversion'), group=NetCDF.groups['inversion'], NetCDF=NetCDF, verbose = verbose)
+        serialize_string(variable_name=str('inversion_class_name'), address_of_child=str('taoinversion'), group=NCData.groups['inversion'], NCData=NCData, verbose = verbose)
         if verbose:
             print('Successfully saved inversion class instance ' + 'taoinversion')
     else:
-        write_string_to_netcdf(variable_name=str('inversion_class_name'), address_of_child=str('inversion'), group=NetCDF.groups['inversion'], NetCDF=NetCDF, verbose = verbose)
+        serialize_string(variable_name=str('inversion_class_name'), address_of_child=str('inversion'), group=NCData.groups['inversion'], NCData=NCData, verbose = verbose)
         if verbose:
             print('Successfully saved inversion class instance ' + 'inversion')
 
 
-def copy_nested_results_struct(parent_struct_name, address_of_struct, group, NetCDF, verbose = False):
+def  (parent_struct_name, address_of_struct, group, NCData, verbose = False):
     '''
-        This function takes a solution class instance and saves the solutionstep instances from <solution>.steps to the netcdf. 
+        This function takes a solution class instance and saves the solutionstep instances from <solution>.steps to the NCData. 
 
         To do this, we get the number of dimensions (substructs) of the parent struct.
@@ -268,5 +282,5 @@
     '''
     if verbose:
-        print("Beginning transfer of nested MATLAB struct to the NetCDF")
+        print("Beginning transfer of nested MATLAB struct to the NCData")
     
     # make a new subgroup to contain all the others:
@@ -274,5 +288,5 @@
 
     # make sure other systems can flag the nested struct type
-    write_string_to_netcdf('this_is_a_nested', 'struct', group, list=False, NetCDF=NetCDF, verbose = verbose)
+    serialize_string('this_is_a_nested', 'struct', group, list=False, NCData=NCData, verbose = verbose)
 
     # other systems know the name of the parent struct because it's covered by the results/qmu functions above
@@ -290,16 +304,101 @@
         for variable in substruct_fields:
             address_of_child = current_substruct.__dict__[variable]
-            create_var(variable, address_of_child, subgroup, NetCDF, verbose = verbose)
+            serialize_var(variable, address_of_child, subgroup, NCData, verbose = verbose)
     
     if verbose:
-        print(f'Successfully transferred struct {parent_struct_name} to the NetCDF\n')
-    
+        print(f'Successfully transferred struct {parent_struct_name} to the NCData\n')
+
+
+
+
+def serialize_array_of_objects(list_name, address_of_child, group, NCData, verbose):
+    # Get the dimensions of the cell array
+    if len(np.shape(address_of_child)) > 1: 
+        rows, cols = np.shape(address_of_child)
+    else: rows, cols = 1, np.shape(address_of_child)[0]
+
+    # Make subgroup to represent the array
+    name_of_subgroup = f"{str(rows)}x{str(cols)}_cell_array_of_objects"
+    subgroup = group.createGroup(name_of_subgroup)
+
+    # Save the name of the cell array
+    serialize_string('name_of_cell_array', list_name, subgroup, NCData, verbose)
+
+    # Save the dimensions of the cell array
+    rowsID = subgroup.createVariable('rows', int, ('int',))
+    colsID = subgroup.createVariable('cols', int, ('int',))
+    rowsID[:] = rows
+    colsID[:] = cols
+
+
+    # If this is a multidimensional cell array, iterate over rows here and cols in serialize_objects
+    if rows > 1:
+        for row in range(rows):
+            # Make a subgroup for each row
+            name_of_subgroup = f"Row_{row+1}_of_{rows}"
+            subgroup = group.createGroup(name_of_subgroup)
+            serialize_objects(address_of_child, subgroup, NCData, cols, verbose)
+    else:
+        serialize_objects(address_of_child, subgroup, NCData, cols, verbose)
+
+
+
+def serialize_objects(address_of_child, group, NCData, cols, verbose):
+    for col in range(cols):
+        # Make subgroup to contain each col of array
+        name_of_subgroup = f'Col_{col+1}_of_{cols}'
+        subgroup = group.createGroup(name_of_subgroup)
+
+        # index the current item
+        variable = address_of_child[col]
+
+        # Get the kind of object we're working with:
+        # see if it's a solution instance
+        if isinstance(variable, solution) and len(variable.steps) != 0:
+            pass
+            # this needs more work...
+            #name_raw = list(address_of_child[col - 1].keys())[0]
+            #variable_name = name_raw
+            #serialize_nested_struct(variable_name, variable, subgroup, NCData, verbose)
         
-def create_var(variable_name, address_of_child, group, NetCDF, verbose = False):
+        # see if it's a general class -- assume ISSM classes all have __dict__
+        elif hasattr(variable, '__dict__'):
+            # Handle class instances
+            serialize_class_instance(variable, subgroup, NCData, verbose)
+        else:
+            print('ERROR: Cell arrays of mixed types are not yet supported in read_NCData!')
+            print('Deserialization will not be able to complete!')
+            # Handle regular data structures that are already supported
+            serialize_var(variable_name, variable, subgroup, NCData, verbose)
+
+
+
+
+def serialize_class_instance(instance, group, NCData, verbose):
+    # get parent class name:
+    name = instance.__class__.__name__
+
+    # save the name of the class
+    serialize_string(variable_name='class_is_a', address_of_child=name, group=group, NCData=NCData, verbose = verbose)
+
+    # make subgroup to contain attributes
+    name_of_subgroup = 'Properties_of_' + name
+    subgroup = group.createGroup(name_of_subgroup)
+
+    # get attributes
+    keys = instance.__dict__.keys()
+
+    for name in keys:
+        serialize_var(name, instance.__dict__[name], subgroup, NCData, verbose)
+    
+
+
+        
+def serialize_var(variable_name, address_of_child, group, NCData, verbose = False):
     # There are lots of different variable types that we need to handle from the md class
     
     # This first conditional statement will catch numpy arrays of any dimension and save them
     if isinstance(address_of_child, np.ndarray):
-        write_numpy_array_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose=verbose)
+        serialize_numpy_array(variable_name, address_of_child, group, NCData, verbose=verbose)
     
     # check if it's an int
@@ -315,9 +414,9 @@
     # or a string
     elif isinstance(address_of_child, str):
-        write_string_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose=verbose)
+        serialize_string(variable_name, address_of_child, group, NCData, verbose=verbose)
 
     #or a bool
     elif isinstance(address_of_child, bool) or isinstance(address_of_child, np.bool_):
-        # 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'
+        # 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'
         variable = group.createVariable(variable_name, int, ('int',))
         variable[:] = int(address_of_child)
@@ -331,5 +430,5 @@
     elif isinstance(address_of_child,list) and isinstance(address_of_child[0],str):
         for string in address_of_child:
-            write_string_to_netcdf(variable_name, string, group, list=True, NetCDF=NetCDF, verbose=verbose)
+            serialize_string(variable_name, string, group, list=True, NCData=NCData, verbose=verbose)
 
     # or a regular list
@@ -352,16 +451,16 @@
     
     if verbose:
-        print(f'Successfully transferred data from {variable_name} to the NetCDF')
-    
-
-def write_string_to_netcdf(variable_name, address_of_child, group, list=False, NetCDF=None, verbose = False):
-    # netcdf and strings dont get along.. we have to do it 'custom':
+        print(f'Successfully transferred data from {variable_name} to the NCData')
+    
+
+def serialize_string(variable_name, address_of_child, group, list=False, NCData=None, verbose = False):
+    # NCData and strings dont get along.. we have to do it 'custom':
     # if we hand it an address we need to do it this way:
     if list == True:
         """
-        Save a list of strings to a NetCDF file.
+        Save a list of strings to a NCData file.
     
         Convert a list of strings to a numpy.char_array with utf-8 encoded elements
-        and size rows x cols with each row the same # of cols and save to NetCDF
+        and size rows x cols with each row the same # of cols and save to NCData
         as char array.
         """
@@ -399,5 +498,5 @@
                 arr[i] = new_list[i]
     
-            # save array to netcdf file
+            # save array to NCData file
             string_var[:] = arr
 
@@ -412,5 +511,5 @@
         length_of_the_string = len(the_string_to_save)
         numpy_datatype = 'S' + str(length_of_the_string)
-        str_out = netCDF4.stringtochar(np.array([the_string_to_save], dtype=numpy_datatype))        
+        str_out = NCData4.stringtochar(np.array([the_string_to_save], dtype=numpy_datatype))        
     
         # we'll need to make a new dimension for the string if it doesn't already exist
@@ -431,8 +530,8 @@
 
 
-def write_numpy_array_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose = False):
-    # to make a nested array in netCDF, we have to get the dimensions of the array,
-    # create corresponding dimensions in the netCDF file, then we can make a variable
-    # in the netCDF with dimensions identical to those in the original array
+def serialize_numpy_array(variable_name, address_of_child, group, NCData, verbose = False):
+    # to make a nested array in NCData, we have to get the dimensions of the array,
+    # create corresponding dimensions in the NCData file, then we can make a variable
+    # in the NCData with dimensions identical to those in the original array
     
     # start by getting the data type at the lowest level in the array:
