Skip to content

rename losses.py to soiling.py #937

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/examples/plot_greensboro_kimber_soiling.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

# %%
# This example shows basic usage of pvlib's Kimber Soiling model [1]_ with
# :py:meth:`pvlib.losses.soiling_kimber`.
# :py:func:`pvlib.soiling.kimber`.
#
# References
# ----------
Expand All @@ -33,7 +33,7 @@
import pathlib
from matplotlib import pyplot as plt
from pvlib.iotools import read_tmy3
from pvlib.losses import soiling_kimber
from pvlib.soiling import kimber
import pvlib

# get full path to the data directory
Expand All @@ -45,7 +45,7 @@
greensboro_rain = greensboro.Lprecipdepth
# calculate soiling with no wash dates and cleaning threshold of 25-mm of rain
THRESHOLD = 25.0
soiling_no_wash = soiling_kimber(greensboro_rain, cleaning_threshold=THRESHOLD)
soiling_no_wash = kimber(greensboro_rain, cleaning_threshold=THRESHOLD)
soiling_no_wash.name = 'soiling'
# daily rain totals
daily_rain = greensboro_rain.iloc[:-1].resample('D').sum()
Expand Down
6 changes: 2 additions & 4 deletions docs/sphinx/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,8 @@ Functions for fitting diode models

Other
-----

.. autosummary::
:toctree: generated/

pvsystem.retrieve_sam
pvsystem.systemdef
pvsystem.scale_voltage_current_power
Expand All @@ -332,8 +330,8 @@ Effects on PV System Output
.. autosummary::
:toctree: generated/

losses.soiling_hsu
losses.soiling_kimber
soiling.hsu
soiling.kimber



Expand Down
8 changes: 7 additions & 1 deletion docs/sphinx/source/whatsnew/v0.7.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ API Changes
* :py:func:`pvlib.iotools.read_tmy3` when coerced to a single year now returns
indices that are monotonically increasing. Therefore, the last index will be
January 1, 00:00 of the *next* year. (:pull:`910`)
* Renamed ``pvlib.losses`` to :py:mod:`pvlib.soiling`. Additional loss
models will go into code modules named for the loss or effect type.
(:issue:`935`, :issue:`891`)
* Renamed ``pvlib.losses.soiling_hsu`` to :py:func:`pvlib.soiling.hsu`
(:issue:`935`)

Enhancements
~~~~~~~~~~~~
Expand All @@ -19,7 +24,8 @@ Enhancements
* Add :py:func:`~pvlib.pvsystem.PVSystem.faiman` and added
``temperature_model='faiman'`` option to :py:class:`~pvlib.modelchain.ModelChain`
(:pull:`897`) (:issue:`836`).
* Add Kimber soiling model :py:func:`pvlib.losses.soiling_kimber`. (:pull:`860`)
* Add Kimber soiling model :py:func:`pvlib.soiling.kimber`. (:pull:`860`,
:issue`935`)
* Add :func:`~pvlib.iotools.read_pvgis_tmy` for files downloaded using the
PVGIS tool. (:issue:`880`)
* Add new module :py:mod:`pvlib.snow` to contain models related to snow coverage and effects on a PV system. (:pull:`764`)
Expand Down
2 changes: 1 addition & 1 deletion pvlib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
from pvlib import modelchain # noqa: F401
from pvlib import singlediode # noqa: F401
from pvlib import bifacial # noqa: F401
from pvlib import losses # noqa: F401
from pvlib import soiling # noqa: F401
from pvlib import snow # noqa: F401
15 changes: 7 additions & 8 deletions pvlib/losses.py → pvlib/soiling.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
"""
This module contains functions for losses of various types: soiling, mismatch,
snow cover, etc.
This module contains functions for soiling models
"""

import datetime
Expand All @@ -10,8 +9,8 @@
from pvlib.tools import cosd


