__init__.py 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. from __future__ import annotations
  2. from typing import Callable
  3. from timetomodel import ModelSpecs
  4. from flexmeasures.data.models.forecasting.model_specs.naive import (
  5. naive_specs_configurator as naive_specs,
  6. )
  7. from flexmeasures.data.models.forecasting.model_specs.linear_regression import (
  8. ols_specs_configurator as linear_ols_specs,
  9. )
  10. model_map = {
  11. "naive": naive_specs,
  12. "linear": linear_ols_specs,
  13. "linear-ols": linear_ols_specs,
  14. } # use lower case only
  15. def lookup_model_specs_configurator(
  16. model_search_term: str = "linear-OLS",
  17. ) -> Callable[
  18. ..., # See model_spec_factory.create_initial_model_specs for an up-to-date type annotation
  19. # Annotating here would require Python>=3.10 (specifically, ParamSpec from PEP 612)
  20. tuple[ModelSpecs, str, str],
  21. ]:
  22. """
  23. This function maps a model-identifying search term to a model configurator function, which can make model meta data.
  24. Why use a string? It might be stored on RQ jobs. It might also leave more freedom, we can then
  25. map multiple terms to the same model or vice versa (e.g. when different versions exist).
  26. Model meta data in this context means a tuple of:
  27. * timetomodel.ModelSpecs. To fill in those specs, a configurator should accept:
  28. - old_sensor: Union[Asset, Market, WeatherSensor],
  29. - start: datetime, # Start of forecast period
  30. - end: datetime, # End of forecast period
  31. - horizon: timedelta, # Duration between time of forecasting and time which is forecast
  32. - ex_post_horizon: timedelta = None,
  33. - custom_model_params: dict = None, # overwrite forecasting params, useful for testing or experimentation
  34. * a model_identifier (useful in case the model_search_term was generic, e.g. "latest")
  35. * a fallback_model_search_term: a string which the forecasting machinery can use to choose
  36. a different model (using this mapping again) in case of failure.
  37. So to implement a model, write such a function and decide here which search term(s) map(s) to it.
  38. """
  39. if model_search_term.lower() not in model_map.keys():
  40. raise Exception("No model found for search term '%s'" % model_search_term)
  41. return model_map[model_search_term.lower()]