openstef-models 4.4.2__tar.gz → 4.4.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. {openstef_models-4.4.2 → openstef_models-4.4.4}/PKG-INFO +1 -1
  2. {openstef_models-4.4.2 → openstef_models-4.4.4}/pyproject.toml +1 -1
  3. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/forecasting/flatliner_forecaster.py +16 -4
  4. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/presets/forecasting_workflow.py +1 -0
  5. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/forecasting/test_flatliner_forecaster.py +54 -0
  6. {openstef_models-4.4.2 → openstef_models-4.4.4}/.gitignore +0 -0
  7. {openstef_models-4.4.2 → openstef_models-4.4.4}/README.md +0 -0
  8. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/__init__.py +0 -0
  9. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/explainability/__init__.py +0 -0
  10. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/explainability/mixins.py +0 -0
  11. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/explainability/plotters/__init__.py +0 -0
  12. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/explainability/plotters/contributions_plotter.py +0 -0
  13. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/explainability/plotters/feature_importance_plotter.py +0 -0
  14. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/integrations/__init__.py +0 -0
  15. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/integrations/joblib/__init__.py +0 -0
  16. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/integrations/joblib/joblib_model_serializer.py +0 -0
  17. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/integrations/mlflow/__init__.py +0 -0
  18. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/integrations/mlflow/mlflow_storage.py +0 -0
  19. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/integrations/mlflow/mlflow_storage_callback.py +0 -0
  20. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/integrations/optuna/__init__.py +0 -0
  21. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/integrations/optuna/tuner.py +0 -0
  22. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/mixins/__init__.py +0 -0
  23. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/mixins/callbacks.py +0 -0
  24. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/mixins/model_serializer.py +0 -0
  25. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/__init__.py +0 -0
  26. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/component_splitting/__init__.py +0 -0
  27. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/component_splitting/component_splitter.py +0 -0
  28. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/component_splitting/constant_component_splitter.py +0 -0
  29. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/component_splitting/linear_component_splitter.py +0 -0
  30. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/component_splitting/linear_component_splitter_model/linear_component_splitter_model.z +0 -0
  31. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/component_splitting/linear_component_splitter_model/linear_component_splitter_model.z.license +0 -0
  32. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/component_splitting_model.py +0 -0
  33. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/forecasting/__init__.py +0 -0
  34. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/forecasting/base_case_forecaster.py +0 -0
  35. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/forecasting/constant_quantile_forecaster.py +0 -0
  36. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/forecasting/forecaster.py +0 -0
  37. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/forecasting/gblinear_forecaster.py +0 -0
  38. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/forecasting/lgbm_forecaster.py +0 -0
  39. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/forecasting/lgbmlinear_forecaster.py +0 -0
  40. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/forecasting/median_forecaster.py +0 -0
  41. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/forecasting/xgboost_forecaster.py +0 -0
  42. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/models/forecasting_model.py +0 -0
  43. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/presets/__init__.py +0 -0
  44. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/testing.py +0 -0
  45. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/__init__.py +0 -0
  46. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/energy_domain/__init__.py +0 -0
  47. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/energy_domain/wind_power_feature_adder.py +0 -0
  48. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/general/__init__.py +0 -0
  49. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/general/dimensionality_reducer.py +0 -0
  50. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/general/empty_feature_remover.py +0 -0
  51. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/general/flagger.py +0 -0
  52. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/general/imputer.py +0 -0
  53. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/general/nan_dropper.py +0 -0
  54. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/general/outlier_handler.py +0 -0
  55. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/general/sample_weighter.py +0 -0
  56. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/general/scaler.py +0 -0
  57. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/general/selector.py +0 -0
  58. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/general/shifter.py +0 -0
  59. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/postprocessing/__init__.py +0 -0
  60. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/postprocessing/confidence_interval_applicator.py +0 -0
  61. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/postprocessing/conformalized_quantile_calibrator.py +0 -0
  62. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/postprocessing/isotonic_quantile_calibrator.py +0 -0
  63. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/postprocessing/quantile_sorter.py +0 -0
  64. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/time_domain/__init__.py +0 -0
  65. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/time_domain/cyclic_features_adder.py +0 -0
  66. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/time_domain/datetime_features_adder.py +0 -0
  67. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/time_domain/holiday_features_adder.py +0 -0
  68. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/time_domain/lags_adder.py +0 -0
  69. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/time_domain/rolling_aggregates_adder.py +0 -0
  70. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/time_domain/versioned_lags_adder.py +0 -0
  71. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/validation/__init__.py +0 -0
  72. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/validation/completeness_checker.py +0 -0
  73. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/validation/flatline_checker.py +0 -0
  74. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/validation/input_consistency_checker.py +0 -0
  75. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/weather_domain/__init__.py +0 -0
  76. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/weather_domain/atmosphere_derived_features_adder.py +0 -0
  77. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/weather_domain/daylight_feature_adder.py +0 -0
  78. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/transforms/weather_domain/radiation_derived_features_adder.py +0 -0
  79. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/utils/__init__.py +0 -0
  80. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/utils/data_split.py +0 -0
  81. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/utils/evaluation_functions.py +0 -0
  82. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/utils/feature_selection.py +0 -0
  83. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/utils/loss_functions.py +0 -0
  84. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/utils/multi_quantile_regressor.py +0 -0
  85. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/utils/xgboost.py +0 -0
  86. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/workflows/__init__.py +0 -0
  87. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/workflows/callbacks/__init__.py +0 -0
  88. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/workflows/callbacks/data_save.py +0 -0
  89. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/workflows/callbacks/model_performance_callback.py +0 -0
  90. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/workflows/custom_component_split_workflow.py +0 -0
  91. {openstef_models-4.4.2 → openstef_models-4.4.4}/src/openstef_models/workflows/custom_forecasting_workflow.py +0 -0
  92. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/__init__.py +0 -0
  93. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/integration/__init__.py +0 -0
  94. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/integration/test_integration.py +0 -0
  95. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/__init__.py +0 -0
  96. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/explainability/__init__.py +0 -0
  97. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/explainability/plotters/__init__.py +0 -0
  98. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/explainability/plotters/test_contributions_plotter.py +0 -0
  99. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/integrations/__init__.py +0 -0
  100. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/integrations/joblib/__init__.py +0 -0
  101. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/integrations/joblib/test_joblib_model_serializer.py +0 -0
  102. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/integrations/mlflow/__init__.py +0 -0
  103. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/integrations/mlflow/test_mlflow_storage.py +0 -0
  104. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/integrations/mlflow/test_mlflow_storage_callback.py +0 -0
  105. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/integrations/optuna/__init__.py +0 -0
  106. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/integrations/optuna/test_tuner.py +0 -0
  107. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/__init__.py +0 -0
  108. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/component_splitting/__init__.py +0 -0
  109. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/component_splitting/test_constant_component_splitter.py +0 -0
  110. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/component_splitting/test_linear_component_splitter.py +0 -0
  111. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/forecasting/__init__.py +0 -0
  112. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/forecasting/conftest.py +0 -0
  113. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/forecasting/test_base_case_forecaster.py +0 -0
  114. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/forecasting/test_constant_quantile_forecaster.py +0 -0
  115. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/forecasting/test_gblinear_forecaster.py +0 -0
  116. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/forecasting/test_lgbm_forecaster.py +0 -0
  117. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/forecasting/test_lgbmlinear_forecaster.py +0 -0
  118. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/forecasting/test_median_forecaster.py +0 -0
  119. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/forecasting/test_xgboost_forecaster.py +0 -0
  120. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/models/test_forecasting_model.py +0 -0
  121. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/test_example.py +0 -0
  122. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/__init__.py +0 -0
  123. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/energy_domain/__init__.py +0 -0
  124. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/energy_domain/test_wind_power_feature_adder.py +0 -0
  125. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/general/__init__.py +0 -0
  126. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/general/test_dimensionality_reducer.py +0 -0
  127. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/general/test_empty_feature_remover.py +0 -0
  128. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/general/test_flagger.py +0 -0
  129. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/general/test_imputer.py +0 -0
  130. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/general/test_nan_dropper.py +0 -0
  131. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/general/test_outlier_handler.py +0 -0
  132. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/general/test_sample_weighter.py +0 -0
  133. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/general/test_scaler.py +0 -0
  134. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/general/test_selector.py +0 -0
  135. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/general/test_shifter.py +0 -0
  136. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/postprocessing/__init__.py +0 -0
  137. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/postprocessing/test_confidence_interval_applicator.py +0 -0
  138. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/postprocessing/test_conformalized_quantile_calibrator.py +0 -0
  139. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/postprocessing/test_isotonic_quantile_calibrator.py +0 -0
  140. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/postprocessing/test_quantile_sorter.py +0 -0
  141. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/time_domain/__init__.py +0 -0
  142. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/time_domain/test_cyclic_features_adder.py +0 -0
  143. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/time_domain/test_datetime_features_adder.py +0 -0
  144. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/time_domain/test_holiday_features_adder.py +0 -0
  145. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/time_domain/test_lags_adder.py +0 -0
  146. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/time_domain/test_rolling_aggregates_adder.py +0 -0
  147. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/time_domain/test_versioned_lags_adder.py +0 -0
  148. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/validation/__init__.py +0 -0
  149. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/validation/test_completeness_checker.py +0 -0
  150. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/validation/test_flatline_checker.py +0 -0
  151. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/validation/test_input_consistency_checker.py +0 -0
  152. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/weather_domain/__init__.py +0 -0
  153. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/weather_domain/test_atmosphere_derived_features_adder.py +0 -0
  154. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/weather_domain/test_daylight_feature_adder.py +0 -0
  155. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/transforms/weather_domain/test_radiation_derived_featuers_adder.py +0 -0
  156. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/utils/__init__.py +0 -0
  157. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/utils/test_data_split.py +0 -0
  158. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/utils/test_feature_selection.py +0 -0
  159. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/utils/test_loss_functions.py +0 -0
  160. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/utils/test_multi_quantile_regressor.py +0 -0
  161. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/workflows/__init__.py +0 -0
  162. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/workflows/callbacks/__init__.py +0 -0
  163. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/workflows/callbacks/test_model_performance_callback.py +0 -0
  164. {openstef_models-4.4.2 → openstef_models-4.4.4}/tests/unit/workflows/test_custom_forecasting_workflow.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: openstef-models