def soiling_hsu(rainfall, cleaning_threshold, tilt, pm2_5, pm10,
depo_veloc=None, rain_accum_period=pd.Timedelta('1h')):
def hsu(rainfall, cleaning_threshold, tilt, pm2_5, pm10,
depo_veloc=None, rain_accum_period=pd.Timedelta('1h')):
"""
Calculates soiling ratio given particulate and rain data using the model
from Humboldt State University (HSU).
Expand Down Expand Up @@ -66,7 +65,7 @@ def soiling_hsu(rainfall, cleaning_threshold, tilt, pm2_5, pm10,
try:
from scipy.special import erf
except ImportError:
raise ImportError("The soiling_hsu function requires scipy.")
raise ImportError("The pvlib.soiling.hsu function requires scipy.")

# never use mutable input arguments
if depo_veloc is None:
Expand Down Expand Up @@ -96,9 +95,9 @@ def soiling_hsu(rainfall, cleaning_threshold, tilt, pm2_5, pm10,
return soiling_ratio


def soiling_kimber(rainfall, cleaning_threshold=6, soiling_loss_rate=0.0015,
grace_period=14, max_soiling=0.3, manual_wash_dates=None,
initial_soiling=0, rain_accum_period=24):
def kimber(rainfall, cleaning_threshold=6, soiling_loss_rate=0.0015,
grace_period=14, max_soiling=0.3, manual_wash_dates=None,
initial_soiling=0, rain_accum_period=24):
"""
Calculates fraction of energy lost due to soiling given rainfall data and
daily loss rate using the Kimber model.
Expand Down
64 changes: 28 additions & 36 deletions pvlib/tests/test_losses.py → pvlib/tests/test_soiling.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import numpy as np
import pandas as pd
from pandas.util.testing import assert_series_equal
from pvlib.losses import soiling_hsu, soiling_kimber
from pvlib.soiling import hsu, kimber
from pvlib.iotools import read_tmy3
from conftest import (
requires_scipy, needs_pandas_0_22, DATA_DIR)
Expand Down Expand Up @@ -75,7 +75,7 @@ def rainfall_input():

@requires_scipy
@needs_pandas_0_22
def test_soiling_hsu_no_cleaning(rainfall_input, expected_output):
def test_hsu_no_cleaning(rainfall_input, expected_output):
"""Test Soiling HSU function"""

rainfall = rainfall_input
Expand All @@ -85,15 +85,15 @@ def test_soiling_hsu_no_cleaning(rainfall_input, expected_output):
tilt = 0.
expected_no_cleaning = expected_output

result = soiling_hsu(rainfall=rainfall, cleaning_threshold=10., tilt=tilt,
pm2_5=pm2_5, pm10=pm10, depo_veloc=depo_veloc,
rain_accum_period=pd.Timedelta('1h'))
result = hsu(rainfall=rainfall, cleaning_threshold=10., tilt=tilt,
pm2_5=pm2_5, pm10=pm10, depo_veloc=depo_veloc,
rain_accum_period=pd.Timedelta('1h'))
assert_series_equal(result, expected_no_cleaning)


@requires_scipy
@needs_pandas_0_22
def test_soiling_hsu(rainfall_input, expected_output_2):
def test_hsu(rainfall_input, expected_output_2):
"""Test Soiling HSU function with cleanings"""

rainfall = rainfall_input
Expand All @@ -104,21 +104,21 @@ def test_soiling_hsu(rainfall_input, expected_output_2):
expected = expected_output_2

# three cleaning events at 4:00-6:00, 8:00-11:00, and 17:00-20:00
result = soiling_hsu(rainfall=rainfall, cleaning_threshold=0.5, tilt=tilt,
pm2_5=pm2_5, pm10=pm10, depo_veloc=depo_veloc,
rain_accum_period=pd.Timedelta('3h'))
result = hsu(rainfall=rainfall, cleaning_threshold=0.5, tilt=tilt,
pm2_5=pm2_5, pm10=pm10, depo_veloc=depo_veloc,
rain_accum_period=pd.Timedelta('3h'))

assert_series_equal(result, expected)


