diff --git a/docs/sphinx/source/api.rst b/docs/sphinx/source/api.rst index cd5b0ced40..6569202046 100644 --- a/docs/sphinx/source/api.rst +++ b/docs/sphinx/source/api.rst @@ -369,6 +369,13 @@ Other Effects on PV System Output =========================== +Loss models +^^^^^^^^^^^ +.. autosummary:: + :toctree: generated/ + + pvsystem.combine_loss_factors + .. autosummary:: :toctree: generated/ diff --git a/docs/sphinx/source/whatsnew/v0.8.0.rst b/docs/sphinx/source/whatsnew/v0.8.0.rst index 75e223b045..b64c839a29 100644 --- a/docs/sphinx/source/whatsnew/v0.8.0.rst +++ b/docs/sphinx/source/whatsnew/v0.8.0.rst @@ -92,6 +92,9 @@ Enhancements PVSystem, LocalizedPVSystem, SingleAxisTracker, and LocalizedSingleAxisTracker repr methods. (:issue:`1027`) * Added ability for :py:func:`pvlib.soiling.hsu` to accept arbitrary time intervals. (:pull:`980`) +* Add :py:func:`pvlib.pvsystem.combine_loss_factors` as general purpose + function to combine loss factors with a common index. + Partialy addresses :issue:`988`. Contributed by Brock Taute :ghuser:`btaute` Bug fixes ~~~~~~~~~ diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index bf1b3bab06..2134801c8d 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -2310,6 +2310,48 @@ def pvwatts_losses(soiling=2, shading=3, snow=0, mismatch=2, wiring=2, return losses +def combine_loss_factors(index, *losses, fill_method='ffill'): + r""" + Combines Series loss fractions while setting a common index. + + The separate losses are compounded using the following equation: + + .. math:: + + L_{total} = 1 - [ 1 - \Pi_i ( 1 - L_i ) ] + + :math:`L_{total}` is the total loss returned + :math:`L_i` is each individual loss factor input + + Note the losses must each be a series with a DatetimeIndex. + All losses will be resampled to match the index parameter using + the fill method specified (defaults to "fill forward"). + + Parameters + ---------- + index : DatetimeIndex + The index of the returned loss factors + + *losses : Series + One or more Series of fractions to be compounded + + fill_method : {'ffill', 'bfill', 'nearest'}, default 'ffill' + Method to use for filling holes in reindexed DataFrame + + Returns + ------- + Series + Fractions resulting from the combination of each loss factor + """ + combined_factor = 1 + + for loss in losses: + loss = loss.reindex(index, method=fill_method) + combined_factor *= (1 - loss) + + return 1 - combined_factor + + snlinverter = deprecated('0.8', alternative='inverter.sandia', name='snlinverter', removal='0.9')(inverter.sandia) diff --git a/pvlib/tests/test_pvsystem.py b/pvlib/tests/test_pvsystem.py index 4febb71f43..2ad26937b4 100644 --- a/pvlib/tests/test_pvsystem.py +++ b/pvlib/tests/test_pvsystem.py @@ -1299,6 +1299,18 @@ def test_PVSystem_pvwatts_ac_kwargs(mocker): assert out < pdc +def test_combine_loss_factors(): + test_index = pd.date_range(start='1990/01/01T12:00', periods=365, freq='D') + loss_1 = pd.Series(.10, index=test_index) + loss_2 = pd.Series(.05, index=pd.date_range(start='1990/01/01T12:00', + periods=365*2, freq='D')) + loss_3 = pd.Series(.02, index=pd.date_range(start='1990/01/01', + periods=12, freq='MS')) + expected = pd.Series(.1621, index=test_index) + out = pvsystem.combine_loss_factors(test_index, loss_1, loss_2, loss_3) + assert_series_equal(expected, out) + + @fail_on_pvlib_version('0.9') def test_deprecated_09(cec_inverter_parameters, adr_inverter_parameters): # deprecated function pvsystem.snlinverter