Skip to content

Commit

Permalink
Numpy 2.0 compatibility (#2027)
Browse files Browse the repository at this point in the history
* change `np.Inf` to `np.inf`

AttributeError: `np.Inf` was removed in the NumPy 2.0 release. Use `np.inf` instead.

* change `np.NaN` to `np.nan`

AttributeError: `np.NaN` was removed in the NumPy 2.0 release. Use `np.nan` instead.

* fix np.uint8 range issue

OverflowError: Python integer 450 out of bounds for uint8

* use `scipy.integrate.trapezoid` instead of `np.trapz`

DeprecationWarning: `trapz` is deprecated. Use `trapezoid` instead, or one of the numerical integration functions in `scipy.integrate`.

* advance minimum scipy from 1.5 to 1.6 for integrate.trapezoid

* whatsnew PR number
  • Loading branch information
kandersolar committed May 1, 2024
1 parent 25ec296 commit 8668a61
Show file tree
Hide file tree
Showing 19 changed files with 31 additions and 25 deletions.
2 changes: 1 addition & 1 deletion benchmarks/asv.conf.json
Expand Up @@ -117,7 +117,7 @@
"build": "",
"numpy": "1.17.5",
"pandas": "1.3.0",
"scipy": "1.5.0",
"scipy": "1.6.0",
// Note: these don't have a minimum in setup.py
"h5py": "3.1.0",
"ephem": "3.7.6.0",
Expand Down
2 changes: 1 addition & 1 deletion ci/requirements-py3.10.yml
Expand Up @@ -21,7 +21,7 @@ dependencies:
- python=3.10
- pytz
- requests
- scipy >= 1.5.0
- scipy >= 1.6.0
- statsmodels
- pip:
- nrel-pysam>=2.0
Expand Down
2 changes: 1 addition & 1 deletion ci/requirements-py3.11.yml
Expand Up @@ -21,7 +21,7 @@ dependencies:
- python=3.11
- pytz
- requests
- scipy >= 1.5.0
- scipy >= 1.6.0
- statsmodels
- pip:
- nrel-pysam>=2.0
Expand Down
2 changes: 1 addition & 1 deletion ci/requirements-py3.12.yml
Expand Up @@ -21,7 +21,7 @@ dependencies:
- python=3.12
- pytz
- requests
- scipy >= 1.5.0
- scipy >= 1.6.0
- statsmodels
- pip:
- nrel-pysam>=2.0
Expand Down
2 changes: 1 addition & 1 deletion ci/requirements-py3.7-min.yml
Expand Up @@ -16,7 +16,7 @@ dependencies:
- h5py==3.1.0
- numpy==1.17.3
- pandas==1.3.0
- scipy==1.5.0
- scipy==1.6.0
- pytest-rerunfailures # conda version is >3.6
- pytest-remotedata # conda package is 0.3.0, needs > 0.3.1
- requests-mock
2 changes: 1 addition & 1 deletion ci/requirements-py3.7.yml
Expand Up @@ -21,7 +21,7 @@ dependencies:
- python=3.7
- pytz
- requests
- scipy >= 1.5.0
- scipy >= 1.6.0
- statsmodels
- pip:
- nrel-pysam>=2.0
Expand Down
2 changes: 1 addition & 1 deletion ci/requirements-py3.8.yml
Expand Up @@ -21,7 +21,7 @@ dependencies:
- python=3.8
- pytz
- requests
- scipy >= 1.5.0
- scipy >= 1.6.0
- statsmodels
- pip:
- nrel-pysam>=2.0
Expand Down
2 changes: 1 addition & 1 deletion ci/requirements-py3.9.yml
Expand Up @@ -21,7 +21,7 @@ dependencies:
- python=3.9
- pytz
- requests
- scipy >= 1.5.0
- scipy >= 1.6.0
- statsmodels
- pip:
- nrel-pysam>=2.0
Expand Down
1 change: 1 addition & 0 deletions docs/sphinx/source/whatsnew/v0.10.5.rst
Expand Up @@ -30,6 +30,7 @@ Documentation

Requirements
~~~~~~~~~~~~
* Minimum version of scipy advanced from 1.5.0 to 1.6.0. (:pull:`2027`)


Contributors
Expand Down
3 changes: 2 additions & 1 deletion pvlib/bifacial/utils.py
Expand Up @@ -4,6 +4,7 @@
"""
import numpy as np
from pvlib.tools import sind, cosd, tand
from scipy.integrate import trapezoid


def _solar_projection_tangent(solar_zenith, solar_azimuth, surface_azimuth):
Expand Down Expand Up @@ -220,7 +221,7 @@ def vf_ground_sky_2d_integ(surface_tilt, gcr, height, pitch, max_rows=10,
vf = vf_ground_sky_2d(r, gcr, z, pitch, height, max_rows)
fz_sky[:, k] = vf[:, 0] # remove spurious rotation dimension
# calculate the integrated view factor for all of the ground between rows
return np.trapz(fz_sky, z, axis=0)
return trapezoid(fz_sky, z, axis=0)


def _vf_poly(surface_tilt, gcr, x, delta):
Expand Down
2 changes: 1 addition & 1 deletion pvlib/iotools/srml.py
Expand Up @@ -92,7 +92,7 @@ def read_srml(filename, map_variables=True):
# Mask data marked with quality flag 99 (bad or missing data)
for col in columns[::2]:
missing = data[col + '_flag'] == 99
data[col] = data[col].where(~(missing), np.NaN)
data[col] = data[col].where(~(missing), np.nan)
return data


Expand Down
2 changes: 1 addition & 1 deletion pvlib/iotools/surfrad.py
Expand Up @@ -152,7 +152,7 @@ def read_surfrad(filename, map_variables=True):

data = _format_index(data)
missing = data == -9999.9
data = data.where(~missing, np.NaN)
data = data.where(~missing, np.nan)

if map_variables:
data.rename(columns=VARIABLE_MAP, inplace=True)
Expand Down
4 changes: 3 additions & 1 deletion pvlib/location.py
Expand Up @@ -439,8 +439,10 @@ def lookup_altitude(latitude, longitude):
# 255 is a special value that means nodata. Fallback to 0 if nodata.
if alt == 255:
return 0
# convert from np.uint8 to float so that the following operations succeed
alt = float(alt)
# Altitude is encoded in 28 meter steps from -450 meters to 6561 meters
# There are 0-254 possible altitudes, with 255 reserved for nodata.
alt *= 28
alt -= 450
return float(alt)
return alt
2 changes: 1 addition & 1 deletion pvlib/pvsystem.py
Expand Up @@ -2536,7 +2536,7 @@ def singlediode(photocurrent, saturation_current, resistance_series,


def max_power_point(photocurrent, saturation_current, resistance_series,
resistance_shunt, nNsVth, d2mutau=0, NsVbi=np.Inf,
resistance_shunt, nNsVth, d2mutau=0, NsVbi=np.inf,
method='brentq'):
"""
Given the single diode equation coefficients, calculates the maximum power
Expand Down
8 changes: 4 additions & 4 deletions pvlib/singlediode.py
Expand Up @@ -58,7 +58,7 @@ def estimate_voc(photocurrent, saturation_current, nNsVth):

def bishop88(diode_voltage, photocurrent, saturation_current,
resistance_series, resistance_shunt, nNsVth, d2mutau=0,
NsVbi=np.Inf, breakdown_factor=0., breakdown_voltage=-5.5,
NsVbi=np.inf, breakdown_factor=0., breakdown_voltage=-5.5,
breakdown_exp=3.28, gradients=False):
r"""
Explicit calculation of points on the IV curve described by the single
Expand Down Expand Up @@ -206,7 +206,7 @@ def bishop88(diode_voltage, photocurrent, saturation_current,

def bishop88_i_from_v(voltage, photocurrent, saturation_current,
resistance_series, resistance_shunt, nNsVth,
d2mutau=0, NsVbi=np.Inf, breakdown_factor=0.,
d2mutau=0, NsVbi=np.inf, breakdown_factor=0.,
breakdown_voltage=-5.5, breakdown_exp=3.28,
method='newton', method_kwargs=None):
"""
Expand Down Expand Up @@ -338,7 +338,7 @@ def vd_from_brent(voc, v, iph, isat, rs, rsh, gamma, d2mutau, NsVbi,

def bishop88_v_from_i(current, photocurrent, saturation_current,
resistance_series, resistance_shunt, nNsVth,
d2mutau=0, NsVbi=np.Inf, breakdown_factor=0.,
d2mutau=0, NsVbi=np.inf, breakdown_factor=0.,
breakdown_voltage=-5.5, breakdown_exp=3.28,
method='newton', method_kwargs=None):
"""
Expand Down Expand Up @@ -469,7 +469,7 @@ def vd_from_brent(voc, i, iph, isat, rs, rsh, gamma, d2mutau, NsVbi,


def bishop88_mpp(photocurrent, saturation_current, resistance_series,
resistance_shunt, nNsVth, d2mutau=0, NsVbi=np.Inf,
resistance_shunt, nNsVth, d2mutau=0, NsVbi=np.inf,
breakdown_factor=0., breakdown_voltage=-5.5,
breakdown_exp=3.28, method='newton', method_kwargs=None):
"""
Expand Down
3 changes: 2 additions & 1 deletion pvlib/spectrum/mismatch.py
Expand Up @@ -6,6 +6,7 @@
import numpy as np
import pandas as pd
from scipy.interpolate import interp1d
from scipy.integrate import trapezoid
import os

from warnings import warn
Expand Down Expand Up @@ -224,7 +225,7 @@ def calc_spectral_mismatch_field(sr, e_sun, e_ref=None):

# a helper function to make usable fraction calculations more readable
def integrate(e):
return np.trapz(e, x=e.T.index, axis=-1)
return trapezoid(e, x=e.T.index, axis=-1)

# calculate usable fractions
uf_sun = integrate(e_sun * sr_sun) / integrate(e_sun)
Expand Down
11 changes: 6 additions & 5 deletions pvlib/tests/bifacial/test_utils.py
Expand Up @@ -6,6 +6,7 @@
from pvlib.bifacial import utils
from pvlib.shading import masking_angle, ground_angle
from pvlib.tools import cosd
from scipy.integrate import trapezoid


@pytest.fixture
Expand Down Expand Up @@ -99,7 +100,7 @@ def test_vf_ground_sky_2d_integ(test_system_fixed_tilt, vectorize):
vf_integ = utils.vf_ground_sky_2d_integ(
ts['rotation'], ts['gcr'], ts['height'], ts['pitch'],
max_rows=1, npoints=3, vectorize=vectorize)
expected_vf_integ = np.trapz(vfs_gnd_sky, pts, axis=0)
expected_vf_integ = trapezoid(vfs_gnd_sky, pts, axis=0)
assert np.isclose(vf_integ, expected_vf_integ, rtol=0.1)


Expand Down Expand Up @@ -134,15 +135,15 @@ def test_vf_row_sky_2d_integ(test_system_fixed_tilt):
x = np.arange(fx0[1], fx1[1], 1e-4)
phi_y = masking_angle(ts['surface_tilt'], ts['gcr'], x)
y = 0.5 * (1 + cosd(ts['surface_tilt'] + phi_y))
y1 = np.trapz(y, x) / (fx1[1] - fx0[1])
y1 = trapezoid(y, x) / (fx1[1] - fx0[1])
expected = np.array([y0, y1])
assert np.allclose(vf, expected, rtol=1e-3)
# with defaults (0, 1)
vf = utils.vf_row_sky_2d_integ(ts['surface_tilt'], ts['gcr'])
x = np.arange(0, 1, 1e-4)
phi_y = masking_angle(ts['surface_tilt'], ts['gcr'], x)
y = 0.5 * (1 + cosd(ts['surface_tilt'] + phi_y))
y1 = np.trapz(y, x) / (1 - 0)
y1 = trapezoid(y, x) / (1 - 0)
assert np.allclose(vf, y1, rtol=1e-3)


Expand Down Expand Up @@ -179,13 +180,13 @@ def test_vf_ground_2d_integ(test_system_fixed_tilt):
x = np.arange(fx0[1], fx1[1], 1e-4)
phi_y = ground_angle(ts['surface_tilt'], ts['gcr'], x)
y = 0.5 * (1 - cosd(phi_y - ts['surface_tilt']))
y1 = np.trapz(y, x) / (fx1[1] - fx0[1])
y1 = trapezoid(y, x) / (fx1[1] - fx0[1])
expected = np.array([y0, y1])
assert np.allclose(vf, expected, rtol=1e-2)
# with defaults (0, 1)
vf = utils.vf_row_ground_2d_integ(ts['surface_tilt'], ts['gcr'], 0, 1)
x = np.arange(0, 1, 1e-4)
phi_y = ground_angle(ts['surface_tilt'], ts['gcr'], x)
y = 0.5 * (1 - cosd(phi_y - ts['surface_tilt']))
y1 = np.trapz(y, x) / (1 - 0)
y1 = trapezoid(y, x) / (1 - 0)
assert np.allclose(vf, y1, rtol=1e-2)
2 changes: 1 addition & 1 deletion pvlib/tests/test_singlediode.py
Expand Up @@ -355,7 +355,7 @@ def test_pvsyst_recombination_loss(method, poa, temp_cell, expected, tol):
# other conditions with breakdown model on and recombination model off
(
(1.e-4, -5.5, 3.28),
(0., np.Inf),
(0., np.inf),
POA,
TCELL,
{
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Expand Up @@ -15,7 +15,7 @@ dependencies = [
'pandas >= 1.3.0',
'pytz',
'requests',
'scipy >= 1.5.0',
'scipy >= 1.6.0',
'h5py',
'importlib-metadata; python_version < "3.8"',
]
Expand Down

0 comments on commit 8668a61

Please sign in to comment.