feat(application): integrate measured-load ingestion training and planner source
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
"""Forecast family fault isolation; no IO, fabricated samples or model switching."""
|
||||
from collections.abc import Mapping
|
||||
from math import isfinite
|
||||
from numbers import Real
|
||||
|
||||
|
||||
def collect_predictions(data, config, models, enabled):
|
||||
"""Return complete finite PV/load series independently for each requested model.
|
||||
|
||||
A model with insufficient history must not prevent other valid families being
|
||||
published. It is omitted, not filled with zeros or replaced by another model.
|
||||
Global raw-telemetry checks still run BEFORE this helper in run_forecast.
|
||||
"""
|
||||
expected = tuple(data['df_fut'].index)
|
||||
if not expected or len(set(expected)) != len(expected):
|
||||
raise ValueError('Nonempty unique future interval index required')
|
||||
expected_keys = set(expected)
|
||||
predictions, errors = {}, {}
|
||||
requested = 0
|
||||
for variant, model in models.items():
|
||||
predictions[variant] = {}
|
||||
if not enabled(config, variant):
|
||||
continue
|
||||
requested += 1
|
||||
try:
|
||||
values = model.predict(data)
|
||||
if not isinstance(values, Mapping) or set(values) != expected_keys:
|
||||
raise ValueError('Missing, extra or non-matching forecast timestamps')
|
||||
cleaned = {}
|
||||
for at in expected:
|
||||
value = values[at]
|
||||
if isinstance(value, bool) or not isinstance(value, Real):
|
||||
raise ValueError('Non-numeric forecast power')
|
||||
value = float(value)
|
||||
if not isfinite(value) or value < 0:
|
||||
raise ValueError('Invalid nonnegative forecast power')
|
||||
cleaned[at] = value
|
||||
predictions[variant] = cleaned
|
||||
except Exception as error:
|
||||
# Expected data failures and unexpected model failures are visible,
|
||||
# but model exception text may contain filesystem paths. Do not leak it.
|
||||
errors[variant] = {'status': 'unavailable', 'errorType': type(error).__name__}
|
||||
if requested and all(not p for p in predictions.values()):
|
||||
raise ValueError('All requested PV/load models failed; no forecasts published')
|
||||
return predictions, errors
|
||||
Reference in New Issue
Block a user