DeltaRCM / pyDeltaRCM

Delta model with a reduced-complexity approach
https://deltarcm.org/pyDeltaRCM/
MIT License
18 stars 11 forks source link

Cleaner path for adding custom model specifications to a yaml config file. #187

Closed amoodie closed 3 years ago

amoodie commented 3 years ago

problem

It is currently possible to specify any parameter in a YAML file, and have this parameter available to a custom model subclass. However, the process is a little clunly, requiring a developer to pop values out of the input file manually. If the parameter is required for configuring anything during the init_tools stages of the model design, then it is necessary to pull the parameter from the yaml file before calling super(). Regardless, it is necessary to create a yaml loader, open the file, parse the file, and pop the kwargs, all manually.

It would be much better to be able to directly have parameters in the yaml assigned to a subclass model, but we also need to protect our attributes of the model from being overwritten (i.e., namespace conflict).

Here is one example of a way to make the subclass work, but is clunky.

class SpecialModel(pyDeltaRCM.DeltaModel):
    def __init__(self, input_file, **kwargs):

        # it would be nice to have a way to get rid of this...
        #   it is needed because non-default params are not set to the model
        #   but we have defined WLD in the file via the preprocessor.
        _file = open(input_file, mode='r')
        _loader = pyDeltaRCM.shared_tools.custom_yaml_loader()
        param_dict = yaml.load(_file, Loader=_loader)
        _file.close()

        # pull the parameters
        self._special = param_dict.pop('special', None)

        # inherit from base model
        super().__init__(input_file, **kwargs)
out_dir: '/tmp'
special: 100

suggestions

We need a way to make sure only parameters that are explicitly stated are called with eval and attached to the model. One possible path is to require a parameter to be specified on the subclass as a @property. Alternatively, maybe just adding the parameter to a self._known_parameter_list could work too (like how we handle saving custom figs and grids.