3
- Version: 4.4.2
3
+ Version: 4.4.4
4
4
  Summary: Core models for OpenSTEF
5
5
  Project-URL: Documentation, https://openstef.github.io/openstef/index.html
6
6
  Project-URL: Homepage, https://lfenergy.org/projects/openstef/
@@ -7,7 +7,7 @@ requires = [ "hatchling" ]
7
7
 
8
8
  [project]
9
9
  name = "openstef-models"
10
- version = "4.4.2"
10
+ version = "4.4.4"
11
11
  description = "Core models for OpenSTEF"
12
12
  readme = "README.md"
13
13
  keywords = [ "energy", "forecasting", "machinelearning" ]
@@ -8,7 +8,8 @@ Provides basic forecasting model that predict constant flatliner zero values. It
8
8
  when a flatline (non-)zero measurement is observed in the past and expected in the future.
9
9
  """
10
10
 
11
- from typing import override
11
+ from datetime import timedelta
12
+ from typing import cast, override
12
13
 
13
14
  import pandas as pd
14
15
  from pydantic import Field, PrivateAttr
@@ -24,8 +25,9 @@ MODEL_CODE_VERSION = 1
24
25
  class FlatlinerForecaster(Forecaster, ExplainableForecaster, ContributionsMixin):
25
26
  """Flatliner forecaster that predicts a flatline of zeros or median.
