pvlib 0.11.2__py3-none-any.whl → 0.12.0__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 (139) hide show
  1. pvlib/__init__.py +1 -0
  2. pvlib/atmosphere.py +0 -9
  3. pvlib/bifacial/infinite_sheds.py +4 -3
  4. pvlib/bifacial/utils.py +2 -1
  5. pvlib/iotools/psm3.py +1 -1
  6. pvlib/iotools/pvgis.py +10 -2
  7. pvlib/iotools/tmy.py +3 -69
  8. pvlib/irradiance.py +14 -0
  9. pvlib/location.py +73 -33
  10. pvlib/modelchain.py +18 -35
  11. pvlib/pvsystem.py +7 -10
  12. pvlib/snow.py +64 -28
  13. pvlib/spectrum/__init__.py +0 -1
  14. pvlib/spectrum/irradiance.py +0 -63
  15. pvlib/spectrum/mismatch.py +3 -3
  16. pvlib/tools.py +6 -5
  17. {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info}/METADATA +5 -3
  18. pvlib-0.12.0.dist-info/RECORD +75 -0
  19. {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info}/WHEEL +1 -1
  20. pvlib/data/BIRD_08_16_2012.csv +0 -8761
  21. pvlib/data/BIRD_08_16_2012_patm.csv +0 -8761
  22. pvlib/data/Burlington, United States SolarAnywhere Time Series 2021 Lat_44_465 Lon_-73_205 TMY3 format.csv +0 -8762
  23. pvlib/data/Burlington, United States SolarAnywhere Time Series 20210101 to 20210103 Lat_44_4675 Lon_-73_2075 SA format.csv +0 -578
  24. pvlib/data/Burlington, United States SolarAnywhere Typical GHI Year Lat_44_465 Lon_-73_205 SA format.csv +0 -74
  25. pvlib/data/CPS SCH275KTL-DO-US-800-250kW_275kVA_1.OND +0 -146
  26. pvlib/data/CRNS0101-05-2019-AZ_Tucson_11_W.txt +0 -4
  27. pvlib/data/CRN_with_problems.txt +0 -3
  28. pvlib/data/ET-M772BH550GL.PAN +0 -75
  29. pvlib/data/NLD_Amsterdam062400_IWEC.epw +0 -8768
  30. pvlib/data/PVsyst_demo.csv +0 -10757
  31. pvlib/data/PVsyst_demo_model.csv +0 -3588
  32. pvlib/data/SRML-day-EUPO1801.txt +0 -1441
  33. pvlib/data/abq19056.dat +0 -6
  34. pvlib/data/bishop88_numerical_precision.csv +0 -101
  35. pvlib/data/bsrn-lr0100-pay0616.dat +0 -86901
  36. pvlib/data/bsrn-pay0616.dat.gz +0 -0
  37. pvlib/data/cams_mcclear_1min_verbose.csv +0 -60
  38. pvlib/data/cams_mcclear_monthly.csv +0 -42
  39. pvlib/data/cams_radiation_1min_verbose.csv +0 -72
  40. pvlib/data/cams_radiation_monthly.csv +0 -47
  41. pvlib/data/detect_clearsky_data.csv +0 -35
  42. pvlib/data/detect_clearsky_threshold_data.csv +0 -126
  43. pvlib/data/greensboro_kimber_soil_manwash.dat +0 -8761
  44. pvlib/data/greensboro_kimber_soil_nowash.dat +0 -8761
  45. pvlib/data/inverter_fit_snl_meas.csv +0 -127
  46. pvlib/data/inverter_fit_snl_sim.csv +0 -19
  47. pvlib/data/ivtools_numdiff.csv +0 -52
  48. pvlib/data/midc_20181014.txt +0 -1441
  49. pvlib/data/midc_raw_20181018.txt +0 -1441
  50. pvlib/data/midc_raw_short_header_20191115.txt +0 -1441
  51. pvlib/data/msn19056.dat +0 -6
  52. pvlib/data/precise_iv_curves1.json +0 -10251
  53. pvlib/data/precise_iv_curves2.json +0 -10251
  54. pvlib/data/precise_iv_curves_parameter_sets1.csv +0 -33
  55. pvlib/data/precise_iv_curves_parameter_sets2.csv +0 -33
  56. pvlib/data/pvgis_hourly_Timeseries_45.000_8.000_SA2_10kWp_CIS_5_2a_2013_2014.json +0 -1
  57. pvlib/data/pvgis_hourly_Timeseries_45.000_8.000_SA_30deg_0deg_2016_2016.csv +0 -35
  58. pvlib/data/pvgis_tmy_meta.json +0 -32
  59. pvlib/data/pvgis_tmy_test.csv +0 -8761
  60. pvlib/data/pvwatts_8760_rackmount.csv +0 -8779
  61. pvlib/data/pvwatts_8760_roofmount.csv +0 -8779
  62. pvlib/data/singleaxis_tracker_wslope.csv +0 -8761
  63. pvlib/data/spectrl2_example_spectra.csv +0 -123
  64. pvlib/data/surfrad-slv16001.dat +0 -1442
  65. pvlib/data/test_psm3_2017.csv +0 -17521
  66. pvlib/data/test_psm3_2019_5min.csv +0 -289
  67. pvlib/data/test_psm3_tmy-2017.csv +0 -8761
  68. pvlib/data/test_read_psm3.csv +0 -17523
  69. pvlib/data/test_read_pvgis_horizon.csv +0 -49
  70. pvlib/data/tmy_45.000_8.000_2005_2023.csv +0 -8789
  71. pvlib/data/tmy_45.000_8.000_2005_2023.epw +0 -8768
  72. pvlib/data/tmy_45.000_8.000_2005_2023.json +0 -1
  73. pvlib/data/tmy_45.000_8.000_2005_2023.txt +0 -8761
  74. pvlib/data/tmy_45.000_8.000_userhorizon.json +0 -1
  75. pvlib/spa_c_files/README.md +0 -81
  76. pvlib/spa_c_files/cspa_py.pxd +0 -43
  77. pvlib/spa_c_files/spa_py.pyx +0 -30
  78. pvlib/tests/__init__.py +0 -0
  79. pvlib/tests/bifacial/__init__.py +0 -0
  80. pvlib/tests/bifacial/test_infinite_sheds.py +0 -317
  81. pvlib/tests/bifacial/test_losses_models.py +0 -54
  82. pvlib/tests/bifacial/test_pvfactors.py +0 -82
  83. pvlib/tests/bifacial/test_utils.py +0 -192
  84. pvlib/tests/conftest.py +0 -476
  85. pvlib/tests/iotools/__init__.py +0 -0
  86. pvlib/tests/iotools/test_acis.py +0 -213
  87. pvlib/tests/iotools/test_bsrn.py +0 -131
  88. pvlib/tests/iotools/test_crn.py +0 -95
  89. pvlib/tests/iotools/test_epw.py +0 -23
  90. pvlib/tests/iotools/test_midc.py +0 -89
  91. pvlib/tests/iotools/test_panond.py +0 -32
  92. pvlib/tests/iotools/test_psm3.py +0 -198
  93. pvlib/tests/iotools/test_pvgis.py +0 -644
  94. pvlib/tests/iotools/test_sodapro.py +0 -298
  95. pvlib/tests/iotools/test_solaranywhere.py +0 -287
  96. pvlib/tests/iotools/test_solargis.py +0 -68
  97. pvlib/tests/iotools/test_solcast.py +0 -324
  98. pvlib/tests/iotools/test_solrad.py +0 -152
  99. pvlib/tests/iotools/test_srml.py +0 -124
  100. pvlib/tests/iotools/test_surfrad.py +0 -75
  101. pvlib/tests/iotools/test_tmy.py +0 -133
  102. pvlib/tests/ivtools/__init__.py +0 -0
  103. pvlib/tests/ivtools/test_sde.py +0 -230
  104. pvlib/tests/ivtools/test_sdm.py +0 -429
  105. pvlib/tests/ivtools/test_utils.py +0 -173
  106. pvlib/tests/spectrum/__init__.py +0 -0
  107. pvlib/tests/spectrum/conftest.py +0 -40
  108. pvlib/tests/spectrum/test_irradiance.py +0 -138
  109. pvlib/tests/spectrum/test_mismatch.py +0 -304
  110. pvlib/tests/spectrum/test_response.py +0 -124
  111. pvlib/tests/spectrum/test_spectrl2.py +0 -72
  112. pvlib/tests/test__deprecation.py +0 -97
  113. pvlib/tests/test_albedo.py +0 -84
  114. pvlib/tests/test_atmosphere.py +0 -351
  115. pvlib/tests/test_clearsky.py +0 -884
  116. pvlib/tests/test_conftest.py +0 -37
  117. pvlib/tests/test_iam.py +0 -555
  118. pvlib/tests/test_inverter.py +0 -213
  119. pvlib/tests/test_irradiance.py +0 -1487
  120. pvlib/tests/test_location.py +0 -356
  121. pvlib/tests/test_modelchain.py +0 -2020
  122. pvlib/tests/test_numerical_precision.py +0 -124
  123. pvlib/tests/test_pvarray.py +0 -71
  124. pvlib/tests/test_pvsystem.py +0 -2511
  125. pvlib/tests/test_scaling.py +0 -207
  126. pvlib/tests/test_shading.py +0 -391
  127. pvlib/tests/test_singlediode.py +0 -608
  128. pvlib/tests/test_snow.py +0 -212
  129. pvlib/tests/test_soiling.py +0 -230
  130. pvlib/tests/test_solarposition.py +0 -966
  131. pvlib/tests/test_spa.py +0 -454
  132. pvlib/tests/test_temperature.py +0 -470
  133. pvlib/tests/test_tools.py +0 -146
  134. pvlib/tests/test_tracking.py +0 -474
  135. pvlib/tests/test_transformer.py +0 -60
  136. pvlib-0.11.2.dist-info/RECORD +0 -191
  137. {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info/licenses}/AUTHORS.md +0 -0
  138. {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info/licenses}/LICENSE +0 -0
  139. {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info}/top_level.txt +0 -0