@requires_scipy
@needs_pandas_0_22
def test_soiling_hsu_defaults(rainfall_input, expected_output_1):
def test_hsu_defaults(rainfall_input, expected_output_1):
"""
Test Soiling HSU function with default deposition velocity and default rain
accumulation period.
"""
result = soiling_hsu(
result = hsu(
rainfall=rainfall_input, cleaning_threshold=0.5, tilt=0.0, pm2_5=1.0,
pm10=2.0)
assert np.allclose(result.values, expected_output_1)
Expand All @@ -132,50 +132,45 @@ def greensboro_rain():


@pytest.fixture
def expected_kimber_soiling_nowash():
def expected_kimber_nowash():
return pd.read_csv(
DATA_DIR / 'greensboro_kimber_soil_nowash.dat',
parse_dates=True, index_col='timestamp')


@needs_pandas_0_22
def test_kimber_soiling_nowash(greensboro_rain,
expected_kimber_soiling_nowash):
def test_kimber_nowash(greensboro_rain, expected_kimber_nowash):
"""Test Kimber soiling model with no manual washes"""
# Greensboro typical expected annual rainfall is 8345mm
assert greensboro_rain.sum() == 8345
# calculate soiling with no wash dates
soiling_nowash = soiling_kimber(greensboro_rain)
nowash = kimber(greensboro_rain)
# test no washes
assert np.allclose(
soiling_nowash.values,
expected_kimber_soiling_nowash['soiling'].values)
assert np.allclose(nowash.values, expected_kimber_nowash['soiling'].values)


@pytest.fixture
def expected_kimber_soiling_manwash():
def expected_kimber_manwash():
return pd.read_csv(
DATA_DIR / 'greensboro_kimber_soil_manwash.dat',
parse_dates=True, index_col='timestamp')


@needs_pandas_0_22
def test_kimber_soiling_manwash(greensboro_rain,
expected_kimber_soiling_manwash):
def test_kimber_manwash(greensboro_rain, expected_kimber_manwash):
"""Test Kimber soiling model with a manual wash"""
# a manual wash date
manwash = [datetime.date(1990, 2, 15), ]
# calculate soiling with manual wash
soiling_manwash = soiling_kimber(
greensboro_rain, manual_wash_dates=manwash)
manwash = kimber(greensboro_rain, manual_wash_dates=manwash)
# test manual wash
assert np.allclose(
soiling_manwash.values,
expected_kimber_soiling_manwash['soiling'].values)
manwash.values,
expected_kimber_manwash['soiling'].values)


@pytest.fixture
def expected_kimber_soiling_norain():
def expected_kimber_norain():
# expected soiling reaches maximum
soiling_loss_rate = 0.0015
max_loss_rate = 0.3
Expand All @@ -186,19 +181,18 @@ def expected_kimber_soiling_norain():


@needs_pandas_0_22
def test_kimber_soiling_norain(greensboro_rain,
expected_kimber_soiling_norain):
def test_kimber_norain(greensboro_rain, expected_kimber_norain):
"""Test Kimber soiling model with no rain"""
# a year with no rain
norain = pd.Series(0, index=greensboro_rain.index)
# calculate soiling with no rain
soiling_norain = soiling_kimber(norain)
norain = kimber(norain)
# test no rain, soiling reaches maximum
assert np.allclose(soiling_norain.values, expected_kimber_soiling_norain)
assert np.allclose(norain.values, expected_kimber_norain)


@pytest.fixture
def expected_kimber_soiling_initial_soil():
def expected_kimber_initial_soil():
# expected soiling reaches maximum
soiling_loss_rate = 0.0015
max_loss_rate = 0.3
Expand All @@ -209,13 +203,11 @@ def expected_kimber_soiling_initial_soil():


@needs_pandas_0_22
def test_kimber_soiling_initial_soil(greensboro_rain,
expected_kimber_soiling_initial_soil):
def test_kimber_initial_soil(greensboro_rain, expected_kimber_initial_soil):
"""Test Kimber soiling model with initial soiling"""
# a year with no rain
norain = pd.Series(0, index=greensboro_rain.index)
# calculate soiling with no rain
soiling_norain = soiling_kimber(norain, initial_soiling=0.1)
norain = kimber(norain, initial_soiling=0.1)
# test no rain, soiling reaches maximum
assert np.allclose(
soiling_norain.values, expected_kimber_soiling_initial_soil)
assert np.allclose(norain.values, expected_kimber_initial_soil)