Skip to content

Commit bef37cf

Browse files
committed
add option to load forecast horizon
1 parent d867326 commit bef37cf

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

nowcasting_datamodel/read/read.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from sqlalchemy.orm import contains_eager, joinedload
1313
from sqlalchemy.orm.session import Session
1414

15+
1516
from nowcasting_datamodel import N_GSP
1617
from nowcasting_datamodel.models import (
1718
ForecastSQL,
@@ -212,6 +213,7 @@ def get_all_gsp_ids_latest_forecast(
212213
start_target_time: Optional[datetime] = None,
213214
preload_children: Optional[bool] = False,
214215
historic: bool = False,
216+
forecast_horizon_hours: Optional[int] = None,
215217
) -> List[ForecastSQL]:
216218
"""
217219
Read forecasts
@@ -235,6 +237,7 @@ def get_all_gsp_ids_latest_forecast(
235237
preload_children=preload_children,
236238
historic=historic,
237239
gsp_ids=list(range(0, N_GSP + 1)),
240+
forecast_horizon_hours=forecast_horizon_hours,
238241
)
239242

240243

@@ -244,6 +247,7 @@ def get_latest_forecast_for_gsps(
244247
start_target_time: Optional[datetime] = None,
245248
preload_children: Optional[bool] = False,
246249
historic: bool = False,
250+
forecast_horizon_hours: Optional[int] = None,
247251
gsp_ids: List[int] = None,
248252
):
249253
"""
@@ -256,6 +260,9 @@ def get_latest_forecast_for_gsps(
256260
:param preload_children: Option to preload children. This is a speed up, if we need them.
257261
:param historic: Option to load historic values or not
258262
:param gsp_ids: Option to filter on gsps. If None, then only the lastest forecast is loaded.
263+
:param forecast_horizon_hours: Optional filter on forecast horizon. For example
264+
forecast_horizon_hours=2, means load the forecast than was made 2 hours before the target time.
265+
Note this only works for non-historic data.
259266
260267
return: List of forecasts objects from database
261268
@@ -293,6 +300,16 @@ def get_latest_forecast_for_gsps(
293300
query=query, start_target_time=start_target_time, historic=historic
294301
)
295302

303+
from sqlalchemy import text
304+
if forecast_horizon_hours is not None:
305+
assert historic is False, Exception(
306+
"Loading a forecast horizon only works on non latest data."
307+
)
308+
query = query.join(ForecastValueSQL).filter(
309+
ForecastValueSQL.target_time - ForecastValueSQL.created_utc
310+
>= text(f"interval '{forecast_horizon_hours} hour'")
311+
)
312+
296313
query = query.join(LocationSQL)
297314

298315
# option to preload values, makes querying quicker

tests/read/test_read_forecast.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import logging
2+
from datetime import datetime, timedelta, timezone
3+
4+
import pytest
5+
from freezegun import freeze_time
6+
7+
from nowcasting_datamodel.fake import (
8+
make_fake_forecast,
9+
make_fake_forecasts,
10+
make_fake_national_forecast,
11+
make_fake_pv_system,
12+
)
13+
from nowcasting_datamodel.models import (
14+
Forecast,
15+
ForecastValue,
16+
ForecastValueLatestSQL,
17+
ForecastValueSQL,
18+
InputDataLastUpdatedSQL,
19+
LocationSQL,
20+
MLModel,
21+
PVSystem,
22+
Status,
23+
national_gb_label,
24+
)
25+
from nowcasting_datamodel.read.read import (
26+
get_all_gsp_ids_latest_forecast,
27+
get_latest_forecast_for_gsps,
28+
get_all_locations,
29+
get_forecast_values,
30+
get_latest_forecast,
31+
get_latest_forecast_created_utc,
32+
get_latest_input_data_last_updated,
33+
get_latest_national_forecast,
34+
get_latest_status,
35+
get_location,
36+
get_model,
37+
get_pv_system,
38+
update_latest_input_data_last_updated,
39+
)
40+
from nowcasting_datamodel.save import save_pv_system
41+
42+
logger = logging.getLogger(__name__)
43+
44+
45+
def test_get_latest_forecast_created_utc_gsp(db_session):
46+
t0_datetime_utc = datetime(2022, 1, 1, 12, tzinfo=timezone.utc)
47+
48+
f1 = make_fake_forecast(gsp_id=1, session=db_session, t0_datetime_utc=t0_datetime_utc)
49+
f2 = make_fake_forecast(gsp_id=1, session=db_session, t0_datetime_utc=t0_datetime_utc)
50+
51+
f1.forecast_values[0].created_utc = datetime(2022, 1, 1, 10, tzinfo=timezone.utc)
52+
f1.forecast_values[1].created_utc = datetime(2022, 1, 1, 10, tzinfo=timezone.utc)
53+
54+
f2.forecast_values[0].created_utc = datetime(2022, 1, 1, 12, tzinfo=timezone.utc)
55+
f2.forecast_values[1].created_utc = datetime(2022, 1, 1, 12, tzinfo=timezone.utc)
56+
57+
db_session.add_all([f1, f2])
58+
db_session.commit()
59+
60+
f = get_latest_forecast_for_gsps(session=db_session, forecast_horizon_hours=2, gsp_ids=[1])
61+
assert len(f) == 1
62+
assert f[0].forecast_values[0].created_utc == datetime(2022, 1, 1, 10, tzinfo=timezone.utc)
63+
assert f[0].forecast_values[0].target_time == datetime(2022, 1, 1, 12, tzinfo=timezone.utc)

0 commit comments

Comments
 (0)