Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/sphinx/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ Transposition models
irradiance.reindl
irradiance.king

.. _dniestmodels:

DNI estimation models
---------------------

Expand Down
19 changes: 9 additions & 10 deletions docs/sphinx/source/introexamples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 data with modeled data. For example, no air temperature
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

necessary input with modeled data.

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 module.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defined for the module


.. ipython:: python

Expand All @@ -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

Expand Down
10 changes: 8 additions & 2 deletions docs/sphinx/source/modelchain.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
---------------------------
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions docs/sphinx/source/whatsnew/v0.6.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
~~~~~~~~~~~~
Expand Down
36 changes: 20 additions & 16 deletions pvlib/modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -839,15 +840,19 @@ 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,
airmass_absolute=self.airmass['airmass_absolute'])

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
Expand Down Expand Up @@ -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
-------
Expand Down
31 changes: 23 additions & 8 deletions pvlib/test/test_modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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))

Expand Down Expand Up @@ -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',
Expand Down