Skip to content

Commit f229255

Browse files
committed
rename function and move to pvlib.spectrum
following the conventions set out in pvlib#1628
1 parent 440ef38 commit f229255

File tree

8 files changed

+207
-206
lines changed

8 files changed

+207
-206
lines changed

docs/sphinx/source/reference/airmass_atmospheric.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,3 @@ Airmass and atmospheric models
1717
atmosphere.kasten96_lt
1818
atmosphere.angstrom_aod_at_lambda
1919
atmosphere.angstrom_alpha
20-
atmosphere.caballero_spectral_correction

docs/sphinx/source/reference/effects_on_pv_system_output/spectrum.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ Spectrum
1010
spectrum.get_example_spectral_response
1111
spectrum.get_am15g
1212
spectrum.calc_spectral_mismatch_field
13+
spectrum.spectral_factor_caballero
1314
spectrum.spectral_factor_firstsolar
1415
spectrum.spectral_factor_sapm

docs/sphinx/source/whatsnew/v0.9.6.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ Deprecations
3333

3434
Enhancements
3535
~~~~~~~~~~~~
36-
* `Added a function :py:func:`pvlib.atmosphere.caballero_spectral_correction` to estimate a spectral mismatch modifier based on absolute (pressure-adjusted)
37-
airmass (AM), aerosol optical depth (AOD) at 500 nm and precipitable water (PW). (:pull:`1296`)
36+
* Added a function :py:func:`pvlib.spectrum.spectral_factor_caballero`
37+
to estimate spectral mismatch modifiers from atmospheric conditions. (:pull:`1296`)
3838
* Added a new irradiance decomposition model :py:func:`pvlib.irradiance.louche`. (:pull:`1705`)
3939
* Add optional encoding parameter to :py:func:`pvlib.iotools.read_tmy3`.
4040
(:issue:`1732`, :pull:`1737`)

pvlib/atmosphere.py

Lines changed: 0 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -533,153 +533,3 @@ def angstrom_alpha(aod1, lambda1, aod2, lambda2):
533533
pvlib.atmosphere.angstrom_aod_at_lambda
534534
"""
535535
return - np.log(aod1 / aod2) / np.log(lambda1 / lambda2)
536-
537-
538-
def caballero_spectral_correction(airmass_absolute, aod500, pw,
539-
module_type=None, coefficients=None,
540-
aod500_ref=0.084, pw_ref=1.42):
541-
r"""
542-
Spectral mismatch modifier based on absolute (pressure-adjusted)
543-
airmass (AM), aerosol optical depth (AOD) at 500 nm and
544-
precipitable water (PW).
545-
546-
Estimates a spectral mismatch modifier :math:`M` representing
547-
the effect on module short circuit current of variation in the
548-
spectral irradiance. :math:`M` is estimated from absolute
549-
(pressure-adjusted) AM, :math:`ama`, AOD at 500 nm, :math:`aod500`
550-
and PW, :math:`pw` [1]_.
551-
552-
The best fit polynomial for each atmospheric parameter (AM, AOD, PW)
553-
and PV technology under study has been obtained from synthetic spectra
554-
generated with SMARTS [2]_, considering the following boundary
555-
conditions:
556-
557-
* :math:`1.0 <= ama <= 5.0`
558-
* :math:`0.05 <= aod500 <= 0.6`
559-
* :math:`0.25 \textrm{cm} <= pw <= 4 \textrm{cm}`
560-
* Spectral range is limited to that of CMP11 (280 nm to 2800 nm)
561-
* All other parameters fixed at G173 standard
562-
563-
Elevation (deg), AOD and PW data were recorded in the city of Jaén,
564-
Spain for one year synchronously with both, broadband and
565-
spectroradiometric measurements of 30º tilted global irradiance
566-
south-facing logged in 5-min intervals. AM was estimated through
567-
elevation data.
568-
569-
Finally, the spectral mismatch factor was calculated for each
570-
of the PV technologies and a multivariable regression adjustment
571-
as a function of AM, AOD and PW was performed according to [3] and [1]_.
572-
As such, the polynomial adjustment coefficients included in [1]
573-
were obtained.
574-
575-
576-
Parameters
577-
----------
578-
airmass_absolute : array-like
579-
absolute (pressure-adjusted) airmass. [unitless]
580-
581-
aod500 : array-like
582-
atmospheric aerosol optical depth at 500 nm. [unitless]
583-
584-
pw : array-like
585-
atmospheric precipitable water. [cm]
586-
587-
module_type : None or string, default None
588-
a string specifying a cell type. Values of 'cdte', 'monosi', 'cigs',
589-
'multisi','asi' and 'perovskite'. If provided,
590-
module_type selects default coefficients for the following modules:
591-
592-
* 'cdte' - anonymous CdTe module.
593-
* 'monosi', - anonymous sc-si module.
594-
* 'multisi', - anonymous mc-si- module.
595-
* 'cigs' - anonymous copper indium gallium selenide module.
596-
* 'asi' - anonymous amorphous silicon module.
597-
* 'perovskite' - anonymous pervoskite module.
598-
599-
coefficients : None or array-like, optional
600-
the coefficients employed have been obtained with experimental
601-
data in the city of Jaén, Spain. It is pending to verify if such
602-
coefficients vary in places with extreme climates where AOD and
603-
pw values are frequently high.
604-
605-
aod500_ref : numeric, default 0.084
606-
atmospheric aerosol optical depth at 500nm value related to the
607-
AM1.5G ASTMG-173-03 reference spectrum. [unitless]
608-
609-
pw_ref : numeric, default 1.42
610-
atmospheric precipitable water value related to the AM1.5G ASTMG-173-03
611-
reference spectrum. [cm]
612-
613-
Returns
614-
-------
615-
modifier: array-like
616-
spectral mismatch factor (unitless) which is can be multiplied
617-
with broadband irradiance reaching a module's cells to estimate
618-
effective irradiance, i.e., the irradiance that is converted to
619-
electrical current.
620-
621-
References
622-
----------
623-
.. [1] Caballero, J.A., Fernández, E., Theristis, M.,
624-
Almonacid, F., and Nofuentes, G. "Spectral Corrections Based on
625-
Air Mass, Aerosol Optical Depth and Precipitable Water
626-
for PV Performance Modeling."
627-
IEEE Journal of Photovoltaics 2018, 8(2), 552-558.
628-
https://doi.org/10.1109/jphotov.2017.2787019
629-
.. [2] Gueymard, Christian. SMARTS2: a simple model of the
630-
atmospheric radiative transfer of sunshine: algorithms
631-
and performance assessment. Cocoa, FL:
632-
Florida Solar Energy Center, 1995.
633-
.. [3] Theristis, M., Fernández, E., Almonacid, F., and
634-
Pérez-Higueras, Pedro. "Spectral Corrections Based
635-
on Air Mass, Aerosol Optical Depth and Precipitable
636-
Water for CPV Performance Modeling."
637-
IEEE Journal of Photovoltaics 2016, 6(6), 1598-1604.
638-
https://doi.org/10.1109/jphotov.2016.2606702
639-
640-
"""
641-
642-
# Experimental coefficients
643-
644-
_coefficients = {}
645-
_coefficients['cdte'] = (
646-
1.0044, 0.0095, -0.0037, 0.0002, 0.0000, -0.0046,
647-
-0.0182, 0, 0.0095, 0.0068, 0, 1)
648-
_coefficients['monosi'] = (
649-
0.9706, 0.0377, -0.0123, 0.0025, -0.0002, 0.0159,
650-
-0.0165, 0, -0.0016, -0.0027, 1, 0)
651-
_coefficients['multisi'] = (
652-
0.9836, 0.0254, -0.0085, 0.0016, -0.0001, 0.0094,
653-
-0.0132, 0, -0.0002, -0.0011, 1, 0)
654-
_coefficients['cigs'] = (
655-
0.9801, 0.0283, -0.0092, 0.0019, -0.0001, 0.0117,
656-
-0.0126, 0, -0.0011, -0.0019, 1, 0)
657-
_coefficients['asi'] = (
658-
1.1060, -0.0848, 0.0302, -0.0076, 0.0006, -0.1283,
659-
0.0986, -0.0254, 0.0156, 0.0146, 1, 0)
660-
_coefficients['perovskite'] = (
661-
1.0637, -0.0491, 0.0180, -0.0047, 0.0004, -0.0773,
662-
0.0583, -0.0159, 0.01251, 0.0109, 1, 0)
663-
664-
if module_type is None and coefficients is None:
665-
raise ValueError('Must provide either `module_type` or `coefficients`')
666-
if module_type is not None and coefficients is not None:
667-
raise ValueError('Only one of `module_type` and `coefficients` should '
668-
'be provided')
669-
if module_type is not None:
670-
coeff = _coefficients[module_type]
671-
else:
672-
coeff = coefficients
673-
674-
# Evaluate spectral correction factor
675-
ama = airmass_absolute
676-
modifier = (
677-
coeff[0] + (ama) * coeff[1] + (ama * ama) * coeff[2]
678-
+ (ama * ama * ama) * coeff[3] + (ama * ama * ama * ama) * coeff[4]
679-
+ (aod500 - aod500_ref) * coeff[5]
680-
+ ((aod500 - aod500_ref) * (ama) * coeff[6]) * coeff[10]
681-
+ ((aod500 - aod500_ref) * (np.log(ama)) * coeff[6]) * coeff[11]
682-
+ (aod500 - aod500_ref) * (ama * ama) * coeff[7]
683-
+ (pw - pw_ref) * coeff[8] + (pw - pw_ref) * (np.log(ama)) * coeff[9])
684-
685-
return modifier

pvlib/spectrum/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
calc_spectral_mismatch_field,
44
get_am15g,
55
get_example_spectral_response,
6+
spectral_factor_caballero,
67
spectral_factor_firstsolar,
78
spectral_factor_sapm,
89
)

pvlib/spectrum/mismatch.py

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,3 +446,153 @@ def spectral_factor_sapm(airmass_absolute, module):
446446
spectral_loss = pd.Series(spectral_loss, airmass_absolute.index)
447447

448448
return spectral_loss
449+
450+
451+
def caballero_spectral_correction(airmass_absolute, aod500, pw,
452+
module_type=None, coefficients=None,
453+
aod500_ref=0.084, pw_ref=1.42):
454+
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+
488+
489+
Parameters
490+
----------
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
498+
atmospheric precipitable water. [cm]
499+
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:
504+
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.
511+
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.
517+
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]
521+
522+
pw_ref : numeric, default 1.42
523+
atmospheric precipitable water value related to the AM1.5G ASTMG-173-03
524+
reference spectrum. [cm]
525+
526+
Returns
527+
-------
528+
modifier: array-like
529+
spectral mismatch factor (unitless) which is can be multiplied
530+
with broadband irradiance reaching a module's cells to estimate
531+
effective irradiance, i.e., the irradiance that is converted to
532+
electrical current.
533+
534+
References
535+
----------
536+
.. [1] Caballero, J.A., Fernández, E., Theristis, M.,
537+
Almonacid, F., and Nofuentes, G. "Spectral Corrections Based on
538+
Air Mass, Aerosol Optical Depth and Precipitable Water
539+
for PV Performance Modeling."
540+
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
556+
557+
_coefficients = {}
558+
_coefficients['cdte'] = (
559+
1.0044, 0.0095, -0.0037, 0.0002, 0.0000, -0.0046,
560+
-0.0182, 0, 0.0095, 0.0068, 0, 1)
561+
_coefficients['monosi'] = (
562+
0.9706, 0.0377, -0.0123, 0.0025, -0.0002, 0.0159,
563+
-0.0165, 0, -0.0016, -0.0027, 1, 0)
564+
_coefficients['multisi'] = (
565+
0.9836, 0.0254, -0.0085, 0.0016, -0.0001, 0.0094,
566+
-0.0132, 0, -0.0002, -0.0011, 1, 0)
567+
_coefficients['cigs'] = (
568+
0.9801, 0.0283, -0.0092, 0.0019, -0.0001, 0.0117,
569+
-0.0126, 0, -0.0011, -0.0019, 1, 0)
570+
_coefficients['asi'] = (
571+
1.1060, -0.0848, 0.0302, -0.0076, 0.0006, -0.1283,
572+
0.0986, -0.0254, 0.0156, 0.0146, 1, 0)
573+
_coefficients['perovskite'] = (
574+
1.0637, -0.0491, 0.0180, -0.0047, 0.0004, -0.0773,
575+
0.0583, -0.0159, 0.01251, 0.0109, 1, 0)
576+
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')
582+
if module_type is not None:
583+
coeff = _coefficients[module_type]
584+
else:
585+
coeff = coefficients
586+
587+
# Evaluate spectral correction factor
588+
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+
598+
return modifier

pvlib/tests/test_atmosphere.py

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -131,56 +131,3 @@ def test_bird_hulstrom80_aod_bb():
131131
aod380, aod500 = 0.22072480948195175, 0.1614279181106312
132132
bird_hulstrom = atmosphere.bird_hulstrom80_aod_bb(aod380, aod500)
133133
assert np.isclose(0.11738229553812768, bird_hulstrom)
134-
135-
136-
@pytest.mark.parametrize("module_type,expected", [
137-
('asi', np.array([0.9108, 0.9897, 0.9707, 1.0265, 1.0798, 0.9537])),
138-
('perovskite', np.array([0.9422, 0.9932, 0.9868, 1.0183, 1.0604, 0.9737])),
139-
('cdte', np.array([0.9824, 1.0000, 1.0065, 1.0117, 1.042, 0.9979])),
140-
('multisi', np.array([0.9907, 0.9979, 1.0203, 1.0081, 1.0058, 1.019])),
141-
('monosi', np.array([0.9935, 0.9987, 1.0264, 1.0074, 0.9999, 1.0263])),
142-
('cigs', np.array([1.0014, 1.0011, 1.0270, 1.0082, 1.0029, 1.026])),
143-
])
144-
def test_caballero_spectral_correction(module_type, expected):
145-
ams = np.array([3.0, 1.5, 3.0, 1.5, 1.5, 3.0])
146-
aods = np.array([1.0, 1.0, 0.02, 0.02, 0.08, 0.08])
147-
pws = np.array([1.42, 1.42, 1.42, 1.42, 4.0, 1.0])
148-
out = atmosphere.caballero_spectral_correction(ams, aods, pws,
149-
module_type=module_type,
150-
aod500_ref=0.084,
151-
pw_ref=1.42)
152-
assert np.allclose(expected, out, atol=1e-3)
153-
154-
155-
def test_caballero_spectral_correction_supplied():
156-
# use the cdte coeffs
157-
coeffs = (
158-
1.0044, 0.0095, -0.0037, 0.0002, 0.0000, -0.0046,
159-
-0.0182, 0, 0.0095, 0.0068, 0, 1)
160-
out = atmosphere.caballero_spectral_correction(1, 1, 1,
161-
coefficients=coeffs,
162-
aod500_ref=0.084,
163-
pw_ref=1.42)
164-
expected = 1.0021964
165-
assert_allclose(out, expected, atol=1e-3)
166-
167-
168-
def test_caballero_spectral_correction_supplied_redundant():
169-
# Error when specifying both module_type and coefficients
170-
coeffs = (
171-
1.0044, 0.0095, -0.0037, 0.0002, 0.0000, -0.0046,
172-
-0.0182, 0, 0.0095, 0.0068, 0, 1)
173-
with pytest.raises(ValueError):
174-
atmosphere.caballero_spectral_correction(1, 1, 1,
175-
module_type='cdte',
176-
coefficients=coeffs,
177-
aod500_ref=0.084, pw_ref=1.42)
178-
179-
180-
def test_caballero_spectral_correction_supplied_ambiguous():
181-
# Error when specifying neither module_type nor coefficients
182-
with pytest.raises(ValueError):
183-
atmosphere.caballero_spectral_correction(1, 1, 1,
184-
module_type=None,
185-
coefficients=None,
186-
aod500_ref=0.084, pw_ref=1.42)

0 commit comments

Comments
 (0)