26
27
 
27
- A simple forecasting model that always predicts zero (or the median of historical
28
- load measurements if configured) for all horizons and quantiles.
28
+ A simple forecasting model that always predicts zero (or a median load value if
29
+ configured) for all horizons and quantiles. The median can be calculated over
30
+ a trailing window when the fallback is responding to a recent flatline.
29
31
 
30
32
  Invariants:
31
33
  - Configuration quantiles determine the number of prediction outputs
@@ -49,6 +51,10 @@ class FlatlinerForecaster(Forecaster, ExplainableForecaster, ContributionsMixin)
49
51
  default=False,
50
52
  description="If True, predict the median of load measurements instead of zero.",
51
53
  )
54
+ median_window: timedelta | None = Field(
55
+ default=None,
56
+ description="Optional trailing window for the median load estimate; None uses all available measurements.",
57
+ )
52
58
 
53
59
  hyperparams: HyperParams = Field(
54
60
  default_factory=HyperParams,
@@ -76,7 +82,13 @@ class FlatlinerForecaster(Forecaster, ExplainableForecaster, ContributionsMixin)
76
82
  data_val: ForecastInputDataset | None = None,
77
83
  ) -> None:
78
84
  if self.predict_median:
79
- self._median_value = float(data.target_series.median())
85
+ target_series = data.target_series
86
+ if self.median_window is not None:
87
+ last_valid_index = cast(pd.Timestamp | None, target_series.last_valid_index())
88
+ if last_valid_index is not None:
89
+ window_start = last_valid_index - self.median_window
90
+ target_series = target_series.loc[window_start:last_valid_index]
91
+ self._median_value = float(target_series.median())
80
92
 
