Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data dictionary for each possible parameter to the model #291

Open
arik-shurygin opened this issue Oct 28, 2024 · 6 comments
Open

Data dictionary for each possible parameter to the model #291

arik-shurygin opened this issue Oct 28, 2024 · 6 comments
Labels
enhancement New feature or request

Comments

@arik-shurygin
Copy link
Collaborator

breakdown each accepted parameter for each configuration file (global, initializer, inferer). Make sure to include the definition, the accepted shape, what each dimension in the shape implies, and possibly downstream parameters that are automatically generated when that parameter is provided.

@edbaskerville
Copy link
Collaborator

I'd love for everything about a parameter to be in the same place (currently, config.py):

  • Name (identifier in code)
  • Human-readable description
  • Type
  • If array, shape in terms of other parameters

The descriptions could be then used to generate model documentation, and the shapes could be used for automatic validation.

e.g.

{
    "name": "WANING_PROTECTIONS",
    "description": "Immune protection for each waning compartment as a fraction of maximum protection."
    "type": np.array,
    "shape": lambda p: (p.NUM_WANING_COMPARTMENTS",),
},

You can probably do this with manual validations in the current system?

Of course I'd prefer that this all be part of a real type system, but hey, Python

@arik-shurygin
Copy link
Collaborator Author

I'd love for everything about a parameter to be in the same place (currently, config.py):

  • Name (identifier in code)
  • Human-readable description
  • Type
  • If array, shape in terms of other parameters

The descriptions could be then used to generate model documentation, and the shapes could be used for automatic validation.

e.g.

{
    "name": "WANING_PROTECTIONS",
    "description": "Immune protection for each waning compartment as a fraction of maximum protection."
    "type": np.array,
    "shape": lambda p: (p.NUM_WANING_COMPARTMENTS",),
},

You can probably do this with manual validations in the current system?

Of course I'd prefer that this all be part of a real type system, but hey, Python

This is a great idea, it also fits in with the efforts outlines in #180, it is likely worth it to specific attributes to the config class with pydoc comments, allowing api generation easily when #217 is tackled

@edbaskerville
Copy link
Collaborator

This is a great idea, it also fits in with the efforts outlines in #180, it is likely worth it to specific attributes to the config class with pydoc comments, allowing api generation easily when #217 is tackled

Meaning make parameters be attributes of an object? Or something else?

A runtime type-ier version of this could be...

from dynode.parameters import parameter, closed_interval

class ScenariosModelParameters(ModelParameters):
    waning_protections: np.array = parameter(
        description = "blah blah blah",
        shape = lambda p: (p.num_waning_compartments,),
        range: closed_interval(0.0, 1.0),
        validation = lambda p: some_extra_validation(),
    )

I'm remembering my SQLAlchemy ORM here: https://docs.sqlalchemy.org/en/20/orm/quickstart.html

@arik-shurygin
Copy link
Collaborator Author

Yeah something like this, this way when someone refers to a Config object they are able to get type hints and information about each parameter they can reference from it.

Currently the code that adds attributes to Config looks like:

def add_file(self, config_json_str):
"""loads a JSON string into self,
overriding any shared names, asserting valid configuration of parameters,
and setting any downstream parameters.
Parameters
----------
config_json_str : str
JSON string representing a dictionary you wish to add into self
Returns
-------
Config
self with the parameters from `config_json_str` added on, as well as
any downstream parameters generated.
"""
# adds another config to self.__dict__ and resets downstream parameters again
config = json.loads(
config_json_str, object_hook=distribution_converter
)
config = self.convert_types(config)
self.__dict__.update(**config)
self.assert_valid_configuration()
self.set_downstream_parameters()
return self

specifically

self.__dict__.update(**config)

is the main point in which all the keys in the JSON are added to the config. If we instead call a bunch of settrs and define ahead of time all of the different types of parameters that come by default in the Config class. This way we get code autocomplete and other quality of life features.

@arik-shurygin arik-shurygin added the enhancement New feature or request label Oct 29, 2024
@arik-shurygin
Copy link
Collaborator Author

arik-shurygin commented Dec 11, 2024

@edbaskerville and I had a separate conversation about using Chex as a parameters library since we are already using Jax in DynODE as a whole, leaving the link here for when this issue is taken on

@edbaskerville
Copy link
Collaborator

Just to clarify, the general idea is to use dataclasses as a convenient built-in notation for typed model parameters. chex implements a jax-compatible dataclass, but we wouldn't necessarily need to use it if it proves cumbersome--can always transform to something else at runtime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants