diff --git a/docs/sphinx/source/whatsnew/v0.6.0.rst b/docs/sphinx/source/whatsnew/v0.6.0.rst index f534fd6213..8f057feb20 100644 --- a/docs/sphinx/source/whatsnew/v0.6.0.rst +++ b/docs/sphinx/source/whatsnew/v0.6.0.rst @@ -55,6 +55,11 @@ API Changes instead of only the function handle (:issue:`417`) * Add DC model methods desoto and pvsyst to ModelChain, and deprecates DC model method singlediode (singlediode defaults to desoto until v0.7.0) (:issue:`487`) +* The behavior of irradiance.perez(return_components=True) has changed. + The function previously returned a tuple of total sky diffuse and + an OrderedDict/DataFrame of components. The function now returns + an OrderedDict/DataFrame with total sky diffuse and each component. + The behavior for return_components=False remains unchanged. (:issue:`434`) Enhancements diff --git a/pvlib/irradiance.py b/pvlib/irradiance.py index 0880594e94..eb63371b81 100644 --- a/pvlib/irradiance.py +++ b/pvlib/irradiance.py @@ -1077,9 +1077,22 @@ def perez(surface_tilt, surface_azimuth, dhi, dni, dni_extra, Returns -------- + numeric, OrderedDict, or DataFrame + Return type controlled by `return_components` argument. + If ``return_components=False``, `sky_diffuse` is returned. + If ``return_components=True``, `diffuse_components` is returned. + sky_diffuse : numeric The sky diffuse component of the solar radiation on a tilted - surface. Array input is currently converted to Series output. + surface. + + diffuse_components : OrderedDict (array input) or DataFrame (Series input) + Keys/columns are: + * sky_diffuse: Total sky diffuse + * isotropic + * circumsolar + * horizon + References ---------- @@ -1161,6 +1174,7 @@ def perez(surface_tilt, surface_azimuth, dhi, dni, dni_extra, if return_components: diffuse_components = OrderedDict() + diffuse_components['sky_diffuse'] = sky_diffuse # Calculate the different components diffuse_components['isotropic'] = dhi * term1 @@ -1175,9 +1189,7 @@ def perez(surface_tilt, surface_azimuth, dhi, dni, dni_extra, else: diffuse_components = {k: np.where(mask, 0, v) for k, v in diffuse_components.items()} - - return sky_diffuse, diffuse_components - + return diffuse_components else: return sky_diffuse diff --git a/pvlib/test/test_irradiance.py b/pvlib/test/test_irradiance.py index 6335b2350c..43e4d531de 100644 --- a/pvlib/test/test_irradiance.py +++ b/pvlib/test/test_irradiance.py @@ -232,29 +232,27 @@ def test_perez(irrad_data, ephem_data, dni_et, relative_airmass): def test_perez_components(irrad_data, ephem_data, dni_et, relative_airmass): dni = irrad_data['dni'].copy() dni.iloc[2] = np.nan - out, df_components = irradiance.perez(40, 180, irrad_data['dhi'], dni, - dni_et, ephem_data['apparent_zenith'], - ephem_data['azimuth'], relative_airmass, - return_components=True) - expected = pd.Series(np.array( - [ 0. , 31.46046871, np.nan, 45.45539877]), - index=irrad_data.index) - expected_components = pd.DataFrame( - np.array([[ 0. , 26.84138589, np.nan, 31.72696071], - [ 0. , 0. , np.nan, 4.47966439], - [ 0. , 4.62212181, np.nan, 9.25316454]]).T, - columns=['isotropic', 'circumsolar', 'horizon'], + out = irradiance.perez(40, 180, irrad_data['dhi'], dni, + dni_et, ephem_data['apparent_zenith'], + ephem_data['azimuth'], relative_airmass, + return_components=True) + expected = pd.DataFrame(np.array( + [[ 0. , 31.46046871, np.nan, 45.45539877], + [ 0. , 26.84138589, np.nan, 31.72696071], + [ 0. , 0. , np.nan, 4.47966439], + [ 0. , 4.62212181, np.nan, 9.25316454]]).T, + columns=['sky_diffuse', 'isotropic', 'circumsolar', 'horizon'], index=irrad_data.index ) if pandas_0_22(): - expected_for_sum = expected.copy() + expected_for_sum = expected['sky_diffuse'].copy() expected_for_sum.iloc[2] = 0 else: - expected_for_sum = expected - sum_components = df_components.sum(axis=1) + expected_for_sum = expected['sky_diffuse'] + sum_components = out.iloc[:, 1:].sum(axis=1) + sum_components.name = 'sky_diffuse' - assert_series_equal(out, expected, check_less_precise=2) - assert_frame_equal(df_components, expected_components) + assert_frame_equal(out, expected, check_less_precise=2) assert_series_equal(sum_components, expected_for_sum, check_less_precise=2) @@ -268,6 +266,15 @@ def test_perez_arrays(irrad_data, ephem_data, dni_et, relative_airmass): expected = np.array( [ 0. , 31.46046871, np.nan, 45.45539877]) assert_allclose(out, expected, atol=1e-2) + assert isinstance(out, np.ndarray) + + +def test_perez_scalar(): + # copied values from fixtures + out = irradiance.perez(40, 180, 118.45831879, 939.95469881, + 1321.1655834833093, 10.56413562, 144.76567754, + 1.01688136) + assert_allclose(out, 109.084332) @pytest.mark.parametrize('model', ['isotropic', 'klucher', 'haydavies',