def run_nwp(forecast, model, run_time, issue_time): """ Calculate benchmark irradiance and power forecasts for a Forecast or ProbabilisticForecast. Forecasts may be run operationally or retrospectively. For operational forecasts, *run_time* is typically set to now. For retrospective forecasts, *run_time* is the time by which the forecast should be run so that it could have been be delivered for the *issue_time*. Forecasts will only use data with timestamps before *run_time*. Parameters ---------- forecast : datamodel.Forecast or datamodel.ProbabilisticForecast The metadata of the desired forecast. model : function NWP model loading and processing function. See :py:mod:`solarforecastarbiter.reference_forecasts.models` for options. run_time : pd.Timestamp Run time of the forecast. issue_time : pd.Timestamp Issue time of the forecast run. Returns ------- ghi : pd.Series or pd.DataFrame dni : pd.Series or pd.DataFrame dhi : pd.Series or pd.DataFrame air_temperature : pd.Series or pd.DataFrame wind_speed : pd.Series or pd.DataFrame ac_power : pd.Series or pd.DataFrame Series are returned for deterministic forecasts, DataFrames are returned for probabilisic forecasts. Examples -------- The following code would return hourly average forecasts derived from the subhourly HRRR model. .. testsetup:: import datetime from solarforecastarbiter import datamodel from solarforecastarbiter.reference_forecasts import models from solarforecastarbiter.reference_forecasts.main import * >>> run_time = pd.Timestamp('20190515T0200Z') >>> issue_time = pd.Timestamp('20190515T0000Z') >>> modeling_parameters = datamodel.FixedTiltModelingParameters( ... surface_tilt=30, surface_azimuth=180, ... ac_capacity=10, dc_capacity=15, ... temperature_coefficient=-0.4, dc_loss_factor=0, ... ac_loss_factor=0) >>> power_plant = datamodel.SolarPowerPlant( ... name='Test plant', latitude=32.2, longitude=-110.9, ... elevation=715, timezone='America/Phoenix', ... modeling_parameters=modeling_parameters) >>> forecast = datamodel.Forecast( ... name='Test plant fx', ... site=power_plant, ... variable='ac_power', ... interval_label='ending', ... interval_value_type='mean', ... interval_length='1h', ... issue_time_of_day=datetime.time(hour=0), ... run_length=pd.Timedelta('24h'), ... lead_time_to_start=pd.Timedelta('0h')) >>> ghi, dni, dhi, temp_air, wind_speed, ac_power = run_nwp( ... forecast, models.hrrr_subhourly_to_hourly_mean, ... run_time, issue_time) """ fetch_metadata = fetch_nwp.model_map[models.get_nwp_model(model)] # absolute date and time for model run most recently available # as of run_time init_time = utils.get_init_time(run_time, fetch_metadata) # absolute start and end times. interval_label still controls # inclusive/exclusive start, end = utils.get_forecast_start_end(forecast, issue_time) site = forecast.site logger.info( 'Calculating forecast for model %s starting at %s from %s to %s', model, init_time, start, end) # model will account for interval_label *forecasts, resampler, solar_position_calculator = model( site.latitude, site.longitude, site.elevation, init_time, start, end, forecast.interval_label) if isinstance(site, datamodel.SolarPowerPlant): solar_position = solar_position_calculator() if isinstance(forecasts[0], pd.DataFrame): # must iterate over columns because pvmodel.irradiance_to_power # calls operations that do not properly broadcast Series along # a DataFrame time index. pvlib.irradiance.haydavies operation # (AI = dni_ens / dni_extra) is the known culprit, though there # may be more. ac_power = {} for col in forecasts[0].columns: member_fx = [fx.get(col) for fx in forecasts] member_ac_power = pvmodel.irradiance_to_power( site.modeling_parameters, solar_position['apparent_zenith'], solar_position['azimuth'], *member_fx) ac_power[col] = member_ac_power ac_power = pd.DataFrame(ac_power) else: ac_power = pvmodel.irradiance_to_power( site.modeling_parameters, solar_position['apparent_zenith'], solar_position['azimuth'], *forecasts) else: ac_power = None # resample data after power calculation resampled = list(map(resampler, (*forecasts, ac_power))) nwpoutput = namedtuple( 'NWPOutput', ['ghi', 'dni', 'dhi', 'air_temperature', 'wind_speed', 'ac_power']) return nwpoutput(*resampled)
def test_get_nwp_model(model, exp): assert models.get_nwp_model(model) == exp