@@ -1,1487 +0,0 @@
1
- import datetime
2
- from collections import OrderedDict
3
- import warnings
4
-
5
- import numpy as np
6
- from numpy import array, nan
7
- import pandas as pd
8
-
9
- import pytest
10
- from numpy.testing import (assert_almost_equal,
11
- assert_allclose)
12
- from pvlib import irradiance, albedo
13
-
14
- from .conftest import (
15
- assert_frame_equal,
16
- assert_series_equal,
17
- requires_ephem,
18
- requires_numba,
19
- fail_on_pvlib_version,
20
- )
21
-
22
- from pvlib._deprecation import pvlibDeprecationWarning
23
-
24
- # fixtures create realistic test input data
25
- # test input data generated at Location(32.2, -111, 'US/Arizona', 700)
26
- # test input data is hard coded to avoid dependencies on other parts of pvlib
27
-
28
-
29
- @pytest.fixture
30
- def times():
31
- # must include night values
32
- return pd.date_range(start='20140624', freq='6h', periods=4,
33
- tz='US/Arizona')
34
-
35
-
36
- @pytest.fixture
37
- def irrad_data(times):
38
- return pd.DataFrame(np.array(
39
- [[0., 0., 0.],
40
- [79.73860422, 316.1949056, 40.46149818],
41
- [1042.48031487, 939.95469881, 118.45831879],
42
- [257.20751138, 646.22886049, 62.03376265]]),
43
- columns=['ghi', 'dni', 'dhi'], index=times)
44
-
45
-
46
- @pytest.fixture
47
- def ephem_data(times):
48
- return pd.DataFrame(np.array(
49
- [[124.0390863, 124.0390863, -34.0390863, -34.0390863,
50
- 352.69550699, -2.36677158],
51
- [82.85457044, 82.97705621, 7.14542956, 7.02294379,
52
- 66.71410338, -2.42072165],
53
- [10.56413562, 10.56725766, 79.43586438, 79.43274234,
54
- 144.76567754, -2.47457321],
55
- [72.41687122, 72.46903556, 17.58312878, 17.53096444,
56
- 287.04104128, -2.52831909]]),
57
- columns=['apparent_zenith', 'zenith', 'apparent_elevation',
58
- 'elevation', 'azimuth', 'equation_of_time'],
59
- index=times)
60
-
61
-
62
- @pytest.fixture
63
- def dni_et():
64
- return np.array(
65
- [1321.1655834833093, 1321.1655834833093, 1321.1655834833093,
66
- 1321.1655834833093])
67
-
68
-
69
- @pytest.fixture
70
- def relative_airmass(times):
71
- return pd.Series([np.nan, 7.58831596, 1.01688136, 3.27930443], times)
72
-
73
-
74
- # setup for et rad test. put it here for readability
75
- timestamp = pd.Timestamp('20161026')
76
- dt_index = pd.DatetimeIndex([timestamp])
77
- doy = timestamp.dayofyear
78
- dt_date = timestamp.date()
79
- dt_datetime = datetime.datetime.combine(dt_date, datetime.time(0))
80
- dt_np64 = np.datetime64(dt_datetime)
81
- value = 1383.636203
82
-
83
-
84
- @pytest.mark.parametrize('testval, expected', [
85
- (doy, value),
86
- (np.float64(doy), value),
87
- (dt_date, value),
88
- (dt_datetime, value),
89
- (dt_np64, value),
90
- (np.array([doy]), np.array([value])),
91
- (pd.Series([doy]), np.array([value])),
92
- (dt_index, pd.Series([value], index=dt_index)),
93
- (timestamp, value)
94
- ])
95
- @pytest.mark.parametrize('method', [
96
- 'asce', 'spencer', 'nrel', pytest.param('pyephem', marks=requires_ephem)])
97
- def test_get_extra_radiation(testval, expected, method):
98
- out = irradiance.get_extra_radiation(testval, method=method)
99
- assert_allclose(out, expected, atol=10)
100
-
101
-
102
- def test_get_extra_radiation_epoch_year():
103
- out = irradiance.get_extra_radiation(doy, method='nrel', epoch_year=2012)
104
- assert_allclose(out, 1382.4926804890767, atol=0.1)
105
-
106
-
107
- @requires_numba
108
- def test_get_extra_radiation_nrel_numba(times):
109
- with warnings.catch_warnings():
110
- # don't warn on method reload
111
- warnings.simplefilter("ignore")
112
- result = irradiance.get_extra_radiation(
113
- times, method='nrel', how='numba', numthreads=4)
114
- # and reset to no-numba state
115
- irradiance.get_extra_radiation(times, method='nrel')
116
- assert_allclose(result,
117
- [1322.332316, 1322.296282, 1322.261205, 1322.227091])
118
-
119
-
120
- def test_get_extra_radiation_invalid():
121
- with pytest.raises(ValueError):
122
- irradiance.get_extra_radiation(300, method='invalid')
123
-
124
-
125
- def test_get_ground_diffuse_simple_float():
126
- result = irradiance.get_ground_diffuse(40, 900)
127
- assert_allclose(result, 26.32000014911496)
128
-
129
-
130
- def test_get_ground_diffuse_simple_series(irrad_data):
131
- ground_irrad = irradiance.get_ground_diffuse(40, irrad_data['ghi'])
132
- assert ground_irrad.name == 'diffuse_ground'
133
-
134
-
135
- def test_get_ground_diffuse_albedo_0(irrad_data):
136
- ground_irrad = irradiance.get_ground_diffuse(
137
- 40, irrad_data['ghi'], albedo=0)
138
- assert (0 == ground_irrad).all()
139
-
140
-
141
- def test_get_ground_diffuse_albedo_series(times):
142
- albedo = pd.Series(0.2, index=times)
143
- ground_irrad = irradiance.get_ground_diffuse(
144
- 45, pd.Series(1000, index=times), albedo)
145
- expected = albedo * 0.5 * (1 - np.sqrt(2) / 2.) * 1000
146
- expected.name = 'diffuse_ground'
147
- assert_series_equal(ground_irrad, expected)
148
-
149
-
150
- def test_grounddiffuse_albedo_invalid_surface(irrad_data):
151
- with pytest.raises(KeyError):
152
- irradiance.get_ground_diffuse(
153
- 40, irrad_data['ghi'], surface_type='invalid')
154
-
155
-
156
- def test_get_ground_diffuse_albedo_surface(irrad_data):
157
- result = irradiance.get_ground_diffuse(40, irrad_data['ghi'],
158
- surface_type='sand')
159
- assert_allclose(result, [0, 3.731058, 48.778813, 12.035025], atol=1e-4)
160
-
161
-
162
- def test_isotropic_float():
163
- result = irradiance.isotropic(40, 100)
164
- assert_allclose(result, 88.30222215594891)
165
-
166
-
167
- def test_isotropic_series(irrad_data):
168
- result = irradiance.isotropic(40, irrad_data['dhi'])
169
- assert_allclose(result, [0, 35.728402, 104.601328, 54.777191], atol=1e-4)
170
-
171
-
172
- def test_klucher_series_float():
173
- # klucher inputs
174
- surface_tilt, surface_azimuth = 40.0, 180.0
175
- dhi, ghi = 100.0, 900.0
176
- solar_zenith, solar_azimuth = 20.0, 180.0
177
- # expect same result for floats and pd.Series
178
- expected = irradiance.klucher(
179
- surface_tilt, surface_azimuth,
180
- pd.Series(dhi), pd.Series(ghi),
181
- pd.Series(solar_zenith), pd.Series(solar_azimuth)
182
- ) # 94.99429931664851
183
- result = irradiance.klucher(
184
- surface_tilt, surface_azimuth, dhi, ghi, solar_zenith, solar_azimuth
185
- )
186
- assert_allclose(result, expected[0])
187
-
188
-
189
- def test_klucher_series(irrad_data, ephem_data):
190
- result = irradiance.klucher(40, 180, irrad_data['dhi'], irrad_data['ghi'],
191
- ephem_data['apparent_zenith'],
192
- ephem_data['azimuth'])
193
- # pvlib matlab 1.4 does not contain the max(cos_tt, 0) correction
194
- # so, these values are different
195
- assert_allclose(result, [0., 36.789794, 109.209347, 56.965916], atol=1e-4)
196
- # expect same result for np.array and pd.Series
197
- expected = irradiance.klucher(
198
- 40, 180, irrad_data['dhi'].values, irrad_data['ghi'].values,
199
- ephem_data['apparent_zenith'].values, ephem_data['azimuth'].values
200
- )
201
- assert_allclose(result, expected, atol=1e-4)
202
-
203
-
204
- def test_haydavies(irrad_data, ephem_data, dni_et):
205
- result = irradiance.haydavies(
206
- 40, 180, irrad_data['dhi'], irrad_data['dni'], dni_et,
207
- ephem_data['apparent_zenith'], ephem_data['azimuth'])
208
- # values from matlab 1.4 code
209
- assert_allclose(result, [0, 27.1775, 102.9949, 33.1909], atol=1e-4)
210
-
211
-
212
- def test_haydavies_components(irrad_data, ephem_data, dni_et):
213
- expected = pd.DataFrame(np.array(
214
- [[0, 27.1775, 102.9949, 33.1909],
215
- [0, 27.1775, 30.1818, 27.9837],
216
- [0, 0, 72.8130, 5.2071],
217
- [0, 0, 0, 0]]).T,
218
- columns=['sky_diffuse', 'isotropic', 'circumsolar', 'horizon'],
219
- index=irrad_data.index
220
- )
221
- # pandas
222
- result = irradiance.haydavies(
223
- 40, 180, irrad_data['dhi'], irrad_data['dni'], dni_et,
224
- ephem_data['apparent_zenith'], ephem_data['azimuth'],
225
- return_components=True)
226
- assert_frame_equal(result, expected, check_less_precise=4)
227
- # numpy
228
- result = irradiance.haydavies(
229
- 40, 180, irrad_data['dhi'].values, irrad_data['dni'].values, dni_et,
230
- ephem_data['apparent_zenith'].values, ephem_data['azimuth'].values,
231
- return_components=True)
232
- assert_allclose(result['sky_diffuse'], expected['sky_diffuse'], atol=1e-4)
233
- assert_allclose(result['isotropic'], expected['isotropic'], atol=1e-4)
234
- assert_allclose(result['circumsolar'], expected['circumsolar'], atol=1e-4)
235
- assert_allclose(result['horizon'], expected['horizon'], atol=1e-4)
236
- assert isinstance(result, dict)
237
- # scalar
238
- result = irradiance.haydavies(
239
- 40, 180, irrad_data['dhi'].values[-1], irrad_data['dni'].values[-1],
240
- dni_et[-1], ephem_data['apparent_zenith'].values[-1],
241
- ephem_data['azimuth'].values[-1], return_components=True)
242
- assert_allclose(result['sky_diffuse'], expected['sky_diffuse'].iloc[-1],
243
- atol=1e-4)
244
- assert_allclose(result['isotropic'], expected['isotropic'].iloc[-1],
245
- atol=1e-4)
246
- assert_allclose(result['circumsolar'], expected['circumsolar'].iloc[-1],
247
- atol=1e-4)
248
- assert_allclose(result['horizon'], expected['horizon'].iloc[-1], atol=1e-4)
249
- assert isinstance(result, dict)
250
-
251
-
252
- def test_reindl(irrad_data, ephem_data, dni_et):
253
- result = irradiance.reindl(
254
- 40, 180, irrad_data['dhi'], irrad_data['dni'], irrad_data['ghi'],
255
- dni_et, ephem_data['apparent_zenith'], ephem_data['azimuth'])
256
- # values from matlab 1.4 code
257
- assert_allclose(result, [0., 27.9412, 104.1317, 34.1663], atol=1e-4)
258
-
259
-
260
- def test_king(irrad_data, ephem_data):
261
- result = irradiance.king(40, irrad_data['dhi'], irrad_data['ghi'],
262
- ephem_data['apparent_zenith'])
263
- assert_allclose(result, [0, 44.629352, 115.182626, 79.719855], atol=1e-4)
264
-
265
-
266
- def test_perez(irrad_data, ephem_data, dni_et, relative_airmass):
267
- dni = irrad_data['dni'].copy()
268
- dni.iloc[2] = np.nan
269
- out = irradiance.perez(40, 180, irrad_data['dhi'], dni,
270
- dni_et, ephem_data['apparent_zenith'],
271
- ephem_data['azimuth'], relative_airmass)
272
- expected = pd.Series(np.array(
273
- [0., 31.46046871, np.nan, 45.45539877]),
274
- index=irrad_data.index)
275
- assert_series_equal(out, expected, check_less_precise=2)
276
-
277
-
278
- def test_perez_driesse(irrad_data, ephem_data, dni_et, relative_airmass):
279
- dni = irrad_data['dni'].copy()
280
- dni.iloc[2] = np.nan
281
- out = irradiance.perez_driesse(40, 180, irrad_data['dhi'], dni,
282
- dni_et, ephem_data['apparent_zenith'],
283
- ephem_data['azimuth'], relative_airmass)
284
- expected = pd.Series(np.array(
285
- [0., 29.991, np.nan, 47.397]),
286
- index=irrad_data.index)
287
- assert_series_equal(out, expected, check_less_precise=2)
288
-
289
-
290
- def test_perez_driesse_airmass(irrad_data, ephem_data, dni_et):
291
- dni = irrad_data['dni'].copy()
292
- dni.iloc[2] = np.nan
293
- out = irradiance.perez_driesse(40, 180, irrad_data['dhi'], dni,
294
- dni_et, ephem_data['apparent_zenith'],
295
- ephem_data['azimuth'], airmass=None)
296
- print(out)
297
- expected = pd.Series(np.array(
298
- [0., 29.991, np.nan, 47.397]),
299
- index=irrad_data.index)
300
- assert_series_equal(out, expected, check_less_precise=2)
301
-
302
-
303
- def test_perez_components(irrad_data, ephem_data, dni_et, relative_airmass):
304
- dni = irrad_data['dni'].copy()
305
- dni.iloc[2] = np.nan
306
- out = irradiance.perez(40, 180, irrad_data['dhi'], dni,
307
- dni_et, ephem_data['apparent_zenith'],
308
- ephem_data['azimuth'], relative_airmass,
309
- return_components=True)
310
- expected = pd.DataFrame(np.array(
311
- [[0., 31.46046871, np.nan, 45.45539877],
312
- [0., 26.84138589, np.nan, 31.72696071],
313
- [0., 0., np.nan, 4.47966439],
314
- [0., 4.62212181, np.nan, 9.25316454]]).T,
315
- columns=['sky_diffuse', 'isotropic', 'circumsolar', 'horizon'],
316
- index=irrad_data.index
317
- )
318
- expected_for_sum = expected['sky_diffuse'].copy()
319
- expected_for_sum.iloc[2] = 0
320
- sum_components = out.iloc[:, 1:].sum(axis=1)
321
- sum_components.name = 'sky_diffuse'
322
-
323
- assert_frame_equal(out, expected, check_less_precise=2)
324
- assert_series_equal(sum_components, expected_for_sum, check_less_precise=2)
325
-
326
-
327
- def test_perez_driesse_components(irrad_data, ephem_data, dni_et,
328
- relative_airmass):
329
- dni = irrad_data['dni'].copy()
330
- dni.iloc[2] = np.nan
331
- out = irradiance.perez_driesse(40, 180, irrad_data['dhi'], dni,
332
- dni_et, ephem_data['apparent_zenith'],
333
- ephem_data['azimuth'], relative_airmass,
334
- return_components=True)
335
-
336
- expected = pd.DataFrame(np.array(
337
- [[0., 29.991, np.nan, 47.397],
338
- [0., 25.806, np.nan, 33.181],
339
- [0., 0.000, np.nan, 4.197],
340
- [0., 4.184, np.nan, 10.018]]).T,
341
- columns=['sky_diffuse', 'isotropic', 'circumsolar', 'horizon'],
342
- index=irrad_data.index
343
- )
344
- expected_for_sum = expected['sky_diffuse'].copy()
345
- expected_for_sum.iloc[2] = 0
346
- sum_components = out.iloc[:, 1:].sum(axis=1)
347
- sum_components.name = 'sky_diffuse'
348
-
349
- assert_frame_equal(out, expected, check_less_precise=2)
350
- assert_series_equal(sum_components, expected_for_sum, check_less_precise=2)
351
-
352
-
353
- def test_perez_negative_horizon():
354
- times = pd.date_range(start='20190101 11:30:00', freq='1h',
355
- periods=5, tz='US/Central')
356
-
357
- # Avoid test dependencies on functionality not being tested by hard-coding
358
- # the inputs. This data corresponds to Goodwin Creek in the afternoon on
359
- # 1/1/2019.
360
- # dni_e is slightly rounded from irradiance.get_extra_radiation
361
- # airmass from atmosphere.get_relative_airmas
362
- inputs = pd.DataFrame(np.array(
363
- [[158, 19, 1, 0, 0],
364
- [249, 165, 136, 93, 50],
365
- [57.746951, 57.564205, 60.813841, 66.989435, 75.353368],
366
- [171.003315, 187.346924, 202.974357, 216.725599, 228.317233],
367
- [1414, 1414, 1414, 1414, 1414],
368
- [1.869315, 1.859981, 2.044429, 2.544943, 3.900136]]).T,
369
- columns=['dni', 'dhi', 'solar_zenith',
370
- 'solar_azimuth', 'dni_extra', 'airmass'],
371
- index=times
372
- )
373
-
374
- out = irradiance.perez(34, 180, inputs['dhi'], inputs['dni'],
375
- inputs['dni_extra'], inputs['solar_zenith'],
376
- inputs['solar_azimuth'], inputs['airmass'],
377
- model='allsitescomposite1990',
378
- return_components=True)
379
-
380
- # sky_diffuse can be less than isotropic under certain conditions as
381
- # horizon goes negative
382
- expected = pd.DataFrame(np.array(
383
- [[281.410185, 152.20879, 123.867898, 82.836412, 43.517015],
384
- [166.785419, 142.24475, 119.173875, 83.525150, 45.725931],
385
- [113.548755, 16.09757, 9.956174, 3.142467, 0],
386
- [1.076010, -6.13353, -5.262151, -3.831230, -2.208923]]).T,
387
- columns=['sky_diffuse', 'isotropic', 'circumsolar', 'horizon'],
388
- index=times
389
- )
390
-
391
- expected_for_sum = expected['sky_diffuse'].copy()
392
- sum_components = out.iloc[:, 1:].sum(axis=1)
393
- sum_components.name = 'sky_diffuse'
394
-
395
- assert_frame_equal(out, expected, check_less_precise=2)
396
- assert_series_equal(sum_components, expected_for_sum, check_less_precise=2)
397
-
398
-
399
- def test_perez_arrays(irrad_data, ephem_data, dni_et, relative_airmass):
400
- dni = irrad_data['dni'].copy()
401
- dni.iloc[2] = np.nan
402
- out = irradiance.perez(40, 180, irrad_data['dhi'].values, dni.values,
403
- dni_et, ephem_data['apparent_zenith'].values,
404
- ephem_data['azimuth'].values,
405
- relative_airmass.values)
406
- expected = np.array(
407
- [0., 31.46046871, np.nan, 45.45539877])
408
- assert_allclose(out, expected, atol=1e-2)
409
- assert isinstance(out, np.ndarray)
410
-
411
-
412
- def test_perez_driesse_arrays(irrad_data, ephem_data, dni_et,
413
- relative_airmass):
414
- dni = irrad_data['dni'].copy()
415
- dni.iloc[2] = np.nan
416
- out = irradiance.perez_driesse(40, 180, irrad_data['dhi'].values,
417
- dni.values, dni_et,
418
- ephem_data['apparent_zenith'].values,
419
- ephem_data['azimuth'].values,
420
- relative_airmass.values)
421
- expected = np.array(
422
- [0., 29.990, np.nan, 47.396])
423
- assert_allclose(out, expected, atol=1e-2)
424
- assert isinstance(out, np.ndarray)
425
-
426
-
427
- def test_perez_scalar():
428
- # copied values from fixtures
429
- out = irradiance.perez(40, 180, 118.45831879, 939.95469881,
430
- 1321.1655834833093, 10.56413562, 144.76567754,
431
- 1.01688136)
432
- # this will fail. out is ndarry with ndim == 0. fix in future version.
433
- # assert np.isscalar(out)
434
- assert_allclose(out, 109.084332)
435
-
436
-
437
- def test_perez_driesse_scalar():
438
- # copied values from fixtures
439
- out = irradiance.perez_driesse(40, 180, 118.458, 939.954,
440
- 1321.165, 10.564, 144.765, 1.016)
441
- # this will fail. out is ndarry with ndim == 0. fix in future version.
442
- # assert np.isscalar(out)
443
- assert_allclose(out, 110.341, atol=1e-2)
444
-
445
-
446
- @pytest.mark.parametrize('model', ['isotropic', 'klucher', 'haydavies',
447
- 'reindl', 'king', 'perez', 'perez-driesse'])
448
- def test_sky_diffuse_zenith_close_to_90(model):
449
- # GH 432
450
- sky_diffuse = irradiance.get_sky_diffuse(
451
- 30, 180, 89.999, 230,
452
- dni=10, ghi=51, dhi=50, dni_extra=1360, airmass=12, model=model)
453
- assert sky_diffuse < 100
454
-
455
-
456
- def test_get_sky_diffuse_model_invalid():
457
- with pytest.raises(ValueError):
458
- irradiance.get_sky_diffuse(
459
- 30, 180, 0, 180, 1000, 1100, 100, dni_extra=1360, airmass=1,
460
- model='invalid')
461
-
462
-
463
- def test_get_sky_diffuse_missing_dni_extra():
464
- msg = 'dni_extra is required'
465
- with pytest.raises(ValueError, match=msg):
466
- irradiance.get_sky_diffuse(
467
- 30, 180, 0, 180, 1000, 1100, 100, airmass=1,
468
- model='haydavies')
469
-
470
-
471
- def test_get_sky_diffuse_missing_airmass(irrad_data, ephem_data, dni_et):
472
- # test assumes location is Tucson, AZ
473
- # calculated airmass should be the equivalent to fixture airmass
474
- dni = irrad_data['dni'].copy()
475
- dni.iloc[2] = np.nan
476
- out = irradiance.get_sky_diffuse(
477
- 40, 180, ephem_data['apparent_zenith'], ephem_data['azimuth'], dni,
478
- irrad_data['ghi'], irrad_data['dhi'], dni_et, model='perez')
479
- expected = pd.Series(np.array(
480
- [0., 31.46046871, np.nan, 45.45539877]),
481
- index=irrad_data.index)
482
- assert_series_equal(out, expected, check_less_precise=2)
483
-
484
-
485
- def test_campbell_norman():
486
- expected = pd.DataFrame(np.array(
487
- [[863.859736967, 653.123094076, 220.65905025]]),
488
- columns=['ghi', 'dni', 'dhi'],
489
- index=[0])
490
- out = irradiance.campbell_norman(
491
- pd.Series([10]), pd.Series([0.5]), pd.Series([109764.21013135818]),
492
- dni_extra=1400)
493
- assert_frame_equal(out, expected)
494
-
495
-
496
- def test_get_total_irradiance(irrad_data, ephem_data, dni_et,
497
- relative_airmass):
498
- models = ['isotropic', 'klucher',
499
- 'haydavies', 'reindl', 'king', 'perez', 'perez-driesse']
500
-
501
- for model in models:
502
- total = irradiance.get_total_irradiance(
503
- 32, 180,
504
- ephem_data['apparent_zenith'], ephem_data['azimuth'],
505
- dni=irrad_data['dni'], ghi=irrad_data['ghi'],
506
- dhi=irrad_data['dhi'],
507
- dni_extra=dni_et, airmass=relative_airmass,
508
- model=model,
509
- surface_type='urban')
510
-
511
- assert total.columns.tolist() == ['poa_global', 'poa_direct',
512
- 'poa_diffuse', 'poa_sky_diffuse',
513
- 'poa_ground_diffuse']
514
-
515
-
516
- @pytest.mark.parametrize('model', ['isotropic', 'klucher',
517
- 'haydavies', 'reindl', 'king',
518
- 'perez', 'perez-driesse'])
519
- def test_get_total_irradiance_albedo(
520
- irrad_data, ephem_data, dni_et, relative_airmass, model):
521
- albedo = pd.Series(0.2, index=ephem_data.index)
522
- total = irradiance.get_total_irradiance(
523
- 32, 180,
524
- ephem_data['apparent_zenith'], ephem_data['azimuth'],
525
- dni=irrad_data['dni'], ghi=irrad_data['ghi'],
526
- dhi=irrad_data['dhi'],
527
- dni_extra=dni_et, airmass=relative_airmass,
528
- model=model,
529
- albedo=albedo)
530
-
531
- assert total.columns.tolist() == ['poa_global', 'poa_direct',
532
- 'poa_diffuse', 'poa_sky_diffuse',
533
- 'poa_ground_diffuse']
534
-
535
-
536
- @pytest.mark.parametrize('model', ['isotropic', 'klucher',
537
- 'haydavies', 'reindl', 'king',
538
- 'perez', 'perez-driesse'])
539
- def test_get_total_irradiance_scalars(model):
540
- total = irradiance.get_total_irradiance(
541
- 32, 180,
542
- 10, 180,
543
- dni=1000, ghi=1100,
544
- dhi=100,
545
- dni_extra=1400, airmass=1,
546
- model=model,
547
- surface_type='urban')
548
-
549
- assert list(total.keys()) == ['poa_global', 'poa_direct',
550
- 'poa_diffuse', 'poa_sky_diffuse',
551
- 'poa_ground_diffuse']
552
- # test that none of the values are nan
553
- assert np.isnan(np.array(list(total.values()))).sum() == 0
554
-
555
-
556
- def test_get_total_irradiance_missing_dni_extra():
557
- msg = 'dni_extra is required'
558
- with pytest.raises(ValueError, match=msg):
559
- irradiance.get_total_irradiance(
560
- 32, 180,
561
- 10, 180,
562
- dni=1000, ghi=1100,
563
- dhi=100,
564
- model='haydavies')
565
-
566
-
567
- def test_get_total_irradiance_missing_airmass():
568
- total = irradiance.get_total_irradiance(
569
- 32, 180,
570
- 10, 180,
571
- dni=1000, ghi=1100,
572
- dhi=100,
573
- dni_extra=1400,
574
- model='perez')
575
- assert list(total.keys()) == ['poa_global', 'poa_direct',
576
- 'poa_diffuse', 'poa_sky_diffuse',
577
- 'poa_ground_diffuse']
578
-
579
-
580
- def test_poa_components(irrad_data, ephem_data, dni_et, relative_airmass):
581
- aoi = irradiance.aoi(40, 180, ephem_data['apparent_zenith'],
582
- ephem_data['azimuth'])
583
- gr_sand = irradiance.get_ground_diffuse(40, irrad_data['ghi'],
584
- surface_type='sand')
585
- diff_perez = irradiance.perez(
586
- 40, 180, irrad_data['dhi'], irrad_data['dni'], dni_et,
587
- ephem_data['apparent_zenith'], ephem_data['azimuth'], relative_airmass)
588
- out = irradiance.poa_components(
589
- aoi, irrad_data['dni'], diff_perez, gr_sand)
590
- expected = pd.DataFrame(np.array(
591
- [[0., -0., 0., 0.,
592
- 0.],
593
- [35.19456561, 0., 35.19456561, 31.4635077,
594
- 3.73105791],
595
- [956.18253696, 798.31939281, 157.86314414, 109.08433162,
596
- 48.77881252],
597
- [90.99624896, 33.50143401, 57.49481495, 45.45978964,
598
- 12.03502531]]),
599
- columns=['poa_global', 'poa_direct', 'poa_diffuse', 'poa_sky_diffuse',
600
- 'poa_ground_diffuse'],
601
- index=irrad_data.index)
602
- assert_frame_equal(out, expected)
603
-
604
-
605
- @pytest.mark.parametrize('pressure,expected', [
606
- (93193, [[830.46567, 0.79742, 0.93505],
607
- [676.18340, 0.63782, 3.02102]]),
608
- (None, [[868.72425, 0.79742, 1.01664],
609
- [680.73800, 0.63782, 3.28463]]),
610
- (101325, [[868.72425, 0.79742, 1.01664],
611
- [680.73800, 0.63782, 3.28463]])
612
- ])
613
- def test_disc_value(pressure, expected):
614
- # see GH 449 for pressure=None vs. 101325.
615
- columns = ['dni', 'kt', 'airmass']
616
- times = pd.DatetimeIndex(['2014-06-24T1200', '2014-06-24T1800'],
617
- tz='America/Phoenix')
618
- ghi = pd.Series([1038.62, 254.53], index=times)
619
- zenith = pd.Series([10.567, 72.469], index=times)
620
- out = irradiance.disc(ghi, zenith, times, pressure=pressure)
621
- expected_values = np.array(expected)
622
- expected = pd.DataFrame(expected_values, columns=columns, index=times)
623
- # check the pandas dataframe. check_less_precise is weird
624
- assert_frame_equal(out, expected, check_less_precise=True)
625
- # use np.assert_allclose to check values more clearly
626
- assert_allclose(out.values, expected_values, atol=1e-5)
627
-
628
-
629
- def test_disc_overirradiance():
630
- columns = ['dni', 'kt', 'airmass']
631
- ghi = np.array([3000])
632
- solar_zenith = np.full_like(ghi, 0)
633
- times = pd.date_range(start='2016-07-19 12:00:00', freq='1s',
634
- periods=len(ghi), tz='America/Phoenix')
635
- out = irradiance.disc(ghi=ghi, solar_zenith=solar_zenith,
636
- datetime_or_doy=times)
637
- expected = pd.DataFrame(np.array(
638
- [[8.72544336e+02, 1.00000000e+00, 9.99493933e-01]]),
639
- columns=columns, index=times)
640
- assert_frame_equal(out, expected)
641
-
642
-
643
- def test_disc_min_cos_zenith_max_zenith():
644
- # map out behavior under difficult conditions with various
645
- # limiting kwargs settings
646
- columns = ['dni', 'kt', 'airmass']
647
- times = pd.DatetimeIndex(['2016-07-19 06:11:00'], tz='America/Phoenix')
648
- out = irradiance.disc(ghi=1.0, solar_zenith=89.99, datetime_or_doy=times)
649
- expected = pd.DataFrame(np.array(
650
- [[0.00000000e+00, 1.16046346e-02, 12.0]]),
651
- columns=columns, index=times)
652
- assert_frame_equal(out, expected)
653
-
654
- # max_zenith and/or max_airmass keep these results reasonable
655
- out = irradiance.disc(ghi=1.0, solar_zenith=89.99, datetime_or_doy=times,
656
- min_cos_zenith=0)
657
- expected = pd.DataFrame(np.array(
658
- [[0.00000000e+00, 1.0, 12.0]]),
659
- columns=columns, index=times)
660
- assert_frame_equal(out, expected)
661
-
662
- # still get reasonable values because of max_airmass=12 limit
663
- out = irradiance.disc(ghi=1.0, solar_zenith=89.99, datetime_or_doy=times,
664
- max_zenith=100)
665
- expected = pd.DataFrame(np.array(
666
- [[0., 1.16046346e-02, 12.0]]),
667
- columns=columns, index=times)
668
- assert_frame_equal(out, expected)
669
-
670
- # still get reasonable values because of max_airmass=12 limit
671
- out = irradiance.disc(ghi=1.0, solar_zenith=89.99, datetime_or_doy=times,
672
- min_cos_zenith=0, max_zenith=100)
673
- expected = pd.DataFrame(np.array(
674
- [[277.50185968, 1.0, 12.0]]),
675
- columns=columns, index=times)
676
- assert_frame_equal(out, expected)
677
-
678
- # max_zenith keeps this result reasonable
679
- out = irradiance.disc(ghi=1.0, solar_zenith=89.99, datetime_or_doy=times,
680
- min_cos_zenith=0, max_airmass=100)
681
- expected = pd.DataFrame(np.array(
682
- [[0.00000000e+00, 1.0, 36.39544757]]),
683
- columns=columns, index=times)
684
- assert_frame_equal(out, expected)
685
-
686
- # allow zenith to be close to 90 and airmass to be infinite
687
- # and we get crazy values
688
- out = irradiance.disc(ghi=1.0, solar_zenith=89.99, datetime_or_doy=times,
689
- max_zenith=100, max_airmass=100)
690
- expected = pd.DataFrame(np.array(
691
- [[6.68577449e+03, 1.16046346e-02, 3.63954476e+01]]),
692
- columns=columns, index=times)
693
- assert_frame_equal(out, expected)
694
-
695
- # allow min cos zenith to be 0, zenith to be close to 90,
696
- # and airmass to be very big and we get even higher DNI values
697
- out = irradiance.disc(ghi=1.0, solar_zenith=89.99, datetime_or_doy=times,
698
- min_cos_zenith=0, max_zenith=100, max_airmass=100)
699
- expected = pd.DataFrame(np.array(
700
- [[7.21238390e+03, 1., 3.63954476e+01]]),
701
- columns=columns, index=times)
702
- assert_frame_equal(out, expected)
703
-
704
-
705
- def test_dirint_value():
706
- times = pd.DatetimeIndex(['2014-06-24T12-0700', '2014-06-24T18-0700'])
707
- ghi = pd.Series([1038.62, 254.53], index=times)
708
- zenith = pd.Series([10.567, 72.469], index=times)
709
- pressure = 93193.
710
- dirint_data = irradiance.dirint(ghi, zenith, times, pressure=pressure)
711
- assert_almost_equal(dirint_data.values,
712
- np.array([868.8, 699.7]), 1)
713
-
714
-
715
- def test_dirint_nans():
716
- times = pd.date_range(start='2014-06-24T12-0700', periods=5, freq='6h')
717
- ghi = pd.Series([np.nan, 1038.62, 1038.62, 1038.62, 1038.62], index=times)
718
- zenith = pd.Series([10.567, np.nan, 10.567, 10.567, 10.567], index=times)
719
- pressure = pd.Series([93193., 93193., np.nan, 93193., 93193.], index=times)
720
- temp_dew = pd.Series([10, 10, 10, np.nan, 10], index=times)
721
- dirint_data = irradiance.dirint(ghi, zenith, times, pressure=pressure,
722
- temp_dew=temp_dew)
723
- assert_almost_equal(dirint_data.values,
724
- np.array([np.nan, np.nan, np.nan, np.nan, 893.1]), 1)
725
-
726
-
727
- def test_dirint_tdew():
728
- times = pd.DatetimeIndex(['2014-06-24T12-0700', '2014-06-24T18-0700'])
729
- ghi = pd.Series([1038.62, 254.53], index=times)
730
- zenith = pd.Series([10.567, 72.469], index=times)
731
- pressure = 93193.
732
- dirint_data = irradiance.dirint(ghi, zenith, times, pressure=pressure,
733
- temp_dew=10)
734
- assert_almost_equal(dirint_data.values,
735
- np.array([882.1, 672.6]), 1)
736
-
737
-
738
- def test_dirint_no_delta_kt():
739
- times = pd.DatetimeIndex(['2014-06-24T12-0700', '2014-06-24T18-0700'])
740
- ghi = pd.Series([1038.62, 254.53], index=times)
741
- zenith = pd.Series([10.567, 72.469], index=times)
742
- pressure = 93193.
743
- dirint_data = irradiance.dirint(ghi, zenith, times, pressure=pressure,
744
- use_delta_kt_prime=False)
745
- assert_almost_equal(dirint_data.values,
746
- np.array([861.9, 670.4]), 1)
747
-
748
-
749
- def test_dirint_coeffs():
750
- coeffs = irradiance._get_dirint_coeffs()
751
- assert coeffs[0, 0, 0, 0] == 0.385230
752
- assert coeffs[0, 1, 2, 1] == 0.229970
753
- assert coeffs[3, 2, 6, 3] == 1.032260
754
-
755
-
756
- def test_dirint_min_cos_zenith_max_zenith():
757
- # map out behavior under difficult conditions with various
758
- # limiting kwargs settings
759
- # times don't have any physical relevance
760
- times = pd.DatetimeIndex(['2014-06-24T12-0700', '2014-06-24T18-0700'])
761
- ghi = pd.Series([0, 1], index=times)
762
- solar_zenith = pd.Series([90, 89.99], index=times)
763
-
764
- out = irradiance.dirint(ghi, solar_zenith, times)
765
- expected = pd.Series([0.0, 0.0], index=times, name='dni')
766
- assert_series_equal(out, expected)
767
-
768
- out = irradiance.dirint(ghi, solar_zenith, times, min_cos_zenith=0)
769
- expected = pd.Series([0.0, 0.0], index=times, name='dni')
770
- assert_series_equal(out, expected)
771
-
772
- out = irradiance.dirint(ghi, solar_zenith, times, max_zenith=90)
773
- expected = pd.Series([0.0, 0.0], index=times, name='dni')
774
- assert_series_equal(out, expected, check_less_precise=True)
775
-
776
- out = irradiance.dirint(ghi, solar_zenith, times, min_cos_zenith=0,
777
- max_zenith=90)
778
- expected = pd.Series([0.0, 144.264507], index=times, name='dni')
779
- assert_series_equal(out, expected, check_less_precise=True)
780
-
781
- out = irradiance.dirint(ghi, solar_zenith, times, min_cos_zenith=0,
782
- max_zenith=100)
783
- expected = pd.Series([0.0, 144.264507], index=times, name='dni')
784
- assert_series_equal(out, expected, check_less_precise=True)
785
-
786
-
787
- def test_ghi_from_poa_driesse(mocker):
788
- # inputs copied from test_gti_dirint
789
- times = pd.DatetimeIndex(
790
- ['2014-06-24T06-0700', '2014-06-24T09-0700', '2014-06-24T12-0700'])
791
- poa_global = np.array([20, 300, 1000])
792
- zenith = np.array([80, 45, 20])
793
- azimuth = np.array([90, 135, 180])
794
- surface_tilt = 30
795
- surface_azimuth = 180
796
-
797
- # test core function
798
- output = irradiance.ghi_from_poa_driesse_2023(
799
- surface_tilt, surface_azimuth, zenith, azimuth,
800
- poa_global, dni_extra=1366.1)
801
-
802
- expected = [22.089, 304.088, 931.143]
803
- assert_allclose(expected, output, atol=0.001)
804
-
805
- # test series output
806
- poa_global = pd.Series([20, 300, 1000], index=times)
807
-
808
- output = irradiance.ghi_from_poa_driesse_2023(
809
- surface_tilt, surface_azimuth, zenith, azimuth,
810
- poa_global, dni_extra=1366.1)
811
-
812
- assert isinstance(output, pd.Series)
813
-
814
- # test full_output option and special cases
815
- poa_global = np.array([0, 1500, np.nan])
816
-
817
- ghi, conv, niter = irradiance.ghi_from_poa_driesse_2023(
818
- surface_tilt, surface_azimuth, zenith, azimuth,
819
- poa_global, dni_extra=1366.1, full_output=True)
820
-
821
- expected = [0, np.nan, np.nan]
822
- assert_allclose(expected, ghi, atol=0.001)
823
-
824
- expected = [True, False, False]
825
- assert_allclose(expected, conv)
826
-
827
- expected = [0, -1, 0]
828
- assert_allclose(expected, niter)
829
-
830
- # test xtol argument
831
- poa_global = pd.Series([20, 300, 1000], index=times)
832
- # test exception
833
- xtol = -3.14159 # negative value raises exception in scipy.optimize.bisect
834
- with pytest.raises(ValueError, match=rf"xtol too small \({xtol:g} <= 0\)"):
835
- output = irradiance.ghi_from_poa_driesse_2023(
836
- surface_tilt, surface_azimuth, zenith, azimuth,
837
- poa_global, dni_extra=1366.1, xtol=xtol)
838
- # test propagation
839
- xtol = 3.141592
840
- bisect_spy = mocker.spy(irradiance, "bisect")
841
- output = irradiance.ghi_from_poa_driesse_2023(
842
- surface_tilt, surface_azimuth, zenith, azimuth,
843
- poa_global, dni_extra=1366.1, xtol=xtol)
844
- assert bisect_spy.call_args[1]["xtol"] == xtol
845
-
846
-
847
- def test_gti_dirint():
848
- times = pd.DatetimeIndex(
849
- ['2014-06-24T06-0700', '2014-06-24T09-0700', '2014-06-24T12-0700'])
850
- poa_global = np.array([20, 300, 1000])
851
- aoi = np.array([100, 70, 10])
852
- zenith = np.array([80, 45, 20])
853
- azimuth = np.array([90, 135, 180])
854
- surface_tilt = 30
855
- surface_azimuth = 180
856
-
857
- # test defaults
858
- output = irradiance.gti_dirint(
859
- poa_global, aoi, zenith, azimuth, times, surface_tilt, surface_azimuth)
860
-
861
- expected_col_order = ['ghi', 'dni', 'dhi']
862
- expected = pd.DataFrame(array(
863
- [[21.05796198, 0., 21.05796198],
864
- [291.40037163, 63.41290679, 246.56067523],
865
- [931.04078010, 695.94965324, 277.06172442]]),
866
- columns=expected_col_order, index=times)
867
-
868
- assert_frame_equal(output, expected)
869
-
870
- # test ignore calculate_gt_90
871
- output = irradiance.gti_dirint(
872
- poa_global, aoi, zenith, azimuth, times, surface_tilt, surface_azimuth,
873
- calculate_gt_90=False)
874
-
875
- expected_no_90 = expected.copy()
876
- expected_no_90.iloc[0, :] = np.nan
877
-
878
- assert_frame_equal(output, expected_no_90)
879
-
880
- # test pressure input
881
- pressure = 93193.
882
- output = irradiance.gti_dirint(
883
- poa_global, aoi, zenith, azimuth, times, surface_tilt, surface_azimuth,
884
- pressure=pressure)
885
-
886
- expected = pd.DataFrame(array(
887
- [[21.05796198, 0., 21.05796198],
888
- [293.21310935, 63.27500913, 248.47092131],
889
- [932.46756378, 648.05001357, 323.49974813]]),
890
- columns=expected_col_order, index=times)
891
-
892
- assert_frame_equal(output, expected)
893
-
894
- # test albedo input
895
- albedo = 0.05
896
- output = irradiance.gti_dirint(
897
- poa_global, aoi, zenith, azimuth, times, surface_tilt, surface_azimuth,
898
- albedo=albedo)
899
-
900
- expected = pd.DataFrame(array(
901
- [[21.3592591, 0., 21.3592591],
902
- [294.4985420, 66.25848451, 247.64671830],
903
- [941.7943404, 727.50552952, 258.16276278]]),
904
- columns=expected_col_order, index=times)
905
-
906
- assert_frame_equal(output, expected)
907
-
908
- # test with albedo as a Series
909
- albedo = pd.Series(0.05, index=times)
910
- output = irradiance.gti_dirint(
911
- poa_global, aoi, zenith, azimuth, times, surface_tilt, surface_azimuth,
912
- albedo=albedo)
913
-
914
- assert_frame_equal(output, expected)
915
-
916
- # test temp_dew input
917
- temp_dew = np.array([70, 80, 20])
918
- output = irradiance.gti_dirint(
919
- poa_global, aoi, zenith, azimuth, times, surface_tilt, surface_azimuth,
920
- temp_dew=temp_dew)
921
-
922
- expected = pd.DataFrame(array(
923
- [[21.05796198, 0., 21.05796198],
924
- [295.06070190, 38.20346345, 268.0467738],
925
- [931.79627208, 689.81549269, 283.5817439]]),
926
- columns=expected_col_order, index=times)
927
-
928
- assert_frame_equal(output, expected)
929
-
930
-
931
- def test_erbs():
932
- index = pd.DatetimeIndex(['20190101']*3 + ['20190620'])
933
- ghi = pd.Series([0, 50, 1000, 1000], index=index)
934
- zenith = pd.Series([120, 85, 10, 10], index=index)
935
- expected = pd.DataFrame(np.array(
936
- [[0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
937
- [9.67192672e+01, 4.15703604e+01, 4.05723511e-01],
938
- [7.94205651e+02, 2.17860117e+02, 7.18132729e-01],
939
- [8.42001578e+02, 1.70790318e+02, 7.68214312e-01]]),
940
- columns=['dni', 'dhi', 'kt'], index=index)
941
-
942
- out = irradiance.erbs(ghi, zenith, index)
943
-
944
- assert_frame_equal(np.round(out, 0), np.round(expected, 0))
945
-
946
-
947
- def test_erbs_driesse():
948
- index = pd.DatetimeIndex(['20190101']*3 + ['20190620'])
949
- ghi = pd.Series([0, 50, 1000, 1000], index=index)
950
- zenith = pd.Series([120, 85, 10, 10], index=index)
951
- # expected values are the same as for erbs original test
952
- expected = pd.DataFrame(np.array(
953
- [[0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
954
- [9.67192672e+01, 4.15703604e+01, 4.05723511e-01],
955
- [7.94205651e+02, 2.17860117e+02, 7.18132729e-01],
956
- [8.42001578e+02, 1.70790318e+02, 7.68214312e-01]]),
957
- columns=['dni', 'dhi', 'kt'], index=index)
958
-
959
- out = irradiance.erbs_driesse(ghi, zenith, index)
960
-
961
- assert_frame_equal(np.round(out, 0), np.round(expected, 0))
962
-
963
- # test with the new optional dni_extra argument
964
- dni_extra = irradiance.get_extra_radiation(index)
965
-
966
- out = irradiance.erbs_driesse(ghi, zenith, dni_extra=dni_extra)
967
-
968
- assert_frame_equal(np.round(out, 0), np.round(expected, 0))
969
-
970
- # test for required inputs
971
- with pytest.raises(ValueError):
972
- irradiance.erbs_driesse(ghi, zenith)
973
-
974
-
975
- def test_boland():
976
- index = pd.DatetimeIndex(['20190101']*3 + ['20190620'])
977
- ghi = pd.Series([0, 50, 1000, 1000], index=index)
978
- zenith = pd.Series([120, 85, 10, 10], index=index)
979
- expected = pd.DataFrame(np.array(
980
- [[0.0, 0.0, 0.0],
981
- [81.9448546, 42.8580353, 0.405723511],
982
- [723.764990, 287.230626, 0.718132729],
983
- [805.020419, 207.209650, 0.768214312]]),
984
- columns=['dni', 'dhi', 'kt'], index=index)
985
-
986
- out = irradiance.boland(ghi, zenith, index)
987
-
988
- assert np.allclose(out, expected)
989
-
990
-
991
- def test_orgill_hollands():
992
- index = pd.DatetimeIndex(['20190101']*3 + ['20190620'])
993
- ghi = pd.Series([0, 50, 1000, 1000], index=index)
994
- zenith = pd.Series([120, 85, 10, 10], index=index)
995
- expected = pd.DataFrame(np.array(
996
- [[0.0, 0.0, 0.0],
997
- [108.731366, 40.5234370, 0.405723511],
998
- [776.155771, 235.635779, 0.718132729],
999
- [835.696102, 177.000000, 0.768214312]]),
1000
- columns=['dni', 'dhi', 'kt'], index=index)
1001
-
1002
- out = irradiance.orgill_hollands(ghi, zenith, index)
1003
-
1004
- assert np.allclose(out, expected)
1005
-
1006
-
1007
- def test_erbs_min_cos_zenith_max_zenith():
1008
- # map out behavior under difficult conditions with various
1009
- # limiting kwargs settings
1010
- columns = ['dni', 'dhi', 'kt']
1011
- times = pd.DatetimeIndex(['2016-07-19 06:11:00'], tz='America/Phoenix')
1012
-
1013
- # max_zenith keeps these results reasonable
1014
- out = irradiance.erbs(ghi=1.0, zenith=89.99999,
1015
- datetime_or_doy=times, min_cos_zenith=0)
1016
- expected = pd.DataFrame(np.array(
1017
- [[0., 1., 1.]]),
1018
- columns=columns, index=times)
1019
- assert_frame_equal(out, expected)
1020
-
1021
- # 4-5 9s will produce bad behavior without max_zenith limit
1022
- out = irradiance.erbs(ghi=1.0, zenith=89.99999,
1023
- datetime_or_doy=times, max_zenith=100)
1024
- expected = pd.DataFrame(np.array(
1025
- [[6.00115286e+03, 9.98952601e-01, 1.16377640e-02]]),
1026
- columns=columns, index=times)
1027
- assert_frame_equal(out, expected)
1028
-
1029
- # 1-2 9s will produce bad behavior without either limit
1030
- out = irradiance.erbs(ghi=1.0, zenith=89.99, datetime_or_doy=times,
1031
- min_cos_zenith=0, max_zenith=100)
1032
- expected = pd.DataFrame(np.array(
1033
- [[4.78419761e+03, 1.65000000e-01, 1.00000000e+00]]),
1034
- columns=columns, index=times)
1035
- assert_frame_equal(out, expected)
1036
-
1037
- # check default behavior under hardest condition
1038
- out = irradiance.erbs(ghi=1.0, zenith=90, datetime_or_doy=times)
1039
- expected = pd.DataFrame(np.array(
1040
- [[0., 1., 0.01163776]]),
1041
- columns=columns, index=times)
1042
- assert_frame_equal(out, expected)
1043
-
1044
-
1045
- def test_erbs_all_scalar():
1046
- ghi = 1000
1047
- zenith = 10
1048
- doy = 180
1049
-
1050
- expected = OrderedDict()
1051
- expected['dni'] = 8.42358014e+02
1052
- expected['dhi'] = 1.70439297e+02
1053
- expected['kt'] = 7.68919470e-01
1054
-
1055
- out = irradiance.erbs(ghi, zenith, doy)
1056
-
1057
- for k, v in out.items():
1058
- assert_allclose(v, expected[k], 1e-2)
1059
-
1060
-
1061
- def test_dirindex(times):
1062
- ghi = pd.Series([0, 0, 1038.62, 254.53], index=times)
1063
- ghi_clearsky = pd.Series(
1064
- np.array([0., 79.73860422, 1042.48031487, 257.20751138]),
1065
- index=times
1066
- )
1067
- dni_clear = pd.Series(
1068
- np.array([0., 316.1949056, 939.95469881, 646.22886049]),
1069
- index=times
1070
- )
1071
- zenith = pd.Series(
1072
- np.array([124.0390863, 82.85457044, 10.56413562, 72.41687122]),
1073
- index=times
1074
- )
1075
- pressure = 93193.
1076
- tdew = 10.
1077
- out = irradiance.dirindex(ghi, ghi_clearsky, dni_clear,
1078
- zenith, times, pressure=pressure,
1079
- temp_dew=tdew)
1080
- dirint_close_values = irradiance.dirint(ghi, zenith, times,
1081
- pressure=pressure,
1082
- use_delta_kt_prime=True,
1083
- temp_dew=tdew).values
1084
- expected_out = np.array([np.nan, 0., 748.31562800, 630.73752100])
1085
-
1086
- tolerance = 1e-8
1087
- assert np.allclose(out, expected_out, rtol=tolerance, atol=0,
1088
- equal_nan=True)
1089
- tol_dirint = 0.2
1090
- assert np.allclose(
1091
- out.values,
1092
- dirint_close_values,
1093
- rtol=tol_dirint,
1094
- atol=0,
1095
- equal_nan=True)
1096
-
1097
-
1098
- @fail_on_pvlib_version("0.13")
1099
- def test_dirindex_ghi_clearsky_deprecation():
1100
- times = pd.DatetimeIndex(['2014-06-24T18-1200'])
1101
- ghi = pd.Series([1038.62], index=times)
1102
- ghi_clearsky = pd.Series([1042.48031487], index=times)
1103
- dni_clearsky = pd.Series([939.95469881], index=times)
1104
- zenith = pd.Series([10.56413562], index=times)
1105
- pressure, tdew = 93193, 10
1106
- with pytest.warns(pvlibDeprecationWarning, match='ghi_clear'):
1107
- irradiance.dirindex(
1108
- ghi=ghi, ghi_clearsky=ghi_clearsky, dni_clear=dni_clearsky,
1109
- zenith=zenith, times=times, pressure=pressure, temp_dew=tdew)
1110
-
1111
-
1112
- def test_dirindex_min_cos_zenith_max_zenith():
1113
- # map out behavior under difficult conditions with various
1114
- # limiting kwargs settings
1115
- # times don't have any physical relevance
1116
- times = pd.DatetimeIndex(['2014-06-24T12-0700', '2014-06-24T18-0700'])
1117
- ghi = pd.Series([0, 1], index=times)
1118
- ghi_clearsky = pd.Series([0, 1], index=times)
1119
- dni_clear = pd.Series([0, 5], index=times)
1120
- solar_zenith = pd.Series([90, 89.99], index=times)
1121
-
1122
- out = irradiance.dirindex(ghi, ghi_clearsky, dni_clear, solar_zenith,
1123
- times)
1124
- expected = pd.Series([nan, nan], index=times)
1125
- assert_series_equal(out, expected)
1126
-
1127
- out = irradiance.dirindex(ghi, ghi_clearsky, dni_clear, solar_zenith,
1128
- times, min_cos_zenith=0)
1129
- expected = pd.Series([nan, nan], index=times)
1130
- assert_series_equal(out, expected)
1131
-
1132
- out = irradiance.dirindex(ghi, ghi_clearsky, dni_clear, solar_zenith,
1133
- times, max_zenith=90)
1134
- expected = pd.Series([nan, nan], index=times)
1135
- assert_series_equal(out, expected)
1136
-
1137
- out = irradiance.dirindex(ghi, ghi_clearsky, dni_clear, solar_zenith,
1138
- times, min_cos_zenith=0, max_zenith=100)
1139
- expected = pd.Series([nan, 5.], index=times)
1140
- assert_series_equal(out, expected)
1141
-
1142
-
1143
- @fail_on_pvlib_version("0.13")
1144
- def test_dirindex_dni_clearsky_deprecation():
1145
- times = pd.DatetimeIndex(['2014-06-24T12-0700', '2014-06-24T18-0700'])
1146
- ghi = pd.Series([0, 1], index=times)
1147
- ghi_clearsky = pd.Series([0, 1], index=times)
1148
- dni_clear = pd.Series([0, 5], index=times)
1149
- solar_zenith = pd.Series([90, 89.99], index=times)
1150
- with pytest.warns(pvlibDeprecationWarning, match='dni_clear'):
1151
- irradiance.dirindex(ghi, ghi_clearsky, dni_clearsky=dni_clear,
1152
- zenith=solar_zenith, times=times,
1153
- min_cos_zenith=0)
1154
-
1155
-
1156
- def test_dni():
1157
- ghi = pd.Series([90, 100, 100, 100, 100])
1158
- dhi = pd.Series([100, 90, 50, 50, 50])
1159
- zenith = pd.Series([80, 100, 85, 70, 85])
1160
- dni_clear = pd.Series([50, 50, 200, 50, 300])
1161
-
1162
- dni = irradiance.dni(ghi, dhi, zenith,
1163
- dni_clear=dni_clear, clearsky_tolerance=2)
1164
- assert_series_equal(dni,
1165
- pd.Series([float('nan'), float('nan'), 400,
1166
- 146.190220008, 573.685662283]))
1167
-
1168
- dni = irradiance.dni(ghi, dhi, zenith)
1169
- assert_series_equal(dni,
1170
- pd.Series([float('nan'), float('nan'), 573.685662283,
1171
- 146.190220008, 573.685662283]))
1172
-
1173
-
1174
- @fail_on_pvlib_version("0.13")
1175
- def test_dni_dni_clearsky_deprecation():
1176
- ghi = pd.Series([90, 100, 100, 100, 100])
1177
- dhi = pd.Series([100, 90, 50, 50, 50])
1178
- zenith = pd.Series([80, 100, 85, 70, 85])
1179
- dni_clear = pd.Series([50, 50, 200, 50, 300])
1180
- with pytest.warns(pvlibDeprecationWarning, match='dni_clear'):
1181
- irradiance.dni(ghi, dhi, zenith,
1182
- clearsky_dni=dni_clear, clearsky_tolerance=2)
1183
-
1184
-
1185
- @pytest.mark.parametrize(
1186
- 'surface_tilt,surface_azimuth,solar_zenith,' +
1187
- 'solar_azimuth,aoi_expected,aoi_proj_expected',
1188
- [(0, 0, 0, 0, 0, 1),
1189
- (30, 180, 30, 180, 0, 1),
1190
- (30, 180, 150, 0, 180, -1),
1191
- (90, 0, 30, 60, 75.5224878, 0.25),
1192
- (90, 0, 30, 170, 119.4987042, -0.4924038)])
1193
- def test_aoi_and_aoi_projection(surface_tilt, surface_azimuth, solar_zenith,
1194
- solar_azimuth, aoi_expected,
1195
- aoi_proj_expected):
1196
- aoi = irradiance.aoi(surface_tilt, surface_azimuth, solar_zenith,
1197
- solar_azimuth)
1198
- assert_allclose(aoi, aoi_expected, atol=1e-5)
1199
-
1200
- aoi_projection = irradiance.aoi_projection(
1201
- surface_tilt, surface_azimuth, solar_zenith, solar_azimuth)
1202
- assert_allclose(aoi_projection, aoi_proj_expected, atol=1e-6)
1203
-
1204
-
1205
- def test_aoi_projection_precision():
1206
- # GH 1185 -- test that aoi_projection does not exceed 1.0, and when
1207
- # given identical inputs, the returned projection is very close to 1.0
1208
-
1209
- # scalars
1210
- zenith = 89.26778228223463
1211
- azimuth = 60.932028605997004
1212
- projection = irradiance.aoi_projection(zenith, azimuth, zenith, azimuth)
1213
- assert projection <= 1
1214
- assert np.isclose(projection, 1)
1215
-
1216
- # arrays
1217
- zeniths = np.array([zenith])
1218
- azimuths = np.array([azimuth])
1219
- projections = irradiance.aoi_projection(zeniths, azimuths,
1220
- zeniths, azimuths)
1221
- assert all(projections <= 1)
1222
- assert all(np.isclose(projections, 1))
1223
- assert projections.dtype == np.dtype('float64')
1224
-
1225
-
1226
- @pytest.fixture
1227
- def airmass_kt():
1228
- # disc algorithm stopped at am=12. test am > 12 for out of range behavior
1229
- return np.array([1, 5, 12, 20])
1230
-
1231
-
1232
- def test_kt_kt_prime_factor(airmass_kt):
1233
- out = irradiance._kt_kt_prime_factor(airmass_kt)
1234
- expected = np.array([0.999971, 0.723088, 0.548811, 0.471068])
1235
- assert_allclose(out, expected, atol=1e-5)
1236
-
1237
-
1238
- def test_clearsky_index():
1239
- ghi = np.array([-1., 0., 1., 500., 1000., np.nan])
1240
- ghi_measured, ghi_modeled = np.meshgrid(ghi, ghi)
1241
- # default max_clearsky_index
1242
- with np.errstate(invalid='ignore', divide='ignore'):
1243
- out = irradiance.clearsky_index(ghi_measured, ghi_modeled)
1244
- expected = np.array(
1245
- [[1., 0., 0., 0., 0., np.nan],
1246
- [0., 0., 0., 0., 0., np.nan],
1247
- [0., 0., 1., 2., 2., np.nan],
1248
- [0., 0., 0.002, 1., 2., np.nan],
1249
- [0., 0., 0.001, 0.5, 1., np.nan],
1250
- [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan]])
1251
- assert_allclose(out, expected, atol=0.001)
1252
- # specify max_clearsky_index
1253
- with np.errstate(invalid='ignore', divide='ignore'):
1254
- out = irradiance.clearsky_index(ghi_measured, ghi_modeled,
1255
- max_clearsky_index=1.5)
1256
- expected = np.array(
1257
- [[1., 0., 0., 0., 0., np.nan],
1258
- [0., 0., 0., 0., 0., np.nan],
1259
- [0., 0., 1., 1.5, 1.5, np.nan],
1260
- [0., 0., 0.002, 1., 1.5, np.nan],
1261
- [0., 0., 0.001, 0.5, 1., np.nan],
1262
- [np.nan, np.nan, np.nan, np.nan, np.nan, np.nan]])
1263
- assert_allclose(out, expected, atol=0.001)
1264
- # scalars
1265
- out = irradiance.clearsky_index(10, 1000)
1266
- expected = 0.01
1267
- assert_allclose(out, expected, atol=0.001)
1268
- # series
1269
- times = pd.date_range(start='20180601', periods=2, freq='12h')
1270
- ghi_measured = pd.Series([100, 500], index=times)
1271
- ghi_modeled = pd.Series([500, 1000], index=times)
1272
- out = irradiance.clearsky_index(ghi_measured, ghi_modeled)
1273
- expected = pd.Series([0.2, 0.5], index=times)
1274
- assert_series_equal(out, expected)
1275
-
1276
-
1277
- @fail_on_pvlib_version("0.13")
1278
- def test_clearsky_index_clearsky_ghi_deprecation():
1279
- with pytest.warns(pvlibDeprecationWarning, match='ghi_clear'):
1280
- ghi, clearsky_ghi = 200, 300
1281
- irradiance.clearsky_index(ghi, clearsky_ghi=clearsky_ghi)
1282
-
1283
-
1284
- def test_clearness_index():
1285
- ghi = np.array([-1, 0, 1, 1000])
1286
- solar_zenith = np.array([180, 90, 89.999, 0])
1287
- ghi, solar_zenith = np.meshgrid(ghi, solar_zenith)
1288
- # default min_cos_zenith
1289
- out = irradiance.clearness_index(ghi, solar_zenith, 1370)
1290
- # np.set_printoptions(precision=3, floatmode='maxprec', suppress=True)
1291
- expected = np.array(
1292
- [[0., 0., 0.011, 2.],
1293
- [0., 0., 0.011, 2.],
1294
- [0., 0., 0.011, 2.],
1295
- [0., 0., 0.001, 0.73]])
1296
- assert_allclose(out, expected, atol=0.001)
1297
- # specify min_cos_zenith
1298
- with np.errstate(invalid='ignore', divide='ignore'):
1299
- out = irradiance.clearness_index(ghi, solar_zenith, 1400,
1300
- min_cos_zenith=0)
1301
- expected = np.array(
1302
- [[0., nan, 2., 2.],
1303
- [0., 0., 2., 2.],
1304
- [0., 0., 2., 2.],
1305
- [0., 0., 0.001, 0.714]])
1306
- assert_allclose(out, expected, atol=0.001)
1307
- # specify max_clearness_index
1308
- out = irradiance.clearness_index(ghi, solar_zenith, 1370,
1309
- max_clearness_index=0.82)
1310
- expected = np.array(
1311
- [[0., 0., 0.011, 0.82],
1312
- [0., 0., 0.011, 0.82],
1313
- [0., 0., 0.011, 0.82],
1314
- [0., 0., 0.001, 0.73]])
1315
- assert_allclose(out, expected, atol=0.001)
1316
- # specify min_cos_zenith and max_clearness_index
1317
- with np.errstate(invalid='ignore', divide='ignore'):
1318
- out = irradiance.clearness_index(ghi, solar_zenith, 1400,
1319
- min_cos_zenith=0,
1320
- max_clearness_index=0.82)
1321
- expected = np.array(
1322
- [[0., nan, 0.82, 0.82],
1323
- [0., 0., 0.82, 0.82],
1324
- [0., 0., 0.82, 0.82],
1325
- [0., 0., 0.001, 0.714]])
1326
- assert_allclose(out, expected, atol=0.001)
1327
- # scalars
1328
- out = irradiance.clearness_index(1000, 10, 1400)
1329
- expected = 0.725
1330
- assert_allclose(out, expected, atol=0.001)
1331
- # series
1332
- times = pd.date_range(start='20180601', periods=2, freq='12h')
1333
- ghi = pd.Series([0, 1000], index=times)
1334
- solar_zenith = pd.Series([90, 0], index=times)
1335
- extra_radiation = pd.Series([1360, 1400], index=times)
1336
- out = irradiance.clearness_index(ghi, solar_zenith, extra_radiation)
1337
- expected = pd.Series([0, 0.714285714286], index=times)
1338
- assert_series_equal(out, expected)
1339
-
1340
-
1341
- def test_clearness_index_zenith_independent(airmass_kt):
1342
- clearness_index = np.array([-1, 0, .1, 1])
1343
- clearness_index, airmass_kt = np.meshgrid(clearness_index, airmass_kt)
1344
- out = irradiance.clearness_index_zenith_independent(clearness_index,
1345
- airmass_kt)
1346
- expected = np.array(
1347
- [[0., 0., 0.1, 1.],
1348
- [0., 0., 0.138, 1.383],
1349
- [0., 0., 0.182, 1.822],
1350
- [0., 0., 0.212, 2.]])
1351
- assert_allclose(out, expected, atol=0.001)
1352
- # test max_clearness_index
1353
- out = irradiance.clearness_index_zenith_independent(
1354
- clearness_index, airmass_kt, max_clearness_index=0.82)
1355
- expected = np.array(
1356
- [[0., 0., 0.1, 0.82],
1357
- [0., 0., 0.138, 0.82],
1358
- [0., 0., 0.182, 0.82],
1359
- [0., 0., 0.212, 0.82]])
1360
- assert_allclose(out, expected, atol=0.001)
1361
- # scalars
1362
- out = irradiance.clearness_index_zenith_independent(.4, 2)
1363
- expected = 0.443
1364
- assert_allclose(out, expected, atol=0.001)
1365
- # series
1366
- times = pd.date_range(start='20180601', periods=2, freq='12h')
1367
- clearness_index = pd.Series([0, .5], index=times)
1368
- airmass = pd.Series([np.nan, 2], index=times)
1369
- out = irradiance.clearness_index_zenith_independent(clearness_index,
1370
- airmass)
1371
- expected = pd.Series([np.nan, 0.553744437562], index=times)
1372
- assert_series_equal(out, expected)
1373
-
1374
-
1375
- def test_complete_irradiance():
1376
- # Generate dataframe to test on
1377
- times = pd.date_range('2010-07-05 7:00:00-0700', periods=2, freq='h')
1378
- i = pd.DataFrame({'ghi': [372.103976116, 497.087579068],
1379
- 'dhi': [356.543700, 465.44400],
1380
- 'dni': [49.63565561689957, 62.10624908037814]},
1381
- index=times)
1382
- # Define the solar position and clearsky dataframe
1383
- solar_position = pd.DataFrame({'apparent_zenith': [71.7303262449161,
1384
- 59.369],
1385
- 'zenith': [71.7764, 59.395]},
1386
- index=pd.DatetimeIndex([
1387
- '2010-07-05 07:00:00-0700',
1388
- '2010-07-05 08:00:00-0700']))
1389
- clearsky = pd.DataFrame({'dni': [625.5254880160008, 778.7766443075865],
1390
- 'ghi': [246.3508023804681, 469.461381740857],
1391
- 'dhi': [50.25488725346631, 72.66909939636372]},
1392
- index=pd.DatetimeIndex([
1393
- '2010-07-05 07:00:00-0700',
1394
- '2010-07-05 08:00:00-0700']))
1395
- # Test scenario where DNI is generated via component sum equation
1396
- complete_df = irradiance.complete_irradiance(
1397
- solar_position.apparent_zenith,
1398
- ghi=i.ghi,
1399
- dhi=i.dhi,
1400
- dni=None,
1401
- dni_clear=clearsky.dni)
1402
- # Assert that the ghi, dhi, and dni series match the original dataframe
1403
- # values
1404
- assert_frame_equal(complete_df, i)
1405
- # Test scenario where GHI is generated via component sum equation
1406
- complete_df = irradiance.complete_irradiance(
1407
- solar_position.apparent_zenith,
1408
- ghi=None,
1409
- dhi=i.dhi,
1410
- dni=i.dni,
1411
- dni_clear=clearsky.dni)
1412
- # Assert that the ghi, dhi, and dni series match the original dataframe
1413
- # values
1414
- assert_frame_equal(complete_df, i)
1415
- # Test scenario where DHI is generated via component sum equation
1416
- complete_df = irradiance.complete_irradiance(
1417
- solar_position.apparent_zenith,
1418
- ghi=i.ghi,
1419
- dhi=None,
1420
- dni=i.dni,
1421
- dni_clear=clearsky.dni)
1422
- # Assert that the ghi, dhi, and dni series match the original dataframe
1423
- # values
1424
- assert_frame_equal(complete_df, i)
1425
- # Test scenario where all parameters are passed (throw error)
1426
- with pytest.raises(ValueError):
1427
- irradiance.complete_irradiance(solar_position.apparent_zenith,
1428
- ghi=i.ghi,
1429
- dhi=i.dhi,
1430
- dni=i.dni,
1431
- dni_clear=clearsky.dni)
1432
- # Test scenario where only one parameter is passed (throw error)
1433
- with pytest.raises(ValueError):
1434
- irradiance.complete_irradiance(solar_position.apparent_zenith,
1435
- ghi=None,
1436
- dhi=None,
1437
- dni=i.dni,
1438
- dni_clear=clearsky.dni)
1439
-
1440
-
1441
- def test_louche():
1442
-
1443
- index = pd.DatetimeIndex(['20190101']*3 + ['20190620']*1)
1444
- ghi = pd.Series([0, 50, 1000, 1000], index=index)
1445
- zenith = pd.Series([91, 85, 10, 10], index=index)
1446
- expected = pd.DataFrame(np.array(
1447
- [[0, 0, 0],
1448
- [130.089669, 38.661938, 0.405724],
1449
- [828.498650, 184.088106, 0.718133],
1450
- [887.407348, 126.074364, 0.768214]]),
1451
- columns=['dni', 'dhi', 'kt'], index=index)
1452
-
1453
- out = irradiance.louche(ghi, zenith, index)
1454
-
1455
- assert_frame_equal(out, expected)
1456
-
1457
-
1458
- def test_SURFACE_ALBEDOS_deprecated():
1459
- with pytest.warns(pvlibDeprecationWarning, match='SURFACE_ALBEDOS has been'
1460
- ' moved to the albedo module as of v0.11.0. Please use'
1461
- ' pvlib.albedo.SURFACE_ALBEDOS.'):
1462
- irradiance.SURFACE_ALBEDOS
1463
-
1464
-
1465
- @pytest.mark.filterwarnings("ignore:SURFACE_ALBEDOS")
1466
- def test_SURFACE_ALBEDO_equals():
1467
- assert irradiance.SURFACE_ALBEDOS == albedo.SURFACE_ALBEDOS
1468
-
1469
-
1470
- def test_diffuse_par_spitters():
1471
- solar_zenith, global_diffuse_fraction = np.meshgrid(
1472
- [90, 85, 75, 60, 40, 30, 10, 0], [0.01, 0.1, 0.3, 0.6, 0.8, 0.99]
1473
- )
1474
- solar_zenith = solar_zenith.ravel()
1475
- global_diffuse_fraction = global_diffuse_fraction.ravel()
1476
- result = irradiance.diffuse_par_spitters(
1477
- solar_zenith, global_diffuse_fraction
1478
- )
1479
- expected = np.array([
1480
- 0.01300, 0.01290, 0.01226, 0.01118, 0.01125, 0.01189, 0.01293, 0.01300,
1481
- 0.12970, 0.12874, 0.12239, 0.11174, 0.11236, 0.11868, 0.12905, 0.12970,
1482
- 0.38190, 0.37931, 0.36201, 0.33273, 0.33446, 0.35188, 0.38014, 0.38190,
1483
- 0.71520, 0.71178, 0.68859, 0.64787, 0.65033, 0.67472, 0.71288, 0.71520,
1484
- 0.88640, 0.88401, 0.86755, 0.83745, 0.83931, 0.85746, 0.88478, 0.88640,
1485
- 0.99591, 0.99576, 0.99472, 0.99270, 0.99283, 0.99406, 0.99581, 0.99591,
1486
- ]) # fmt: skip
1487
- assert_allclose(result, expected, atol=1e-5)