From 9486677f97fd48bc2701fee08ddc290b7ef469e1 Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Thu, 29 Dec 2022 12:57:47 -0500 Subject: [PATCH 01/12] migrate spectral modifiers to pvlib.spectrum --- .../effects_on_pv_system_output/spectrum.rst | 2 + docs/sphinx/source/whatsnew/v0.9.5.rst | 5 + pvlib/__init__.py | 4 +- pvlib/atmosphere.py | 177 +-------------- pvlib/pvsystem.py | 58 ++--- pvlib/spectrum/__init__.py | 9 +- pvlib/spectrum/mismatch.py | 214 ++++++++++++++++++ pvlib/tests/test_atmosphere.py | 68 +----- pvlib/tests/test_pvsystem.py | 28 +-- pvlib/tests/test_spectrum.py | 81 ++++++- 10 files changed, 346 insertions(+), 300 deletions(-) diff --git a/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst b/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst index b6fe7f4684..024d5a721e 100644 --- a/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst +++ b/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst @@ -10,3 +10,5 @@ Spectrum spectrum.get_example_spectral_response spectrum.get_am15g spectrum.calc_spectral_mismatch_field + spectrum.first_solar_spectral_correction + spectrum.sapm_spectral_correction diff --git a/docs/sphinx/source/whatsnew/v0.9.5.rst b/docs/sphinx/source/whatsnew/v0.9.5.rst index adf31d02f6..11400d8d69 100644 --- a/docs/sphinx/source/whatsnew/v0.9.5.rst +++ b/docs/sphinx/source/whatsnew/v0.9.5.rst @@ -12,6 +12,11 @@ the ``pvlib`` `conda channel`_. We recommend Deprecations ~~~~~~~~~~~~ +* Functions for calculating spectral modifiers have been moved to :py:mod:`pvlib.spectrum`: + ``pvlib.atmosphere.first_solar_spectral_correction`` is now + :py:func:`pvlib.spectrum.first_solar_spectral_correction` and + ``pvlib.pvsystem.sapm_spectral_loss`` is now + :py:func:`pvlib.spectrum.sapm_spectral_correction`. (:pull:`1628`) Enhancements diff --git a/pvlib/__init__.py b/pvlib/__init__.py index ff6b375017..dfd5f1dc2a 100644 --- a/pvlib/__init__.py +++ b/pvlib/__init__.py @@ -1,6 +1,9 @@ from pvlib.version import __version__ # noqa: F401 from pvlib import ( # noqa: F401 + # list spectrum first so it's available for atmosphere & pvsystem (GH 1628) + spectrum, + atmosphere, bifacial, clearsky, @@ -20,7 +23,6 @@ soiling, solarposition, spa, - spectrum, temperature, tools, tracking, diff --git a/pvlib/atmosphere.py b/pvlib/atmosphere.py index ff1ce8d4d5..890cc4fc22 100644 --- a/pvlib/atmosphere.py +++ b/pvlib/atmosphere.py @@ -3,11 +3,11 @@ absolute airmass and to determine pressure from altitude or vice versa. """ -from warnings import warn - import numpy as np import pandas as pd +import pvlib +from pvlib._deprecation import deprecated APPARENT_ZENITH_MODELS = ('simple', 'kasten1966', 'kastenyoung1989', 'gueymard1993', 'pickering2002') @@ -321,175 +321,10 @@ def gueymard94_pw(temp_air, relative_humidity): return pw -def first_solar_spectral_correction(pw, airmass_absolute, - module_type=None, coefficients=None, - min_pw=0.1, max_pw=8): - r""" - Spectral mismatch modifier based on precipitable water and absolute - (pressure-adjusted) airmass. - - Estimates a spectral mismatch modifier :math:`M` representing the effect on - module short circuit current of variation in the spectral - irradiance. :math:`M` is estimated from absolute (pressure currected) air - mass, :math:`AM_a`, and precipitable water, :math:`Pw`, using the following - function: - - .. math:: - - M = c_1 + c_2 AM_a + c_3 Pw + c_4 AM_a^{0.5} - + c_5 Pw^{0.5} + c_6 \frac{AM_a} {Pw^{0.5}} - - Default coefficients are determined for several cell types with - known quantum efficiency curves, by using the Simple Model of the - Atmospheric Radiative Transfer of Sunshine (SMARTS) [1]_. Using - SMARTS, spectrums are simulated with all combinations of AMa and - Pw where: - - * :math:`0.5 \textrm{cm} <= Pw <= 5 \textrm{cm}` - * :math:`1.0 <= AM_a <= 5.0` - * Spectral range is limited to that of CMP11 (280 nm to 2800 nm) - * spectrum simulated on a plane normal to the sun - * All other parameters fixed at G173 standard - - From these simulated spectra, M is calculated using the known - quantum efficiency curves. Multiple linear regression is then - applied to fit Eq. 1 to determine the coefficients for each module. - - Based on the PVLIB Matlab function ``pvl_FSspeccorr`` by Mitchell - Lee and Alex Panchula of First Solar, 2016 [2]_. - - Parameters - ---------- - pw : array-like - atmospheric precipitable water. [cm] - - airmass_absolute : array-like - absolute (pressure-adjusted) airmass. [unitless] - - min_pw : float, default 0.1 - minimum atmospheric precipitable water. Any pw value lower than min_pw - is set to min_pw to avoid model divergence. [cm] - - max_pw : float, default 8 - maximum atmospheric precipitable water. Any pw value higher than max_pw - is set to NaN to avoid model divergence. [cm] - - module_type : None or string, default None - a string specifying a cell type. Values of 'cdte', 'monosi', 'xsi', - 'multisi', and 'polysi' (can be lower or upper case). If provided, - module_type selects default coefficients for the following modules: - - * 'cdte' - First Solar Series 4-2 CdTe module. - * 'monosi', 'xsi' - First Solar TetraSun module. - * 'multisi', 'polysi' - anonymous multi-crystalline silicon module. - * 'cigs' - anonymous copper indium gallium selenide module. - * 'asi' - anonymous amorphous silicon module. - - The module used to calculate the spectral correction - coefficients corresponds to the Multi-crystalline silicon - Manufacturer 2 Model C from [3]_. The spectral response (SR) of CIGS - and a-Si modules used to derive coefficients can be found in [4]_ - - coefficients : None or array-like, default None - Allows for entry of user-defined spectral correction - coefficients. Coefficients must be of length 6. Derivation of - coefficients requires use of SMARTS and PV module quantum - efficiency curve. Useful for modeling PV module types which are - not included as defaults, or to fine tune the spectral - correction to a particular PV module. Note that the parameters for - modules with very similar quantum efficiency should be similar, - in most cases limiting the need for module specific coefficients. - - Returns - ------- - modifier: array-like - spectral mismatch factor (unitless) which is can be multiplied - with broadband irradiance reaching a module's cells to estimate - effective irradiance, i.e., the irradiance that is converted to - electrical current. - - References - ---------- - .. [1] Gueymard, Christian. SMARTS2: a simple model of the atmospheric - radiative transfer of sunshine: algorithms and performance - assessment. Cocoa, FL: Florida Solar Energy Center, 1995. - .. [2] Lee, Mitchell, and Panchula, Alex. "Spectral Correction for - Photovoltaic Module Performance Based on Air Mass and Precipitable - Water." IEEE Photovoltaic Specialists Conference, Portland, 2016 - .. [3] Marion, William F., et al. User's Manual for Data for Validating - Models for PV Module Performance. National Renewable Energy - Laboratory, 2014. http://www.nrel.gov/docs/fy14osti/61610.pdf - .. [4] Schweiger, M. and Hermann, W, Influence of Spectral Effects - on Energy Yield of Different PV Modules: Comparison of Pwat and - MMF Approach, TUV Rheinland Energy GmbH report 21237296.003, - January 2017 - """ - - # --- Screen Input Data --- - - # *** Pw *** - # Replace Pw Values below 0.1 cm with 0.1 cm to prevent model from - # diverging" - pw = np.atleast_1d(pw) - pw = pw.astype('float64') - if np.min(pw) < min_pw: - pw = np.maximum(pw, min_pw) - warn(f'Exceptionally low pw values replaced with {min_pw} cm to ' - 'prevent model divergence') - - # Warn user about Pw data that is exceptionally high - if np.max(pw) > max_pw: - pw[pw > max_pw] = np.nan - warn('Exceptionally high pw values replaced by np.nan: ' - 'check input data.') - - # *** AMa *** - # Replace Extremely High AM with AM 10 to prevent model divergence - # AM > 10 will only occur very close to sunset - if np.max(airmass_absolute) > 10: - airmass_absolute = np.minimum(airmass_absolute, 10) - - # Warn user about AMa data that is exceptionally low - if np.min(airmass_absolute) < 0.58: - warn('Exceptionally low air mass: ' + - 'model not intended for extra-terrestrial use') - # pvl_absoluteairmass(1,pvl_alt2pres(4340)) = 0.58 Elevation of - # Mina Pirquita, Argentian = 4340 m. Highest elevation city with - # population over 50,000. - - _coefficients = {} - _coefficients['cdte'] = ( - 0.86273, -0.038948, -0.012506, 0.098871, 0.084658, -0.0042948) - _coefficients['monosi'] = ( - 0.85914, -0.020880, -0.0058853, 0.12029, 0.026814, -0.0017810) - _coefficients['xsi'] = _coefficients['monosi'] - _coefficients['polysi'] = ( - 0.84090, -0.027539, -0.0079224, 0.13570, 0.038024, -0.0021218) - _coefficients['multisi'] = _coefficients['polysi'] - _coefficients['cigs'] = ( - 0.85252, -0.022314, -0.0047216, 0.13666, 0.013342, -0.0008945) - _coefficients['asi'] = ( - 1.12094, -0.047620, -0.0083627, -0.10443, 0.098382, -0.0033818) - - if module_type is not None and coefficients is None: - coefficients = _coefficients[module_type.lower()] - elif module_type is None and coefficients is not None: - pass - elif module_type is None and coefficients is None: - raise TypeError('No valid input provided, both module_type and ' + - 'coefficients are None') - else: - raise TypeError('Cannot resolve input, must supply only one of ' + - 'module_type and coefficients') - - # Evaluate Spectral Shift - coeff = coefficients - ama = airmass_absolute - modifier = ( - coeff[0] + coeff[1]*ama + coeff[2]*pw + coeff[3]*np.sqrt(ama) + - coeff[4]*np.sqrt(pw) + coeff[5]*ama/np.sqrt(pw)) - - return modifier +first_solar_spectral_correction = deprecated( + since='0.9.5', + alternative='pvlib.spectrum.first_solar_spectral_correction' +)(pvlib.spectrum.first_solar_spectral_correction) def bird_hulstrom80_aod_bb(aod380, aod500): diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 48371ca961..4bd0981e6a 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -19,7 +19,7 @@ from pvlib._deprecation import deprecated from pvlib import (atmosphere, iam, inverter, irradiance, - singlediode as _singlediode, temperature) + singlediode as _singlediode, spectrum, temperature) from pvlib.tools import _build_kwargs, _build_args @@ -672,8 +672,8 @@ def sapm_celltemp(self, poa_global, temp_air, wind_speed): @_unwrap_single_value def sapm_spectral_loss(self, airmass_absolute): """ - Use the :py:func:`sapm_spectral_loss` function, the input - parameters, and ``self.module_parameters`` to calculate F1. + Use the :py:func:`pvlib.spectrum.sapm_spectral_correction` function, + the input parameters, and ``self.module_parameters`` to calculate F1. Parameters ---------- @@ -686,7 +686,8 @@ def sapm_spectral_loss(self, airmass_absolute): The SAPM spectral loss coefficient. """ return tuple( - sapm_spectral_loss(airmass_absolute, array.module_parameters) + spectrum.sapm_spectral_correction(airmass_absolute, + array.module_parameters) for array in self.arrays ) @@ -884,7 +885,7 @@ def noct_sam_celltemp(self, poa_global, temp_air, wind_speed, @_unwrap_single_value def first_solar_spectral_loss(self, pw, airmass_absolute): """ - Use :py:func:`pvlib.atmosphere.first_solar_spectral_correction` to + Use :py:func:`pvlib.spectrum.first_solar_spectral_correction` to calculate the spectral loss modifier. The model coefficients are specific to the module's cell type, and are determined by searching for one of the following keys in self.module_parameters (in order): @@ -925,7 +926,7 @@ def _spectral_correction(array, pw): module_type = array._infer_cell_type() coefficients = None - return atmosphere.first_solar_spectral_correction( + return spectrum.first_solar_spectral_correction( pw, airmass_absolute, module_type, coefficients ) @@ -2598,43 +2599,10 @@ def sapm(effective_irradiance, temp_cell, module): return out -def sapm_spectral_loss(airmass_absolute, module): - """ - Calculates the SAPM spectral loss coefficient, F1. - - Parameters - ---------- - airmass_absolute : numeric - Absolute airmass - - module : dict-like - A dict, Series, or DataFrame defining the SAPM performance - parameters. See the :py:func:`sapm` notes section for more - details. - - Returns - ------- - F1 : numeric - The SAPM spectral loss coefficient. - - Notes - ----- - nan airmass values will result in 0 output. - """ - - am_coeff = [module['A4'], module['A3'], module['A2'], module['A1'], - module['A0']] - - spectral_loss = np.polyval(am_coeff, airmass_absolute) - - spectral_loss = np.where(np.isnan(spectral_loss), 0, spectral_loss) - - spectral_loss = np.maximum(0, spectral_loss) - - if isinstance(airmass_absolute, pd.Series): - spectral_loss = pd.Series(spectral_loss, airmass_absolute.index) - - return spectral_loss +sapm_spectral_loss = deprecated( + since='0.9.5', + alternative='pvlib.spectrum.sapm_spectral_correction' +)(spectrum.sapm_spectral_correction) def sapm_effective_irradiance(poa_direct, poa_diffuse, airmass_absolute, aoi, @@ -2694,11 +2662,11 @@ def sapm_effective_irradiance(poa_direct, poa_diffuse, airmass_absolute, aoi, See also -------- pvlib.iam.sapm - pvlib.pvsystem.sapm_spectral_loss + pvlib.spectrum.sapm_spectral_correction pvlib.pvsystem.sapm """ - F1 = sapm_spectral_loss(airmass_absolute, module) + F1 = spectrum.sapm_spectral_correction(airmass_absolute, module) F2 = iam.sapm(aoi, module) Ee = F1 * (poa_direct * F2 + module['FD'] * poa_diffuse) diff --git a/pvlib/spectrum/__init__.py b/pvlib/spectrum/__init__.py index b3d838acfe..d6d1ebcabe 100644 --- a/pvlib/spectrum/__init__.py +++ b/pvlib/spectrum/__init__.py @@ -1,3 +1,8 @@ from pvlib.spectrum.spectrl2 import spectrl2 # noqa: F401 -from pvlib.spectrum.mismatch import (get_example_spectral_response, get_am15g, - calc_spectral_mismatch_field) +from pvlib.spectrum.mismatch import ( + calc_spectral_mismatch_field, + first_solar_spectral_correction, + get_am15g, + get_example_spectral_response, + sapm_spectral_correction, +) # noqa: F401 diff --git a/pvlib/spectrum/mismatch.py b/pvlib/spectrum/mismatch.py index 5db4649ddd..d158fcc930 100644 --- a/pvlib/spectrum/mismatch.py +++ b/pvlib/spectrum/mismatch.py @@ -8,6 +8,10 @@ from scipy.interpolate import interp1d import os +from warnings import warn + +from pvlib._deprecation import deprecated + def get_example_spectral_response(wavelength=None): ''' @@ -235,3 +239,213 @@ def integrate(e): smm = pd.Series(smm, index=e_sun.index) return smm + + +def first_solar_spectral_correction(pw, airmass_absolute, + module_type=None, coefficients=None, + min_pw=0.1, max_pw=8): + r""" + Spectral mismatch modifier based on precipitable water and absolute + (pressure-adjusted) airmass. + + Estimates a spectral mismatch modifier :math:`M` representing the effect on + module short circuit current of variation in the spectral + irradiance. :math:`M` is estimated from absolute (pressure currected) air + mass, :math:`AM_a`, and precipitable water, :math:`Pw`, using the following + function: + + .. math:: + + M = c_1 + c_2 AM_a + c_3 Pw + c_4 AM_a^{0.5} + + c_5 Pw^{0.5} + c_6 \frac{AM_a} {Pw^{0.5}} + + Default coefficients are determined for several cell types with + known quantum efficiency curves, by using the Simple Model of the + Atmospheric Radiative Transfer of Sunshine (SMARTS) [1]_. Using + SMARTS, spectrums are simulated with all combinations of AMa and + Pw where: + + * :math:`0.5 \textrm{cm} <= Pw <= 5 \textrm{cm}` + * :math:`1.0 <= AM_a <= 5.0` + * Spectral range is limited to that of CMP11 (280 nm to 2800 nm) + * spectrum simulated on a plane normal to the sun + * All other parameters fixed at G173 standard + + From these simulated spectra, M is calculated using the known + quantum efficiency curves. Multiple linear regression is then + applied to fit Eq. 1 to determine the coefficients for each module. + + Based on the PVLIB Matlab function ``pvl_FSspeccorr`` by Mitchell + Lee and Alex Panchula of First Solar, 2016 [2]_. + + Parameters + ---------- + pw : array-like + atmospheric precipitable water. [cm] + + airmass_absolute : array-like + absolute (pressure-adjusted) airmass. [unitless] + + min_pw : float, default 0.1 + minimum atmospheric precipitable water. Any pw value lower than min_pw + is set to min_pw to avoid model divergence. [cm] + + max_pw : float, default 8 + maximum atmospheric precipitable water. Any pw value higher than max_pw + is set to NaN to avoid model divergence. [cm] + + module_type : None or string, default None + a string specifying a cell type. Values of 'cdte', 'monosi', 'xsi', + 'multisi', and 'polysi' (can be lower or upper case). If provided, + module_type selects default coefficients for the following modules: + + * 'cdte' - First Solar Series 4-2 CdTe module. + * 'monosi', 'xsi' - First Solar TetraSun module. + * 'multisi', 'polysi' - anonymous multi-crystalline silicon module. + * 'cigs' - anonymous copper indium gallium selenide module. + * 'asi' - anonymous amorphous silicon module. + + The module used to calculate the spectral correction + coefficients corresponds to the Multi-crystalline silicon + Manufacturer 2 Model C from [3]_. The spectral response (SR) of CIGS + and a-Si modules used to derive coefficients can be found in [4]_ + + coefficients : None or array-like, default None + Allows for entry of user-defined spectral correction + coefficients. Coefficients must be of length 6. Derivation of + coefficients requires use of SMARTS and PV module quantum + efficiency curve. Useful for modeling PV module types which are + not included as defaults, or to fine tune the spectral + correction to a particular PV module. Note that the parameters for + modules with very similar quantum efficiency should be similar, + in most cases limiting the need for module specific coefficients. + + Returns + ------- + modifier: array-like + spectral mismatch factor (unitless) which is can be multiplied + with broadband irradiance reaching a module's cells to estimate + effective irradiance, i.e., the irradiance that is converted to + electrical current. + + References + ---------- + .. [1] Gueymard, Christian. SMARTS2: a simple model of the atmospheric + radiative transfer of sunshine: algorithms and performance + assessment. Cocoa, FL: Florida Solar Energy Center, 1995. + .. [2] Lee, Mitchell, and Panchula, Alex. "Spectral Correction for + Photovoltaic Module Performance Based on Air Mass and Precipitable + Water." IEEE Photovoltaic Specialists Conference, Portland, 2016 + .. [3] Marion, William F., et al. User's Manual for Data for Validating + Models for PV Module Performance. National Renewable Energy + Laboratory, 2014. http://www.nrel.gov/docs/fy14osti/61610.pdf + .. [4] Schweiger, M. and Hermann, W, Influence of Spectral Effects + on Energy Yield of Different PV Modules: Comparison of Pwat and + MMF Approach, TUV Rheinland Energy GmbH report 21237296.003, + January 2017 + """ + + # --- Screen Input Data --- + + # *** Pw *** + # Replace Pw Values below 0.1 cm with 0.1 cm to prevent model from + # diverging" + pw = np.atleast_1d(pw) + pw = pw.astype('float64') + if np.min(pw) < min_pw: + pw = np.maximum(pw, min_pw) + warn(f'Exceptionally low pw values replaced with {min_pw} cm to ' + 'prevent model divergence') + + # Warn user about Pw data that is exceptionally high + if np.max(pw) > max_pw: + pw[pw > max_pw] = np.nan + warn('Exceptionally high pw values replaced by np.nan: ' + 'check input data.') + + # *** AMa *** + # Replace Extremely High AM with AM 10 to prevent model divergence + # AM > 10 will only occur very close to sunset + if np.max(airmass_absolute) > 10: + airmass_absolute = np.minimum(airmass_absolute, 10) + + # Warn user about AMa data that is exceptionally low + if np.min(airmass_absolute) < 0.58: + warn('Exceptionally low air mass: ' + + 'model not intended for extra-terrestrial use') + # pvl_absoluteairmass(1,pvl_alt2pres(4340)) = 0.58 Elevation of + # Mina Pirquita, Argentian = 4340 m. Highest elevation city with + # population over 50,000. + + _coefficients = {} + _coefficients['cdte'] = ( + 0.86273, -0.038948, -0.012506, 0.098871, 0.084658, -0.0042948) + _coefficients['monosi'] = ( + 0.85914, -0.020880, -0.0058853, 0.12029, 0.026814, -0.0017810) + _coefficients['xsi'] = _coefficients['monosi'] + _coefficients['polysi'] = ( + 0.84090, -0.027539, -0.0079224, 0.13570, 0.038024, -0.0021218) + _coefficients['multisi'] = _coefficients['polysi'] + _coefficients['cigs'] = ( + 0.85252, -0.022314, -0.0047216, 0.13666, 0.013342, -0.0008945) + _coefficients['asi'] = ( + 1.12094, -0.047620, -0.0083627, -0.10443, 0.098382, -0.0033818) + + if module_type is not None and coefficients is None: + coefficients = _coefficients[module_type.lower()] + elif module_type is None and coefficients is not None: + pass + elif module_type is None and coefficients is None: + raise TypeError('No valid input provided, both module_type and ' + + 'coefficients are None') + else: + raise TypeError('Cannot resolve input, must supply only one of ' + + 'module_type and coefficients') + + # Evaluate Spectral Shift + coeff = coefficients + ama = airmass_absolute + modifier = ( + coeff[0] + coeff[1]*ama + coeff[2]*pw + coeff[3]*np.sqrt(ama) + + coeff[4]*np.sqrt(pw) + coeff[5]*ama/np.sqrt(pw)) + + return modifier + + +def sapm_spectral_correction(airmass_absolute, module): + """ + Calculates the SAPM spectral loss coefficient, F1. + + Parameters + ---------- + airmass_absolute : numeric + Absolute airmass + + module : dict-like + A dict, Series, or DataFrame defining the SAPM performance + parameters. See the :py:func:`sapm` notes section for more + details. + + Returns + ------- + F1 : numeric + The SAPM spectral loss coefficient. + + Notes + ----- + nan airmass values will result in 0 output. + """ + + am_coeff = [module['A4'], module['A3'], module['A2'], module['A1'], + module['A0']] + + spectral_loss = np.polyval(am_coeff, airmass_absolute) + + spectral_loss = np.where(np.isnan(spectral_loss), 0, spectral_loss) + + spectral_loss = np.maximum(0, spectral_loss) + + if isinstance(airmass_absolute, pd.Series): + spectral_loss = pd.Series(spectral_loss, airmass_absolute.index) + + return spectral_loss diff --git a/pvlib/tests/test_atmosphere.py b/pvlib/tests/test_atmosphere.py index 69bb3215dc..29e101975f 100644 --- a/pvlib/tests/test_atmosphere.py +++ b/pvlib/tests/test_atmosphere.py @@ -9,6 +9,8 @@ from pvlib import atmosphere +from pvlib._deprecation import pvlibDeprecationWarning + def test_pres2alt(): out = atmosphere.pres2alt(np.array([10000, 90000, 101325])) @@ -85,68 +87,10 @@ def test_gueymard94_pw(): assert_allclose(pws, expected, atol=0.01) -@pytest.mark.parametrize("module_type,expect", [ - ('cdte', np.array( - [[ 0.9905102 , 0.9764032 , 0.93975028], - [ 1.02928735, 1.01881074, 0.98578821], - [ 1.04750335, 1.03814456, 1.00623986]])), - ('monosi', np.array( - [[ 0.9776977 , 1.02043409, 1.03574032], - [ 0.98630905, 1.03055092, 1.04736262], - [ 0.98828494, 1.03299036, 1.05026561]])), - ('polysi', np.array( - [[ 0.9770408 , 1.01705849, 1.02613202], - [ 0.98992828, 1.03173953, 1.04260662], - [ 0.99352435, 1.03588785, 1.04730718]])), - ('cigs', np.array( - [[ 0.9745919 , 1.02821696, 1.05067895], - [ 0.97529378, 1.02967497, 1.05289307], - [ 0.97269159, 1.02730558, 1.05075651]])), - ('asi', np.array( - [[ 1.0555275 , 0.87707583, 0.72243772], - [ 1.11225204, 0.93665901, 0.78487953], - [ 1.14555295, 0.97084011, 0.81994083]])) -]) -def test_first_solar_spectral_correction(module_type, expect): - ams = np.array([1, 3, 5]) - pws = np.array([1, 3, 5]) - ams, pws = np.meshgrid(ams, pws) - out = atmosphere.first_solar_spectral_correction(pws, ams, module_type) - assert_allclose(out, expect, atol=0.001) - - -def test_first_solar_spectral_correction_supplied(): - # use the cdte coeffs - coeffs = (0.87102, -0.040543, -0.00929202, 0.10052, 0.073062, -0.0034187) - out = atmosphere.first_solar_spectral_correction(1, 1, coefficients=coeffs) - expected = 0.99134828 - assert_allclose(out, expected, atol=1e-3) - - -def test_first_solar_spectral_correction_ambiguous(): - with pytest.raises(TypeError): - atmosphere.first_solar_spectral_correction(1, 1) - - -def test_first_solar_spectral_correction_range(): - with pytest.warns(UserWarning, match='Exceptionally high pw values'): - out = atmosphere.first_solar_spectral_correction(np.array([.1, 3, 10]), - np.array([1, 3, 5]), - module_type='monosi') - expected = np.array([0.96080878, 1.03055092, nan]) - assert_allclose(out, expected, atol=1e-3) - with pytest.warns(UserWarning, match='Exceptionally high pw values'): - out = atmosphere.first_solar_spectral_correction(6, 1.5, max_pw=5, - module_type='monosi') - with pytest.warns(UserWarning, match='Exceptionally low pw values'): - out = atmosphere.first_solar_spectral_correction(np.array([0, 3, 8]), - np.array([1, 3, 5]), - module_type='monosi') - expected = np.array([0.96080878, 1.03055092, 1.04932727]) - assert_allclose(out, expected, atol=1e-3) - with pytest.warns(UserWarning, match='Exceptionally low pw values'): - out = atmosphere.first_solar_spectral_correction(0.2, 1.5, min_pw=1, - module_type='monosi') +def test_first_solar_spectral_correction_deprecated(): + with pytest.warns(pvlibDeprecationWarning, + match='Use pvlib.spectrum.first_solar_spectral'): + atmosphere.first_solar_spectral_correction(1, 1, 'cdte') def test_kasten96_lt(): diff --git a/pvlib/tests/test_pvsystem.py b/pvlib/tests/test_pvsystem.py index 7fa013d0dc..b2ee0f2ec7 100644 --- a/pvlib/tests/test_pvsystem.py +++ b/pvlib/tests/test_pvsystem.py @@ -14,6 +14,7 @@ from pvlib import atmosphere from pvlib import iam as _iam from pvlib import irradiance +from pvlib import spectrum from pvlib.location import Location from pvlib.pvsystem import FixedMount from pvlib import temperature @@ -253,28 +254,19 @@ def test_PVSystem_multi_array_sapm(sapm_module_params): system.sapm(500, temp_cell) -@pytest.mark.parametrize('airmass,expected', [ - (1.5, 1.00028714375), - (np.array([[10, np.nan]]), np.array([[0.999535, 0]])), - (pd.Series([5]), pd.Series([1.0387675])) -]) -def test_sapm_spectral_loss(sapm_module_params, airmass, expected): - - out = pvsystem.sapm_spectral_loss(airmass, sapm_module_params) - - if isinstance(airmass, pd.Series): - assert_series_equal(out, expected, check_less_precise=4) - else: - assert_allclose(out, expected, atol=1e-4) +def test_sapm_spectral_loss_deprecated(sapm_module_params): + with pytest.warns(pvlibDeprecationWarning, + match='Use pvlib.spectrum.sapm_spectral_correction'): + pvsystem.sapm_spectral_loss(1, sapm_module_params) def test_PVSystem_sapm_spectral_loss(sapm_module_params, mocker): - mocker.spy(pvsystem, 'sapm_spectral_loss') + mocker.spy(spectrum, 'sapm_spectral_correction') system = pvsystem.PVSystem(module_parameters=sapm_module_params) airmass = 2 out = system.sapm_spectral_loss(airmass) - pvsystem.sapm_spectral_loss.assert_called_once_with(airmass, - sapm_module_params) + spectrum.sapm_spectral_correction.assert_called_once_with( + airmass, sapm_module_params) assert_allclose(out, 1, atol=0.5) @@ -302,12 +294,12 @@ def test_PVSystem_multi_array_sapm_spectral_loss(sapm_module_params): ]) def test_PVSystem_first_solar_spectral_loss(module_parameters, module_type, coefficients, mocker): - mocker.spy(atmosphere, 'first_solar_spectral_correction') + mocker.spy(spectrum, 'first_solar_spectral_correction') system = pvsystem.PVSystem(module_parameters=module_parameters) pw = 3 airmass_absolute = 3 out = system.first_solar_spectral_loss(pw, airmass_absolute) - atmosphere.first_solar_spectral_correction.assert_called_once_with( + spectrum.first_solar_spectral_correction.assert_called_once_with( pw, airmass_absolute, module_type, coefficients) assert_allclose(out, 1, atol=0.5) diff --git a/pvlib/tests/test_spectrum.py b/pvlib/tests/test_spectrum.py index 80b53d2af3..aceb492f95 100644 --- a/pvlib/tests/test_spectrum.py +++ b/pvlib/tests/test_spectrum.py @@ -4,7 +4,7 @@ import numpy as np from pvlib import spectrum -from .conftest import DATA_DIR +from .conftest import DATA_DIR, assert_series_equal SPECTRL2_TEST_DATA = DATA_DIR / 'spectrl2_example_spectra.csv' @@ -171,3 +171,82 @@ def test_calc_spectral_mismatch_field(spectrl2_data): mm = spectrum.calc_spectral_mismatch_field(sr, e_sun=e_sun) assert mm.index is e_sun.index assert_allclose(mm, expected, rtol=1e-6) + + +@pytest.mark.parametrize("module_type,expect", [ + ('cdte', np.array( + [[ 0.99051020, 0.97640320, 0.93975028], + [ 1.02928735, 1.01881074, 0.98578821], + [ 1.04750335, 1.03814456, 1.00623986]])), + ('monosi', np.array( + [[ 0.97769770, 1.02043409, 1.03574032], + [ 0.98630905, 1.03055092, 1.04736262], + [ 0.98828494, 1.03299036, 1.05026561]])), + ('polysi', np.array( + [[ 0.97704080, 1.01705849, 1.02613202], + [ 0.98992828, 1.03173953, 1.04260662], + [ 0.99352435, 1.03588785, 1.04730718]])), + ('cigs', np.array( + [[ 0.97459190, 1.02821696, 1.05067895], + [ 0.97529378, 1.02967497, 1.05289307], + [ 0.97269159, 1.02730558, 1.05075651]])), + ('asi', np.array( + [[ 1.05552750, 0.87707583, 0.72243772], + [ 1.11225204, 0.93665901, 0.78487953], + [ 1.14555295, 0.97084011, 0.81994083]])) +]) +def test_first_solar_spectral_correction(module_type, expect): + ams = np.array([1, 3, 5]) + pws = np.array([1, 3, 5]) + ams, pws = np.meshgrid(ams, pws) + out = spectrum.first_solar_spectral_correction(pws, ams, module_type) + assert_allclose(out, expect, atol=0.001) + + +def test_first_solar_spectral_correction_supplied(): + # use the cdte coeffs + coeffs = (0.87102, -0.040543, -0.00929202, 0.10052, 0.073062, -0.0034187) + out = spectrum.first_solar_spectral_correction(1, 1, coefficients=coeffs) + expected = 0.99134828 + assert_allclose(out, expected, atol=1e-3) + + +def test_first_solar_spectral_correction_ambiguous(): + with pytest.raises(TypeError): + spectrum.first_solar_spectral_correction(1, 1) + + +def test_first_solar_spectral_correction_range(): + with pytest.warns(UserWarning, match='Exceptionally high pw values'): + out = spectrum.first_solar_spectral_correction(np.array([.1, 3, 10]), + np.array([1, 3, 5]), + module_type='monosi') + expected = np.array([0.96080878, 1.03055092, np.nan]) + assert_allclose(out, expected, atol=1e-3) + with pytest.warns(UserWarning, match='Exceptionally high pw values'): + out = spectrum.first_solar_spectral_correction(6, 1.5, max_pw=5, + module_type='monosi') + with pytest.warns(UserWarning, match='Exceptionally low pw values'): + out = spectrum.first_solar_spectral_correction(np.array([0, 3, 8]), + np.array([1, 3, 5]), + module_type='monosi') + expected = np.array([0.96080878, 1.03055092, 1.04932727]) + assert_allclose(out, expected, atol=1e-3) + with pytest.warns(UserWarning, match='Exceptionally low pw values'): + out = spectrum.first_solar_spectral_correction(0.2, 1.5, min_pw=1, + module_type='monosi') + + +@pytest.mark.parametrize('airmass,expected', [ + (1.5, 1.00028714375), + (np.array([[10, np.nan]]), np.array([[0.999535, 0]])), + (pd.Series([5]), pd.Series([1.0387675])) +]) +def test_sapm_spectral_loss(sapm_module_params, airmass, expected): + + out = spectrum.sapm_spectral_correction(airmass, sapm_module_params) + + if isinstance(airmass, pd.Series): + assert_series_equal(out, expected, check_less_precise=4) + else: + assert_allclose(out, expected, atol=1e-4) From 91ada5444ceeae5dab76324337259935437d085d Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Thu, 29 Dec 2022 13:05:31 -0500 Subject: [PATCH 02/12] stickler --- pvlib/spectrum/__init__.py | 4 ++-- pvlib/spectrum/mismatch.py | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/pvlib/spectrum/__init__.py b/pvlib/spectrum/__init__.py index d6d1ebcabe..0e9e125e95 100644 --- a/pvlib/spectrum/__init__.py +++ b/pvlib/spectrum/__init__.py @@ -1,8 +1,8 @@ from pvlib.spectrum.spectrl2 import spectrl2 # noqa: F401 -from pvlib.spectrum.mismatch import ( +from pvlib.spectrum.mismatch import ( # noqa: F401 calc_spectral_mismatch_field, first_solar_spectral_correction, get_am15g, get_example_spectral_response, sapm_spectral_correction, -) # noqa: F401 +) diff --git a/pvlib/spectrum/mismatch.py b/pvlib/spectrum/mismatch.py index d158fcc930..956a64adb6 100644 --- a/pvlib/spectrum/mismatch.py +++ b/pvlib/spectrum/mismatch.py @@ -10,8 +10,6 @@ from warnings import warn -from pvlib._deprecation import deprecated - def get_example_spectral_response(wavelength=None): ''' From 6a69804431fee37313a6121d20c11993048f65ed Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Thu, 29 Dec 2022 15:01:06 -0500 Subject: [PATCH 03/12] get fslr correction to 100% coverage --- pvlib/tests/test_spectrum.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pvlib/tests/test_spectrum.py b/pvlib/tests/test_spectrum.py index aceb492f95..0f2a7cd75d 100644 --- a/pvlib/tests/test_spectrum.py +++ b/pvlib/tests/test_spectrum.py @@ -216,6 +216,23 @@ def test_first_solar_spectral_correction_ambiguous(): spectrum.first_solar_spectral_correction(1, 1) +def test_first_solar_spectral_correction_ambiguous_both(): + # use the cdte coeffs + coeffs = (0.87102, -0.040543, -0.00929202, 0.10052, 0.073062, -0.0034187) + with pytest.raises(TypeError): + spectrum.first_solar_spectral_correction(1, 1, 'cdte', + coefficients=coeffs) + +def test_first_solar_spectral_correction_large_airmass(): + # test that airmass > 10 is treated same as airmass==10 + m_eq10 = spectrum.first_solar_spectral_correction(1, 10, 'monosi') + m_gt10 = spectrum.first_solar_spectral_correction(1, 15, 'monosi') + assert_allclose(m_eq10, m_gt10) + +def test_first_solar_spectral_correction_low_airmass(): + with pytest.warns(UserWarning, match='Exceptionally low air mass'): + _ = spectrum.first_solar_spectral_correction(1, 0.1, 'monosi') + def test_first_solar_spectral_correction_range(): with pytest.warns(UserWarning, match='Exceptionally high pw values'): out = spectrum.first_solar_spectral_correction(np.array([.1, 3, 10]), From 6d4aa00d587a4c7e52378f7681b48e911d19829d Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Thu, 29 Dec 2022 15:02:07 -0500 Subject: [PATCH 04/12] stickler! --- pvlib/tests/test_spectrum.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pvlib/tests/test_spectrum.py b/pvlib/tests/test_spectrum.py index 0f2a7cd75d..ddf0dc8add 100644 --- a/pvlib/tests/test_spectrum.py +++ b/pvlib/tests/test_spectrum.py @@ -223,16 +223,19 @@ def test_first_solar_spectral_correction_ambiguous_both(): spectrum.first_solar_spectral_correction(1, 1, 'cdte', coefficients=coeffs) + def test_first_solar_spectral_correction_large_airmass(): # test that airmass > 10 is treated same as airmass==10 m_eq10 = spectrum.first_solar_spectral_correction(1, 10, 'monosi') m_gt10 = spectrum.first_solar_spectral_correction(1, 15, 'monosi') assert_allclose(m_eq10, m_gt10) + def test_first_solar_spectral_correction_low_airmass(): with pytest.warns(UserWarning, match='Exceptionally low air mass'): _ = spectrum.first_solar_spectral_correction(1, 0.1, 'monosi') + def test_first_solar_spectral_correction_range(): with pytest.warns(UserWarning, match='Exceptionally high pw values'): out = spectrum.first_solar_spectral_correction(np.array([.1, 3, 10]), From f90e0b99e20f68a05f92023d539a71384aa89af2 Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Mon, 20 Feb 2023 16:03:41 -0500 Subject: [PATCH 05/12] change new names to sapm and first_solar in coordination with #1658, drop "spectral_correction" from the new function names --- .../effects_on_pv_system_output/spectrum.rst | 4 +- docs/sphinx/source/whatsnew/v0.9.5.rst | 4 +- pvlib/atmosphere.py | 4 +- pvlib/pvsystem.py | 20 ++++----- pvlib/spectrum/__init__.py | 4 +- pvlib/spectrum/mismatch.py | 7 ++-- pvlib/tests/test_atmosphere.py | 2 +- pvlib/tests/test_spectrum.py | 41 +++++++++---------- 8 files changed, 41 insertions(+), 45 deletions(-) diff --git a/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst b/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst index 024d5a721e..a47ca40dfe 100644 --- a/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst +++ b/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst @@ -10,5 +10,5 @@ Spectrum spectrum.get_example_spectral_response spectrum.get_am15g spectrum.calc_spectral_mismatch_field - spectrum.first_solar_spectral_correction - spectrum.sapm_spectral_correction + spectrum.first_solar + spectrum.sapm diff --git a/docs/sphinx/source/whatsnew/v0.9.5.rst b/docs/sphinx/source/whatsnew/v0.9.5.rst index 11400d8d69..c3c9f324e1 100644 --- a/docs/sphinx/source/whatsnew/v0.9.5.rst +++ b/docs/sphinx/source/whatsnew/v0.9.5.rst @@ -14,9 +14,9 @@ Deprecations ~~~~~~~~~~~~ * Functions for calculating spectral modifiers have been moved to :py:mod:`pvlib.spectrum`: ``pvlib.atmosphere.first_solar_spectral_correction`` is now - :py:func:`pvlib.spectrum.first_solar_spectral_correction` and + :py:func:`pvlib.spectrum.first_solar` and ``pvlib.pvsystem.sapm_spectral_loss`` is now - :py:func:`pvlib.spectrum.sapm_spectral_correction`. (:pull:`1628`) + :py:func:`pvlib.spectrum.sapm`. (:pull:`1628`) Enhancements diff --git a/pvlib/atmosphere.py b/pvlib/atmosphere.py index 890cc4fc22..b6e3665d1b 100644 --- a/pvlib/atmosphere.py +++ b/pvlib/atmosphere.py @@ -323,8 +323,8 @@ def gueymard94_pw(temp_air, relative_humidity): first_solar_spectral_correction = deprecated( since='0.9.5', - alternative='pvlib.spectrum.first_solar_spectral_correction' -)(pvlib.spectrum.first_solar_spectral_correction) + alternative='pvlib.spectrum.first_solar' +)(pvlib.spectrum.first_solar) def bird_hulstrom80_aod_bb(aod380, aod500): diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 4bd0981e6a..3b57cf6b38 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -672,7 +672,7 @@ def sapm_celltemp(self, poa_global, temp_air, wind_speed): @_unwrap_single_value def sapm_spectral_loss(self, airmass_absolute): """ - Use the :py:func:`pvlib.spectrum.sapm_spectral_correction` function, + Use the :py:func:`pvlib.spectrum.sapm` function, the input parameters, and ``self.module_parameters`` to calculate F1. Parameters @@ -686,8 +686,7 @@ def sapm_spectral_loss(self, airmass_absolute): The SAPM spectral loss coefficient. """ return tuple( - spectrum.sapm_spectral_correction(airmass_absolute, - array.module_parameters) + spectrum.sapm(airmass_absolute, array.module_parameters) for array in self.arrays ) @@ -885,7 +884,7 @@ def noct_sam_celltemp(self, poa_global, temp_air, wind_speed, @_unwrap_single_value def first_solar_spectral_loss(self, pw, airmass_absolute): """ - Use :py:func:`pvlib.spectrum.first_solar_spectral_correction` to + Use :py:func:`pvlib.spectrum.first_solar` to calculate the spectral loss modifier. The model coefficients are specific to the module's cell type, and are determined by searching for one of the following keys in self.module_parameters (in order): @@ -926,9 +925,8 @@ def _spectral_correction(array, pw): module_type = array._infer_cell_type() coefficients = None - return spectrum.first_solar_spectral_correction( - pw, airmass_absolute, - module_type, coefficients + return spectrum.first_solar( + pw, airmass_absolute, module_type, coefficients ) return tuple( itertools.starmap(_spectral_correction, zip(self.arrays, pw)) @@ -2601,8 +2599,8 @@ def sapm(effective_irradiance, temp_cell, module): sapm_spectral_loss = deprecated( since='0.9.5', - alternative='pvlib.spectrum.sapm_spectral_correction' -)(spectrum.sapm_spectral_correction) + alternative='pvlib.spectrum.sapm' +)(spectrum.sapm) def sapm_effective_irradiance(poa_direct, poa_diffuse, airmass_absolute, aoi, @@ -2662,11 +2660,11 @@ def sapm_effective_irradiance(poa_direct, poa_diffuse, airmass_absolute, aoi, See also -------- pvlib.iam.sapm - pvlib.spectrum.sapm_spectral_correction + pvlib.spectrum.sapm pvlib.pvsystem.sapm """ - F1 = spectrum.sapm_spectral_correction(airmass_absolute, module) + F1 = spectrum.sapm(airmass_absolute, module) F2 = iam.sapm(aoi, module) Ee = F1 * (poa_direct * F2 + module['FD'] * poa_diffuse) diff --git a/pvlib/spectrum/__init__.py b/pvlib/spectrum/__init__.py index 0e9e125e95..7dadb40fbd 100644 --- a/pvlib/spectrum/__init__.py +++ b/pvlib/spectrum/__init__.py @@ -1,8 +1,8 @@ from pvlib.spectrum.spectrl2 import spectrl2 # noqa: F401 from pvlib.spectrum.mismatch import ( # noqa: F401 calc_spectral_mismatch_field, - first_solar_spectral_correction, + first_solar, get_am15g, get_example_spectral_response, - sapm_spectral_correction, + sapm, ) diff --git a/pvlib/spectrum/mismatch.py b/pvlib/spectrum/mismatch.py index 956a64adb6..4b7593bce4 100644 --- a/pvlib/spectrum/mismatch.py +++ b/pvlib/spectrum/mismatch.py @@ -239,9 +239,8 @@ def integrate(e): return smm -def first_solar_spectral_correction(pw, airmass_absolute, - module_type=None, coefficients=None, - min_pw=0.1, max_pw=8): +def first_solar(pw, airmass_absolute, module_type=None, coefficients=None, + min_pw=0.1, max_pw=8): r""" Spectral mismatch modifier based on precipitable water and absolute (pressure-adjusted) airmass. @@ -410,7 +409,7 @@ def first_solar_spectral_correction(pw, airmass_absolute, return modifier -def sapm_spectral_correction(airmass_absolute, module): +def sapm(airmass_absolute, module): """ Calculates the SAPM spectral loss coefficient, F1. diff --git a/pvlib/tests/test_atmosphere.py b/pvlib/tests/test_atmosphere.py index 29e101975f..f944a5f4c3 100644 --- a/pvlib/tests/test_atmosphere.py +++ b/pvlib/tests/test_atmosphere.py @@ -89,7 +89,7 @@ def test_gueymard94_pw(): def test_first_solar_spectral_correction_deprecated(): with pytest.warns(pvlibDeprecationWarning, - match='Use pvlib.spectrum.first_solar_spectral'): + match='Use pvlib.spectrum.first_solar'): atmosphere.first_solar_spectral_correction(1, 1, 'cdte') diff --git a/pvlib/tests/test_spectrum.py b/pvlib/tests/test_spectrum.py index ddf0dc8add..69e27e225d 100644 --- a/pvlib/tests/test_spectrum.py +++ b/pvlib/tests/test_spectrum.py @@ -195,65 +195,64 @@ def test_calc_spectral_mismatch_field(spectrl2_data): [ 1.11225204, 0.93665901, 0.78487953], [ 1.14555295, 0.97084011, 0.81994083]])) ]) -def test_first_solar_spectral_correction(module_type, expect): +def test_first_solar(module_type, expect): ams = np.array([1, 3, 5]) pws = np.array([1, 3, 5]) ams, pws = np.meshgrid(ams, pws) - out = spectrum.first_solar_spectral_correction(pws, ams, module_type) + out = spectrum.first_solar(pws, ams, module_type) assert_allclose(out, expect, atol=0.001) -def test_first_solar_spectral_correction_supplied(): +def test_first_solar_supplied(): # use the cdte coeffs coeffs = (0.87102, -0.040543, -0.00929202, 0.10052, 0.073062, -0.0034187) - out = spectrum.first_solar_spectral_correction(1, 1, coefficients=coeffs) + out = spectrum.first_solar(1, 1, coefficients=coeffs) expected = 0.99134828 assert_allclose(out, expected, atol=1e-3) -def test_first_solar_spectral_correction_ambiguous(): +def test_first_solar_ambiguous(): with pytest.raises(TypeError): - spectrum.first_solar_spectral_correction(1, 1) + spectrum.first_solar(1, 1) -def test_first_solar_spectral_correction_ambiguous_both(): +def test_first_solar_ambiguous_both(): # use the cdte coeffs coeffs = (0.87102, -0.040543, -0.00929202, 0.10052, 0.073062, -0.0034187) with pytest.raises(TypeError): - spectrum.first_solar_spectral_correction(1, 1, 'cdte', - coefficients=coeffs) + spectrum.first_solar(1, 1, 'cdte', coefficients=coeffs) -def test_first_solar_spectral_correction_large_airmass(): +def test_first_solar_large_airmass(): # test that airmass > 10 is treated same as airmass==10 - m_eq10 = spectrum.first_solar_spectral_correction(1, 10, 'monosi') - m_gt10 = spectrum.first_solar_spectral_correction(1, 15, 'monosi') + m_eq10 = spectrum.first_solar(1, 10, 'monosi') + m_gt10 = spectrum.first_solar(1, 15, 'monosi') assert_allclose(m_eq10, m_gt10) -def test_first_solar_spectral_correction_low_airmass(): +def test_first_solar_low_airmass(): with pytest.warns(UserWarning, match='Exceptionally low air mass'): - _ = spectrum.first_solar_spectral_correction(1, 0.1, 'monosi') + _ = spectrum.first_solar(1, 0.1, 'monosi') -def test_first_solar_spectral_correction_range(): +def test_first_solar_range(): with pytest.warns(UserWarning, match='Exceptionally high pw values'): - out = spectrum.first_solar_spectral_correction(np.array([.1, 3, 10]), + out = spectrum.first_solar(np.array([.1, 3, 10]), np.array([1, 3, 5]), module_type='monosi') expected = np.array([0.96080878, 1.03055092, np.nan]) assert_allclose(out, expected, atol=1e-3) with pytest.warns(UserWarning, match='Exceptionally high pw values'): - out = spectrum.first_solar_spectral_correction(6, 1.5, max_pw=5, + out = spectrum.first_solar(6, 1.5, max_pw=5, module_type='monosi') with pytest.warns(UserWarning, match='Exceptionally low pw values'): - out = spectrum.first_solar_spectral_correction(np.array([0, 3, 8]), + out = spectrum.first_solar(np.array([0, 3, 8]), np.array([1, 3, 5]), module_type='monosi') expected = np.array([0.96080878, 1.03055092, 1.04932727]) assert_allclose(out, expected, atol=1e-3) with pytest.warns(UserWarning, match='Exceptionally low pw values'): - out = spectrum.first_solar_spectral_correction(0.2, 1.5, min_pw=1, + out = spectrum.first_solar(0.2, 1.5, min_pw=1, module_type='monosi') @@ -262,9 +261,9 @@ def test_first_solar_spectral_correction_range(): (np.array([[10, np.nan]]), np.array([[0.999535, 0]])), (pd.Series([5]), pd.Series([1.0387675])) ]) -def test_sapm_spectral_loss(sapm_module_params, airmass, expected): +def test_sapm(sapm_module_params, airmass, expected): - out = spectrum.sapm_spectral_correction(airmass, sapm_module_params) + out = spectrum.sapm(airmass, sapm_module_params) if isinstance(airmass, pd.Series): assert_series_equal(out, expected, check_less_precise=4) From 2f789d752e8d9db32b66ca5edb5aa99322bba98c Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Mon, 20 Feb 2023 16:06:33 -0500 Subject: [PATCH 06/12] improve whatsnew --- docs/sphinx/source/whatsnew/v0.9.5.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/sphinx/source/whatsnew/v0.9.5.rst b/docs/sphinx/source/whatsnew/v0.9.5.rst index c3c9f324e1..a14e54f79b 100644 --- a/docs/sphinx/source/whatsnew/v0.9.5.rst +++ b/docs/sphinx/source/whatsnew/v0.9.5.rst @@ -13,10 +13,10 @@ the ``pvlib`` `conda channel`_. We recommend Deprecations ~~~~~~~~~~~~ * Functions for calculating spectral modifiers have been moved to :py:mod:`pvlib.spectrum`: - ``pvlib.atmosphere.first_solar_spectral_correction`` is now - :py:func:`pvlib.spectrum.first_solar` and - ``pvlib.pvsystem.sapm_spectral_loss`` is now - :py:func:`pvlib.spectrum.sapm`. (:pull:`1628`) + :py:func:`pvlib.atmosphere.first_solar_spectral_correction` is deprecated and + replaced by :py:func:`~pvlib.spectrum.first_solar`, and + :py:func`pvlib.pvsystem.sapm_spectral_loss` is deprecated and replaced by + :py:func:`~pvlib.spectrum.sapm`. (:pull:`1628`) Enhancements From cf98dabbefb3b23deedfb7ad197cb362bde9236d Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Mon, 20 Feb 2023 16:18:06 -0500 Subject: [PATCH 07/12] more renaming --- pvlib/tests/test_pvsystem.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/pvlib/tests/test_pvsystem.py b/pvlib/tests/test_pvsystem.py index b2ee0f2ec7..9645321fce 100644 --- a/pvlib/tests/test_pvsystem.py +++ b/pvlib/tests/test_pvsystem.py @@ -256,17 +256,16 @@ def test_PVSystem_multi_array_sapm(sapm_module_params): def test_sapm_spectral_loss_deprecated(sapm_module_params): with pytest.warns(pvlibDeprecationWarning, - match='Use pvlib.spectrum.sapm_spectral_correction'): + match='Use pvlib.spectrum.sapm'): pvsystem.sapm_spectral_loss(1, sapm_module_params) def test_PVSystem_sapm_spectral_loss(sapm_module_params, mocker): - mocker.spy(spectrum, 'sapm_spectral_correction') + mocker.spy(spectrum, 'sapm') system = pvsystem.PVSystem(module_parameters=sapm_module_params) airmass = 2 out = system.sapm_spectral_loss(airmass) - spectrum.sapm_spectral_correction.assert_called_once_with( - airmass, sapm_module_params) + spectrum.sapm.assert_called_once_with(airmass, sapm_module_params) assert_allclose(out, 1, atol=0.5) @@ -294,12 +293,12 @@ def test_PVSystem_multi_array_sapm_spectral_loss(sapm_module_params): ]) def test_PVSystem_first_solar_spectral_loss(module_parameters, module_type, coefficients, mocker): - mocker.spy(spectrum, 'first_solar_spectral_correction') + mocker.spy(spectrum, 'first_solar') system = pvsystem.PVSystem(module_parameters=module_parameters) pw = 3 airmass_absolute = 3 out = system.first_solar_spectral_loss(pw, airmass_absolute) - spectrum.first_solar_spectral_correction.assert_called_once_with( + spectrum.first_solar.assert_called_once_with( pw, airmass_absolute, module_type, coefficients) assert_allclose(out, 1, atol=0.5) From 41430daabce517d9524ed235f860403a03ed87d2 Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Wed, 22 Feb 2023 14:06:25 -0500 Subject: [PATCH 08/12] rename to spectral_factor_X --- .../effects_on_pv_system_output/spectrum.rst | 4 +- docs/sphinx/source/whatsnew/v0.9.5.rst | 4 +- pvlib/atmosphere.py | 4 +- pvlib/pvsystem.py | 17 +++--- pvlib/spectrum/__init__.py | 4 +- pvlib/spectrum/mismatch.py | 6 +-- pvlib/tests/test_atmosphere.py | 2 +- pvlib/tests/test_pvsystem.py | 10 ++-- pvlib/tests/test_spectrum.py | 52 +++++++++---------- 9 files changed, 52 insertions(+), 51 deletions(-) diff --git a/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst b/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst index a47ca40dfe..ed6cdc0b51 100644 --- a/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst +++ b/docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst @@ -10,5 +10,5 @@ Spectrum spectrum.get_example_spectral_response spectrum.get_am15g spectrum.calc_spectral_mismatch_field - spectrum.first_solar - spectrum.sapm + spectrum.spectral_factor_firstsolar + spectrum.spectral_factor_sapm diff --git a/docs/sphinx/source/whatsnew/v0.9.5.rst b/docs/sphinx/source/whatsnew/v0.9.5.rst index a14e54f79b..3c5e5c0135 100644 --- a/docs/sphinx/source/whatsnew/v0.9.5.rst +++ b/docs/sphinx/source/whatsnew/v0.9.5.rst @@ -14,9 +14,9 @@ Deprecations ~~~~~~~~~~~~ * Functions for calculating spectral modifiers have been moved to :py:mod:`pvlib.spectrum`: :py:func:`pvlib.atmosphere.first_solar_spectral_correction` is deprecated and - replaced by :py:func:`~pvlib.spectrum.first_solar`, and + replaced by :py:func:`~pvlib.spectrum.spectral_factor_firstsolar`, and :py:func`pvlib.pvsystem.sapm_spectral_loss` is deprecated and replaced by - :py:func:`~pvlib.spectrum.sapm`. (:pull:`1628`) + :py:func:`~pvlib.spectrum.spectral_factor_sapm`. (:pull:`1628`) Enhancements diff --git a/pvlib/atmosphere.py b/pvlib/atmosphere.py index b6e3665d1b..9b2e09f080 100644 --- a/pvlib/atmosphere.py +++ b/pvlib/atmosphere.py @@ -323,8 +323,8 @@ def gueymard94_pw(temp_air, relative_humidity): first_solar_spectral_correction = deprecated( since='0.9.5', - alternative='pvlib.spectrum.first_solar' -)(pvlib.spectrum.first_solar) + alternative='pvlib.spectrum.spectral_factor_firstsolar' +)(pvlib.spectrum.spectral_factor_firstsolar) def bird_hulstrom80_aod_bb(aod380, aod500): diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 3b57cf6b38..4043d3ec79 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -672,7 +672,7 @@ def sapm_celltemp(self, poa_global, temp_air, wind_speed): @_unwrap_single_value def sapm_spectral_loss(self, airmass_absolute): """ - Use the :py:func:`pvlib.spectrum.sapm` function, + Use the :py:func:`pvlib.spectrum.spectral_factor_sapm` function, the input parameters, and ``self.module_parameters`` to calculate F1. Parameters @@ -686,7 +686,8 @@ def sapm_spectral_loss(self, airmass_absolute): The SAPM spectral loss coefficient. """ return tuple( - spectrum.sapm(airmass_absolute, array.module_parameters) + spectrum.spectral_factor_sapm(airmass_absolute, + array.module_parameters) for array in self.arrays ) @@ -884,7 +885,7 @@ def noct_sam_celltemp(self, poa_global, temp_air, wind_speed, @_unwrap_single_value def first_solar_spectral_loss(self, pw, airmass_absolute): """ - Use :py:func:`pvlib.spectrum.first_solar` to + Use :py:func:`pvlib.spectrum.spectral_factor_firstsolar` to calculate the spectral loss modifier. The model coefficients are specific to the module's cell type, and are determined by searching for one of the following keys in self.module_parameters (in order): @@ -925,7 +926,7 @@ def _spectral_correction(array, pw): module_type = array._infer_cell_type() coefficients = None - return spectrum.first_solar( + return spectrum.spectral_factor_firstsolar( pw, airmass_absolute, module_type, coefficients ) return tuple( @@ -2599,8 +2600,8 @@ def sapm(effective_irradiance, temp_cell, module): sapm_spectral_loss = deprecated( since='0.9.5', - alternative='pvlib.spectrum.sapm' -)(spectrum.sapm) + alternative='pvlib.spectrum.spectral_factor_sapm' +)(spectrum.spectral_factor_sapm) def sapm_effective_irradiance(poa_direct, poa_diffuse, airmass_absolute, aoi, @@ -2660,11 +2661,11 @@ def sapm_effective_irradiance(poa_direct, poa_diffuse, airmass_absolute, aoi, See also -------- pvlib.iam.sapm - pvlib.spectrum.sapm + pvlib.spectrum.spectral_factor_sapm pvlib.pvsystem.sapm """ - F1 = spectrum.sapm(airmass_absolute, module) + F1 = spectrum.spectral_factor_sapm(airmass_absolute, module) F2 = iam.sapm(aoi, module) Ee = F1 * (poa_direct * F2 + module['FD'] * poa_diffuse) diff --git a/pvlib/spectrum/__init__.py b/pvlib/spectrum/__init__.py index 7dadb40fbd..70d3918b49 100644 --- a/pvlib/spectrum/__init__.py +++ b/pvlib/spectrum/__init__.py @@ -1,8 +1,8 @@ from pvlib.spectrum.spectrl2 import spectrl2 # noqa: F401 from pvlib.spectrum.mismatch import ( # noqa: F401 calc_spectral_mismatch_field, - first_solar, get_am15g, get_example_spectral_response, - sapm, + spectral_factor_firstsolar, + spectral_factor_sapm, ) diff --git a/pvlib/spectrum/mismatch.py b/pvlib/spectrum/mismatch.py index 4b7593bce4..a7e7cf0851 100644 --- a/pvlib/spectrum/mismatch.py +++ b/pvlib/spectrum/mismatch.py @@ -239,8 +239,8 @@ def integrate(e): return smm -def first_solar(pw, airmass_absolute, module_type=None, coefficients=None, - min_pw=0.1, max_pw=8): +def spectral_factor_firstsolar(pw, airmass_absolute, module_type=None, + coefficients=None, min_pw=0.1, max_pw=8): r""" Spectral mismatch modifier based on precipitable water and absolute (pressure-adjusted) airmass. @@ -409,7 +409,7 @@ def first_solar(pw, airmass_absolute, module_type=None, coefficients=None, return modifier -def sapm(airmass_absolute, module): +def spectral_factor_sapm(airmass_absolute, module): """ Calculates the SAPM spectral loss coefficient, F1. diff --git a/pvlib/tests/test_atmosphere.py b/pvlib/tests/test_atmosphere.py index f944a5f4c3..babdc9d406 100644 --- a/pvlib/tests/test_atmosphere.py +++ b/pvlib/tests/test_atmosphere.py @@ -89,7 +89,7 @@ def test_gueymard94_pw(): def test_first_solar_spectral_correction_deprecated(): with pytest.warns(pvlibDeprecationWarning, - match='Use pvlib.spectrum.first_solar'): + match='Use pvlib.spectrum.spectral_factor_firstsolar'): atmosphere.first_solar_spectral_correction(1, 1, 'cdte') diff --git a/pvlib/tests/test_pvsystem.py b/pvlib/tests/test_pvsystem.py index 9645321fce..732e841a19 100644 --- a/pvlib/tests/test_pvsystem.py +++ b/pvlib/tests/test_pvsystem.py @@ -256,16 +256,16 @@ def test_PVSystem_multi_array_sapm(sapm_module_params): def test_sapm_spectral_loss_deprecated(sapm_module_params): with pytest.warns(pvlibDeprecationWarning, - match='Use pvlib.spectrum.sapm'): + match='Use pvlib.spectrum.spectral_factor_sapm'): pvsystem.sapm_spectral_loss(1, sapm_module_params) def test_PVSystem_sapm_spectral_loss(sapm_module_params, mocker): - mocker.spy(spectrum, 'sapm') + mocker.spy(spectrum, 'spectral_factor_sapm') system = pvsystem.PVSystem(module_parameters=sapm_module_params) airmass = 2 out = system.sapm_spectral_loss(airmass) - spectrum.sapm.assert_called_once_with(airmass, sapm_module_params) + spectrum.spectral_factor_sapm.assert_called_once_with(airmass, sapm_module_params) assert_allclose(out, 1, atol=0.5) @@ -293,12 +293,12 @@ def test_PVSystem_multi_array_sapm_spectral_loss(sapm_module_params): ]) def test_PVSystem_first_solar_spectral_loss(module_parameters, module_type, coefficients, mocker): - mocker.spy(spectrum, 'first_solar') + mocker.spy(spectrum, 'spectral_factor_firstsolar') system = pvsystem.PVSystem(module_parameters=module_parameters) pw = 3 airmass_absolute = 3 out = system.first_solar_spectral_loss(pw, airmass_absolute) - spectrum.first_solar.assert_called_once_with( + spectrum.spectral_factor_firstsolar.assert_called_once_with( pw, airmass_absolute, module_type, coefficients) assert_allclose(out, 1, atol=0.5) diff --git a/pvlib/tests/test_spectrum.py b/pvlib/tests/test_spectrum.py index 69e27e225d..444e45733c 100644 --- a/pvlib/tests/test_spectrum.py +++ b/pvlib/tests/test_spectrum.py @@ -195,65 +195,65 @@ def test_calc_spectral_mismatch_field(spectrl2_data): [ 1.11225204, 0.93665901, 0.78487953], [ 1.14555295, 0.97084011, 0.81994083]])) ]) -def test_first_solar(module_type, expect): +def test_spectral_factor_firstsolar(module_type, expect): ams = np.array([1, 3, 5]) pws = np.array([1, 3, 5]) ams, pws = np.meshgrid(ams, pws) - out = spectrum.first_solar(pws, ams, module_type) + out = spectrum.spectral_factor_firstsolar(pws, ams, module_type) assert_allclose(out, expect, atol=0.001) -def test_first_solar_supplied(): +def test_spectral_factor_firstsolar_supplied(): # use the cdte coeffs coeffs = (0.87102, -0.040543, -0.00929202, 0.10052, 0.073062, -0.0034187) - out = spectrum.first_solar(1, 1, coefficients=coeffs) + out = spectrum.spectral_factor_firstsolar(1, 1, coefficients=coeffs) expected = 0.99134828 assert_allclose(out, expected, atol=1e-3) -def test_first_solar_ambiguous(): +def test_spectral_factor_firstsolar_ambiguous(): with pytest.raises(TypeError): - spectrum.first_solar(1, 1) + spectrum.spectral_factor_firstsolar(1, 1) -def test_first_solar_ambiguous_both(): +def test_spectral_factor_firstsolar_ambiguous_both(): # use the cdte coeffs coeffs = (0.87102, -0.040543, -0.00929202, 0.10052, 0.073062, -0.0034187) with pytest.raises(TypeError): - spectrum.first_solar(1, 1, 'cdte', coefficients=coeffs) + spectrum.spectral_factor_firstsolar(1, 1, 'cdte', coefficients=coeffs) -def test_first_solar_large_airmass(): +def test_spectral_factor_firstsolar_large_airmass(): # test that airmass > 10 is treated same as airmass==10 - m_eq10 = spectrum.first_solar(1, 10, 'monosi') - m_gt10 = spectrum.first_solar(1, 15, 'monosi') + m_eq10 = spectrum.spectral_factor_firstsolar(1, 10, 'monosi') + m_gt10 = spectrum.spectral_factor_firstsolar(1, 15, 'monosi') assert_allclose(m_eq10, m_gt10) -def test_first_solar_low_airmass(): +def test_spectral_factor_firstsolar_low_airmass(): with pytest.warns(UserWarning, match='Exceptionally low air mass'): - _ = spectrum.first_solar(1, 0.1, 'monosi') + _ = spectrum.spectral_factor_firstsolar(1, 0.1, 'monosi') -def test_first_solar_range(): +def test_spectral_factor_firstsolar_range(): with pytest.warns(UserWarning, match='Exceptionally high pw values'): - out = spectrum.first_solar(np.array([.1, 3, 10]), - np.array([1, 3, 5]), - module_type='monosi') + out = spectrum.spectral_factor_firstsolar(np.array([.1, 3, 10]), + np.array([1, 3, 5]), + module_type='monosi') expected = np.array([0.96080878, 1.03055092, np.nan]) assert_allclose(out, expected, atol=1e-3) with pytest.warns(UserWarning, match='Exceptionally high pw values'): - out = spectrum.first_solar(6, 1.5, max_pw=5, - module_type='monosi') + out = spectrum.spectral_factor_firstsolar(6, 1.5, max_pw=5, + module_type='monosi') with pytest.warns(UserWarning, match='Exceptionally low pw values'): - out = spectrum.first_solar(np.array([0, 3, 8]), - np.array([1, 3, 5]), - module_type='monosi') + out = spectrum.spectral_factor_firstsolar(np.array([0, 3, 8]), + np.array([1, 3, 5]), + module_type='monosi') expected = np.array([0.96080878, 1.03055092, 1.04932727]) assert_allclose(out, expected, atol=1e-3) with pytest.warns(UserWarning, match='Exceptionally low pw values'): - out = spectrum.first_solar(0.2, 1.5, min_pw=1, - module_type='monosi') + out = spectrum.spectral_factor_firstsolar(0.2, 1.5, min_pw=1, + module_type='monosi') @pytest.mark.parametrize('airmass,expected', [ @@ -261,9 +261,9 @@ def test_first_solar_range(): (np.array([[10, np.nan]]), np.array([[0.999535, 0]])), (pd.Series([5]), pd.Series([1.0387675])) ]) -def test_sapm(sapm_module_params, airmass, expected): +def test_spectral_factor_sapm(sapm_module_params, airmass, expected): - out = spectrum.sapm(airmass, sapm_module_params) + out = spectrum.spectral_factor_sapm(airmass, sapm_module_params) if isinstance(airmass, pd.Series): assert_series_equal(out, expected, check_less_precise=4) From c4cbc2d14ae2e7a3f9c268988fb4de737e610bf0 Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Wed, 22 Feb 2023 14:09:58 -0500 Subject: [PATCH 09/12] tweaks --- docs/sphinx/source/whatsnew/v0.9.5.rst | 2 +- pvlib/tests/test_pvsystem.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/sphinx/source/whatsnew/v0.9.5.rst b/docs/sphinx/source/whatsnew/v0.9.5.rst index 3c5e5c0135..5c56b097fa 100644 --- a/docs/sphinx/source/whatsnew/v0.9.5.rst +++ b/docs/sphinx/source/whatsnew/v0.9.5.rst @@ -15,7 +15,7 @@ Deprecations * Functions for calculating spectral modifiers have been moved to :py:mod:`pvlib.spectrum`: :py:func:`pvlib.atmosphere.first_solar_spectral_correction` is deprecated and replaced by :py:func:`~pvlib.spectrum.spectral_factor_firstsolar`, and - :py:func`pvlib.pvsystem.sapm_spectral_loss` is deprecated and replaced by + :py:func:`pvlib.pvsystem.sapm_spectral_loss` is deprecated and replaced by :py:func:`~pvlib.spectrum.spectral_factor_sapm`. (:pull:`1628`) diff --git a/pvlib/tests/test_pvsystem.py b/pvlib/tests/test_pvsystem.py index 732e841a19..794272fc34 100644 --- a/pvlib/tests/test_pvsystem.py +++ b/pvlib/tests/test_pvsystem.py @@ -265,7 +265,8 @@ def test_PVSystem_sapm_spectral_loss(sapm_module_params, mocker): system = pvsystem.PVSystem(module_parameters=sapm_module_params) airmass = 2 out = system.sapm_spectral_loss(airmass) - spectrum.spectral_factor_sapm.assert_called_once_with(airmass, sapm_module_params) + spectrum.spectral_factor_sapm.assert_called_once_with(airmass, + sapm_module_params) assert_allclose(out, 1, atol=0.5) From c33eba04735f51741bf5ea999fb55583b45ccc1a Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Fri, 12 May 2023 16:59:37 -0400 Subject: [PATCH 10/12] v0.9.5 -> v0.9.6 --- docs/sphinx/source/whatsnew/v0.9.5.rst | 5 ----- docs/sphinx/source/whatsnew/v0.9.6.rst | 5 +++++ pvlib/atmosphere.py | 2 +- pvlib/pvsystem.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/sphinx/source/whatsnew/v0.9.5.rst b/docs/sphinx/source/whatsnew/v0.9.5.rst index 335a1e2805..e043ade80b 100644 --- a/docs/sphinx/source/whatsnew/v0.9.5.rst +++ b/docs/sphinx/source/whatsnew/v0.9.5.rst @@ -12,11 +12,6 @@ the ``pvlib`` `conda channel `_. We recommend Deprecations ~~~~~~~~~~~~ -* Functions for calculating spectral modifiers have been moved to :py:mod:`pvlib.spectrum`: - :py:func:`pvlib.atmosphere.first_solar_spectral_correction` is deprecated and - replaced by :py:func:`~pvlib.spectrum.spectral_factor_firstsolar`, and - :py:func:`pvlib.pvsystem.sapm_spectral_loss` is deprecated and replaced by - :py:func:`~pvlib.spectrum.spectral_factor_sapm`. (:pull:`1628`) Enhancements diff --git a/docs/sphinx/source/whatsnew/v0.9.6.rst b/docs/sphinx/source/whatsnew/v0.9.6.rst index 7d1271086f..876d940c5f 100644 --- a/docs/sphinx/source/whatsnew/v0.9.6.rst +++ b/docs/sphinx/source/whatsnew/v0.9.6.rst @@ -7,6 +7,11 @@ v0.9.6 (Anticipated June 2023) Deprecations ~~~~~~~~~~~~ +* Functions for calculating spectral modifiers have been moved to :py:mod:`pvlib.spectrum`: + :py:func:`pvlib.atmosphere.first_solar_spectral_correction` is deprecated and + replaced by :py:func:`~pvlib.spectrum.spectral_factor_firstsolar`, and + :py:func:`pvlib.pvsystem.sapm_spectral_loss` is deprecated and replaced by + :py:func:`~pvlib.spectrum.spectral_factor_sapm`. (:pull:`1628`) Enhancements diff --git a/pvlib/atmosphere.py b/pvlib/atmosphere.py index ff04a506f1..394ac43291 100644 --- a/pvlib/atmosphere.py +++ b/pvlib/atmosphere.py @@ -337,7 +337,7 @@ def gueymard94_pw(temp_air, relative_humidity): first_solar_spectral_correction = deprecated( - since='0.9.5', + since='0.9.6', alternative='pvlib.spectrum.spectral_factor_firstsolar' )(pvlib.spectrum.spectral_factor_firstsolar) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 4bc081e35b..ea621e11f3 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2600,7 +2600,7 @@ def sapm(effective_irradiance, temp_cell, module): sapm_spectral_loss = deprecated( - since='0.9.5', + since='0.9.6', alternative='pvlib.spectrum.spectral_factor_sapm' )(spectrum.spectral_factor_sapm) From 84bfd99aa8e86bbd0edb56b1f2297154d84fee55 Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Fri, 12 May 2023 17:00:55 -0400 Subject: [PATCH 11/12] 0.9.5 whatsnew cleanup --- docs/sphinx/source/whatsnew/v0.9.5.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/sphinx/source/whatsnew/v0.9.5.rst b/docs/sphinx/source/whatsnew/v0.9.5.rst index e043ade80b..23766d566e 100644 --- a/docs/sphinx/source/whatsnew/v0.9.5.rst +++ b/docs/sphinx/source/whatsnew/v0.9.5.rst @@ -10,10 +10,6 @@ the ``pvlib`` `conda channel `_. We recommend :ref:`installation`). -Deprecations -~~~~~~~~~~~~ - - Enhancements ~~~~~~~~~~~~ * Added the optional ``string_factor`` parameter to From 8ff04cb87cd0a31de53c07d4bda6c394dd313ddd Mon Sep 17 00:00:00 2001 From: Kevin Anderson Date: Fri, 9 Jun 2023 16:13:26 -0400 Subject: [PATCH 12/12] 0.9.6 -> 0.10.0 in deprecation warnings Co-Authored-By: Cliff Hansen <5393711+cwhanse@users.noreply.github.com> --- pvlib/atmosphere.py | 2 +- pvlib/pvsystem.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pvlib/atmosphere.py b/pvlib/atmosphere.py index 394ac43291..08e40b9fc2 100644 --- a/pvlib/atmosphere.py +++ b/pvlib/atmosphere.py @@ -337,7 +337,7 @@ def gueymard94_pw(temp_air, relative_humidity): first_solar_spectral_correction = deprecated( - since='0.9.6', + since='0.10.0', alternative='pvlib.spectrum.spectral_factor_firstsolar' )(pvlib.spectrum.spectral_factor_firstsolar) diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index 7a3f2485d7..6d5a5b2ef4 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2603,7 +2603,7 @@ def sapm(effective_irradiance, temp_cell, module): sapm_spectral_loss = deprecated( - since='0.9.6', + since='0.10.0', alternative='pvlib.spectrum.spectral_factor_sapm' )(spectrum.spectral_factor_sapm)