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,474 +0,0 @@
1
- import numpy as np
2
- from numpy import nan
3
- import pandas as pd
4
-
5
- import pytest
6
- from numpy.testing import assert_allclose
7
-
8
- import pvlib
9
- from pvlib import tracking
10
- from .conftest import DATA_DIR, assert_frame_equal, assert_series_equal
11
- from pvlib._deprecation import pvlibDeprecationWarning
12
-
13
- SINGLEAXIS_COL_ORDER = ['tracker_theta', 'aoi',
14
- 'surface_azimuth', 'surface_tilt']
15
-
16
-
17
- def test_solar_noon():
18
- index = pd.date_range(start='20180701T1200', freq='1s', periods=1)
19
- apparent_zenith = pd.Series([10], index=index)
20
- apparent_azimuth = pd.Series([180], index=index)
21
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
22
- axis_tilt=0, axis_azimuth=0,
23
- max_angle=90, backtrack=True,
24
- gcr=2.0/7.0)
25
-
26
- expect = pd.DataFrame({'tracker_theta': 0, 'aoi': 10,
27
- 'surface_azimuth': 90, 'surface_tilt': 0},
28
- index=index, dtype=np.float64)
29
- expect = expect[SINGLEAXIS_COL_ORDER]
30
-
31
- assert_frame_equal(expect, tracker_data)
32
-
33
-
34
- def test_scalars():
35
- apparent_zenith = 10
36
- apparent_azimuth = 180
37
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
38
- axis_tilt=0, axis_azimuth=0,
39
- max_angle=90, backtrack=True,
40
- gcr=2.0/7.0)
41
- assert isinstance(tracker_data, dict)
42
- expect = {'tracker_theta': 0, 'aoi': 10, 'surface_azimuth': 90,
43
- 'surface_tilt': 0}
44
- for k, v in expect.items():
45
- assert np.isclose(tracker_data[k], v)
46
-
47
-
48
- def test_arrays():
49
- apparent_zenith = np.array([10])
50
- apparent_azimuth = np.array([180])
51
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
52
- axis_tilt=0, axis_azimuth=0,
53
- max_angle=90, backtrack=True,
54
- gcr=2.0/7.0)
55
- assert isinstance(tracker_data, dict)
56
- expect = {'tracker_theta': 0, 'aoi': 10, 'surface_azimuth': 90,
57
- 'surface_tilt': 0}
58
- for k, v in expect.items():
59
- assert_allclose(tracker_data[k], v, atol=1e-7)
60
-
61
-
62
- def test_nans():
63
- apparent_zenith = np.array([10, np.nan, 10])
64
- apparent_azimuth = np.array([180, 180, np.nan])
65
- with np.errstate(invalid='ignore'):
66
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
67
- axis_tilt=0, axis_azimuth=0,
68
- max_angle=90, backtrack=True,
69
- gcr=2.0/7.0)
70
- expect = {'tracker_theta': np.array([0, nan, nan]),
71
- 'aoi': np.array([10, nan, nan]),
72
- 'surface_azimuth': np.array([90, nan, nan]),
73
- 'surface_tilt': np.array([0, nan, nan])}
74
- for k, v in expect.items():
75
- assert_allclose(tracker_data[k], v, atol=1e-7)
76
-
77
- # repeat with Series because nans can differ
78
- apparent_zenith = pd.Series(apparent_zenith)
79
- apparent_azimuth = pd.Series(apparent_azimuth)
80
- with np.errstate(invalid='ignore'):
81
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
82
- axis_tilt=0, axis_azimuth=0,
83
- max_angle=90, backtrack=True,
84
- gcr=2.0/7.0)
85
- expect = pd.DataFrame(np.array(
86
- [[ 0., 10., 90., 0.],
87
- [nan, nan, nan, nan],
88
- [nan, nan, nan, nan]]),
89
- columns=['tracker_theta', 'aoi', 'surface_azimuth', 'surface_tilt'])
90
- assert_frame_equal(tracker_data, expect)
91
-
92
-
93
- def test_arrays_multi():
94
- apparent_zenith = np.array([[10, 10], [10, 10]])
95
- apparent_azimuth = np.array([[180, 180], [180, 180]])
96
- # singleaxis should fail for num dim > 1
97
- with pytest.raises(ValueError):
98
- tracking.singleaxis(apparent_zenith, apparent_azimuth,
99
- axis_tilt=0, axis_azimuth=0,
100
- max_angle=90, backtrack=True,
101
- gcr=2.0/7.0)
102
- # uncomment if we ever get singleaxis to support num dim > 1 arrays
103
- # assert isinstance(tracker_data, dict)
104
- # expect = {'tracker_theta': np.full_like(apparent_zenith, 0),
105
- # 'aoi': np.full_like(apparent_zenith, 10),
106
- # 'surface_azimuth': np.full_like(apparent_zenith, 90),
107
- # 'surface_tilt': np.full_like(apparent_zenith, 0)}
108
- # for k, v in expect.items():
109
- # assert_allclose(tracker_data[k], v)
110
-
111
-
112
- def test_azimuth_north_south():
113
- apparent_zenith = pd.Series([60])
114
- apparent_azimuth = pd.Series([90])
115
-
116
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
117
- axis_tilt=0, axis_azimuth=180,
118
- max_angle=90, backtrack=True,
119
- gcr=2.0/7.0)
120
-
121
- expect = pd.DataFrame({'tracker_theta': -60, 'aoi': 0,
122
- 'surface_azimuth': 90, 'surface_tilt': 60},
123
- index=[0], dtype=np.float64)
124
- expect = expect[SINGLEAXIS_COL_ORDER]
125
-
126
- assert_frame_equal(expect, tracker_data)
127
-
128
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
129
- axis_tilt=0, axis_azimuth=0,
130
- max_angle=90, backtrack=True,
131
- gcr=2.0/7.0)
132
-
133
- expect['tracker_theta'] *= -1
134
-
135
- assert_frame_equal(expect, tracker_data)
136
-
137
-
138
- def test_max_angle():
139
- apparent_zenith = pd.Series([60])
140
- apparent_azimuth = pd.Series([90])
141
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
142
- axis_tilt=0, axis_azimuth=0,
143
- max_angle=45, backtrack=True,
144
- gcr=2.0/7.0)
145
-
146
- expect = pd.DataFrame({'aoi': 15, 'surface_azimuth': 90,
147
- 'surface_tilt': 45, 'tracker_theta': 45},
148
- index=[0], dtype=np.float64)
149
- expect = expect[SINGLEAXIS_COL_ORDER]
150
-
151
- assert_frame_equal(expect, tracker_data)
152
-
153
-
154
- def test_min_angle():
155
- apparent_zenith = pd.Series([60])
156
- apparent_azimuth = pd.Series([270])
157
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
158
- axis_tilt=0, axis_azimuth=0,
159
- max_angle=(-45, 50), backtrack=True,
160
- gcr=2.0/7.0)
161
-
162
- expect = pd.DataFrame({'aoi': 15, 'surface_azimuth': 270,
163
- 'surface_tilt': 45, 'tracker_theta': -45},
164
- index=[0], dtype=np.float64)
165
- expect = expect[SINGLEAXIS_COL_ORDER]
166
-
167
- assert_frame_equal(expect, tracker_data)
168
-
169
-
170
- def test_backtrack():
171
- apparent_zenith = pd.Series([80])
172
- apparent_azimuth = pd.Series([90])
173
-
174
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
175
- axis_tilt=0, axis_azimuth=0,
176
- max_angle=90, backtrack=False,
177
- gcr=2.0/7.0)
178
-
179
- expect = pd.DataFrame({'aoi': 0, 'surface_azimuth': 90,
180
- 'surface_tilt': 80, 'tracker_theta': 80},
181
- index=[0], dtype=np.float64)
182
- expect = expect[SINGLEAXIS_COL_ORDER]
183
-
184
- assert_frame_equal(expect, tracker_data)
185
-
186
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
187
- axis_tilt=0, axis_azimuth=0,
188
- max_angle=90, backtrack=True,
189
- gcr=2.0/7.0)
190
-
191
- expect = pd.DataFrame({'aoi': 52.5716, 'surface_azimuth': 90,
192
- 'surface_tilt': 27.42833, 'tracker_theta': 27.4283},
193
- index=[0], dtype=np.float64)
194
- expect = expect[SINGLEAXIS_COL_ORDER]
195
-
196
- assert_frame_equal(expect, tracker_data)
197
-
198
-
199
- def test_axis_tilt():
200
- apparent_zenith = pd.Series([30])
201
- apparent_azimuth = pd.Series([135])
202
-
203
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
204
- axis_tilt=30, axis_azimuth=180,
205
- max_angle=90, backtrack=True,
206
- gcr=2.0/7.0)
207
-
208
- expect = pd.DataFrame({'aoi': 7.286245, 'surface_azimuth': 142.65730,
209
- 'surface_tilt': 35.98741,
210
- 'tracker_theta': -20.88121},
211
- index=[0], dtype=np.float64)
212
- expect = expect[SINGLEAXIS_COL_ORDER]
213
-
214
- assert_frame_equal(expect, tracker_data)
215
-
216
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
217
- axis_tilt=30, axis_azimuth=0,
218
- max_angle=90, backtrack=True,
219
- gcr=2.0/7.0)
220
-
221
- expect = pd.DataFrame({'aoi': 47.6632, 'surface_azimuth': 50.96969,
222
- 'surface_tilt': 42.5152, 'tracker_theta': 31.6655},
223
- index=[0], dtype=np.float64)
224
- expect = expect[SINGLEAXIS_COL_ORDER]
225
-
226
- assert_frame_equal(expect, tracker_data)
227
-
228
-
229
- def test_axis_azimuth():
230
- apparent_zenith = pd.Series([30])
231
- apparent_azimuth = pd.Series([90])
232
-
233
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
234
- axis_tilt=0, axis_azimuth=90,
235
- max_angle=90, backtrack=True,
236
- gcr=2.0/7.0)
237
-
238
- expect = pd.DataFrame({'aoi': 30, 'surface_azimuth': 180,
239
- 'surface_tilt': 0, 'tracker_theta': 0},
240
- index=[0], dtype=np.float64)
241
- expect = expect[SINGLEAXIS_COL_ORDER]
242
-
243
- assert_frame_equal(expect, tracker_data)
244
-
245
- apparent_zenith = pd.Series([30])
246
- apparent_azimuth = pd.Series([180])
247
-
248
- tracker_data = tracking.singleaxis(apparent_zenith, apparent_azimuth,
249
- axis_tilt=0, axis_azimuth=90,
250
- max_angle=90, backtrack=True,
251
- gcr=2.0/7.0)
252
-
253
- expect = pd.DataFrame({'aoi': 0, 'surface_azimuth': 180,
254
- 'surface_tilt': 30, 'tracker_theta': 30},
255
- index=[0], dtype=np.float64)
256
- expect = expect[SINGLEAXIS_COL_ORDER]
257
-
258
- assert_frame_equal(expect, tracker_data)
259
-
260
-
261
- def test_horizon_flat():
262
- # GH 569
263
- solar_azimuth = np.array([0, 180, 359])
264
- solar_zenith = np.array([100, 45, 100])
265
- solar_azimuth = pd.Series(solar_azimuth)
266
- solar_zenith = pd.Series(solar_zenith)
267
- # depending on platform and numpy versions this will generate
268
- # RuntimeWarning: invalid value encountered in > < >=
269
- out = tracking.singleaxis(solar_zenith, solar_azimuth, axis_tilt=0,
270
- axis_azimuth=180, backtrack=False, max_angle=180)
271
- expected = pd.DataFrame(np.array(
272
- [[ nan, nan, nan, nan],
273
- [ 0., 45., 270., 0.],
274
- [ nan, nan, nan, nan]]),
275
- columns=['tracker_theta', 'aoi', 'surface_azimuth', 'surface_tilt'])
276
- assert_frame_equal(out, expected)
277
-
278
-
279
- def test_horizon_tilted():
280
- # GH 569
281
- solar_azimuth = np.array([0, 180, 359])
282
- solar_zenith = np.full_like(solar_azimuth, 45)
283
- solar_azimuth = pd.Series(solar_azimuth)
284
- solar_zenith = pd.Series(solar_zenith)
285
- out = tracking.singleaxis(solar_zenith, solar_azimuth, axis_tilt=90,
286
- axis_azimuth=180, backtrack=False, max_angle=180)
287
- expected = pd.DataFrame(np.array(
288
- [[-180., 45., 0., 90.],
289
- [ 0., 45., 180., 90.],
290
- [ 179., 45., 359., 90.]]),
291
- columns=['tracker_theta', 'aoi', 'surface_azimuth', 'surface_tilt'])
292
- assert_frame_equal(out, expected)
293
-
294
-
295
- def test_low_sun_angles():
296
- # GH 656, 824
297
- result = tracking.singleaxis(
298
- apparent_zenith=80, apparent_azimuth=338, axis_tilt=30,
299
- axis_azimuth=180, max_angle=60, backtrack=True, gcr=0.35)
300
- expected = {
301
- 'tracker_theta': np.array([60.0]),
302
- 'aoi': np.array([80.420987]),
303
- 'surface_azimuth': np.array([253.897886]),
304
- 'surface_tilt': np.array([64.341094])}
305
- for k, v in result.items():
306
- assert_allclose(expected[k], v)
307
-
308
-
309
- def test_calc_axis_tilt():
310
- # expected values
311
- expected_axis_tilt = 2.239 # [degrees]
312
- expected_side_slope = 9.86649274360294 # [degrees]
313
- expected = DATA_DIR / 'singleaxis_tracker_wslope.csv'
314
- expected = pd.read_csv(expected, index_col='timestamp', parse_dates=True)
315
- # solar positions
316
- starttime = '2017-01-01T00:30:00-0300'
317
- stoptime = '2017-12-31T23:59:59-0300'
318
- lat, lon = -27.597300, -48.549610
319
- times = pd.DatetimeIndex(pd.date_range(starttime, stoptime, freq='h'))
320
- solpos = pvlib.solarposition.get_solarposition(times, lat, lon)
321
- # singleaxis tracker w/slope data
322
- slope_azimuth, slope_tilt = 77.34, 10.1149
323
- axis_azimuth = 0.0
324
- max_angle = 75.0
325
- # Note: GCR is relative to horizontal distance between rows
326
- gcr = 0.33292759 # GCR = length / horizontal_pitch = 1.64 / 5 / cos(9.86)
327
- # calculate tracker axis zenith
328
- axis_tilt = tracking.calc_axis_tilt(
329
- slope_azimuth, slope_tilt, axis_azimuth=axis_azimuth)
330
- assert np.isclose(axis_tilt, expected_axis_tilt)
331
- # calculate cross-axis tilt and relative rotation
332
- cross_axis_tilt = tracking.calc_cross_axis_tilt(
333
- slope_azimuth, slope_tilt, axis_azimuth, axis_tilt)
334
- assert np.isclose(cross_axis_tilt, expected_side_slope)
335
- sat = tracking.singleaxis(
336
- solpos.apparent_zenith, solpos.azimuth, axis_tilt, axis_azimuth,
337
- max_angle, backtrack=True, gcr=gcr, cross_axis_tilt=cross_axis_tilt)
338
- np.testing.assert_allclose(
339
- sat['tracker_theta'], expected['tracker_theta'], atol=1e-7)
340
- np.testing.assert_allclose(sat['aoi'], expected['aoi'], atol=1e-7)
341
- np.testing.assert_allclose(
342
- sat['surface_azimuth'], expected['surface_azimuth'], atol=1e-7)
343
- np.testing.assert_allclose(
344
- sat['surface_tilt'], expected['surface_tilt'], atol=1e-7)
345
-
346
-
347
- def test_slope_aware_backtracking():
348
- """
349
- Test validation data set from https://www.nrel.gov/docs/fy20osti/76626.pdf
350
- """
351
- index = pd.date_range('2019-01-01T08:00', '2019-01-01T17:00', freq='h')
352
- index = index.tz_localize('Etc/GMT+5')
353
- expected_data = pd.DataFrame(index=index, data=[
354
- ( 2.404287, 122.79177, -84.440, -10.899),
355
- (11.263058, 133.288729, -72.604, -25.747),
356
- (18.733558, 145.285552, -59.861, -59.861),
357
- (24.109076, 158.939435, -45.578, -45.578),
358
- (26.810735, 173.931802, -28.764, -28.764),
359
- (26.482495, 189.371536, -8.475, -8.475),
360
- (23.170447, 204.13681, 15.120, 15.120),
361
- (17.296785, 217.446538, 39.562, 39.562),
362
- ( 9.461862, 229.102218, 61.587, 32.339),
363
- ( 0.524817, 239.330401, 79.530, 5.490),
364
- ], columns=['ApparentElevation', 'SolarAzimuth',
365
- 'TrueTracking', 'Backtracking'])
366
- expected_axis_tilt = 9.666
367
- expected_slope_angle = -2.576
368
- slope_azimuth, slope_tilt = 180.0, 10.0
369
- axis_azimuth = 195.0
370
- axis_tilt = tracking.calc_axis_tilt(
371
- slope_azimuth, slope_tilt, axis_azimuth)
372
- assert np.isclose(axis_tilt, expected_axis_tilt, rtol=1e-3, atol=1e-3)
373
- cross_axis_tilt = tracking.calc_cross_axis_tilt(
374
- slope_azimuth, slope_tilt, axis_azimuth, axis_tilt)
375
- assert np.isclose(
376
- cross_axis_tilt, expected_slope_angle, rtol=1e-3, atol=1e-3)
377
- sat = tracking.singleaxis(
378
- 90.0-expected_data['ApparentElevation'], expected_data['SolarAzimuth'],
379
- axis_tilt, axis_azimuth, max_angle=90.0, backtrack=True, gcr=0.5,
380
- cross_axis_tilt=cross_axis_tilt)
381
- assert_series_equal(sat['tracker_theta'],
382
- expected_data['Backtracking'].rename('tracker_theta'),
383
- check_less_precise=True)
384
- truetracking = tracking.singleaxis(
385
- 90.0-expected_data['ApparentElevation'], expected_data['SolarAzimuth'],
386
- axis_tilt, axis_azimuth, max_angle=90.0, backtrack=False, gcr=0.5,
387
- cross_axis_tilt=cross_axis_tilt)
388
- assert_series_equal(truetracking['tracker_theta'],
389
- expected_data['TrueTracking'].rename('tracker_theta'),
390
- check_less_precise=True)
391
-
392
-
393
- def test_singleaxis_aoi_gh1221():
394
- # vertical tracker
395
- loc = pvlib.location.Location(40.1134, -88.3695)
396
- dr = pd.date_range(
397
- start='02-Jun-1998 00:00:00', end='02-Jun-1998 23:55:00', freq='5min',
398
- tz='Etc/GMT+6')
399
- sp = loc.get_solarposition(dr)
400
- tr = pvlib.tracking.singleaxis(
401
- sp['apparent_zenith'], sp['azimuth'], axis_tilt=90, axis_azimuth=180,
402
- max_angle=0.001, backtrack=False)
403
- fixed = pvlib.irradiance.aoi(90, 180, sp['apparent_zenith'], sp['azimuth'])
404
- fixed[np.isnan(tr['aoi'])] = np.nan
405
- assert np.allclose(tr['aoi'], fixed, equal_nan=True)
406
-
407
-
408
- def test_calc_surface_orientation_types():
409
- # numpy arrays
410
- rotations = np.array([-10, 0, 10])
411
- expected_tilts = np.array([10, 0, 10], dtype=float)
412
- expected_azimuths = np.array([270, 90, 90], dtype=float)
413
- out = tracking.calc_surface_orientation(tracker_theta=rotations)
414
- np.testing.assert_allclose(expected_tilts, out['surface_tilt'])
415
- np.testing.assert_allclose(expected_azimuths, out['surface_azimuth'])
416
-
417
- # pandas Series
418
- rotations = pd.Series(rotations)
419
- expected_tilts = pd.Series(expected_tilts).rename('surface_tilt')
420
- expected_azimuths = pd.Series(expected_azimuths).rename('surface_azimuth')
421
- out = tracking.calc_surface_orientation(tracker_theta=rotations)
422
- assert_series_equal(expected_tilts, out['surface_tilt'])
423
- assert_series_equal(expected_azimuths, out['surface_azimuth'])
424
-
425
- # float
426
- for rotation, expected_tilt, expected_azimuth in zip(
427
- rotations, expected_tilts, expected_azimuths):
428
- out = tracking.calc_surface_orientation(rotation)
429
- assert out['surface_tilt'] == pytest.approx(expected_tilt)
430
- assert out['surface_azimuth'] == pytest.approx(expected_azimuth)
431
-
432
-
433
- def test_calc_surface_orientation_kwargs():
434
- # non-default axis tilt & azimuth
435
- rotations = np.array([-10, 0, 10])
436
- expected_tilts = np.array([22.2687445, 20.0, 22.2687445])
437
- expected_azimuths = np.array([152.72683041, 180.0, 207.27316959])
438
- out = tracking.calc_surface_orientation(rotations,
439
- axis_tilt=20,
440
- axis_azimuth=180)
441
- np.testing.assert_allclose(out['surface_tilt'], expected_tilts)
442
- np.testing.assert_allclose(out['surface_azimuth'], expected_azimuths)
443
-
444
-
445
- def test_calc_surface_orientation_special():
446
- # special cases for rotations
447
- rotations = np.array([-180, -90, -0, 0, 90, 180])
448
- expected_tilts = np.array([180, 90, 0, 0, 90, 180], dtype=float)
449
- expected_azimuths = [270, 270, 90, 90, 90, 90]
450
- out = tracking.calc_surface_orientation(rotations)
451
- np.testing.assert_allclose(out['surface_tilt'], expected_tilts)
452
- np.testing.assert_allclose(out['surface_azimuth'], expected_azimuths)
453
-
454
- # special case for axis_tilt
455
- rotations = np.array([-10, 0, 10])
456
- expected_tilts = np.array([90, 90, 90], dtype=float)
457
- expected_azimuths = np.array([350, 0, 10], dtype=float)
458
- out = tracking.calc_surface_orientation(rotations, axis_tilt=90)
459
- np.testing.assert_allclose(out['surface_tilt'], expected_tilts)
460
- np.testing.assert_allclose(out['surface_azimuth'], expected_azimuths)
461
-
462
- # special cases for axis_azimuth
463
- rotations = np.array([-10, 0, 10])
464
- expected_tilts = np.array([10, 0, 10], dtype=float)
465
- expected_azimuth_offsets = np.array([-90, 90, 90], dtype=float)
466
- for axis_azimuth in [0, 90, 180, 270, 360]:
467
- expected_azimuths = (axis_azimuth + expected_azimuth_offsets) % 360
468
- out = tracking.calc_surface_orientation(rotations,
469
- axis_azimuth=axis_azimuth)
470
- np.testing.assert_allclose(out['surface_tilt'], expected_tilts)
471
- # the rounding is a bit ugly, but necessary to test approximately equal
472
- # in a modulo-360 sense.
473
- np.testing.assert_allclose(np.round(out['surface_azimuth'], 4) % 360,
474
- expected_azimuths, rtol=1e-5, atol=1e-5)
@@ -1,60 +0,0 @@
1
- import pandas as pd
2
-
3
- from numpy.testing import assert_allclose
4
-
5
- from pvlib import transformer
6
-
7
-
8
- def test_simple_efficiency():
9
-
10
- # define test inputs
11
- input_power = pd.Series([
12
- -800.0,
13
- 436016.609823837,
14
- 1511820.16603752,
15
- 1580687.44677249,
16
- 1616441.79660171
17
- ])
18
- no_load_loss = 0.002
19
- load_loss = 0.007
20
- transformer_rating = 2750000
21
-
22
- # define expected test results
23
- expected_output_power = pd.Series([
24
- -6300.10103234071,
25
- 430045.854892526,
26
- 1500588.39919874,
27
- 1568921.77089526,
28
- 1604389.62839879
29
- ])
30
-
31
- # run test function with test inputs
32
- calculated_output_power = transformer.simple_efficiency(
33
- input_power=input_power,
34
- no_load_loss=no_load_loss,
35
- load_loss=load_loss,
36
- transformer_rating=transformer_rating
37
- )
38
-
39
- # determine if expected results are obtained
40
- assert_allclose(calculated_output_power, expected_output_power)
41
-
42
-
43
- def test_simple_efficiency_known_values():
44
- no_load_loss = 0.005
45
- load_loss = 0.01
46
- rating = 1000
47
- args = (no_load_loss, load_loss, rating)
48
-
49
- # verify correct behavior at no-load condition
50
- assert_allclose(
51
- transformer.simple_efficiency(no_load_loss*rating, *args),
52
- 0.0
53
- )
54
-
55
- # verify correct behavior at rated condition
56
- assert_allclose(
57
- transformer.simple_efficiency(rating*(1 + no_load_loss + load_loss),
58
- *args),
59
- rating,
60
- )