Changeset 27834


Ignore:
Timestamp:
07/18/23 16:04:30 (20 months ago)
Author:
musselman
Message:

Added functionality to store subclass instances of the results class in the write_netCDF file.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/m/contrib/musselman/write_netCDF_commit.py

    r27832 r27834  
    11# imports
     2import netCDF4
    23from netCDF4 import Dataset
    34import numpy as np
     
    67from os import path, remove
    78from model import *
     9from results import *
    810
    911
     
    3739    # Walk through the model_var class and compare subclass states to empty_model
    3840    walk_through_model(model_var, model_name)
    39    
     41
     42    # in order to handle some subclasses in the results class, we have to utilize this band-aid
     43    # 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
     44    try:
     45        # if results has meaningful data, save the name of the subclass and class instance
     46        NetCDF.groups['results']
     47        results_subclasses_bandaid(model_var)
     48        # otherwise, ignore
     49    except KeyError:
     50        pass
     51       
    4052    NetCDF.close()
    4153    print('Model successfully saved as NetCDF4')
    4254   
     55
     56
     57def results_subclasses_bandaid(model_var):
     58    # since the results class may have nested classes within it, we need to record the name of the
     59    # nested class instance variable as it appears in the model that we're trying to save
     60    quality_control = []
     61    for class_instance_name in model_var.results.__dict__.keys():
     62        # for each class instance in results, see which class its from and record that info in the netcdf to recreate structure later
     63        # check to see if there is a solutionstep class instance
     64        if isinstance(model_var.results.__dict__[class_instance_name],solutionstep):
     65            quality_control.append(1)
     66            write_string_to_netcdf(variable_name=str('solutionstep'), adress_of_child=str(class_instance_name), group=NetCDF.groups['results'])
     67        # check to see if there is a solution class instance
     68        if isinstance(model_var.results.__dict__[class_instance_name],solution):
     69            quality_control.append(1)
     70            write_string_to_netcdf(variable_name=str('solution'), adress_of_child=str(class_instance_name), group=NetCDF.groups['results'])
     71        # check to see if there is a resultsdakota class instance
     72        if isinstance(model_var.results.__dict__[class_instance_name],resultsdakota):
     73            quality_control.append(1)
     74            write_string_to_netcdf(variable_name=str('resultsdakota'), adress_of_child=str(class_instance_name), group=NetCDF.groups['results'])
     75    if len(quality_control) != len(model_var.results.__dict__.keys()):
     76        print('Error: The class instance within your model.results class is not currently supported by this application')
     77        print(type(model_var.results.__dict__[class_instance_name]))
     78    else:
     79        print('The results class was successfully stored on disk')
     80
    4381
    4482   
     
    82120    try:
    83121        # enter the subclass, see if it has nested classes and/or attributes
    84         # then compare attribute states between models and write to netCDF if they differ
    85         # repeat starting from new location
     122        # then compare attributes between models and write to netCDF if they differ
     123        # if subclass found, walk through it and repeat
    86124        for child in eval(adress + '.__dict__.keys()'):
    87125            # make a string variable so we can send thru this func again
     
    89127            # If the attribute is unchanged, move onto the next layer
    90128            adress_of_child_in_empty_class = 'empty_model' + adress_of_child.removeprefix(str(model_name))
    91             if type(child) == type(eval(adress_of_child_in_empty_class)):
    92                 walk_through_subclasses(model_var, adress_of_child, model_name)
    93             # If it has been modified, record it in the NetCDF file
    94             else:
     129            # using try/except here because sometimes a model can have class instances/attributes that are not
     130            # in the framework of an empty model. If this is the case, we move to the except statement
     131            try:
     132                if type(child) == type(eval(adress_of_child_in_empty_class)):
     133                    walk_through_subclasses(model_var, adress_of_child, model_name)
     134                # If it has been modified, record it in the NetCDF file
     135                else:
     136                    create_group(model_var, adress_of_child)
     137                    walk_through_subclasses(model_var, adress_of_child, model_name)
     138            except AttributeError:
    95139                create_group(model_var, adress_of_child)
    96140                walk_through_subclasses(model_var, adress_of_child, model_name)
    97     except: pass
    98 
    99  
     141    except Exception as e: print(e)
     142
     143
     144       
    100145def create_group(model_var, adress_of_child):
    101146    # start by splitting the adress_of_child into its components
     
    133178        variable = group.createVariable(variable_name, float, ('float',))
    134179        variable[:] = eval(adress_of_child)
    135        
     180
    136181    # or a string
    137182    elif isinstance(eval(adress_of_child), str):
    138183        write_string_to_netcdf(variable_name, adress_of_child, group)
    139184       
    140     # or a list of strings -- this needs work as it can only handle a list of 1 string
    141     elif isinstance(eval(adress_of_child)[0],str):
    142         for string in eval(adress_of_child):
    143             write_string_to_netcdf(variable_name, string, group)
    144        
    145     # or a list
    146     elif isinstance(eval(adress_of_child), list):
    147         variable = group.createVariable(variable_name, type(eval(adress_of_child)[0]), ('Unlim',))
    148         variable[:] = eval(adress_of_child)
    149        
    150185    # or an empty list
    151186    elif isinstance(eval(adress_of_child), list) and len(eval(adress_of_child))==0:
    152187        variable = group.createVariable(variable_name, int, ('int',))
     188
     189    # or a list of strings -- this needs work as it can only handle a list of 1 string
     190    elif isinstance(eval(adress_of_child),list) and isinstance(eval(adress_of_child)[0],str):
     191        for string in eval(adress_of_child):
     192            write_string_to_netcdf(variable_name, string, group)
     193
     194    # or a regular list
     195    elif isinstance(eval(adress_of_child), list):
     196        print(eval(adress_of_child))
     197        variable = group.createVariable(variable_name, type(eval(adress_of_child)[0]), ('Unlim',))
     198        variable[:] = eval(adress_of_child)
    153199
    154200    # anything else... (will likely need to add more cases; ie dict)
     
    163209    print('Successfully transferred data from ' + adress_of_child + ' to the NetCDF')
    164210   
     211
     212
    165213
    166214def write_string_to_netcdf(variable_name, adress_of_child, group):
     
    171219        length_of_the_string = len(the_string_to_save)
    172220        numpy_datatype = 'S' + str(length_of_the_string)
    173         str_out = netCDF4.stringtochar(np.array(['the_string_to_save'], dtype=numpy_datatype))
     221        str_out = netCDF4.stringtochar(np.array([the_string_to_save], dtype=numpy_datatype))
    174222    #otherwise we need to treat it like a string:
    175223    except:
     
    177225        length_of_the_string = len(the_string_to_save)
    178226        numpy_datatype = 'S' + str(length_of_the_string)
    179         str_out = netCDF4.stringtochar(np.array(['the_string_to_save'], dtype=numpy_datatype))       
     227        str_out = netCDF4.stringtochar(np.array([the_string_to_save], dtype=numpy_datatype))       
    180228
    181229    # we'll need to make a new dimension for the string if it doesn't already exist
     230    name_of_dimension = 'char' + str(length_of_the_string)
    182231    try:
    183         name_of_dimension = 'char' + str(length_of_the_string)
    184232        group.createDimension(name_of_dimension, length_of_the_string)
    185233    except: pass
    186234    # now we can make a variable in this dimension:
    187     string = group.createVariable(variable_name, 'S1', ('nchar'))
     235    string = group.createVariable(variable_name, 'S1', (name_of_dimension))
    188236    #finally we can write the variable:
    189     string[:] = the_string_to_save   
     237    string[:] = str_out
    190238
    191239
Note: See TracChangeset for help on using the changeset viewer.