-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
main.py
263 lines (221 loc) · 9.02 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
"""
UK analysis dashboard for OCF
"""
import os
from datetime import datetime, timedelta
import pandas as pd
import streamlit as st
from nowcasting_datamodel.connection import DatabaseConnection
from nowcasting_datamodel.models.metric import MetricValue
from auth import check_password
from forecast import forecast_page
from get_data import get_metric_value
from plots.all_gsps import make_all_gsps_plots
from plots.forecast_horizon import (
make_mae_by_forecast_horizon,
make_mae_forecast_horizon_group_by_forecast_horizon,
make_mae_vs_forecast_horizon_group_by_date,
)
from plots.mae_and_rmse import make_rmse_and_mae_plot, make_mae_plot
from plots.pinball_and_exceedance_plots import make_pinball_or_exceedance_plot
from plots.ramp_rate import make_ramp_rate_plot
from plots.utils import (
get_x_y, get_recent_available_model_names, model_is_probabilistic, model_is_gsp_regional
)
from pvsite_forecast import pvsite_forecast_page
from sites_toolbox import sites_toolbox_page
from status import status_page
from tables.raw import make_raw_table
from tables.summary import make_recent_summary_stats, make_forecast_horizon_table
from users import user_page
from nwp_page import nwp_page
from satellite_page import satellite_page
from adjuster import adjuster_page
st.get_option("theme.primaryColor")
st.set_page_config(layout="wide", page_title="OCF Dashboard")
def metric_page():
# Set up sidebar
# Select start and end date
st.sidebar.subheader("Select date range for charts")
starttime = st.sidebar.date_input("Start Date", datetime.today() - timedelta(days=30))
endtime = st.sidebar.date_input("End Date", datetime.today())
# Adjuster option
use_adjuster = st.sidebar.radio("Use adjuster", [True, False], index=1)
# Select model
st.sidebar.subheader("Select Forecast Model")
# Get the models run in the last week
connection = DatabaseConnection(url=os.environ["DB_URL"], echo=True)
with connection.get_session() as session:
models = get_recent_available_model_names(session)
# Default model is pvnet_v2
model_name = st.sidebar.selectbox("Select model", models, index=models.index("pvnet_v2"))
# Get metrics for comparing MAE and RMSE without forecast horizon
with connection.get_session() as session:
# read database metric values
name_mae = "Daily Latest MAE"
name_rmse = "Daily Latest RMSE"
name_mae_gsp_sum = "Daily Latest MAE All GSPs"
if use_adjuster:
name_mae = "Daily Latest MAE with adjuster"
name_rmse = "Daily Latest RMSE with adjuster"
name_mae_gsp_sum = "Daily Latest MAE All GSPs"
name_pvlive_mae = "PVLive MAE"
name_pvlive_rmse = "PVLive RMSE"
metric_values_mae = get_metric_value(
session=session,
name=name_mae,
gsp_id=0,
start_datetime_utc=starttime,
end_datetime_utc=endtime,
model_name=model_name,
)
metric_values_rmse = get_metric_value(
session=session,
name=name_rmse,
gsp_id=0,
start_datetime_utc=starttime,
end_datetime_utc=endtime,
model_name=model_name,
)
# Get metric value for mae with pvlive gsp sum truths for comparison
metric_values_mae_gsp_sum = get_metric_value(
session=session,
name=name_mae_gsp_sum,
start_datetime_utc=starttime,
end_datetime_utc=endtime,
model_name=model_name,
)
# pvlive
metric_values_pvlive_mae = get_metric_value(
session=session,
name=name_pvlive_mae,
start_datetime_utc=starttime,
end_datetime_utc=endtime,
gsp_id=0,
)
metric_values_pvlive_rmse = get_metric_value(
session=session,
name=name_pvlive_rmse,
start_datetime_utc=starttime,
end_datetime_utc=endtime,
gsp_id=0,
)
# transform SQL object into something readable
x_mae_all_gsp, y_mae_all_gsp = get_x_y(metric_values=metric_values_mae_gsp_sum)
x_mae, y_mae = get_x_y(metric_values=metric_values_mae)
x_rmse, y_rmse = get_x_y(metric_values=metric_values_rmse)
x_plive_mae, y_plive_mae = get_x_y(metric_values=metric_values_pvlive_mae)
x_plive_rmse, y_plive_rmse = get_x_y(metric_values=metric_values_pvlive_rmse)
st.markdown(
f'<h1 style="color:#63BCAF;font-size:48px;">{"Metrics"}</h1>',
unsafe_allow_html=True,
)
make_recent_summary_stats(values=y_mae)
make_recent_summary_stats(values=y_rmse, title="Recent RMSE")
st.sidebar.subheader("Select Forecast Horizon")
forecast_horizon_selection = st.sidebar.multiselect(
"Select",
# 0-8 hours in 30 mintue chunks, 8-36 hours in 3 hour chunks
list(range(0, 480, 30)) + list(range(480, 36 * 60, 180)),
[60, 120, 240, 420],
)
df_mae = pd.DataFrame(
{
"MAE": y_mae,
"datetime_utc": x_mae,
}
)
df_rmse = pd.DataFrame(
{
"RMSE": y_rmse,
"datetime_utc": x_rmse,
}
)
# Make MAE plot
fig = make_mae_plot(df_mae)
st.plotly_chart(fig, theme="streamlit")
# get metrics per forecast horizon
metric_values_by_forecast_horizon = {}
with connection.get_session() as session:
# read database metric values
for forecast_horizon in forecast_horizon_selection:
metric_values = get_metric_value(
session=session,
name=name_mae,
gsp_id=0,
forecast_horizon_minutes=forecast_horizon,
start_datetime_utc=starttime,
end_datetime_utc=endtime,
model_name=model_name,
)
metric_values = [MetricValue.from_orm(value) for value in metric_values]
metric_values_by_forecast_horizon[forecast_horizon] = metric_values
fig2 = make_mae_by_forecast_horizon(
df_mae, forecast_horizon_selection, metric_values_by_forecast_horizon
)
with st.expander("MAE by Forecast Horizon"):
st.plotly_chart(fig2, theme="streamlit")
fig3 = make_mae_forecast_horizon_group_by_forecast_horizon(
forecast_horizon_selection, metric_values_by_forecast_horizon
)
with st.expander("MAE by Forecast Horizon by Date"):
st.plotly_chart(fig3, theme="streamlit")
all_forecast_horizons_df, fig4 = make_mae_vs_forecast_horizon_group_by_date(
forecast_horizon_selection, metric_values_by_forecast_horizon
)
with st.expander("MAE Forecast Horizon Values by Date"):
st.plotly_chart(fig4, theme="streamlit")
# comparing MAE and RMSE
fig5 = make_rmse_and_mae_plot(
df_mae, df_rmse, x_plive_mae, x_plive_rmse, y_plive_mae, y_plive_rmse
)
with st.expander("Quartz Solar and PVlive MAE with RMSE"):
st.plotly_chart(fig5, theme="streamlit")
st.write(
"PVLive is the difference between the intraday and day after PVLive values."
)
fig6 = make_all_gsps_plots(x_mae_all_gsp, y_mae_all_gsp)
if model_is_gsp_regional(model_name):
with st.expander("MAE All GSPs"):
st.plotly_chart(fig6, theme="streamlit")
fig7 = make_ramp_rate_plot(session=session, model_name=model_name, starttime=starttime, endtime=endtime)
with st.expander("Ramp Rate"):
st.plotly_chart(fig7, theme="streamlit")
if model_is_probabilistic(model_name):
with connection.get_session() as session:
with st.expander("Pinball loss"):
fig7 = make_pinball_or_exceedance_plot(
session=session,
model_name=model_name,
starttime=starttime,
endtime=endtime,
forecast_horizon_selection=forecast_horizon_selection,
metric_name="Pinball loss",
)
st.plotly_chart(fig7, theme="streamlit")
with st.expander("Exceedance"):
fig8 = make_pinball_or_exceedance_plot(
session=session,
model_name=model_name,
starttime=starttime,
endtime=endtime,
forecast_horizon_selection=forecast_horizon_selection,
metric_name="Exceedance",
)
st.plotly_chart(fig8, theme="streamlit")
make_forecast_horizon_table(all_forecast_horizons_df, y_plive_mae)
make_raw_table(df_mae, df_rmse)
if check_password():
page_names_to_funcs = {
"Metrics": metric_page,
"Status": status_page,
"Forecast": forecast_page,
"PV Site Forecast": pvsite_forecast_page,
"Sites Toolbox": sites_toolbox_page,
"API Users": user_page,
"NWP": nwp_page,
"Satellite": satellite_page,
"Adjuster": adjuster_page,
}
demo_name = st.sidebar.selectbox("Choose a page", page_names_to_funcs.keys())
page_names_to_funcs[demo_name]()