diff --git a/docs/sphinx/source/api.rst b/docs/sphinx/source/api.rst index 3c128bbf80..45ef9ec50a 100644 --- a/docs/sphinx/source/api.rst +++ b/docs/sphinx/source/api.rst @@ -170,6 +170,8 @@ Transposition models irradiance.reindl irradiance.king +.. _dniestmodels: + DNI estimation models --------------------- diff --git a/docs/sphinx/source/introexamples.rst b/docs/sphinx/source/introexamples.rst index 56f11cc52b..6cd0d54f63 100644 --- a/docs/sphinx/source/introexamples.rst +++ b/docs/sphinx/source/introexamples.rst @@ -134,14 +134,13 @@ The following code demonstrates how to use :py:class:`~pvlib.modelchain.ModelChain` objects to accomplish our system modeling goal. ModelChain objects provide convenience methods that can provide default selections for models and can also fill -necessary input data with modeled data. In our example below, we use -convenience methods. For example, no irradiance data is provided as -input, so the ModelChain object substitutes irradiance from a clear-sky -model via the prepare_inputs method. Also, no irradiance transposition -model is specified (keyword argument `transposition` for ModelChain) so -the ModelChain defaults to the `haydavies` model. In this example, -ModelChain infers the DC power model from the module provided by -examining the parameters defined for module. +necessary input with modeled data. For example, no air temperature +or wind speed data is provided in the input *weather* DataFrame, +so the ModelChain object defaults to 20 C and 0 m/s. Also, no irradiance +transposition model is specified (keyword argument `transposition` for +ModelChain) so the ModelChain defaults to the `haydavies` model. In this +example, ModelChain infers the DC power model from the module provided +by examining the parameters defined for the module. .. ipython:: python @@ -157,12 +156,12 @@ examining the parameters defined for module. times = naive_times.tz_localize(timezone) location = Location(latitude, longitude, name=name, altitude=altitude, tz=timezone) - # very experimental + weather = location.get_clearsky(times) mc = ModelChain(system, location, orientation_strategy='south_at_latitude_tilt') # model results (ac, dc) and intermediates (aoi, temps, etc.) # assigned as mc object attributes - mc.run_model(times) + mc.run_model(times=times, weather=weather) annual_energy = mc.ac.sum() energies[name] = annual_energy diff --git a/docs/sphinx/source/modelchain.rst b/docs/sphinx/source/modelchain.rst index f7e9d608ea..1b324801b3 100644 --- a/docs/sphinx/source/modelchain.rst +++ b/docs/sphinx/source/modelchain.rst @@ -24,7 +24,8 @@ Modeling with a :py:class:`~.ModelChain` typically involves 3 steps: 1. Creating the :py:class:`~.ModelChain`. 2. Executing the :py:meth:`ModelChain.run_model() <.ModelChain.run_model>` method with prepared weather data. -3. Examining the model results that :py:meth:`~.ModelChain.run_model` stored in attributes of the :py:class:`~.ModelChain`. +3. Examining the model results that :py:meth:`~.ModelChain.run_model` + stored in attributes of the :py:class:`~.ModelChain`. A simple ModelChain example --------------------------- @@ -212,8 +213,13 @@ method, :py:meth:`~pvlib.modelchain.ModelChain.prepare_inputs`, computes parameters such as solar position, airmass, angle of incidence, and plane of array irradiance. The :py:meth:`~pvlib.modelchain.ModelChain.prepare_inputs` method also -assigns default values for irradiance (clear sky), temperature (20 C), +assigns default values for temperature (20 C) and wind speed (0 m/s) if these inputs are not provided. +:py:meth:`~pvlib.modelchain.ModelChain.prepare_inputs` requires all irradiance +components (GHI, DNI, and DHI). See +:py:meth:`~pvlib.modelchain.ModelChain.complete_irradiance` and +:ref:`dniestmodels` for methods and functions that can help fully define +the irradiance inputs. Next, :py:meth:`~pvlib.modelchain.ModelChain.run_model` calls the wrapper methods for AOI loss, spectral loss, effective irradiance, cell diff --git a/docs/sphinx/source/whatsnew/v0.6.2.rst b/docs/sphinx/source/whatsnew/v0.6.2.rst index 9fc91bfa1a..43779005f1 100644 --- a/docs/sphinx/source/whatsnew/v0.6.2.rst +++ b/docs/sphinx/source/whatsnew/v0.6.2.rst @@ -23,6 +23,9 @@ API Changes *ghi* or *zenith*. * Added *min_cos_zenith* and *max_zenith* keyword arguments to :py:func:`~pvlib.irradiance.erbs`. (:issue:`681`) +* Deprecated :py:meth:`~pvlib.modelchain.ModelChain.prepare_inputs` + assumption of clear sky if no irradiance fields were provided. + (:issue:`705`, :issue:`707`) Enhancements ~~~~~~~~~~~~ diff --git a/pvlib/modelchain.py b/pvlib/modelchain.py index 1dbbc137c6..bcb0b4ff23 100644 --- a/pvlib/modelchain.py +++ b/pvlib/modelchain.py @@ -810,19 +810,20 @@ def prepare_inputs(self, times=None, weather=None): Times at which to evaluate the model. Can be None if attribute `times` is already set. weather : None or DataFrame, default None - If ``None``, the weather attribute is used. If the weather - attribute is also ``None`` assumes air temperature is 20 C, wind - speed is 0 m/s and irradiation calculated from clear sky - data. Column names must be ``'wind_speed'``, ``'temp_air'``, - ``'dni'``, ``'ghi'``, ``'dhi'``. Do not pass incomplete irradiation - data. Use method - :py:meth:`~pvlib.modelchain.ModelChain.complete_irradiance` - instead. + If ``None``, the weather attribute is used. Column names + must be ``'dni'``, ``'ghi'``, ``'dhi'``, ``'wind_speed'``, + ``'temp_air'``. All irradiance components are required. + Assumes air temperature is 20 C and wind speed is 0 m/s if + not provided. Notes ----- Assigns attributes: ``times``, ``solar_position``, ``airmass``, ``total_irrad``, `aoi` + + See also + -------- + ModelChain.complete_irradiance """ if weather is not None: self.weather = weather @@ -839,6 +840,10 @@ def prepare_inputs(self, times=None, weather=None): solar_position=self.solar_position, model=self.airmass_model) if not any([x in ['ghi', 'dni', 'dhi'] for x in self.weather.columns]): + warnings.warn('Clear sky assumption for no input irradiance is ' + 'deprecated and will be removed in v0.7.0. Use ' + 'location.get_clearsky instead', + pvlibDeprecationWarning) self.weather[['ghi', 'dni', 'dhi']] = self.location.get_clearsky( self.solar_position.index, self.clearsky_model, solar_position=self.solar_position, @@ -846,8 +851,8 @@ def prepare_inputs(self, times=None, weather=None): if not {'ghi', 'dni', 'dhi'} <= set(self.weather.columns): raise ValueError( - "Uncompleted irradiance data set. Please check you input " + - "data.\nData set needs to have 'dni', 'dhi' and 'ghi'.\n" + + "Uncompleted irradiance data set. Please check your input " + "data.\nData set needs to have 'dni', 'dhi' and 'ghi'.\n" "Detected data: {0}".format(list(self.weather.columns))) # PVSystem.get_irradiance and SingleAxisTracker.get_irradiance @@ -903,12 +908,11 @@ def run_model(self, times=None, weather=None): Times at which to evaluate the model. Can be None if attribute `times` is already set. weather : None or DataFrame, default None - If None, assumes air temperature is 20 C, wind speed is 0 - m/s and irradiation calculated from clear sky data. Column - names must be 'wind_speed', 'temp_air', 'dni', 'ghi', 'dhi'. - Do not pass incomplete irradiation data. Use method - :py:meth:`~pvlib.modelchain.ModelChain.complete_irradiance` - instead. + If ``None``, the weather attribute is used. Column names + must be ``'dni'``, ``'ghi'``, ``'dhi'``, ``'wind_speed'``, + ``'temp_air'``. All irradiance components are required. + Assumes air temperature is 20 C and wind speed is 0 m/s if + not provided. Returns ------- diff --git a/pvlib/test/test_modelchain.py b/pvlib/test/test_modelchain.py index 1bbab81f13..9f4a228116 100644 --- a/pvlib/test/test_modelchain.py +++ b/pvlib/test/test_modelchain.py @@ -19,7 +19,7 @@ import pytest from test_pvsystem import sam_data, pvsyst_module_params -from conftest import fail_on_pvlib_version, requires_scipy +from conftest import fail_on_pvlib_version, requires_scipy, requires_tables @pytest.fixture @@ -153,7 +153,9 @@ def test_orientation_strategy(strategy, expected, system, location): def test_run_model(system, location): mc = ModelChain(system, location) times = pd.date_range('20160101 1200-0700', periods=2, freq='6H') - ac = mc.run_model(times).ac + + with pytest.warns(pvlibDeprecationWarning): + ac = mc.run_model(times).ac expected = pd.Series(np.array([ 183.522449305, -2.00000000e-02]), index=times) @@ -374,14 +376,12 @@ def constant_spectral_loss(mc): @pytest.mark.parametrize('spectral_model', [ 'sapm', 'first_solar', 'no_loss', constant_spectral_loss ]) -def test_spectral_models(system, location, spectral_model): - times = pd.date_range('20160101 1200-0700', periods=3, freq='6H') - weather = pd.DataFrame(data=[0.3, 0.5, 1.0], - index=times, - columns=['precipitable_water']) +def test_spectral_models(system, location, spectral_model, weather): + # add pw to weather dataframe + weather['precipitable_water'] = [0.3, 0.5] mc = ModelChain(system, location, dc_model='sapm', aoi_model='no_loss', spectral_model=spectral_model) - spectral_modifier = mc.run_model(times=times, + spectral_modifier = mc.run_model(times=weather.index, weather=weather).spectral_modifier assert isinstance(spectral_modifier, (pd.Series, float, int)) @@ -493,6 +493,21 @@ def test_deprecated_07(): ac_model='snlinverter') +@requires_tables +@fail_on_pvlib_version('0.7') +def test_deprecated_clearsky_07(): + # explicit system creation call because fail_on_pvlib_version + # does not support decorators. + system = PVSystem(module_parameters={'pdc0': 1, 'gamma_pdc': -0.003}) + location = Location(32.2, -110.9) + mc = ModelChain(system, location, dc_model='pvwatts', ac_model='pvwatts', + aoi_model='no_loss', spectral_model='no_loss') + times = pd.date_range(start='20160101 1200-0700', + end='20160101 1800-0700', freq='6H') + with pytest.warns(pvlibDeprecationWarning): + mc.prepare_inputs(times=times) + + @requires_scipy def test_basic_chain_required(sam_data): times = pd.date_range(start='20160101 1200-0700',