pvlib 0.11.2__py3-none-any.whl → 0.12.1a1__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 (147) hide show
  1. pvlib/__init__.py +1 -0
  2. pvlib/atmosphere.py +40 -40
  3. pvlib/bifacial/infinite_sheds.py +4 -3
  4. pvlib/bifacial/utils.py +2 -1
  5. pvlib/iotools/__init__.py +6 -0
  6. pvlib/iotools/psm3.py +1 -1
  7. pvlib/iotools/psm4.py +819 -0
  8. pvlib/iotools/pvgis.py +10 -2
  9. pvlib/iotools/tmy.py +3 -69
  10. pvlib/irradiance.py +38 -15
  11. pvlib/ivtools/sdm/__init__.py +20 -0
  12. pvlib/ivtools/sdm/_fit_desoto_pvsyst_sandia.py +585 -0
  13. pvlib/ivtools/sdm/cec.py +93 -0
  14. pvlib/ivtools/sdm/desoto.py +401 -0
  15. pvlib/ivtools/sdm/pvsyst.py +630 -0
  16. pvlib/location.py +73 -33
  17. pvlib/modelchain.py +19 -36
  18. pvlib/pvsystem.py +114 -65
  19. pvlib/snow.py +64 -28
  20. pvlib/spectrum/__init__.py +0 -1
  21. pvlib/spectrum/irradiance.py +2 -64
  22. pvlib/spectrum/mismatch.py +3 -3
  23. pvlib/tools.py +6 -5
  24. {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.dist-info}/METADATA +6 -5
  25. pvlib-0.12.1a1.dist-info/RECORD +80 -0
  26. {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.dist-info}/WHEEL +1 -1
  27. pvlib/data/BIRD_08_16_2012.csv +0 -8761
  28. pvlib/data/BIRD_08_16_2012_patm.csv +0 -8761
  29. pvlib/data/Burlington, United States SolarAnywhere Time Series 2021 Lat_44_465 Lon_-73_205 TMY3 format.csv +0 -8762
  30. pvlib/data/Burlington, United States SolarAnywhere Time Series 20210101 to 20210103 Lat_44_4675 Lon_-73_2075 SA format.csv +0 -578
  31. pvlib/data/Burlington, United States SolarAnywhere Typical GHI Year Lat_44_465 Lon_-73_205 SA format.csv +0 -74
  32. pvlib/data/CPS SCH275KTL-DO-US-800-250kW_275kVA_1.OND +0 -146
  33. pvlib/data/CRNS0101-05-2019-AZ_Tucson_11_W.txt +0 -4
  34. pvlib/data/CRN_with_problems.txt +0 -3
  35. pvlib/data/ET-M772BH550GL.PAN +0 -75
  36. pvlib/data/NLD_Amsterdam062400_IWEC.epw +0 -8768
  37. pvlib/data/PVsyst_demo.csv +0 -10757
  38. pvlib/data/PVsyst_demo_model.csv +0 -3588
  39. pvlib/data/SRML-day-EUPO1801.txt +0 -1441
  40. pvlib/data/abq19056.dat +0 -6
  41. pvlib/data/bishop88_numerical_precision.csv +0 -101
  42. pvlib/data/bsrn-lr0100-pay0616.dat +0 -86901
  43. pvlib/data/bsrn-pay0616.dat.gz +0 -0
  44. pvlib/data/cams_mcclear_1min_verbose.csv +0 -60
  45. pvlib/data/cams_mcclear_monthly.csv +0 -42
  46. pvlib/data/cams_radiation_1min_verbose.csv +0 -72
  47. pvlib/data/cams_radiation_monthly.csv +0 -47
  48. pvlib/data/detect_clearsky_data.csv +0 -35
  49. pvlib/data/detect_clearsky_threshold_data.csv +0 -126
  50. pvlib/data/greensboro_kimber_soil_manwash.dat +0 -8761
  51. pvlib/data/greensboro_kimber_soil_nowash.dat +0 -8761
  52. pvlib/data/inverter_fit_snl_meas.csv +0 -127
  53. pvlib/data/inverter_fit_snl_sim.csv +0 -19
  54. pvlib/data/ivtools_numdiff.csv +0 -52
  55. pvlib/data/midc_20181014.txt +0 -1441
  56. pvlib/data/midc_raw_20181018.txt +0 -1441
  57. pvlib/data/midc_raw_short_header_20191115.txt +0 -1441
  58. pvlib/data/msn19056.dat +0 -6
  59. pvlib/data/precise_iv_curves1.json +0 -10251
  60. pvlib/data/precise_iv_curves2.json +0 -10251
  61. pvlib/data/precise_iv_curves_parameter_sets1.csv +0 -33
  62. pvlib/data/precise_iv_curves_parameter_sets2.csv +0 -33
  63. pvlib/data/pvgis_hourly_Timeseries_45.000_8.000_SA2_10kWp_CIS_5_2a_2013_2014.json +0 -1
  64. pvlib/data/pvgis_hourly_Timeseries_45.000_8.000_SA_30deg_0deg_2016_2016.csv +0 -35
  65. pvlib/data/pvgis_tmy_meta.json +0 -32
  66. pvlib/data/pvgis_tmy_test.csv +0 -8761
  67. pvlib/data/pvwatts_8760_rackmount.csv +0 -8779
  68. pvlib/data/pvwatts_8760_roofmount.csv +0 -8779
  69. pvlib/data/singleaxis_tracker_wslope.csv +0 -8761
  70. pvlib/data/spectrl2_example_spectra.csv +0 -123
  71. pvlib/data/surfrad-slv16001.dat +0 -1442
  72. pvlib/data/test_psm3_2017.csv +0 -17521
  73. pvlib/data/test_psm3_2019_5min.csv +0 -289
  74. pvlib/data/test_psm3_tmy-2017.csv +0 -8761
  75. pvlib/data/test_read_psm3.csv +0 -17523
  76. pvlib/data/test_read_pvgis_horizon.csv +0 -49
  77. pvlib/data/tmy_45.000_8.000_2005_2023.csv +0 -8789
  78. pvlib/data/tmy_45.000_8.000_2005_2023.epw +0 -8768
  79. pvlib/data/tmy_45.000_8.000_2005_2023.json +0 -1
  80. pvlib/data/tmy_45.000_8.000_2005_2023.txt +0 -8761
  81. pvlib/data/tmy_45.000_8.000_userhorizon.json +0 -1
  82. pvlib/ivtools/sdm.py +0 -1379
  83. pvlib/spa_c_files/README.md +0 -81
  84. pvlib/spa_c_files/cspa_py.pxd +0 -43
  85. pvlib/spa_c_files/spa_py.pyx +0 -30
  86. pvlib/tests/__init__.py +0 -0
  87. pvlib/tests/bifacial/__init__.py +0 -0
  88. pvlib/tests/bifacial/test_infinite_sheds.py +0 -317
  89. pvlib/tests/bifacial/test_losses_models.py +0 -54
  90. pvlib/tests/bifacial/test_pvfactors.py +0 -82
  91. pvlib/tests/bifacial/test_utils.py +0 -192
  92. pvlib/tests/conftest.py +0 -476
  93. pvlib/tests/iotools/__init__.py +0 -0
  94. pvlib/tests/iotools/test_acis.py +0 -213
  95. pvlib/tests/iotools/test_bsrn.py +0 -131
  96. pvlib/tests/iotools/test_crn.py +0 -95
  97. pvlib/tests/iotools/test_epw.py +0 -23
  98. pvlib/tests/iotools/test_midc.py +0 -89
  99. pvlib/tests/iotools/test_panond.py +0 -32
  100. pvlib/tests/iotools/test_psm3.py +0 -198
  101. pvlib/tests/iotools/test_pvgis.py +0 -644
  102. pvlib/tests/iotools/test_sodapro.py +0 -298
  103. pvlib/tests/iotools/test_solaranywhere.py +0 -287
  104. pvlib/tests/iotools/test_solargis.py +0 -68
  105. pvlib/tests/iotools/test_solcast.py +0 -324
  106. pvlib/tests/iotools/test_solrad.py +0 -152
  107. pvlib/tests/iotools/test_srml.py +0 -124
  108. pvlib/tests/iotools/test_surfrad.py +0 -75
  109. pvlib/tests/iotools/test_tmy.py +0 -133
  110. pvlib/tests/ivtools/__init__.py +0 -0
  111. pvlib/tests/ivtools/test_sde.py +0 -230
  112. pvlib/tests/ivtools/test_sdm.py +0 -429
  113. pvlib/tests/ivtools/test_utils.py +0 -173
  114. pvlib/tests/spectrum/__init__.py +0 -0
  115. pvlib/tests/spectrum/conftest.py +0 -40
  116. pvlib/tests/spectrum/test_irradiance.py +0 -138
  117. pvlib/tests/spectrum/test_mismatch.py +0 -304
  118. pvlib/tests/spectrum/test_response.py +0 -124
  119. pvlib/tests/spectrum/test_spectrl2.py +0 -72
  120. pvlib/tests/test__deprecation.py +0 -97
  121. pvlib/tests/test_albedo.py +0 -84
  122. pvlib/tests/test_atmosphere.py +0 -351
  123. pvlib/tests/test_clearsky.py +0 -884
  124. pvlib/tests/test_conftest.py +0 -37
  125. pvlib/tests/test_iam.py +0 -555
  126. pvlib/tests/test_inverter.py +0 -213
  127. pvlib/tests/test_irradiance.py +0 -1487
  128. pvlib/tests/test_location.py +0 -356
  129. pvlib/tests/test_modelchain.py +0 -2020
  130. pvlib/tests/test_numerical_precision.py +0 -124
  131. pvlib/tests/test_pvarray.py +0 -71
  132. pvlib/tests/test_pvsystem.py +0 -2511
  133. pvlib/tests/test_scaling.py +0 -207
  134. pvlib/tests/test_shading.py +0 -391
  135. pvlib/tests/test_singlediode.py +0 -608
  136. pvlib/tests/test_snow.py +0 -212
  137. pvlib/tests/test_soiling.py +0 -230
  138. pvlib/tests/test_solarposition.py +0 -966
  139. pvlib/tests/test_spa.py +0 -454
  140. pvlib/tests/test_temperature.py +0 -470
  141. pvlib/tests/test_tools.py +0 -146
  142. pvlib/tests/test_tracking.py +0 -474
  143. pvlib/tests/test_transformer.py +0 -60
  144. pvlib-0.11.2.dist-info/RECORD +0 -191
  145. {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.dist-info/licenses}/AUTHORS.md +0 -0
  146. {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.dist-info/licenses}/LICENSE +0 -0
  147. {pvlib-0.11.2.dist-info → pvlib-0.12.1a1.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)