Skip to content

Commit e1393f7

Browse files
cwhansekandersolarwholmgren
authored
Accept albedo in weather input to ModelChain.run_model method (#1478)
* 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 <[email protected]> * docstring improvements * Apply suggestions from code review Co-authored-by: Will Holmgren <[email protected]> * Update pvlib/tests/test_irradiance.py Co-authored-by: Will Holmgren <[email protected]> * 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 <[email protected]> Co-authored-by: Will Holmgren <[email protected]>
1 parent 2fcd6ba commit e1393f7

11 files changed

+343
-118
lines changed

docs/sphinx/source/whatsnew/v0.9.2.rst

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ Deprecations
88

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

27+
2328
Bug fixes
2429
~~~~~~~~~
2530
* :py:func:`pvlib.irradiance.get_total_irradiance` and
2631
:py:func:`pvlib.solarposition.spa_python` now raise an error instead
27-
of silently ignoring unknown parameters (:pull:`1437`)
32+
of silently ignoring unknown parameters. (:pull:`1437`)
2833
* Fix a bug in :py:func:`pvlib.solarposition.sun_rise_set_transit_ephem`
2934
where passing localized timezones with large UTC offsets could return
30-
rise/set/transit times for the wrong day in recent versions of ``ephem``
35+
rise/set/transit times for the wrong day in recent versions of ``ephem``.
3136
(:issue:`1449`, :pull:`1448`)
3237
* :py:func:`pvlib.iotools.read_tmy3` is now able to accept midnight
3338
timestamps as either 24:00 (which is the standard) as well as 00:00.
@@ -68,6 +73,7 @@ Contributors
6873
* Naman Priyadarshi (:ghuser:`Naman-Priyadarshi`)
6974
* Chencheng Luo (:ghuser:`roger-lcc`)
7075
* Prajwal Borkar (:ghuser:`PrajwalBorkar`)
76+
* Cliff Hansen (:ghuser:`cwhanse`)
7177
* Kevin Anderson (:ghuser:`kanderso-nrel`)
7278
* Cliff Hansen (:ghuser:`cwhanse`)
7379
* Jules Chéron (:ghuser:`jules-ch`)

pvlib/clearsky.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -960,8 +960,8 @@ def bird(zenith, airmass_relative, aod380, aod500, precipitable_water,
960960
Extraterrestrial radiation [W/m^2], defaults to 1364[W/m^2]
961961
asymmetry : numeric
962962
Asymmetry factor, defaults to 0.85
963-
albedo : numeric
964-
Albedo, defaults to 0.2
963+
albedo : numeric, default 0.2
964+
Ground surface albedo. [unitless]
965965
966966
Returns
967967
-------

pvlib/irradiance.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ def beam_component(surface_tilt, surface_azimuth, solar_zenith, solar_azimuth,
304304
def get_total_irradiance(surface_tilt, surface_azimuth,
305305
solar_zenith, solar_azimuth,
306306
dni, ghi, dhi, dni_extra=None, airmass=None,
307-
albedo=.25, surface_type=None,
307+
albedo=0.25, surface_type=None,
308308
model='isotropic',
309309
model_perez='allsitescomposite1990'):
310310
r"""
@@ -344,7 +344,7 @@ def get_total_irradiance(surface_tilt, surface_azimuth,
344344
airmass : None or numeric, default None
345345
Relative airmass (not adjusted for pressure). [unitless]
346346
albedo : numeric, default 0.25
347-
Surface albedo. [unitless]
347+
Ground surface albedo. [unitless]
348348
surface_type : None or str, default None
349349
Surface type. See :py:func:`~pvlib.irradiance.get_ground_diffuse` for
350350
the list of accepted values.
@@ -1872,7 +1872,7 @@ def gti_dirint(poa_global, aoi, solar_zenith, solar_azimuth, times,
18721872
applied.
18731873
18741874
albedo : numeric, default 0.25
1875-
Surface albedo
1875+
Ground surface albedo. [unitless]
18761876
18771877
model : String, default 'perez'
18781878
Irradiance model. See :py:func:`get_sky_diffuse` for allowed values.

pvlib/modelchain.py

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ class ModelChainResult:
268268
_per_array_fields = {'total_irrad', 'aoi', 'aoi_modifier',
269269
'spectral_modifier', 'cell_temperature',
270270
'effective_irradiance', 'dc', 'diode_params',
271-
'dc_ohmic_losses', 'weather'}
271+
'dc_ohmic_losses', 'weather', 'albedo'}
272272

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

369+
albedo: Optional[PerArray[pd.Series]] = None
370+
"""Series (or tuple of Series, one for each array) containing albedo.
371+
"""
372+
369373
def _result_type(self, value):
370374
"""Coerce `value` to the correct type according to
371375
``self._singleton_tuples``."""
@@ -1339,6 +1343,17 @@ def _prep_inputs_solar_pos(self, weather):
13391343
**kwargs)
13401344
return self
13411345

1346+
def _prep_inputs_albedo(self, weather):
1347+
"""
1348+
Get albedo from weather
1349+
"""
1350+
try:
1351+
self.results.albedo = _tuple_from_dfs(weather, 'albedo')
1352+
except KeyError:
1353+
self.results.albedo = tuple([
1354+
a.albedo for a in self.system.arrays])
1355+
return self
1356+
13421357
def _prep_inputs_airmass(self):
13431358
"""
13441359
Assign airmass
@@ -1471,11 +1486,17 @@ def prepare_inputs(self, weather):
14711486
14721487
Parameters
14731488
----------
1474-
weather : DataFrame, or tuple or list of DataFrame
1489+
weather : DataFrame, or tuple or list of DataFrames
14751490
Required column names include ``'dni'``, ``'ghi'``, ``'dhi'``.
1476-
Optional column names are ``'wind_speed'``, ``'temp_air'``; if not
1491+
Optional column names are ``'wind_speed'``, ``'temp_air'``,
1492+
``'albedo'``.
1493+
1494+
If optional columns ``'wind_speed'``, ``'temp_air'`` are not
14771495
provided, air temperature of 20 C and wind speed
1478-
of 0 m/s will be added to the DataFrame.
1496+
of 0 m/s will be added to the ``weather`` DataFrame.
1497+
1498+
If optional column ``'albedo'`` is provided, albedo values in the
1499+
ModelChain's PVSystem.arrays are ignored.
14791500
14801501
If `weather` is a tuple or list, it must be of the same length and
14811502
order as the Arrays of the ModelChain's PVSystem.
@@ -1494,7 +1515,7 @@ def prepare_inputs(self, weather):
14941515
Notes
14951516
-----
14961517
Assigns attributes to ``results``: ``times``, ``weather``,
1497-
``solar_position``, ``airmass``, ``total_irrad``, ``aoi``
1518+
``solar_position``, ``airmass``, ``total_irrad``, ``aoi``, ``albedo``.
14981519
14991520
See also
15001521
--------
@@ -1507,6 +1528,7 @@ def prepare_inputs(self, weather):
15071528

15081529
self._prep_inputs_solar_pos(weather)
15091530
self._prep_inputs_airmass()
1531+
self._prep_inputs_albedo(weather)
15101532

15111533
# PVSystem.get_irradiance and SingleAxisTracker.get_irradiance
15121534
# and PVSystem.get_aoi and SingleAxisTracker.get_aoi
@@ -1531,6 +1553,7 @@ def prepare_inputs(self, weather):
15311553
_tuple_from_dfs(self.results.weather, 'dni'),
15321554
_tuple_from_dfs(self.results.weather, 'ghi'),
15331555
_tuple_from_dfs(self.results.weather, 'dhi'),
1556+
albedo=self.results.albedo,
15341557
airmass=self.results.airmass['airmass_relative'],
15351558
model=self.transposition_model
15361559
)
@@ -1724,16 +1747,32 @@ def run_model(self, weather):
17241747
Parameters
17251748
----------
17261749
weather : DataFrame, or tuple or list of DataFrame
1727-
Irradiance column names must include ``'dni'``, ``'ghi'``, and
1728-
``'dhi'``. If optional columns ``'temp_air'`` and ``'wind_speed'``
1750+
Column names must include:
1751+
1752+
- ``'dni'``
1753+
- ``'ghi'``
1754+
- ``'dhi'``
1755+
1756+
Optional columns are:
1757+
1758+
- ``'temp_air'``
1759+
- ``'cell_temperature'``
1760+
- ``'module_temperature'``
1761+
- ``'wind_speed'``
1762+
- ``'albedo'``
1763+
1764+
If optional columns ``'temp_air'`` and ``'wind_speed'``
17291765
are not provided, air temperature of 20 C and wind speed of 0 m/s
17301766
are added to the DataFrame. If optional column
17311767
``'cell_temperature'`` is provided, these values are used instead
1732-
of `temperature_model`. If optional column `module_temperature`
1733-
is provided, `temperature_model` must be ``'sapm'``.
1768+
of `temperature_model`. If optional column ``'module_temperature'``
1769+
is provided, ``temperature_model`` must be ``'sapm'``.
17341770
1735-
If list or tuple, must be of the same length and order as the
1736-
Arrays of the ModelChain's PVSystem.
1771+
If optional column ``'albedo'`` is provided, ``'albedo'`` may not
1772+
be present on the ModelChain's PVSystem.Arrays.
1773+
1774+
If weather is a list or tuple, it must be of the same length and
1775+
order as the Arrays of the ModelChain's PVSystem.
17371776
17381777
Returns
17391778
-------

0 commit comments

Comments
 (0)