Skip to content

Commit 4ac3a89

Browse files
committed
misc cleanup
- reorder and rename parameters to match pvlib#1768 - remove reference parameters - shorten/simplify docstring - restructure calculation to be more readable
1 parent f229255 commit 4ac3a89

File tree

2 files changed

+73
-112
lines changed

2 files changed

+73
-112
lines changed

pvlib/spectrum/mismatch.py

Lines changed: 66 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ def spectral_factor_firstsolar(pw, airmass_absolute, module_type=None,
320320
Returns
321321
-------
322322
modifier: array-like
323-
spectral mismatch factor (unitless) which is can be multiplied
323+
spectral mismatch factor (unitless) which is multiplied
324324
with broadband irradiance reaching a module's cells to estimate
325325
effective irradiance, i.e., the irradiance that is converted to
326326
electrical current.
@@ -448,85 +448,50 @@ def spectral_factor_sapm(airmass_absolute, module):
448448
return spectral_loss
449449

450450

451-
def caballero_spectral_correction(airmass_absolute, aod500, pw,
452-
module_type=None, coefficients=None,
453-
aod500_ref=0.084, pw_ref=1.42):
451+
def spectral_factor_caballero(precipitable_water, airmass_absolute, aod500,
452+
module_type=None, coefficients=None):
454453
r"""
455-
Spectral mismatch modifier based on absolute (pressure-adjusted)
456-
airmass (AM), aerosol optical depth (AOD) at 500 nm and
457-
precipitable water (PW).
458-
459-
Estimates a spectral mismatch modifier :math:`M` representing
460-
the effect on module short circuit current of variation in the
461-
spectral irradiance. :math:`M` is estimated from absolute
462-
(pressure-adjusted) AM, :math:`ama`, AOD at 500 nm, :math:`aod500`
463-
and PW, :math:`pw` [1]_.
464-
465-
The best fit polynomial for each atmospheric parameter (AM, AOD, PW)
466-
and PV technology under study has been obtained from synthetic spectra
467-
generated with SMARTS [2]_, considering the following boundary
468-
conditions:
469-
470-
* :math:`1.0 <= ama <= 5.0`
471-
* :math:`0.05 <= aod500 <= 0.6`
472-
* :math:`0.25 \textrm{cm} <= pw <= 4 \textrm{cm}`
473-
* Spectral range is limited to that of CMP11 (280 nm to 2800 nm)
474-
* All other parameters fixed at G173 standard
475-
476-
Elevation (deg), AOD and PW data were recorded in the city of Jaén,
477-
Spain for one year synchronously with both, broadband and
478-
spectroradiometric measurements of 30º tilted global irradiance
479-
south-facing logged in 5-min intervals. AM was estimated through
480-
elevation data.
481-
482-
Finally, the spectral mismatch factor was calculated for each
483-
of the PV technologies and a multivariable regression adjustment
484-
as a function of AM, AOD and PW was performed according to [3] and [1]_.
485-
As such, the polynomial adjustment coefficients included in [1]
486-
were obtained.
487-
454+
Estimate a technology-specific spectral mismatch modifier from
455+
airmass, aerosol optical depth, and atmospheric precipitable water,
456+
using the Caballero model.
457+
458+
The model structure was motivated by examining the effect of these three
459+
atmospheric parameters on simulated irradiance spectra and spectral
460+
modifiers. However, the coefficient values reported in [1]_ and
461+
available here via the ``module_type`` parameter were determined
462+
by fitting the model equations to spectral factors calculated from
463+
global tilted spectral irradiance measurements taken in the city of
464+
Jaén, Spain. See [1]_ for details.
488465
489466
Parameters
490467
----------
491-
airmass_absolute : array-like
492-
absolute (pressure-adjusted) airmass. [unitless]
493-
494-
aod500 : array-like
495-
atmospheric aerosol optical depth at 500 nm. [unitless]
496-
497-
pw : array-like
468+
precipitable_water : numeric
498469
atmospheric precipitable water. [cm]
499470
500-
module_type : None or string, default None
501-
a string specifying a cell type. Values of 'cdte', 'monosi', 'cigs',
502-
'multisi','asi' and 'perovskite'. If provided,
503-
module_type selects default coefficients for the following modules:
471+
airmass_absolute : numeric
472+
absolute (pressure-adjusted) airmass. [unitless]
504473
505-
* 'cdte' - anonymous CdTe module.
506-
* 'monosi', - anonymous sc-si module.
507-
* 'multisi', - anonymous mc-si- module.
508-
* 'cigs' - anonymous copper indium gallium selenide module.
509-
* 'asi' - anonymous amorphous silicon module.
510-
* 'perovskite' - anonymous pervoskite module.
474+
aod500 : numeric
475+
atmospheric aerosol optical depth at 500 nm. [unitless]
511476
512-
coefficients : None or array-like, optional
513-
the coefficients employed have been obtained with experimental
514-
data in the city of Jaén, Spain. It is pending to verify if such
515-
coefficients vary in places with extreme climates where AOD and
516-
pw values are frequently high.
477+
module_type : str, optional
478+
One of the following PV technology strings from [1]_:
517479
518-
aod500_ref : numeric, default 0.084
519-
atmospheric aerosol optical depth at 500nm value related to the
520-
AM1.5G ASTMG-173-03 reference spectrum. [unitless]
480+
* ``'cdte'`` - anonymous CdTe module.
481+
* ``'monosi'``, - anonymous sc-si module.
482+
* ``'multisi'``, - anonymous mc-si- module.
483+
* ``'cigs'`` - anonymous copper indium gallium selenide module.
484+
* ``'asi'`` - anonymous amorphous silicon module.
485+
* ``'perovskite'`` - anonymous pervoskite module.
521486
522-
pw_ref : numeric, default 1.42
523-
atmospheric precipitable water value related to the AM1.5G ASTMG-173-03
524-
reference spectrum. [cm]
487+
coefficients : array-like, optional
488+
user-defined coefficients, if not using one of the default coefficient
489+
sets via the ``module_type`` parameter.
525490
526491
Returns
527492
-------
528-
modifier: array-like
529-
spectral mismatch factor (unitless) which is can be multiplied
493+
modifier: numeric
494+
spectral mismatch factor (unitless) which is multiplied
530495
with broadband irradiance reaching a module's cells to estimate
531496
effective irradiance, i.e., the irradiance that is converted to
532497
electrical current.
@@ -538,22 +503,18 @@ def caballero_spectral_correction(airmass_absolute, aod500, pw,
538503
Air Mass, Aerosol Optical Depth and Precipitable Water
539504
for PV Performance Modeling."
540505
IEEE Journal of Photovoltaics 2018, 8(2), 552-558.
541-
https://doi.org/10.1109/jphotov.2017.2787019
542-
.. [2] Gueymard, Christian. SMARTS2: a simple model of the
543-
atmospheric radiative transfer of sunshine: algorithms
544-
and performance assessment. Cocoa, FL:
545-
Florida Solar Energy Center, 1995.
546-
.. [3] Theristis, M., Fernández, E., Almonacid, F., and
547-
Pérez-Higueras, Pedro. "Spectral Corrections Based
548-
on Air Mass, Aerosol Optical Depth and Precipitable
549-
Water for CPV Performance Modeling."
550-
IEEE Journal of Photovoltaics 2016, 6(6), 1598-1604.
551-
https://doi.org/10.1109/jphotov.2016.2606702
552-
553-
"""
554-
555-
# Experimental coefficients
506+
:doi:`10.1109/jphotov.2017.2787019`
507+
"""
508+
509+
if module_type is None and coefficients is None:
510+
raise ValueError('Must provide either `module_type` or `coefficients`')
511+
if module_type is not None and coefficients is not None:
512+
raise ValueError('Only one of `module_type` and `coefficients` should '
513+
'be provided')
556514

515+
# Experimental coefficients from [1]_.
516+
# The extra 0/1 coefficients at the end are used to enable/disable
517+
# terms to match the different equation forms in Table 1.
557518
_coefficients = {}
558519
_coefficients['cdte'] = (
559520
1.0044, 0.0095, -0.0037, 0.0002, 0.0000, -0.0046,
@@ -574,25 +535,34 @@ def caballero_spectral_correction(airmass_absolute, aod500, pw,
574535
1.0637, -0.0491, 0.0180, -0.0047, 0.0004, -0.0773,
575536
0.0583, -0.0159, 0.01251, 0.0109, 1, 0)
576537

577-
if module_type is None and coefficients is None:
578-
raise ValueError('Must provide either `module_type` or `coefficients`')
579-
if module_type is not None and coefficients is not None:
580-
raise ValueError('Only one of `module_type` and `coefficients` should '
581-
'be provided')
582538
if module_type is not None:
583539
coeff = _coefficients[module_type]
584540
else:
585541
coeff = coefficients
586542

587543
# Evaluate spectral correction factor
588544
ama = airmass_absolute
589-
modifier = (
590-
coeff[0] + (ama) * coeff[1] + (ama * ama) * coeff[2]
591-
+ (ama * ama * ama) * coeff[3] + (ama * ama * ama * ama) * coeff[4]
592-
+ (aod500 - aod500_ref) * coeff[5]
593-
+ ((aod500 - aod500_ref) * (ama) * coeff[6]) * coeff[10]
594-
+ ((aod500 - aod500_ref) * (np.log(ama)) * coeff[6]) * coeff[11]
595-
+ (aod500 - aod500_ref) * (ama * ama) * coeff[7]
596-
+ (pw - pw_ref) * coeff[8] + (pw - pw_ref) * (np.log(ama)) * coeff[9])
597-
545+
aod500_ref = 0.084
546+
pw_ref = 1.4164
547+
548+
f_AM = (
549+
coeff[0]
550+
+ coeff[1] * ama
551+
+ coeff[2] * ama**2
552+
+ coeff[3] * ama**3
553+
+ coeff[4] * ama**4
554+
)
555+
# Eq 6, with Table 1
556+
f_AOD = (aod500 - aod500_ref) * (
557+
coeff[5]
558+
+ coeff[10] * coeff[6] * ama
559+
+ coeff[11] * coeff[6] * np.log(ama)
560+
+ coeff[7] * ama**2
561+
)
562+
# Eq 7, with Table 1
563+
f_PW = (precipitable_water - pw_ref) * (
564+
coeff[8]
565+
+ coeff[9] * np.log(ama)
566+
)
567+
modifier = f_AM + f_AOD + f_PW # Eq 5
598568
return modifier

pvlib/tests/test_spectrum.py

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -283,10 +283,8 @@ def test_spectral_factor_caballero(module_type, expected):
283283
ams = np.array([3.0, 1.5, 3.0, 1.5, 1.5, 3.0])
284284
aods = np.array([1.0, 1.0, 0.02, 0.02, 0.08, 0.08])
285285
pws = np.array([1.42, 1.42, 1.42, 1.42, 4.0, 1.0])
286-
out = spectrum.spectral_factor_caballero(ams, aods, pws,
287-
module_type=module_type,
288-
aod500_ref=0.084,
289-
pw_ref=1.42)
286+
out = spectrum.spectral_factor_caballero(pws, ams, aods,
287+
module_type=module_type)
290288
assert np.allclose(expected, out, atol=1e-3)
291289

292290

@@ -295,10 +293,7 @@ def test_spectral_factor_caballero_supplied():
295293
coeffs = (
296294
1.0044, 0.0095, -0.0037, 0.0002, 0.0000, -0.0046,
297295
-0.0182, 0, 0.0095, 0.0068, 0, 1)
298-
out = spectrum.spectral_factor_caballero(1, 1, 1,
299-
coefficients=coeffs,
300-
aod500_ref=0.084,
301-
pw_ref=1.42)
296+
out = spectrum.spectral_factor_caballero(1, 1, 1, coefficients=coeffs)
302297
expected = 1.0021964
303298
assert_allclose(out, expected, atol=1e-3)
304299

@@ -309,16 +304,12 @@ def test_spectral_factor_caballero_supplied_redundant():
309304
1.0044, 0.0095, -0.0037, 0.0002, 0.0000, -0.0046,
310305
-0.0182, 0, 0.0095, 0.0068, 0, 1)
311306
with pytest.raises(ValueError):
312-
spectrum.spectral_factor_caballero(1, 1, 1,
313-
module_type='cdte',
314-
coefficients=coeffs,
315-
aod500_ref=0.084, pw_ref=1.42)
307+
spectrum.spectral_factor_caballero(1, 1, 1, module_type='cdte',
308+
coefficients=coeffs)
316309

317310

318311
def test_spectral_factor_caballero_supplied_ambiguous():
319312
# Error when specifying neither module_type nor coefficients
320313
with pytest.raises(ValueError):
321-
spectrum.spectral_factor_caballero(1, 1, 1,
322-
module_type=None,
323-
coefficients=None,
324-
aod500_ref=0.084, pw_ref=1.42)
314+
spectrum.spectral_factor_caballero(1, 1, 1, module_type=None,
315+
coefficients=None)

0 commit comments

Comments
 (0)