Skip to content

Commit

Permalink
improvements from review
Browse files Browse the repository at this point in the history
  • Loading branch information
cwhanse committed Aug 27, 2020
1 parent b548f63 commit df7520e
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 48 deletions.
41 changes: 16 additions & 25 deletions pvlib/ivtools/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,13 @@

import numpy as np
import pandas as pd
from collections import OrderedDict


# A small number used to decide when a slope is equivalent to zero
EPS = np.finfo('float').eps**(1/3)


constants = OrderedDict()
constants['E0'] = 1000.0
constants['T0'] = 25.0
constants['k'] = 1.38066e-23
constants['q'] = 1.60218e-19
constants = {'E0': 1000.0, 'T0': 25.0, 'k': 1.38066e-23, 'q': 1.60218e-19}


def numdiff(x, f):
Expand Down Expand Up @@ -166,9 +161,6 @@ def rectify_iv_curve(voltage, current, decimals=None):
equal to the average of current at duplicated voltages.
"""

if len(voltage) != len(current):
raise ValueError('voltage and current must have the same length')

df = pd.DataFrame(data=np.vstack((voltage, current)).T, columns=['v', 'i'])
# restrict to first quadrant
df.dropna(inplace=True)
Expand Down Expand Up @@ -240,7 +232,6 @@ def schumaker_qspline(x, y):
y = y.flatten()

n = x.size
assert n == y.size

# compute various values used by the algorithm: differences, length of line
# segments between data points, and ratios of differences.
Expand Down Expand Up @@ -313,12 +304,12 @@ def schumaker_qspline(x, y):

# MATLAB differs from NumPy, boolean indices must be same size as
# array
xk[:(n-1)][u] = tmpx[u]
yk[:(n-1)][u] = tmpy[u]
xk[:(n - 1)][u] = tmpx[u]
yk[:(n - 1)][u] = tmpy[u]
# constant term for each polynomial for intervals without knots
a[:(n-1), 2][u] = tmpy[u]
a[:(n-1), 1][u] = s[:-1][u]
a[:(n-1), 0][u] = 0.5 * diffs[u] / delx[u] # leading coefficients
a[:(n - 1), 2][u] = tmpy[u]
a[:(n - 1), 1][u] = s[:-1][u]
a[:(n - 1), 0][u] = 0.5 * diffs[u] / delx[u] # leading coefficients

# [2], Algorithm 4.1 subpart 2 of Step 5
# original x values that are left points of intervals with internal knots
Expand Down Expand Up @@ -355,7 +346,7 @@ def schumaker_qspline(x, y):
uu[(n + q - 1):(n + q + r - 1), :] = np.array([tmpx[w], tmpx2[w],
tmpy[w], tmps[w],
tmps2[w], delta[w]]).T
xi[:(n-1)][w] = xk[(n + q - 1):(n + q + r - 1)]
xi[:(n - 1)][w] = xk[(n + q - 1):(n + q + r - 1)]

z = np.logical_and(~u, ~v) # last 'else' in Algorithm 4.1 Step 5
z = np.logical_and(z, ~w)
Expand All @@ -372,13 +363,13 @@ def schumaker_qspline(x, y):
# define polynomial coefficients for intervals with added knots
ff = ~u
sbar[:(n-1)][ff] = (
(2 * uu[:(n-1), 5][ff] - uu[:(n-1), 4][ff])
+ (uu[:(n-1), 4][ff] - uu[:(n-1), 3][ff])
* (xi[:(n-1)][ff] - uu[:(n-1), 0][ff])
/ (uu[:(n-1), 1][ff] - uu[:(n-1), 0][ff]))
(2 * uu[:(n - 1), 5][ff] - uu[:(n-1), 4][ff])
+ (uu[:(n - 1), 4][ff] - uu[:(n-1), 3][ff])
* (xi[:(n - 1)][ff] - uu[:(n-1), 0][ff])
/ (uu[:(n - 1), 1][ff] - uu[:(n-1), 0][ff]))
eta[:(n-1)][ff] = (
(sbar[:(n-1)][ff] - uu[:(n-1), 3][ff])
/ (xi[:(n-1)][ff] - uu[:(n-1), 0][ff]))
(sbar[:(n - 1)][ff] - uu[:(n-1), 3][ff])
/ (xi[:(n - 1)][ff] - uu[:(n-1), 0][ff]))

sbar[(n - 1):(n + q + r + ss - 1)] = \
(2 * uu[(n - 1):(n + q + r + ss - 1), 5] -
Expand All @@ -396,9 +387,9 @@ def schumaker_qspline(x, y):
uu[(n - 1):(n + q + r + ss - 1), 0])

# constant term for polynomial for intervals with internal knots
a[:(n-1), 2][~u] = uu[:(n-1), 2][~u]
a[:(n-1), 1][~u] = uu[:(n-1), 3][~u]
a[:(n-1), 0][~u] = 0.5 * eta[:(n-1)][~u] # leading coefficient
a[:(n - 1), 2][~u] = uu[:(n - 1), 2][~u]
a[:(n - 1), 1][~u] = uu[:(n - 1), 3][~u]
a[:(n - 1), 0][~u] = 0.5 * eta[:(n - 1)][~u] # leading coefficient

a[(n - 1):(n + q + r + ss - 1), 2] = \
uu[(n - 1):(n + q + r + ss - 1), 2] + \
Expand Down
42 changes: 21 additions & 21 deletions pvlib/tests/ivtools/test_sdm.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,14 @@ def test_fit_pvsyst_sandia(npts=3000):

pvsyst.update(zip(varlist, [Iph, Io, Rs, Rsh, u]))

expected = sdm.fit_pvsyst_sandia(ivcurves, iv_specs)
modeled = sdm.fit_pvsyst_sandia(ivcurves, iv_specs)
param_res = pvsystem.calcparams_pvsyst(
effective_irradiance=ivcurves['ee'], temp_cell=ivcurves['tc'],
alpha_sc=iv_specs['alpha_sc'], gamma_ref=expected['gamma_ref'],
mu_gamma=expected['mu_gamma'], I_L_ref=expected['I_L_ref'],
I_o_ref=expected['I_o_ref'], R_sh_ref=expected['R_sh_ref'],
R_sh_0=expected['R_sh_0'], R_s=expected['R_s'],
cells_in_series=iv_specs['cells_in_series'], EgRef=expected['EgRef'])
alpha_sc=iv_specs['alpha_sc'], gamma_ref=modeled['gamma_ref'],
mu_gamma=modeled['mu_gamma'], I_L_ref=modeled['I_L_ref'],
I_o_ref=modeled['I_o_ref'], R_sh_ref=modeled['R_sh_ref'],
R_sh_0=modeled['R_sh_0'], R_s=modeled['R_s'],
cells_in_series=iv_specs['cells_in_series'], EgRef=modeled['EgRef'])
iv_res = pvsystem.singlediode(*param_res)

ivcurves['p_mp'] = ivcurves['v_mp'] * ivcurves['i_mp'] # power
Expand All @@ -244,35 +244,35 @@ def test_fit_pvsyst_sandia(npts=3000):
assert all((iv_specs[spec] == pvsyst_specs[spec]) for spec in spec_list)
# I_L_ref, I_o_ref, EgRef, R_sh_ref, R_sh_0, R_sh_exp, R_s, gamma_ref,
# mu_gamma
assert np.isclose(expected['I_L_ref'], pvsyst['I_L_ref'], rtol=6.5e-5)
assert np.isclose(expected['I_o_ref'], pvsyst['I_o_ref'], rtol=0.15)
assert np.isclose(expected['R_s'], pvsyst['R_s'], rtol=0.0035)
assert np.isclose(expected['R_sh_ref'], pvsyst['R_sh_ref'], rtol=0.091)
assert np.isclose(expected['R_sh_0'], pvsyst['R_sh_0'], rtol=0.013)
assert np.isclose(expected['EgRef'], pvsyst['EgRef'], rtol=0.037)
assert np.isclose(expected['gamma_ref'], pvsyst['gamma_ref'], rtol=0.0045)
assert np.isclose(expected['mu_gamma'], pvsyst['mu_gamma'], rtol=0.064)
assert np.isclose(modeled['I_L_ref'], pvsyst['I_L_ref'], rtol=6.5e-5)
assert np.isclose(modeled['I_o_ref'], pvsyst['I_o_ref'], rtol=0.15)
assert np.isclose(modeled['R_s'], pvsyst['R_s'], rtol=0.0035)
assert np.isclose(modeled['R_sh_ref'], pvsyst['R_sh_ref'], rtol=0.091)
assert np.isclose(modeled['R_sh_0'], pvsyst['R_sh_0'], rtol=0.013)
assert np.isclose(modeled['EgRef'], pvsyst['EgRef'], rtol=0.037)
assert np.isclose(modeled['gamma_ref'], pvsyst['gamma_ref'], rtol=0.0045)
assert np.isclose(modeled['mu_gamma'], pvsyst['mu_gamma'], rtol=0.064)

# Iph, Io, Rsh, Rs, u
mask = np.ones(expected['u'].shape, dtype=bool)
mask = np.ones(modeled['u'].shape, dtype=bool)
# exclude one curve with different convergence
umask = mask.copy()
umask[2540] = False
assert all(expected['u'][umask] == pvsyst['u'][:npts][umask])
assert all(modeled['u'][umask] == pvsyst['u'][:npts][umask])
assert np.allclose(
expected['iph'][expected['u']], pvsyst['iph'][:npts][expected['u']],
modeled['iph'][modeled['u']], pvsyst['iph'][:npts][modeled['u']],
equal_nan=True, rtol=0.0009)
assert np.allclose(
expected['io'][expected['u']], pvsyst['io'][:npts][expected['u']],
modeled['io'][modeled['u']], pvsyst['io'][:npts][modeled['u']],
equal_nan=True, rtol=0.096)
assert np.allclose(
expected['rs'][expected['u']], pvsyst['rs'][:npts][expected['u']],
modeled['rs'][modeled['u']], pvsyst['rs'][:npts][modeled['u']],
equal_nan=True, rtol=0.035)
# exclude one curve with Rsh outside 63% tolerance
rshmask = expected['u'].copy()
rshmask = modeled['u'].copy()
rshmask[2545] = False
assert np.allclose(
expected['rsh'][rshmask], pvsyst['rsh'][:npts][rshmask],
modeled['rsh'][rshmask], pvsyst['rsh'][:npts][rshmask],
equal_nan=True, rtol=0.63)


Expand Down
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@
TESTS_REQUIRE = ['nose', 'pytest', 'pytest-cov', 'pytest-mock',
'pytest-timeout', 'pytest-rerunfailures', 'pytest-remotedata']
EXTRAS_REQUIRE = {
'optional': ['ephem', 'cython', 'netcdf4', 'nrel-pysam', 'numba',
'pvfactors', 'scipy', 'siphon', 'tables', 'cftime >= 1.1.1'],
'optional': ['cython', 'ephem', 'netcdf4', 'nrel-pysam', 'numba',
'pvfactors', 'scipy', 'siphon', 'statsmodels', 'tables',
'cftime >= 1.1.1'],
'doc': ['ipython', 'matplotlib', 'sphinx == 1.8.5', 'sphinx_rtd_theme',
'sphinx-gallery', 'docutils == 0.15.2', 'pillow', 'scipy',
'netcdf4', 'siphon', 'tables'],
Expand Down

0 comments on commit df7520e

Please sign in to comment.