Skip to content

Commit 7d38355

Browse files
committed
update docs
1 parent b319f5d commit 7d38355

File tree

1 file changed

+68
-16
lines changed

1 file changed

+68
-16
lines changed

docs/sphinx/source/forecasts.rst

Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ then set the location and time range data.
8282
start = pd.Timestamp(datetime.date.today(), tz=tz)
8383
end = start + pd.Timedelta(days=7)
8484
85+
irrad_vars = ['ghi', 'dni', 'dhi']
86+
8587
8688
Next, we instantiate a GFS model object and get the forecast data
8789
from Unidata.
@@ -118,7 +120,8 @@ problems.
118120
data['wind_speed'] = model.uv_to_speed(data)
119121
120122
# calculate irradiance estimates from cloud cover.
121-
# uses Location.get_solarposition and irradiance.liujordan
123+
# uses a cloud_cover to ghi to dni model or a
124+
# uses a cloud cover to transmittance to irradiance model.
122125
# this step is discussed in more detail in the next section
123126
irrad_data = model.cloud_cover_to_irradiance(data['total_clouds'])
124127
data = data.join(irrad_data, how='outer')
@@ -185,22 +188,71 @@ poor solar position or radiative transfer algorithms. It is often more
185188
accurate to create empirically derived radiation forecasts from the
186189
weather models' cloud cover forecasts.
187190

188-
PVLIB-Python currently uses the Liu-Jordan [Liu60]_ model to convert
189-
total cloud cover forecasts to irradiance forecasts. We encourage pvlib
190-
users to implement new cloud cover to irradiance algorithms. The figure
191-
below shows the result of the Liu-Jordan total cloud cover to irradiance
192-
conversion.
191+
PVLIB-Python provides two basic ways to convert cloud cover forecasts to
192+
irradiance forecasts. One method assumes a linear relationship between
193+
cloud cover and GHI, applies the scaling to a clear sky climatology, and
194+
then uses the DISC model to calculate DNI. The second method assumes a
195+
linear relationship between cloud cover and atmospheric transmittance,
196+
and then uses the Liu-Jordan [Liu60]_ model to calculate GHI, DNI, and
197+
DHI.
198+
199+
*Caveat emptor*: these algorithms are not rigorously verified! The
200+
purpose of the forecast module is to provide a few exceedingly simple
201+
options for users to play with before they develop their own models. We
202+
strongly encourage pvlib users first read the source code and second
203+
to implement new cloud cover to irradiance algorithms.
204+
205+
The essential parts of the clear sky scaling algorithm are as follows.
206+
207+
.. code-block:: python
208+
209+
solpos = location.get_solarposition(cloud_cover.index)
210+
cs = location.get_clearsky(cloud_cover.index, model='ineichen')
211+
# offset and cloud cover in decimal units here
212+
ghi = (offset + (1 - offset) * (1 - cloud_cover)) * ghi_clear
213+
dni = disc(ghi, solpos['zenith'], cloud_cover.index)['dni']
214+
dhi = ghi - dni * np.cos(np.radians(solpos['zenith']))
215+
216+
The figure below shows the result of the total cloud cover to
217+
irradiance conversion using the clear sky scaling algorithm.
193218

194219
.. ipython:: python
195220
196221
# plot irradiance data
197-
irrad_vars = ['dni', 'ghi', 'dhi']
198-
data[irrad_vars].plot();
222+
data = model.rename(raw_data)
223+
irrads = model.cloud_cover_to_irradiance(data['total_clouds'], how='clearsky_scaling')
224+
irrads.plot();
199225
plt.ylabel('Irradiance ($W/m^2$)');
200226
plt.xlabel('Forecast Time ({})'.format(tz));
201-
plt.title('GFS 0.5 deg forecast for lat={}, lon={}'
227+
plt.title('GFS 0.5 deg forecast for lat={}, lon={} using "clearsky_scaling"'
228+
.format(latitude, longitude));
229+
@savefig gfs_irrad_cs.png width=6in
230+
plt.legend();
231+
232+
233+
The essential parts of the Liu-Jordan cloud cover to irradiance algorithm
234+
are as follows.
235+
236+
.. code-block:: python
237+
238+
# cloud cover in percentage units here
239+
transmittance = ((100.0 - cloud_cover) / 100.0) * 0.75
240+
# irrads is a DataFrame containing ghi, dni, dhi
241+
irrads = liujordan(apparent_zenith, transmittance, airmass_absolute)
242+
243+
The figure below shows the result of the Liu-Jordan total cloud cover to
244+
irradiance conversion.
245+
246+
.. ipython:: python
247+
248+
# plot irradiance data
249+
irrads = model.cloud_cover_to_irradiance(data['total_clouds'], how='liujordan')
250+
irrads.plot();
251+
plt.ylabel('Irradiance ($W/m^2$)');
252+
plt.xlabel('Forecast Time ({})'.format(tz));
253+
plt.title('GFS 0.5 deg forecast for lat={}, lon={} using "liujordan"'
202254
.format(latitude, longitude));
203-
@savefig gfs_irrad.png width=6in
255+
@savefig gfs_irrad_lj.png width=6in
204256
plt.legend();
205257
206258
@@ -212,18 +264,18 @@ recalculate the irradiance.
212264

213265
.. ipython:: python
214266
215-
from pvlib import irradiance
216-
total_clouds = data['total_clouds'].resample('5min').interpolate()
217-
solar_position = model.location.get_solarposition(total_clouds.index)
218-
irrad_data = irradiance.liujordan(solar_position['apparent_zenith'], total_clouds)
219-
irrad_data[irrad_vars].plot();
267+
resampled_data = data.resample('5min').interpolate()
268+
resampled_irrads = model.cloud_cover_to_irradiance(resampled_data['total_clouds'], how='clearsky_scaling')
269+
resampled_irrads.plot();
220270
plt.ylabel('Irradiance ($W/m^2$)');
221271
plt.xlabel('Forecast Time ({})'.format(tz));
222-
plt.title('GFS 0.5 deg forecast for lat={}, lon={}'
272+
plt.title('GFS 0.5 deg forecast for lat={}, lon={} resampled'
223273
.format(latitude, longitude));
224274
@savefig gfs_irrad_high_res.png width=6in
225275
plt.legend();
226276
277+
Users may then recombine resampled_irrads and resampled_data using
278+
slicing :py:func:`pandas.concat` or :py:meth:`pandas.DataFrame.join`.
227279

228280
We reiterate that the open source code enables users to customize the
229281
model processing to their liking.

0 commit comments

Comments
 (0)