pvlib 0.11.0a1__py3-none-any.whl → 0.11.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. pvlib/_deprecation.py +73 -0
  2. pvlib/atmosphere.py +236 -1
  3. pvlib/bifacial/__init__.py +4 -4
  4. pvlib/bifacial/loss_models.py +163 -0
  5. pvlib/clearsky.py +53 -51
  6. pvlib/data/pvgis_tmy_meta.json +32 -93
  7. pvlib/data/pvgis_tmy_test.csv +8761 -0
  8. pvlib/data/tmy_45.000_8.000_2005_2023.csv +8789 -0
  9. pvlib/data/tmy_45.000_8.000_2005_2023.epw +8768 -0
  10. pvlib/data/tmy_45.000_8.000_2005_2023.json +1 -0
  11. pvlib/data/tmy_45.000_8.000_2005_2023.txt +8761 -0
  12. pvlib/data/tmy_45.000_8.000_userhorizon.json +1 -1
  13. pvlib/iam.py +4 -4
  14. pvlib/iotools/midc.py +1 -1
  15. pvlib/iotools/pvgis.py +39 -13
  16. pvlib/irradiance.py +237 -173
  17. pvlib/ivtools/sdm.py +75 -52
  18. pvlib/location.py +5 -5
  19. pvlib/modelchain.py +1 -1
  20. pvlib/pvsystem.py +134 -86
  21. pvlib/shading.py +8 -8
  22. pvlib/singlediode.py +1 -1
  23. pvlib/solarposition.py +101 -80
  24. pvlib/spa.py +28 -24
  25. pvlib/spectrum/__init__.py +9 -4
  26. pvlib/spectrum/irradiance.py +273 -0
  27. pvlib/spectrum/mismatch.py +118 -508
  28. pvlib/spectrum/response.py +280 -0
  29. pvlib/spectrum/spectrl2.py +18 -17
  30. pvlib/temperature.py +49 -3
  31. pvlib/tests/bifacial/test_losses_models.py +54 -0
  32. pvlib/tests/iotools/test_pvgis.py +58 -12
  33. pvlib/tests/ivtools/test_sdm.py +23 -1
  34. pvlib/tests/spectrum/__init__.py +0 -0
  35. pvlib/tests/spectrum/conftest.py +40 -0
  36. pvlib/tests/spectrum/test_irradiance.py +138 -0
  37. pvlib/tests/{test_spectrum.py → spectrum/test_mismatch.py} +32 -306
  38. pvlib/tests/spectrum/test_response.py +124 -0
  39. pvlib/tests/spectrum/test_spectrl2.py +72 -0
  40. pvlib/tests/test__deprecation.py +97 -0
  41. pvlib/tests/test_atmosphere.py +218 -0
  42. pvlib/tests/test_clearsky.py +44 -26
  43. pvlib/tests/test_conftest.py +0 -44
  44. pvlib/tests/test_irradiance.py +62 -16
  45. pvlib/tests/test_pvsystem.py +17 -1
  46. pvlib/tests/test_solarposition.py +117 -36
  47. pvlib/tests/test_spa.py +30 -1
  48. pvlib/tools.py +26 -2
  49. pvlib/tracking.py +53 -47
  50. {pvlib-0.11.0a1.dist-info → pvlib-0.11.2.dist-info}/METADATA +34 -31
  51. {pvlib-0.11.0a1.dist-info → pvlib-0.11.2.dist-info}/RECORD +55 -47
  52. {pvlib-0.11.0a1.dist-info → pvlib-0.11.2.dist-info}/WHEEL +1 -1
  53. pvlib/data/aod550_tcwv_20121101_test.nc +0 -0
  54. pvlib/data/pvgis_tmy_test.dat +0 -8761
  55. pvlib/data/tmy_45.000_8.000_2005_2016.csv +0 -8789
  56. pvlib/data/tmy_45.000_8.000_2005_2016.epw +0 -8768
  57. pvlib/data/tmy_45.000_8.000_2005_2016.json +0 -1
  58. pvlib/data/tmy_45.000_8.000_2005_2016.txt +0 -8761
  59. pvlib/data/variables_style_rules.csv +0 -55
  60. {pvlib-0.11.0a1.dist-info → pvlib-0.11.2.dist-info}/AUTHORS.md +0 -0
  61. {pvlib-0.11.0a1.dist-info → pvlib-0.11.2.dist-info}/LICENSE +0 -0
  62. {pvlib-0.11.0a1.dist-info → pvlib-0.11.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,273 @@
1
+ """
2
+ The ``irradiance`` module in the ``spectrum`` package provides functions for
3
+ calculations related to spectral irradiance data.
4
+ """
5
+
6
+ import pvlib
7
+ from pvlib._deprecation import deprecated
8
+ import numpy as np
9
+ import pandas as pd
10
+ from pathlib import Path
11
+ from functools import partial
12
+ from scipy import constants
13
+ from scipy.integrate import trapezoid
14
+
15
+
16
+ @deprecated(
17
+ since="0.11",
18
+ removal="0.12",
19
+ name="pvlib.spectrum.get_am15g",
20
+ alternative="pvlib.spectrum.get_reference_spectra",
21
+ addendum=(
22
+ "The new function reads more data. Use it with "
23
+ + "standard='ASTM G173-03' and extract the 'global' column."
24
+ ),
25
+ )
26
+ def get_am15g(wavelength=None):
27
+ r"""
28
+ Read the ASTM G173-03 AM1.5 global spectrum on a 37-degree tilted surface,
29
+ optionally interpolated to the specified wavelength(s).
30
+
31
+ Global (tilted) irradiance includes direct and diffuse irradiance from sky
32
+ and ground reflections, and is more formally called hemispherical
33
+ irradiance (on a tilted surface). In the context of photovoltaic systems
34
+ the irradiance on a flat receiver is frequently called plane-of-array (POA)
35
+ irradiance.
36
+
37
+ Parameters
38
+ ----------
39
+ wavelength: 1-D sequence of numeric, optional
40
+ Wavelengths at which the spectrum is interpolated.
41
+ By default the 2002 wavelengths of the standard are returned. [nm].
42
+
43
+ Returns
44
+ -------
45
+ am15g: pandas.Series
46
+ The AM1.5g standard spectrum indexed by ``wavelength``. [W/(m²nm)].
47
+
48
+ Notes
49
+ -----
50
+ If ``wavelength`` is specified this function uses linear interpolation.
51
+
52
+ If the values in ``wavelength`` are too widely spaced, the integral of the
53
+ spectrum may deviate from the standard value of 1000.37 W/m².
54
+
55
+ The values in the data file provided with pvlib-python are copied from an
56
+ Excel file distributed by NREL, which is found here:
57
+ https://www.nrel.gov/grid/solar-resource/assets/data/astmg173.xls
58
+
59
+ More information about reference spectra is found here:
60
+ https://www.nrel.gov/grid/solar-resource/spectra-am1.5.html
61
+
62
+ See Also
63
+ --------
64
+ pvlib.spectrum.get_reference_spectra : reads also the direct and
65
+ extraterrestrial components of the spectrum.
66
+
67
+ References
68
+ ----------
69
+ .. [1] ASTM "G173-03 Standard Tables for Reference Solar Spectral
70
+ Irradiances: Direct Normal and Hemispherical on 37° Tilted Surface."
71
+ """ # noqa: E501
72
+ # Contributed by Anton Driesse (@adriesse), PV Performance Labs. Aug. 2022
73
+ # modified by @echedey-ls, as a wrapper of spectrum.get_reference_spectra
74
+ standard = get_reference_spectra(wavelength, standard="ASTM G173-03")
75
+ return standard["global"]
76
+
77
+
78
+ def get_reference_spectra(wavelengths=None, standard="ASTM G173-03"):
79
+ r"""
80
+ Read a standard spectrum specified by ``standard``, optionally
81
+ interpolated to the specified wavelength(s).
82
+
83
+ Defaults to ``ASTM G173-03`` AM1.5 standard [1]_, which returns
84
+ ``extraterrestrial``, ``global`` and ``direct`` spectrum on a 37-degree
85
+ tilted surface, optionally interpolated to the specified wavelength(s).
86
+
87
+ Parameters
88
+ ----------
89
+ wavelengths : numeric, optional
90
+ Wavelengths at which the spectrum is interpolated. [nm].
91
+ If not provided, the original wavelengths from the specified standard
92
+ are used. Values outside that range are filled with zeros.
93
+
94
+ standard : str, default "ASTM G173-03"
95
+ The reference standard to be read. Only the reference
96
+ ``"ASTM G173-03"`` is available at the moment.
97
+
98
+ Returns
99
+ -------
100
+ standard_spectra : pandas.DataFrame
101
+ The standard spectrum by ``wavelength [nm]``. [W/(m²nm)].
102
+ Column names are ``extraterrestrial``, ``direct`` and ``global``.
103
+
104
+ Notes
105
+ -----
106
+ If ``wavelength`` is specified, linear interpolation is used.
107
+
108
+ If the values in ``wavelength`` are too widely spaced, the integral of each
109
+ spectrum may deviate from its standard value.
110
+ For global spectra, it is about 1000.37 W/m².
111
+
112
+ The values of the ASTM G173-03 provided with pvlib-python are copied from
113
+ an Excel file distributed by NREL, which is found here [2]_:
114
+ https://www.nrel.gov/grid/solar-resource/assets/data/astmg173.xls
115
+
116
+ Examples
117
+ --------
118
+ >>> from pvlib import spectrum
119
+ >>> am15 = spectrum.get_reference_spectra()
120
+ >>> am15_extraterrestrial, am15_global, am15_direct = \
121
+ >>> am15['extraterrestrial'], am15['global'], am15['direct']
122
+ >>> print(am15.head())
123
+ extraterrestrial global direct
124
+ wavelength
125
+ 280.0 0.082 4.730900e-23 2.536100e-26
126
+ 280.5 0.099 1.230700e-21 1.091700e-24
127
+ 281.0 0.150 5.689500e-21 6.125300e-24
128
+ 281.5 0.212 1.566200e-19 2.747900e-22
129
+ 282.0 0.267 1.194600e-18 2.834600e-21
130
+
131
+ >>> am15 = spectrum.get_reference_spectra([300, 500, 800, 1100])
132
+ >>> print(am15)
133
+ extraterrestrial global direct
134
+ wavelength
135
+ 300 0.45794 0.00102 0.000456
136
+ 500 1.91600 1.54510 1.339100
137
+ 800 1.12480 1.07250 0.988590
138
+ 1100 0.60000 0.48577 0.461130
139
+
140
+ References
141
+ ----------
142
+ .. [1] ASTM "G173-03 Standard Tables for Reference Solar Spectral
143
+ Irradiances: Direct Normal and Hemispherical on 37° Tilted Surface."
144
+ .. [2] “Reference Air Mass 1.5 Spectra,” www.nrel.gov.
145
+ https://www.nrel.gov/grid/solar-resource/spectra-am1.5.html
146
+ """ # Contributed by Echedey Luis, inspired by Anton Driesse (get_am15g)
147
+ SPECTRA_FILES = {
148
+ "ASTM G173-03": "ASTMG173.csv",
149
+ }
150
+ pvlib_datapath = Path(pvlib.__path__[0]) / "data"
151
+
152
+ try:
153
+ filepath = pvlib_datapath / SPECTRA_FILES[standard]
154
+ except KeyError:
155
+ raise ValueError(
156
+ f"Invalid standard identifier '{standard}'. Available "
157
+ + "identifiers are: "
158
+ + ", ".join(SPECTRA_FILES.keys())
159
+ )
160
+
161
+ standard = pd.read_csv(
162
+ filepath,
163
+ header=1, # expect first line of description, then column names
164
+ index_col=0, # first column is "wavelength"
165
+ dtype=float,
166
+ )
167
+
168
+ if wavelengths is not None:
169
+ interpolator = partial(
170
+ np.interp, xp=standard.index, left=0.0, right=0.0
171
+ )
172
+ standard = pd.DataFrame(
173
+ index=wavelengths,
174
+ data={
175
+ col: interpolator(x=wavelengths, fp=standard[col])
176
+ for col in standard.columns
177
+ },
178
+ )
179
+
180
+ return standard
181
+
182
+
183
+ def average_photon_energy(spectra):
184
+ r"""
185
+ Calculate the average photon energy of one or more spectral irradiance
186
+ distributions.
187
+
188
+ Parameters
189
+ ----------
190
+ spectra : pandas.Series or pandas.DataFrame
191
+
192
+ Spectral irradiance, must be positive [Wm⁻²nm⁻¹].
193
+ See :term:`spectra`.
194
+
195
+ A single spectrum must be a :py:class:`pandas.Series` with wavelength
196
+ [nm] as the index, while multiple spectra must be rows in a
197
+ :py:class:`pandas.DataFrame` with column headers as wavelength [nm].
198
+
199
+ Returns
200
+ -------
201
+ ape : numeric or pandas.Series
202
+ Average Photon Energy [eV].
203
+ Note: returns ``np.nan`` in the case of all-zero spectral irradiance
204
+ input.
205
+
206
+ Notes
207
+ -----
208
+ The average photon energy (APE) is an index used to characterise the solar
209
+ spectrum. It has been used widely in the physics literature since the
210
+ 1900s, but its application for solar spectral irradiance characterisation
211
+ in the context of PV performance modelling was proposed in 2002 [1]_. The
212
+ APE is calculated based on the principle that a photon's energy is
213
+ inversely proportional to its wavelength:
214
+
215
+ .. math::
216
+
217
+ E_\gamma = \frac{hc}{\lambda},
218
+
219
+ where :math:`E_\gamma` is the energy of a photon with wavelength
220
+ :math:`\lambda`, :math:`h` is the Planck constant, and :math:`c` is the
221
+ speed of light. Therefore, the average energy of all photons within a
222
+ single spectral irradiance distribution provides an indication of the
223
+ general shape of the spectrum. A higher average photon energy
224
+ (shorter wavelength) indicates a blue-shifted spectrum, while a lower
225
+ average photon energy (longer wavelength) would indicate a red-shifted
226
+ spectrum. This value of the average photon energy can be calculated by
227
+ dividing the total energy in the spectrum by the total number of photons
228
+ in the spectrum as follows [1]_:
229
+
230
+ .. math::
231
+
232
+ \overline{E_\gamma} = \frac{1}{q} \cdot \frac{\int G(\lambda) \,
233
+ d\lambda}
234
+ {\int \Phi(\lambda) \, d\lambda}.
235
+
236
+ :math:`\Phi(\lambda)` is the photon flux density as a function of
237
+ wavelength, :math:`G(\lambda)` is the spectral irradiance, :math:`q` is the
238
+ elementary charge used here so that the average photon energy,
239
+ :math:`\overline{E_\gamma}`, is expressed in electronvolts (eV). The
240
+ integrals are computed over the full wavelength range of the ``spectra``
241
+ parameter.
242
+
243
+ References
244
+ ----------
245
+ .. [1] Jardine, C., et al., 2002, January. Influence of spectral effects on
246
+ the performance of multijunction amorphous silicon cells. In Proc.
247
+ Photovoltaic in Europe Conference (pp. 1756-1759).
248
+ """
249
+
250
+ if not isinstance(spectra, (pd.Series, pd.DataFrame)):
251
+ raise TypeError('`spectra` must be either a'
252
+ ' pandas Series or DataFrame')
253
+
254
+ if (spectra < 0).any().any():
255
+ raise ValueError('Spectral irradiance data must be positive')
256
+
257
+ hclambda = pd.Series((constants.h*constants.c)/(spectra.T.index*1e-9))
258
+ hclambda.index = spectra.T.index
259
+ pfd = spectra.div(hclambda)
260
+
261
+ def integrate(e):
262
+ return trapezoid(e, x=e.T.index, axis=-1)
263
+
264
+ int_spectra = integrate(spectra)
265
+ int_pfd = integrate(pfd)
266
+
267
+ with np.errstate(invalid='ignore'):
268
+ ape = (1/constants.elementary_charge)*int_spectra/int_pfd
269
+
270
+ if isinstance(spectra, pd.DataFrame):
271
+ ape = pd.Series(ape, index=spectra.index)
272
+
273
+ return ape