diff --git a/docs/sphinx/source/whatsnew/v0.7.2.rst b/docs/sphinx/source/whatsnew/v0.7.2.rst index f788c6bf0d..a4a93ddaa7 100644 --- a/docs/sphinx/source/whatsnew/v0.7.2.rst +++ b/docs/sphinx/source/whatsnew/v0.7.2.rst @@ -34,7 +34,11 @@ Bug fixes 0.6.4 what's new file. (:issue:`898`) * Compatibility with cftime 1.1. (:issue:`895`) * Add Python3.8 to Azure Pipelines CI (:issue:`903`)(:pull:`904`) - +* Minor implemention changes to avoid runtime and deprecation warnings in + :py:func:`~pvlib.clearsky.detect_clearsky`, + :py:func:`~pvlib.iam.martin_ruiz_diffuse`, + :py:func:`~pvlib.losses.soiling_hsu`, + and various test functions. Documentation ~~~~~~~~~~~~~ diff --git a/pvlib/clearsky.py b/pvlib/clearsky.py index e4cb12f179..8b6c1cc59b 100644 --- a/pvlib/clearsky.py +++ b/pvlib/clearsky.py @@ -712,6 +712,12 @@ def detect_clearsky(measured, clearsky, times, window_length, H = hankel(np.arange(intervals_per_window), # noqa: N806 np.arange(intervals_per_window - 1, len(times))) + # convert pandas input to numpy array, but save knowledge of input state + # so we can return a series if that's what was originally provided + ispandas = isinstance(measured, pd.Series) + measured = np.asarray(measured) + clearsky = np.asarray(clearsky) + # calculate measurement statistics meas_mean = np.mean(measured[H], axis=0) meas_max = np.max(measured[H], axis=0) @@ -771,7 +777,7 @@ def rmse(alpha): % max_iterations, RuntimeWarning) # be polite about returning the same type as was input - if isinstance(measured, pd.Series): + if ispandas: clear_samples = pd.Series(clear_samples, index=times) if return_components: diff --git a/pvlib/iam.py b/pvlib/iam.py index 5715e06762..f6c1b54ccb 100644 --- a/pvlib/iam.py +++ b/pvlib/iam.py @@ -363,11 +363,13 @@ def martin_ruiz_diffuse(surface_tilt, a_r=0.16, c1=0.4244, c2=None): from numpy import pi, sin, cos, exp - # because sin(pi) isn't exactly zero - sin_beta = np.where(surface_tilt < 90, sin(beta), sin(pi - beta)) + # avoid RuntimeWarnings for <, sin, and cos with nan + with np.errstate(invalid='ignore'): + # because sin(pi) isn't exactly zero + sin_beta = np.where(surface_tilt < 90, sin(beta), sin(pi - beta)) - trig_term_sky = sin_beta + (pi - beta - sin_beta) / (1 + cos(beta)) - trig_term_gnd = sin_beta + (beta - sin_beta) / (1 - cos(beta)) # noqa: E222 E261 E501 + trig_term_sky = sin_beta + (pi - beta - sin_beta) / (1 + cos(beta)) + trig_term_gnd = sin_beta + (beta - sin_beta) / (1 - cos(beta)) # noqa: E222 E261 E501 iam_sky = 1 - exp(-(c1 + c2 * trig_term_sky) * trig_term_sky / a_r) iam_gnd = 1 - exp(-(c1 + c2 * trig_term_gnd) * trig_term_gnd / a_r) diff --git a/pvlib/losses.py b/pvlib/losses.py index bcf68889e2..6bb6df9df1 100644 --- a/pvlib/losses.py +++ b/pvlib/losses.py @@ -78,7 +78,8 @@ def soiling_hsu(rainfall, cleaning_threshold, tilt, pm2_5, pm10, tms_cumsum = np.cumsum(tilted_mass_rate * np.ones(rainfall.shape)) mass_no_cleaning = pd.Series(index=rainfall.index, data=tms_cumsum) - mass_removed = pd.Series(index=rainfall.index) + # specify dtype so pandas doesn't assume object + mass_removed = pd.Series(index=rainfall.index, dtype='float64') mass_removed[0] = 0. mass_removed[cleaning_times] = mass_no_cleaning[cleaning_times] accum_mass = mass_no_cleaning - mass_removed.ffill() diff --git a/pvlib/pvsystem.py b/pvlib/pvsystem.py index d9a24b9b52..e1e8a9c65d 100644 --- a/pvlib/pvsystem.py +++ b/pvlib/pvsystem.py @@ -1546,7 +1546,7 @@ def _normalize_sam_product_names(names): import warnings - BAD_CHARS = ' -.()[]:+/",' + BAD_CHARS = ' -.()[]:+/",' GOOD_CHARS = '____________' mapping = str.maketrans(BAD_CHARS, GOOD_CHARS) @@ -1559,7 +1559,8 @@ def _normalize_sam_product_names(names): n_duplicates = norm_names.duplicated().sum() if n_duplicates > 0: - warnings.warn('Normalized names contain %d duplicate(s).' % n_duplicates) + warnings.warn( + 'Normalized names contain %d duplicate(s).' % n_duplicates) return norm_names.values diff --git a/pvlib/tests/conftest.py b/pvlib/tests/conftest.py index b6cd55dea3..7f68f21bd3 100644 --- a/pvlib/tests/conftest.py +++ b/pvlib/tests/conftest.py @@ -1,5 +1,6 @@ from pathlib import Path import platform +import warnings import numpy as np import pandas as pd @@ -153,8 +154,11 @@ def has_numba(): @pytest.fixture(scope="session") def sam_data(): data = {} - data['sandiamod'] = pvlib.pvsystem.retrieve_sam('sandiamod') - data['adrinverter'] = pvlib.pvsystem.retrieve_sam('adrinverter') + with warnings.catch_warnings(): + # ignore messages about duplicate entries in the databases. + warnings.simplefilter("ignore", UserWarning) + data['sandiamod'] = pvlib.pvsystem.retrieve_sam('sandiamod') + data['adrinverter'] = pvlib.pvsystem.retrieve_sam('adrinverter') return data diff --git a/pvlib/tests/test_losses.py b/pvlib/tests/test_losses.py index 74c05e0e7b..d86babd4ed 100644 --- a/pvlib/tests/test_losses.py +++ b/pvlib/tests/test_losses.py @@ -15,8 +15,8 @@ @pytest.fixture def expected_output(): # Sample output (calculated manually) - dt = pd.date_range(start=pd.datetime(2019, 1, 1, 0, 0, 0), - end=pd.datetime(2019, 1, 1, 23, 59, 0), freq='1h') + dt = pd.date_range(start=pd.Timestamp(2019, 1, 1, 0, 0, 0), + end=pd.Timestamp(2019, 1, 1, 23, 59, 0), freq='1h') expected_no_cleaning = pd.Series( data=[0.884980357535360, 0.806308930084762, 0.749974647038078, @@ -35,12 +35,12 @@ def expected_output(): @pytest.fixture def expected_output_2(expected_output): # Sample output (calculated manually) - dt = pd.date_range(start=pd.datetime(2019, 1, 1, 0, 0, 0), - end=pd.datetime(2019, 1, 1, 23, 59, 0), freq='1h') + dt = pd.date_range(start=pd.Timestamp(2019, 1, 1, 0, 0, 0), + end=pd.Timestamp(2019, 1, 1, 23, 59, 0), freq='1h') expected_no_cleaning = expected_output - expected = pd.Series(index=dt) + expected = pd.Series(index=dt, dtype='float64') expected[dt[:4]] = expected_no_cleaning[dt[:4]] expected[dt[4:7]] = 1. expected[dt[7]] = expected_no_cleaning[dt[0]] @@ -55,8 +55,8 @@ def expected_output_2(expected_output): @pytest.fixture def rainfall_input(): - dt = pd.date_range(start=pd.datetime(2019, 1, 1, 0, 0, 0), - end=pd.datetime(2019, 1, 1, 23, 59, 0), freq='1h') + dt = pd.date_range(start=pd.Timestamp(2019, 1, 1, 0, 0, 0), + end=pd.Timestamp(2019, 1, 1, 23, 59, 0), freq='1h') rainfall = pd.Series( data=[0., 0., 0., 0., 1., 0., 0., 0., 0.5, 0.5, 0., 0., 0., 0., 0., 0., 0.3, 0.3, 0.3, 0.3, 0., 0., 0., 0.], index=dt) diff --git a/pvlib/tests/test_pvsystem.py b/pvlib/tests/test_pvsystem.py index 97a60e4c19..e0d113801c 100644 --- a/pvlib/tests/test_pvsystem.py +++ b/pvlib/tests/test_pvsystem.py @@ -1085,7 +1085,7 @@ def test_singlediode_series_ivcurve(cec_module_params): assert_allclose(v, expected[k], atol=1e-2) -def test_scale_voltage_current_power(sam_data): +def test_scale_voltage_current_power(): data = pd.DataFrame( np.array([[2, 1.5, 10, 8, 12, 0.5, 1.5]]), columns=['i_sc', 'i_mp', 'v_oc', 'v_mp', 'p_mp', 'i_x', 'i_xx'],