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