Source code for solarforecastarbiter.reference_forecasts.forecast

"""
Functions for forecasting.
"""

from solarforecastarbiter import pvmodel

# some functions originally implemented in pvlib-python.
# find pvlib-python license in licenses directory.


[docs]def cloud_cover_to_ghi_linear(cloud_cover, ghi_clear, offset=35): """ Convert cloud cover to GHI using a linear relationship. 0% cloud cover returns ghi_clear. 100% cloud cover returns offset*ghi_clear. Parameters ---------- cloud_cover: numeric Cloud cover in %. ghi_clear: numeric GHI under clear sky conditions. offset: numeric, default 35 Determines the minimum GHI. Returns ------- ghi: numeric Cloudy sky GHI. References ---------- Larson et. al. "Day-ahead forecasting of solar power output from photovoltaic plants in the American Southwest" Renewable Energy 91, 11-20 (2016). """ offset = offset / 100. cloud_cover = cloud_cover / 100. ghi = (offset + (1 - offset) * (1 - cloud_cover)) * ghi_clear return ghi
[docs]def cloud_cover_to_irradiance_ghi_clear(cloud_cover, ghi_clear, zenith): """ Estimates irradiance from cloud cover in the following steps: 1. Estimate cloudy sky GHI using a function of cloud_cover and ghi_clear: :py:func:`cloud_cover_to_ghi_linear` 2. Estimate cloudy sky DNI and DHI using the Erbs model. Parameters ---------- site : datamodel.Site cloud_cover : Series Cloud cover in %. zenith : Series Solar zenith Returns ------- ghi : pd.Series, dni : pd.Series, dhi : pd.Series """ ghi = cloud_cover_to_ghi_linear(cloud_cover, ghi_clear) dni, dhi = pvmodel.complete_irradiance_components(ghi, zenith) return ghi, dni, dhi
[docs]def cloud_cover_to_irradiance(latitude, longitude, elevation, cloud_cover, apparent_zenith, zenith): """ Estimates irradiance from cloud cover in the following steps: 1. Determine clear sky GHI using Ineichen model and climatological turbidity. 2. Estimate cloudy sky GHI using a function of cloud_cover and ghi_clear: :py:func:`cloud_cover_to_ghi_linear` 3. Estimate cloudy sky DNI and DHI using the Erbs model. Don't use this function if you already have clear sky GHI. Instead, use :py:func:`cloud_cover_to_irradiance_ghi_clear` Parameters ---------- latitude : float longitude : float elevation : float cloud_cover : Series Cloud cover in %. apparent_zenith : Series Solar apparent zenith zenith : Series Solar zenith Returns ------- ghi : pd.Series dni : pd.Series dhi : pd.Series See also -------- cloud_cover_to_irradiance_ghi_clear cloud_cover_to_ghi_linear """ cs = pvmodel.calculate_clearsky(latitude, longitude, elevation, apparent_zenith) ghi, dni, dhi = cloud_cover_to_irradiance_ghi_clear( cloud_cover, cs['ghi'], zenith) return ghi, dni, dhi
def resample_args(*args, freq='1h'): """Resample all positional arguments, allowing for None. Parameters ---------- *args : list of pd.Series or None Returns ------- list of pd.Series or None """ # this one uses map for fun def f(arg): if arg is None: return None else: return arg.resample(freq).mean() return list(map(f, args))
[docs]def resample(arg, freq='1h', closed=None): """Resamples an argument, allowing for None. Use with map. Parameters ---------- arg : pd.Series or None Returns ------- pd.Series or None """ if arg is None: return None else: return arg.resample(freq, closed=closed).mean()
def interpolate_args(*args, freq='15min'): """Interpolate all positional arguments, allowing for None. Parameters ---------- *args : list of pd.Series or None Returns ------- list of pd.Series or None """ # could add how kwarg to resample_args and lookup method with # getattr but this seems much more clear # this one uses a list comprehension for different fun resampled_args = [ arg if arg is None else arg.resample(freq).interpolate() for arg in args] return resampled_args
[docs]def interpolate(arg, freq='15min', closed=None): """Interpolates an argument, allowing for None. Use with map. Parameters ---------- arg : pd.Series or None Returns ------- pd.Series or None """ # could add how kwarg to resample and lookup method with # getattr but this seems much more clear if arg is None: return None else: return arg.resample(freq, closed=closed).interpolate()
def slice_args(*args, start, end): resampled_args = [arg if arg is None else arg.iloc[start:end] for arg in args] return resampled_args
[docs]def unmix_intervals(cloud_cover): """Convert mixed interval averages into pure interval averages. For example, the GFS 3 hour output contains the following data: * forecast hour 3: average cloud cover from 0 - 3 hours * forecast hour 6: average cloud cover from 0 - 6 hours * forecast hour 9: average cloud cover from 6 - 9 hours * forecast hour 12: average cloud cover from 6 - 12 hours and so on. This function returns: * forecast hour 3: average cloud cover from 0 - 3 hours * forecast hour 6: average cloud cover from 3 - 6 hours * forecast hour 9: average cloud cover from 6 - 9 hours * forecast hour 12: average cloud cover from 9 - 12 hours Parameters ---------- cloud_cover : pd.Series Returns ------- pd.Series """ raise NotImplementedError