-
Notifications
You must be signed in to change notification settings - Fork 5
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
Allow for easier definition of new forcings #393
Conversation
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new forcing classes look great.
I was able to generate forcing using GenericDistributedForcing, LumpedMakkinkForcing, LumpedUserForcing.
Initially LumpedMakkinkForcing.generate example gaveRecipeError: Could not create all tasks
with empty esmvaltool log files. When I disable the log swallowing in run_recipe(), the log files are filled again with esgf creds error. The log swallowing is a bit to much, now can dial it back.
In docs/adding_models.rst we should no longer just mention the Default and Generic forcings. It would be nice to link back to the forcing user guide.
Can you add tests for some of the new algorithms like sources, makkink and merge_esmvaltool_datasets?
The CI is red. Can you make it green?
src/ewatercycle/models.py
Outdated
|
||
_model_entrypoints = entry_points(group="ewatercycle.models") # /NOSONAR | ||
|
||
# Expose as "from ewatercycle.models import Model" for backward compatibility | ||
for _model in _model_entrypoints: | ||
globals()[_model.name] = _model.load() | ||
|
||
|
||
class ModelSources(Mapping): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class look very much like ForcingSource except the return type and its super is from typing vs collections.abc . Can we have the same super? Can we make a Source super class with a generic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are very similar yes. In some way it would be nicer to be able to list models, forcings, and parameter sets all in the same way.
Before this change it was:
ewatercycle.forcing.sources
dir(ewatercycle.models)
which also was cluttered with non-useful infoewatercycle.parameter_sets.available_parameter_sets()
It would also be nice to still unify how to access these... three different ways for what is essentially the same is not very user friendly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have the same super? Can we make a Source super class with a generic?
Done.
It would also be nice to still unify models, forcings, and parameter
I've now unified models and forcings, however parameter_sets it still tbd. Probably better in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice if you did not need a subclass with getitem method.
I tried Mapping[str, DefaultForcing]
and UserDict instead of Mapping, but got stuck on value being a class or an entrypoint.
On my machine it does not make much difference if load() is called or not:
In [1]: from importlib.metadata import entry_points
In [4]: %timeit [f.load() for f in entry_points(group="ewatercycle.forcings")]
7.33 ms ± 158 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [5]: %timeit entry_points(group="ewatercycle.forcings")
7.3 ms ± 81.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
So we could simplify by calling the load() on import.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The subclassing here is to get the typing correct, not to delay the loading.
for the model sources:
def __getitem__(self, key) -> Type[eWaterCycleModel]:
while the forcing sources are:
def __getitem__(self, key) -> Type[DefaultForcing]:
It also allowed me to write a different docstring with appropriate examples for the model vs. forcing sources.
I'll change the warning level to "error" so actual errors are still shown, but useless warning are still hidden. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
Only found 2 links in docs that are 404.
Great progress! |
I tested all models:
Merge + release should be OK. I'll open issues on the respective repos to track the tests breaking. |
|
Ah we are checking the dump of a forcing object in the tests, makes sense that those tests fail. |
Changes:
Added
Changed
I also tried to silence most useless esmvalcore warnings.
I split up the user_guide notebook into 4 parts, because it was too big to easily modify and run. They are now organized under a separate section on the docs, preserving their original structure.
A demo notebook is available here:
_demo_forcing_builder.ipynb.zip
Also closes #232, #387