81
93
  @override
82
94
  def predict(self, data: ForecastInputDataset) -> ForecastDataset:
@@ -566,6 +566,7 @@ def create_forecasting_workflow(
566
566
  quantiles=config.quantiles,
567
567
  horizons=config.horizons,
568
568
  predict_median=config.predict_nonzero_flatliner,
569
+ median_window=config.flatliner_threshold,
569
570
  )
570
571
  postprocessing = [
571
572
  QuantileSorter(),
@@ -10,6 +10,8 @@ import pytest
10
10
  from openstef_core.datasets.validated_datasets import ForecastInputDataset
11
11
  from openstef_core.types import LeadTime, Quantile
12
12
  from openstef_models.models.forecasting.flatliner_forecaster import FlatlinerForecaster
13
+ from openstef_models.models.forecasting_model import ForecastingModel
14
+ from openstef_models.presets import ForecastingWorkflowConfig, create_forecasting_workflow
13
15
 
14
16
 
15
17
  @pytest.fixture
@@ -64,3 +66,55 @@ def test_predict_returns_median_when_predict_median_is_true(sample_forecast_inpu
64
66
  assert isinstance(result.data, pd.DataFrame)
65
67
  assert (result.data == expected_median).all().all()
66
68
  assert set(result.data.columns) == {q.format() for q in forecaster.quantiles}
69
+
70
+
71
+ @pytest.mark.parametrize(
72
+ ("load_values", "median_window", "expected_median"),
73
+ [
74
+ pytest.param([100.0, 110.0, 120.0, 7.0, 7.0, 7.0], timedelta(hours=2), 7.0, id="repeated-value"),
75
+ pytest.param([100.0, 110.0, 120.0, 6.0, 8.0], timedelta(hours=1), 7.0, id="two-different-values"),
76
+ ],
77
+ )
78
+ def test_predict_returns_recent_median_when_median_window_is_set(
79
+ load_values: list[float],
80
+ median_window: timedelta,
81
+ expected_median: float,
82
+ ) -> None:
83
+ # Arrange
84
+ index = pd.date_range("2025-01-01", periods=len(load_values), freq="h")
85
+ data = ForecastInputDataset(
86
+ data=pd.DataFrame({"load": load_values}, index=index),
87
+ sample_interval=timedelta(hours=1),
88
+ )
89
+ forecaster = FlatlinerForecaster(
90
+ quantiles=[Quantile(0.5)],
91
+ horizons=[LeadTime(timedelta(hours=1))],
92
+ predict_median=True,
93
+ median_window=median_window,
94
+ )
95
+
96
+ # Act
97
+ forecaster.fit(data)
98
+ result = forecaster.predict(data)
99
+
100
+ # Assert
101
+ assert (result.data == expected_median).all().all()
102
+
103
+
104
+ def test_flatliner_workflow_uses_threshold_for_median_window() -> None:
105
+ # Arrange
106
+ config = ForecastingWorkflowConfig(
107
+ model_id="flatliner-test",
108
+ model="flatliner",
109
+ flatliner_threshold=timedelta(hours=6),
110
+ predict_nonzero_flatliner=True,
111
+ mlflow_storage=None,
112
+ )
113
+
114
+ # Act
115
+ workflow = create_forecasting_workflow(config)
116
+
117
+ # Assert
118
+ assert isinstance(workflow.model, ForecastingModel)
119
+ assert isinstance(workflow.model.forecaster, FlatlinerForecaster)
120
+ assert workflow.model.forecaster.median_window == timedelta(hours=6)