Skip to content

Commit

Permalink
Accept albedo in weather input to ModelChain.run_model method (#1478)
Browse files Browse the repository at this point in the history
* permit albedo to be a Series

* work on modelchain

* fix tests

* shh stickler, docstrings

* improve coverage

* improve coverage correctly

* finalize coverage, stickler

* whatsnew

* from review

* don't mutate inputs

* get_irradiance in tracking.py

* shh stickler

* shh stickler

* improvements from review

* update whatsnew

* Apply suggestions from code review

Co-authored-by: Kevin Anderson <kevin.anderson@nrel.gov>

* docstring improvements

* Apply suggestions from code review

Co-authored-by: Will Holmgren <william.holmgren@gmail.com>

* Update pvlib/tests/test_irradiance.py

Co-authored-by: Will Holmgren <william.holmgren@gmail.com>

* from review

* one more

* more use of fixture, add Array.get_irradiance test

* more decimal places

* spacing

* line length

* write albedo from system.arrays to ModelChainResult

Co-authored-by: Kevin Anderson <kevin.anderson@nrel.gov>
Co-authored-by: Will Holmgren <william.holmgren@gmail.com>
  • Loading branch information
3 people committed Aug 19, 2022
1 parent 2fcd6ba commit e1393f7
Show file tree
Hide file tree
Showing 11 changed files with 343 additions and 118 deletions.
10 changes: 8 additions & 2 deletions docs/sphinx/source/whatsnew/v0.9.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ Deprecations

Enhancements
~~~~~~~~~~~~
* albedo can now be provided as a column in the `weather` DataFrame input to
:py:method:`pvlib.modelchain.ModelChain.run_model`. (:issue:`1387`, :pull:`1478`)
* albedo is now available as an input to :py:meth:`pvlib.pvsystem.PVSystem.get_irradiance`
and :py:meth:`pvlib.pvsystem.Array.get_irradiance`. (:pull:`1478`)
* :py:func:`pvlib.iotools.read_surfrad` now also accepts remote files
with https links in addition to files on the SURFRAD FTP server
(:pull:`1459`)
Expand All @@ -20,14 +24,15 @@ Enhancements
* Add support for `PEP517 <https://peps.python.org/pep-0517/>`_ & `PEP518 <https://peps.python.org/pep-0518/>`_
with setuptools build backend. (:pull:`1495`)


Bug fixes
~~~~~~~~~
* :py:func:`pvlib.irradiance.get_total_irradiance` and
:py:func:`pvlib.solarposition.spa_python` now raise an error instead
of silently ignoring unknown parameters (:pull:`1437`)
of silently ignoring unknown parameters. (:pull:`1437`)
* Fix a bug in :py:func:`pvlib.solarposition.sun_rise_set_transit_ephem`
where passing localized timezones with large UTC offsets could return
rise/set/transit times for the wrong day in recent versions of ``ephem``
rise/set/transit times for the wrong day in recent versions of ``ephem``.
(:issue:`1449`, :pull:`1448`)
* :py:func:`pvlib.iotools.read_tmy3` is now able to accept midnight
timestamps as either 24:00 (which is the standard) as well as 00:00.
Expand Down Expand Up @@ -68,6 +73,7 @@ Contributors
* Naman Priyadarshi (:ghuser:`Naman-Priyadarshi`)
* Chencheng Luo (:ghuser:`roger-lcc`)
* Prajwal Borkar (:ghuser:`PrajwalBorkar`)
* Cliff Hansen (:ghuser:`cwhanse`)
* Kevin Anderson (:ghuser:`kanderso-nrel`)
* Cliff Hansen (:ghuser:`cwhanse`)
* Jules Chéron (:ghuser:`jules-ch`)
Expand Down
4 changes: 2 additions & 2 deletions pvlib/clearsky.py
Original file line number Diff line number Diff line change
Expand Up @@ -960,8 +960,8 @@ def bird(zenith, airmass_relative, aod380, aod500, precipitable_water,
Extraterrestrial radiation [W/m^2], defaults to 1364[W/m^2]
asymmetry : numeric
Asymmetry factor, defaults to 0.85
albedo : numeric
Albedo, defaults to 0.2
albedo : numeric, default 0.2
Ground surface albedo. [unitless]
Returns
-------
Expand Down
6 changes: 3 additions & 3 deletions pvlib/irradiance.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ def beam_component(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
def get_total_irradiance(surface_tilt, surface_azimuth,
solar_zenith, solar_azimuth,
dni, ghi, dhi, dni_extra=None, airmass=None,
albedo=.25, surface_type=None,
albedo=0.25, surface_type=None,
model='isotropic',
model_perez='allsitescomposite1990'):
r"""
Expand Down Expand Up @@ -344,7 +344,7 @@ def get_total_irradiance(surface_tilt, surface_azimuth,
airmass : None or numeric, default None
Relative airmass (not adjusted for pressure). [unitless]
albedo : numeric, default 0.25
Surface albedo. [unitless]
Ground surface albedo. [unitless]
surface_type : None or str, default None
Surface type. See :py:func:`~pvlib.irradiance.get_ground_diffuse` for
the list of accepted values.
Expand Down Expand Up @@ -1872,7 +1872,7 @@ def gti_dirint(poa_global, aoi, solar_zenith, solar_azimuth, times,
applied.
albedo : numeric, default 0.25
Surface albedo
Ground surface albedo. [unitless]
model : String, default 'perez'
Irradiance model. See :py:func:`get_sky_diffuse` for allowed values.
Expand Down
61 changes: 50 additions & 11 deletions pvlib/modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ class ModelChainResult:
_per_array_fields = {'total_irrad', 'aoi', 'aoi_modifier',
'spectral_modifier', 'cell_temperature',
'effective_irradiance', 'dc', 'diode_params',
'dc_ohmic_losses', 'weather'}
'dc_ohmic_losses', 'weather', 'albedo'}

# system-level information
solar_position: Optional[pd.DataFrame] = field(default=None)
Expand Down Expand Up @@ -366,6 +366,10 @@ class ModelChainResult:
"""DatetimeIndex containing a copy of the index of the input weather data.
"""

albedo: Optional[PerArray[pd.Series]] = None
"""Series (or tuple of Series, one for each array) containing albedo.
"""

def _result_type(self, value):
"""Coerce `value` to the correct type according to
``self._singleton_tuples``."""
Expand Down Expand Up @@ -1339,6 +1343,17 @@ def _prep_inputs_solar_pos(self, weather):
**kwargs)
return self

def _prep_inputs_albedo(self, weather):
"""
Get albedo from weather
"""
try:
self.results.albedo = _tuple_from_dfs(weather, 'albedo')
except KeyError:
self.results.albedo = tuple([
a.albedo for a in self.system.arrays])
return self

def _prep_inputs_airmass(self):
"""
Assign airmass
Expand Down Expand Up @@ -1471,11 +1486,17 @@ def prepare_inputs(self, weather):
Parameters
----------
weather : DataFrame, or tuple or list of DataFrame
weather : DataFrame, or tuple or list of DataFrames
Required column names include ``'dni'``, ``'ghi'``, ``'dhi'``.
Optional column names are ``'wind_speed'``, ``'temp_air'``; if not
Optional column names are ``'wind_speed'``, ``'temp_air'``,
``'albedo'``.
If optional columns ``'wind_speed'``, ``'temp_air'`` are not
provided, air temperature of 20 C and wind speed
of 0 m/s will be added to the DataFrame.
of 0 m/s will be added to the ``weather`` DataFrame.
If optional column ``'albedo'`` is provided, albedo values in the
ModelChain's PVSystem.arrays are ignored.
If `weather` is a tuple or list, it must be of the same length and
order as the Arrays of the ModelChain's PVSystem.
Expand All @@ -1494,7 +1515,7 @@ def prepare_inputs(self, weather):
Notes
-----
Assigns attributes to ``results``: ``times``, ``weather``,
``solar_position``, ``airmass``, ``total_irrad``, ``aoi``
``solar_position``, ``airmass``, ``total_irrad``, ``aoi``, ``albedo``.
See also
--------
Expand All @@ -1507,6 +1528,7 @@ def prepare_inputs(self, weather):

self._prep_inputs_solar_pos(weather)
self._prep_inputs_airmass()
self._prep_inputs_albedo(weather)

# PVSystem.get_irradiance and SingleAxisTracker.get_irradiance
# and PVSystem.get_aoi and SingleAxisTracker.get_aoi
Expand All @@ -1531,6 +1553,7 @@ def prepare_inputs(self, weather):
_tuple_from_dfs(self.results.weather, 'dni'),
_tuple_from_dfs(self.results.weather, 'ghi'),
_tuple_from_dfs(self.results.weather, 'dhi'),
albedo=self.results.albedo,
airmass=self.results.airmass['airmass_relative'],
model=self.transposition_model
)
Expand Down Expand Up @@ -1724,16 +1747,32 @@ def run_model(self, weather):
Parameters
----------
weather : DataFrame, or tuple or list of DataFrame
Irradiance column names must include ``'dni'``, ``'ghi'``, and
``'dhi'``. If optional columns ``'temp_air'`` and ``'wind_speed'``
Column names must include:
- ``'dni'``
- ``'ghi'``
- ``'dhi'``
Optional columns are:
- ``'temp_air'``
- ``'cell_temperature'``
- ``'module_temperature'``
- ``'wind_speed'``
- ``'albedo'``
If optional columns ``'temp_air'`` and ``'wind_speed'``
are not provided, air temperature of 20 C and wind speed of 0 m/s
are added to the DataFrame. If optional column
``'cell_temperature'`` is provided, these values are used instead
of `temperature_model`. If optional column `module_temperature`
is provided, `temperature_model` must be ``'sapm'``.
of `temperature_model`. If optional column ``'module_temperature'``
is provided, ``temperature_model`` must be ``'sapm'``.
If list or tuple, must be of the same length and order as the
Arrays of the ModelChain's PVSystem.
If optional column ``'albedo'`` is provided, ``'albedo'`` may not
be present on the ModelChain's PVSystem.Arrays.
If weather is a list or tuple, it must be of the same length and
order as the Arrays of the ModelChain's PVSystem.
Returns
-------
Expand Down
Loading

0 comments on commit e1393f7

Please sign in to comment.