pvlib 0.11.2__py3-none-any.whl → 0.12.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. pvlib/__init__.py +1 -0
  2. pvlib/atmosphere.py +0 -9
  3. pvlib/bifacial/infinite_sheds.py +4 -3
  4. pvlib/bifacial/utils.py +2 -1
  5. pvlib/iotools/psm3.py +1 -1
  6. pvlib/iotools/pvgis.py +10 -2
  7. pvlib/iotools/tmy.py +3 -69
  8. pvlib/irradiance.py +14 -0
  9. pvlib/location.py +73 -33
  10. pvlib/modelchain.py +18 -35
  11. pvlib/pvsystem.py +7 -10
  12. pvlib/snow.py +64 -28
  13. pvlib/spectrum/__init__.py +0 -1
  14. pvlib/spectrum/irradiance.py +0 -63
  15. pvlib/spectrum/mismatch.py +3 -3
  16. pvlib/tools.py +6 -5
  17. {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info}/METADATA +5 -3
  18. pvlib-0.12.0.dist-info/RECORD +75 -0
  19. {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info}/WHEEL +1 -1
  20. pvlib/data/BIRD_08_16_2012.csv +0 -8761
  21. pvlib/data/BIRD_08_16_2012_patm.csv +0 -8761
  22. pvlib/data/Burlington, United States SolarAnywhere Time Series 2021 Lat_44_465 Lon_-73_205 TMY3 format.csv +0 -8762
  23. pvlib/data/Burlington, United States SolarAnywhere Time Series 20210101 to 20210103 Lat_44_4675 Lon_-73_2075 SA format.csv +0 -578
  24. pvlib/data/Burlington, United States SolarAnywhere Typical GHI Year Lat_44_465 Lon_-73_205 SA format.csv +0 -74
  25. pvlib/data/CPS SCH275KTL-DO-US-800-250kW_275kVA_1.OND +0 -146
  26. pvlib/data/CRNS0101-05-2019-AZ_Tucson_11_W.txt +0 -4
  27. pvlib/data/CRN_with_problems.txt +0 -3
  28. pvlib/data/ET-M772BH550GL.PAN +0 -75
  29. pvlib/data/NLD_Amsterdam062400_IWEC.epw +0 -8768
  30. pvlib/data/PVsyst_demo.csv +0 -10757
  31. pvlib/data/PVsyst_demo_model.csv +0 -3588
  32. pvlib/data/SRML-day-EUPO1801.txt +0 -1441
  33. pvlib/data/abq19056.dat +0 -6
  34. pvlib/data/bishop88_numerical_precision.csv +0 -101
  35. pvlib/data/bsrn-lr0100-pay0616.dat +0 -86901
  36. pvlib/data/bsrn-pay0616.dat.gz +0 -0
  37. pvlib/data/cams_mcclear_1min_verbose.csv +0 -60
  38. pvlib/data/cams_mcclear_monthly.csv +0 -42
  39. pvlib/data/cams_radiation_1min_verbose.csv +0 -72
  40. pvlib/data/cams_radiation_monthly.csv +0 -47
  41. pvlib/data/detect_clearsky_data.csv +0 -35
  42. pvlib/data/detect_clearsky_threshold_data.csv +0 -126
  43. pvlib/data/greensboro_kimber_soil_manwash.dat +0 -8761
  44. pvlib/data/greensboro_kimber_soil_nowash.dat +0 -8761
  45. pvlib/data/inverter_fit_snl_meas.csv +0 -127
  46. pvlib/data/inverter_fit_snl_sim.csv +0 -19
  47. pvlib/data/ivtools_numdiff.csv +0 -52
  48. pvlib/data/midc_20181014.txt +0 -1441
  49. pvlib/data/midc_raw_20181018.txt +0 -1441
  50. pvlib/data/midc_raw_short_header_20191115.txt +0 -1441
  51. pvlib/data/msn19056.dat +0 -6
  52. pvlib/data/precise_iv_curves1.json +0 -10251
  53. pvlib/data/precise_iv_curves2.json +0 -10251
  54. pvlib/data/precise_iv_curves_parameter_sets1.csv +0 -33
  55. pvlib/data/precise_iv_curves_parameter_sets2.csv +0 -33
  56. pvlib/data/pvgis_hourly_Timeseries_45.000_8.000_SA2_10kWp_CIS_5_2a_2013_2014.json +0 -1
  57. pvlib/data/pvgis_hourly_Timeseries_45.000_8.000_SA_30deg_0deg_2016_2016.csv +0 -35
  58. pvlib/data/pvgis_tmy_meta.json +0 -32
  59. pvlib/data/pvgis_tmy_test.csv +0 -8761
  60. pvlib/data/pvwatts_8760_rackmount.csv +0 -8779
  61. pvlib/data/pvwatts_8760_roofmount.csv +0 -8779
  62. pvlib/data/singleaxis_tracker_wslope.csv +0 -8761
  63. pvlib/data/spectrl2_example_spectra.csv +0 -123
  64. pvlib/data/surfrad-slv16001.dat +0 -1442
  65. pvlib/data/test_psm3_2017.csv +0 -17521
  66. pvlib/data/test_psm3_2019_5min.csv +0 -289
  67. pvlib/data/test_psm3_tmy-2017.csv +0 -8761
  68. pvlib/data/test_read_psm3.csv +0 -17523
  69. pvlib/data/test_read_pvgis_horizon.csv +0 -49
  70. pvlib/data/tmy_45.000_8.000_2005_2023.csv +0 -8789
  71. pvlib/data/tmy_45.000_8.000_2005_2023.epw +0 -8768
  72. pvlib/data/tmy_45.000_8.000_2005_2023.json +0 -1
  73. pvlib/data/tmy_45.000_8.000_2005_2023.txt +0 -8761
  74. pvlib/data/tmy_45.000_8.000_userhorizon.json +0 -1
  75. pvlib/spa_c_files/README.md +0 -81
  76. pvlib/spa_c_files/cspa_py.pxd +0 -43
  77. pvlib/spa_c_files/spa_py.pyx +0 -30
  78. pvlib/tests/__init__.py +0 -0
  79. pvlib/tests/bifacial/__init__.py +0 -0
  80. pvlib/tests/bifacial/test_infinite_sheds.py +0 -317
  81. pvlib/tests/bifacial/test_losses_models.py +0 -54
  82. pvlib/tests/bifacial/test_pvfactors.py +0 -82
  83. pvlib/tests/bifacial/test_utils.py +0 -192
  84. pvlib/tests/conftest.py +0 -476
  85. pvlib/tests/iotools/__init__.py +0 -0
  86. pvlib/tests/iotools/test_acis.py +0 -213
  87. pvlib/tests/iotools/test_bsrn.py +0 -131
  88. pvlib/tests/iotools/test_crn.py +0 -95
  89. pvlib/tests/iotools/test_epw.py +0 -23
  90. pvlib/tests/iotools/test_midc.py +0 -89
  91. pvlib/tests/iotools/test_panond.py +0 -32
  92. pvlib/tests/iotools/test_psm3.py +0 -198
  93. pvlib/tests/iotools/test_pvgis.py +0 -644
  94. pvlib/tests/iotools/test_sodapro.py +0 -298
  95. pvlib/tests/iotools/test_solaranywhere.py +0 -287
  96. pvlib/tests/iotools/test_solargis.py +0 -68
  97. pvlib/tests/iotools/test_solcast.py +0 -324
  98. pvlib/tests/iotools/test_solrad.py +0 -152
  99. pvlib/tests/iotools/test_srml.py +0 -124
  100. pvlib/tests/iotools/test_surfrad.py +0 -75
  101. pvlib/tests/iotools/test_tmy.py +0 -133
  102. pvlib/tests/ivtools/__init__.py +0 -0
  103. pvlib/tests/ivtools/test_sde.py +0 -230
  104. pvlib/tests/ivtools/test_sdm.py +0 -429
  105. pvlib/tests/ivtools/test_utils.py +0 -173
  106. pvlib/tests/spectrum/__init__.py +0 -0
  107. pvlib/tests/spectrum/conftest.py +0 -40
  108. pvlib/tests/spectrum/test_irradiance.py +0 -138
  109. pvlib/tests/spectrum/test_mismatch.py +0 -304
  110. pvlib/tests/spectrum/test_response.py +0 -124
  111. pvlib/tests/spectrum/test_spectrl2.py +0 -72
  112. pvlib/tests/test__deprecation.py +0 -97
  113. pvlib/tests/test_albedo.py +0 -84
  114. pvlib/tests/test_atmosphere.py +0 -351
  115. pvlib/tests/test_clearsky.py +0 -884
  116. pvlib/tests/test_conftest.py +0 -37
  117. pvlib/tests/test_iam.py +0 -555
  118. pvlib/tests/test_inverter.py +0 -213
  119. pvlib/tests/test_irradiance.py +0 -1487
  120. pvlib/tests/test_location.py +0 -356
  121. pvlib/tests/test_modelchain.py +0 -2020
  122. pvlib/tests/test_numerical_precision.py +0 -124
  123. pvlib/tests/test_pvarray.py +0 -71
  124. pvlib/tests/test_pvsystem.py +0 -2511
  125. pvlib/tests/test_scaling.py +0 -207
  126. pvlib/tests/test_shading.py +0 -391
  127. pvlib/tests/test_singlediode.py +0 -608
  128. pvlib/tests/test_snow.py +0 -212
  129. pvlib/tests/test_soiling.py +0 -230
  130. pvlib/tests/test_solarposition.py +0 -966
  131. pvlib/tests/test_spa.py +0 -454
  132. pvlib/tests/test_temperature.py +0 -470
  133. pvlib/tests/test_tools.py +0 -146
  134. pvlib/tests/test_tracking.py +0 -474
  135. pvlib/tests/test_transformer.py +0 -60
  136. pvlib-0.11.2.dist-info/RECORD +0 -191
  137. {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info/licenses}/AUTHORS.md +0 -0
  138. {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info/licenses}/LICENSE +0 -0
  139. {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info}/top_level.txt +0 -0
@@ -1,192 +0,0 @@
1
- """
2
- test bifical.utils
3
- """
4
- import numpy as np
5
- import pytest
6
- from pvlib.bifacial import utils
7
- from pvlib.shading import masking_angle, ground_angle
8
- from pvlib.tools import cosd
9
- from scipy.integrate import trapezoid
10
-
11
-
12
- @pytest.fixture
13
- def test_system_fixed_tilt():
14
- syst = {'height': 1.0,
15
- 'pitch': 2.,
16
- 'surface_tilt': 30.,
17
- 'surface_azimuth': 180.,
18
- 'axis_azimuth': None,
19
- 'rotation': -30.}
20
- syst['gcr'] = 1.0 / syst['pitch']
21
- # view factors from 3 points on the ground between rows to the sky
22
- pts = np.linspace(0, 1, num=3)
23
- sqr3 = np.sqrt(3) / 4
24
- # c_i,j = cos(angle from point i to edge of row j), j=0 is row = -1
25
- # c_i,j = cos(angle from point i to edge of row j), j=0 is row = -1
26
- c00 = (-2 - sqr3) / np.sqrt(1.25**2 + (2 + sqr3)**2) # right edge row -1
27
- c01 = -sqr3 / np.sqrt(1.25**2 + sqr3**2) # right edge row 0
28
- c02 = sqr3 / np.sqrt(0.75**2 + sqr3**2) # left edge of row 0
29
- c03 = (2 - sqr3) / np.sqrt(1.25**2 + (2 - sqr3)**2) # right edge of row 1
30
- vf_0 = 0.5 * (c03 - c02 + c01 - c00) # vf at point 0
31
- c10 = (-3 - sqr3) / np.sqrt(1.25**2 + (3 + sqr3)**2) # right edge row -1
32
- c11 = (-1 - sqr3) / np.sqrt(1.25**2 + (1 + sqr3)**2) # right edge row 0
33
- c12 = (-1 + sqr3) / np.sqrt(0.75**2 + (-1 + sqr3)**2) # left edge row 0
34
- c13 = (1 - sqr3) / np.sqrt(1.25**2 + (1 - sqr3)**2) # right edge row
35
- vf_1 = 0.5 * (c13 - c12 + c11 - c10) # vf at point 1
36
- c20 = -(4 + sqr3) / np.sqrt(1.25**2 + (4 + sqr3)**2) # right edge row -1
37
- c21 = (-2 + sqr3) / np.sqrt(0.75**2 + (-2 + sqr3)**2) # left edge row 0
38
- c22 = (-2 - sqr3) / np.sqrt(1.25**2 + (2 + sqr3)**2) # right edge row 0
39
- c23 = (0 - sqr3) / np.sqrt(1.25**2 + (0 - sqr3)**2) # right edge row 1
40
- vf_2 = 0.5 * (c23 - c22 + c21 - c20) # vf at point 1
41
- vfs_ground_sky = np.array([[vf_0], [vf_1], [vf_2]])
42
- return syst, pts, vfs_ground_sky
43
-
44
-
45
- def test__solar_projection_tangent():
46
- tan_phi_f = utils._solar_projection_tangent(
47
- 30, 150, 180)
48
- tan_phi_b = utils._solar_projection_tangent(
49
- 30, 150, 0)
50
- assert np.allclose(tan_phi_f, 0.5)
51
- assert np.allclose(tan_phi_b, -0.5)
52
- assert np.allclose(tan_phi_f, -tan_phi_b)
53
-
54
-
55
- @pytest.mark.parametrize(
56
- "gcr,surface_tilt,surface_azimuth,solar_zenith,solar_azimuth,expected",
57
- [(0.5, 0., 180., 0., 180., 0.5),
58
- (1.0, 0., 180., 0., 180., 0.0),
59
- (1.0, 90., 180., 0., 180., 1.0),
60
- (0.5, 45., 180., 45., 270., 1.0 - np.sqrt(2) / 4),
61
- (0.5, 45., 180., 90., 180., 0.),
62
- (np.sqrt(2) / 2, 45, 180, 0, 180, 0.5),
63
- (np.sqrt(2) / 2, 45, 180, 45, 180, 0.0),
64
- (np.sqrt(2) / 2, 45, 180, 45, 90, 0.5),
65
- (np.sqrt(2) / 2, 45, 180, 45, 0, 1.0),
66
- (np.sqrt(2) / 2, 45, 180, 45, 135, 0.5 * (1 - np.sqrt(2) / 2)),
67
- ])
68
- def test__unshaded_ground_fraction(
69
- surface_tilt, surface_azimuth, solar_zenith, solar_azimuth, gcr,
70
- expected):
71
- # frontside, same for both sides
72
- f_sky_beam_f = utils._unshaded_ground_fraction(
73
- surface_tilt, surface_azimuth, solar_zenith, solar_azimuth, gcr)
74
- assert np.allclose(f_sky_beam_f, expected)
75
- # backside, should be the same as frontside
76
- f_sky_beam_b = utils._unshaded_ground_fraction(
77
- 180. - surface_tilt, surface_azimuth - 180., solar_zenith,
78
- solar_azimuth, gcr)
79
- assert np.allclose(f_sky_beam_b, expected)
80
-
81
-
82
- def test__vf_ground_sky_2d(test_system_fixed_tilt):
83
- # vector input
84
- ts, pts, vfs_gnd_sky = test_system_fixed_tilt
85
- vfs = utils.vf_ground_sky_2d(ts['rotation'], ts['gcr'], pts,
86
- ts['pitch'], ts['height'], max_rows=1)
87
- assert np.allclose(vfs, vfs_gnd_sky, rtol=0.1) # middle point vf is off
88
- # test with singleton x
89
- vf = utils.vf_ground_sky_2d(ts['rotation'], ts['gcr'], pts[0],
90
- ts['pitch'], ts['height'], max_rows=1)
91
- assert np.isclose(vf, vfs_gnd_sky[0])
92
-
93
-
94
- @pytest.mark.parametrize("vectorize", [True, False])
95
- def test_vf_ground_sky_2d_integ(test_system_fixed_tilt, vectorize):
96
- ts, pts, vfs_gnd_sky = test_system_fixed_tilt
97
- # pass rotation here since max_rows=1 for the hand-solved case in
98
- # the fixture test_system, which means the ground-to-sky view factor
99
- # isn't summed over enough rows for symmetry to hold.
100
- vf_integ = utils.vf_ground_sky_2d_integ(
101
- ts['rotation'], ts['gcr'], ts['height'], ts['pitch'],
102
- max_rows=1, npoints=3, vectorize=vectorize)
103
- expected_vf_integ = trapezoid(vfs_gnd_sky, pts, axis=0)
104
- assert np.isclose(vf_integ, expected_vf_integ, rtol=0.1)
105
-
106
-
107
- def test_vf_row_sky_2d(test_system_fixed_tilt):
108
- ts, _, _ = test_system_fixed_tilt
109
- # with float input, fx at top of row
110
- vf = utils.vf_row_sky_2d(ts['surface_tilt'], ts['gcr'], 1.)
111
- expected = 0.5 * (1 + cosd(ts['surface_tilt']))
112
- assert np.isclose(vf, expected)
113
- # with array input
114
- fx = np.array([0., 0.5, 1.])
115
- vf = utils.vf_row_sky_2d(ts['surface_tilt'], ts['gcr'], fx)
116
- phi = masking_angle(ts['surface_tilt'], ts['gcr'], fx)
117
- expected = 0.5 * (1 + cosd(ts['surface_tilt'] + phi))
118
- assert np.allclose(vf, expected)
119
-
120
-
121
- def test_vf_row_sky_2d_integ(test_system_fixed_tilt):
122
- ts, _, _ = test_system_fixed_tilt
123
- # with float input, check end position
124
- with np.errstate(invalid='ignore'):
125
- vf = utils.vf_row_sky_2d_integ(ts['surface_tilt'], ts['gcr'], 1., 1.)
126
- expected = utils.vf_row_sky_2d(ts['surface_tilt'], ts['gcr'], 1.)
127
- assert np.isclose(vf, expected)
128
- # with array input
129
- fx0 = np.array([0., 0.5])
130
- fx1 = np.array([0., 0.8])
131
- with np.errstate(invalid='ignore'):
132
- vf = utils.vf_row_sky_2d_integ(ts['surface_tilt'], ts['gcr'], fx0, fx1)
133
- phi = masking_angle(ts['surface_tilt'], ts['gcr'], fx0[0])
134
- y0 = 0.5 * (1 + cosd(ts['surface_tilt'] + phi))
135
- x = np.arange(fx0[1], fx1[1], 1e-4)
136
- phi_y = masking_angle(ts['surface_tilt'], ts['gcr'], x)
137
- y = 0.5 * (1 + cosd(ts['surface_tilt'] + phi_y))
138
- y1 = trapezoid(y, x) / (fx1[1] - fx0[1])
139
- expected = np.array([y0, y1])
140
- assert np.allclose(vf, expected, rtol=1e-3)
141
- # with defaults (0, 1)
142
- vf = utils.vf_row_sky_2d_integ(ts['surface_tilt'], ts['gcr'])
143
- x = np.arange(0, 1, 1e-4)
144
- phi_y = masking_angle(ts['surface_tilt'], ts['gcr'], x)
145
- y = 0.5 * (1 + cosd(ts['surface_tilt'] + phi_y))
146
- y1 = trapezoid(y, x) / (1 - 0)
147
- assert np.allclose(vf, y1, rtol=1e-3)
148
-
149
-
150
- def test_vf_row_ground_2d(test_system_fixed_tilt):
151
- ts, _, _ = test_system_fixed_tilt
152
- # with float input, fx at bottom of row
153
- vf = utils.vf_row_ground_2d(ts['surface_tilt'], ts['gcr'], 0.)
154
- expected = 0.5 * (1. - cosd(ts['surface_tilt']))
155
- assert np.isclose(vf, expected)
156
- # with array input
157
- fx = np.array([0., 0.5, 1.0])
158
- vf = utils.vf_row_ground_2d(ts['surface_tilt'], ts['gcr'], fx)
159
- phi = ground_angle(ts['surface_tilt'], ts['gcr'], fx)
160
- expected = 0.5 * (1 - cosd(phi - ts['surface_tilt']))
161
- assert np.allclose(vf, expected)
162
-
163
-
164
- def test_vf_ground_2d_integ(test_system_fixed_tilt):
165
- ts, _, _ = test_system_fixed_tilt
166
- # with float input, check end position
167
- with np.errstate(invalid='ignore'):
168
- vf = utils.vf_row_ground_2d_integ(ts['surface_tilt'], ts['gcr'],
169
- 0., 0.)
170
- expected = utils.vf_row_ground_2d(ts['surface_tilt'], ts['gcr'], 0.)
171
- assert np.isclose(vf, expected)
172
- # with array input
173
- fx0 = np.array([0., 0.5])
174
- fx1 = np.array([0., 0.8])
175
- with np.errstate(invalid='ignore'):
176
- vf = utils.vf_row_ground_2d_integ(ts['surface_tilt'], ts['gcr'],
177
- fx0, fx1)
178
- phi = ground_angle(ts['surface_tilt'], ts['gcr'], fx0[0])
179
- y0 = 0.5 * (1 - cosd(phi - ts['surface_tilt']))
180
- x = np.arange(fx0[1], fx1[1], 1e-4)
181
- phi_y = ground_angle(ts['surface_tilt'], ts['gcr'], x)
182
- y = 0.5 * (1 - cosd(phi_y - ts['surface_tilt']))
183
- y1 = trapezoid(y, x) / (fx1[1] - fx0[1])
184
- expected = np.array([y0, y1])
185
- assert np.allclose(vf, expected, rtol=1e-2)
186
- # with defaults (0, 1)
187
- vf = utils.vf_row_ground_2d_integ(ts['surface_tilt'], ts['gcr'], 0, 1)
188
- x = np.arange(0, 1, 1e-4)
189
- phi_y = ground_angle(ts['surface_tilt'], ts['gcr'], x)
190
- y = 0.5 * (1 - cosd(phi_y - ts['surface_tilt']))
191
- y1 = trapezoid(y, x) / (1 - 0)
192
- assert np.allclose(vf, y1, rtol=1e-2)
pvlib/tests/conftest.py DELETED
@@ -1,476 +0,0 @@
1
- from pathlib import Path
2
- import platform
3
- import warnings
4
-
5
- import pandas as pd
6
- import os
7
- from packaging.version import Version
8
- import pytest
9
- from functools import wraps
10
-
11
- import pvlib
12
- from pvlib.location import Location
13
-
14
-
15
- pvlib_base_version = Version(Version(pvlib.__version__).base_version)
16
-
17
-
18
- # decorator takes one argument: the base version for which it should fail
19
- # for example @fail_on_pvlib_version('0.7') will cause a test to fail
20
- # on pvlib versions 0.7a, 0.7b, 0.7rc1, etc.
21
- def fail_on_pvlib_version(version):
22
- # second level of decorator takes the function under consideration
23
- def wrapper(func):
24
- # third level defers computation until the test is called
25
- # this allows the specific test to fail at test runtime,
26
- # rather than at decoration time (when the module is imported)
27
- @wraps(func)
28
- def inner(*args, **kwargs):
29
- # fail if the version is too high
30
- if pvlib_base_version >= Version(version):
31
- pytest.fail('the tested function is scheduled to be '
32
- 'removed in %s' % version)
33
- # otherwise return the function to be executed
34
- else:
35
- return func(*args, **kwargs)
36
- return inner
37
- return wrapper
38
-
39
-
40
- def _check_pandas_assert_kwargs(kwargs):
41
- # handles the change in API related to default
42
- # tolerances in pandas 1.1.0. See pvlib GH #1018
43
- if Version(pd.__version__) >= Version('1.1.0'):
44
- if kwargs.pop('check_less_precise', False):
45
- kwargs['atol'] = 1e-3
46
- kwargs['rtol'] = 1e-3
47
- else:
48
- kwargs['atol'] = 1e-5
49
- kwargs['rtol'] = 1e-5
50
- else:
51
- kwargs.pop('rtol', None)
52
- kwargs.pop('atol', None)
53
- return kwargs
54
-
55
-
56
- def assert_index_equal(left, right, **kwargs):
57
- kwargs = _check_pandas_assert_kwargs(kwargs)
58
- pd.testing.assert_index_equal(left, right, **kwargs)
59
-
60
-
61
- def assert_series_equal(left, right, **kwargs):
62
- kwargs = _check_pandas_assert_kwargs(kwargs)
63
- pd.testing.assert_series_equal(left, right, **kwargs)
64
-
65
-
66
- def assert_frame_equal(left, right, **kwargs):
67
- kwargs = _check_pandas_assert_kwargs(kwargs)
68
- pd.testing.assert_frame_equal(left, right, **kwargs)
69
-
70
-
71
- # commonly used directories in the tests
72
- TEST_DIR = Path(__file__).parent
73
- DATA_DIR = TEST_DIR.parent / 'data'
74
-
75
-
76
- # pytest-rerunfailures variables
77
- RERUNS = 5
78
- RERUNS_DELAY = 2
79
-
80
-
81
- platform_is_windows = platform.system() == 'Windows'
82
- skip_windows = pytest.mark.skipif(platform_is_windows,
83
- reason='does not run on windows')
84
-
85
-
86
- try:
87
- # Attempt to load BSRN credentials used for testing pvlib.iotools.get_bsrn
88
- bsrn_username = os.environ["BSRN_FTP_USERNAME"]
89
- bsrn_password = os.environ["BSRN_FTP_PASSWORD"]
90
- has_bsrn_credentials = True
91
- except KeyError:
92
- has_bsrn_credentials = False
93
-
94
- requires_bsrn_credentials = pytest.mark.skipif(
95
- not has_bsrn_credentials, reason='requires bsrn credentials')
96
-
97
-
98
- try:
99
- # Attempt to load SolarAnywhere API key used for testing
100
- # pvlib.iotools.get_solaranywhere
101
- solaranywhere_api_key = os.environ["SOLARANYWHERE_API_KEY"]
102
- has_solaranywhere_credentials = True
103
- except KeyError:
104
- has_solaranywhere_credentials = False
105
-
106
- requires_solaranywhere_credentials = pytest.mark.skipif(
107
- not has_solaranywhere_credentials,
108
- reason='requires solaranywhere credentials')
109
-
110
-
111
- try:
112
- import statsmodels # noqa: F401
113
- has_statsmodels = True
114
- except ImportError:
115
- has_statsmodels = False
116
-
117
- requires_statsmodels = pytest.mark.skipif(
118
- not has_statsmodels, reason='requires statsmodels')
119
-
120
-
121
- try:
122
- import ephem # noqa: F401
123
- has_ephem = True
124
- except ImportError:
125
- has_ephem = False
126
-
127
- requires_ephem = pytest.mark.skipif(not has_ephem, reason='requires ephem')
128
-
129
-
130
- def has_spa_c():
131
- try:
132
- from pvlib.spa_c_files.spa_py import spa_calc # noqa: F401
133
- except ImportError:
134
- return False
135
- else:
136
- return True
137
-
138
-
139
- requires_spa_c = pytest.mark.skipif(not has_spa_c(), reason="requires spa_c")
140
-
141
-
142
- try:
143
- import numba # noqa: F401
144
- has_numba = True
145
- except ImportError:
146
- has_numba = False
147
-
148
-
149
- requires_numba = pytest.mark.skipif(not has_numba, reason="requires numba")
150
-
151
-
152
- try:
153
- import pvfactors # noqa: F401
154
- has_pvfactors = True
155
- except ImportError:
156
- has_pvfactors = False
157
-
158
- requires_pvfactors = pytest.mark.skipif(not has_pvfactors,
159
- reason='requires pvfactors')
160
-
161
-
162
- try:
163
- import PySAM # noqa: F401
164
- has_pysam = True
165
- except ImportError:
166
- has_pysam = False
167
-
168
- requires_pysam = pytest.mark.skipif(not has_pysam, reason="requires PySAM")
169
-
170
-
171
- has_pandas_2_0 = Version(pd.__version__) >= Version("2.0.0")
172
- requires_pandas_2_0 = pytest.mark.skipif(not has_pandas_2_0,
173
- reason="requires pandas>=2.0.0")
174
-
175
-
176
- @pytest.fixture()
177
- def golden():
178
- return Location(39.742476, -105.1786, 'America/Denver', 1830.14)
179
-
180
-
181
- @pytest.fixture()
182
- def golden_mst():
183
- return Location(39.742476, -105.1786, 'MST', 1830.14)
184
-
185
-
186
- @pytest.fixture()
187
- def expected_solpos():
188
- return pd.DataFrame({'elevation': 39.872046,
189
- 'apparent_zenith': 50.111622,
190
- 'azimuth': 194.340241,
191
- 'apparent_elevation': 39.888378},
192
- index=['2003-10-17T12:30:30Z'])
193
-
194
-
195
- @pytest.fixture(scope="session")
196
- def sam_data():
197
- data = {}
198
- with warnings.catch_warnings():
199
- # ignore messages about duplicate entries in the databases.
200
- warnings.simplefilter("ignore", UserWarning)
201
- data['sandiamod'] = pvlib.pvsystem.retrieve_sam('sandiamod')
202
- data['adrinverter'] = pvlib.pvsystem.retrieve_sam('adrinverter')
203
- return data
204
-
205
-
206
- @pytest.fixture(scope="function")
207
- def pvsyst_module_params():
208
- """
209
- Define some PVSyst module parameters for testing.
210
-
211
- The scope of the fixture is set to ``'function'`` to allow tests to modify
212
- parameters if required without affecting other tests.
213
- """
214
- parameters = {
215
- 'gamma_ref': 1.05,
216
- 'mu_gamma': 0.001,
217
- 'I_L_ref': 6.0,
218
- 'I_o_ref': 5e-9,
219
- 'EgRef': 1.121,
220
- 'R_sh_ref': 300,
221
- 'R_sh_0': 1000,
222
- 'R_s': 0.5,
223
- 'R_sh_exp': 5.5,
224
- 'cells_in_series': 60,
225
- 'alpha_sc': 0.001,
226
- }
227
- return parameters
228
-
229
-
230
- @pytest.fixture(scope='function')
231
- def adr_inverter_parameters():
232
- """
233
- Define some ADR inverter parameters for testing.
234
-
235
- The scope of the fixture is set to ``'function'`` to allow tests to modify
236
- parameters if required without affecting other tests.
237
- """
238
- parameters = {
239
- 'Name': 'Ablerex Electronics Co., Ltd.: ES 2200-US-240 (240Vac)'
240
- '[CEC 2011]',
241
- 'Vac': 240.,
242
- 'Pacmax': 2110.,
243
- 'Pnom': 2200.,
244
- 'Vnom': 396.,
245
- 'Vmin': 155.,
246
- 'Vmax': 413.,
247
- 'Vdcmax': 500.,
248
- 'MPPTHi': 450.,
249
- 'MPPTLow': 150.,
250
- 'Pnt': 0.25,
251
- 'ADRCoefficients': [0.01385, 0.0152, 0.00794, 0.00286, -0.01872,
252
- -0.01305, 0.0, 0.0, 0.0]
253
- }
254
- return parameters
255
-
256
-
257
- @pytest.fixture(scope='function')
258
- def cec_inverter_parameters():
259
- """
260
- Define some CEC inverter parameters for testing.
261
-
262
- The scope of the fixture is set to ``'function'`` to allow tests to modify
263
- parameters if required without affecting other tests.
264
- """
265
- parameters = {
266
- 'Name': 'ABB: MICRO-0.25-I-OUTD-US-208 208V [CEC 2014]',
267
- 'Vac': 208.0,
268
- 'Paco': 250.0,
269
- 'Pdco': 259.5220505,
270
- 'Vdco': 40.24260317,
271
- 'Pso': 1.771614224,
272
- 'C0': -2.48e-5,
273
- 'C1': -9.01e-5,
274
- 'C2': 6.69e-4,
275
- 'C3': -0.0189,
276
- 'Pnt': 0.02,
277
- 'Vdcmax': 65.0,
278
- 'Idcmax': 10.0,
279
- 'Mppt_low': 20.0,
280
- 'Mppt_high': 50.0,
281
- }
282
- return parameters
283
-
284
-
285
- @pytest.fixture(scope='function')
286
- def cec_module_params():
287
- """
288
- Define some CEC module parameters for testing.
289
-
290
- The scope of the fixture is set to ``'function'`` to allow tests to modify
291
- parameters if required without affecting other tests.
292
- """
293
- parameters = {
294
- 'Name': 'Example Module',
295
- 'BIPV': 'Y',
296
- 'Date': '4/28/2008',
297
- 'T_NOCT': 65,
298
- 'A_c': 0.67,
299
- 'N_s': 18,
300
- 'I_sc_ref': 7.5,
301
- 'V_oc_ref': 10.4,
302
- 'I_mp_ref': 6.6,
303
- 'V_mp_ref': 8.4,
304
- 'alpha_sc': 0.003,
305
- 'beta_oc': -0.04,
306
- 'a_ref': 0.473,
307
- 'I_L_ref': 7.545,
308
- 'I_o_ref': 1.94e-09,
309
- 'R_s': 0.094,
310
- 'R_sh_ref': 15.72,
311
- 'Adjust': 10.6,
312
- 'gamma_r': -0.5,
313
- 'Version': 'MM105',
314
- 'PTC': 48.9,
315
- 'Technology': 'Multi-c-Si',
316
- }
317
- return parameters
318
-
319
-
320
- @pytest.fixture(scope='function')
321
- def cec_module_cs5p_220m():
322
- """
323
- Define Canadian Solar CS5P-220M module parameters for testing.
324
-
325
- The scope of the fixture is set to ``'function'`` to allow tests to modify
326
- parameters if required without affecting other tests.
327
- """
328
- parameters = {
329
- 'Name': 'Canadian Solar CS5P-220M',
330
- 'BIPV': 'N',
331
- 'Date': '10/5/2009',
332
- 'T_NOCT': 42.4,
333
- 'A_c': 1.7,
334
- 'N_s': 96,
335
- 'I_sc_ref': 5.1,
336
- 'V_oc_ref': 59.4,
337
- 'I_mp_ref': 4.69,
338
- 'V_mp_ref': 46.9,
339
- 'alpha_sc': 0.004539,
340
- 'beta_oc': -0.22216,
341
- 'a_ref': 2.6373,
342
- 'I_L_ref': 5.114,
343
- 'I_o_ref': 8.196e-10,
344
- 'R_s': 1.065,
345
- 'R_sh_ref': 381.68,
346
- 'Adjust': 8.7,
347
- 'gamma_r': -0.476,
348
- 'Version': 'MM106',
349
- 'PTC': 200.1,
350
- 'Technology': 'Mono-c-Si',
351
- }
352
- return parameters
353
-
354
-
355
- @pytest.fixture(scope='function')
356
- def cec_module_spr_e20_327():
357
- """
358
- Define SunPower SPR-E20-327 module parameters for testing.
359
-
360
- The scope of the fixture is set to ``'function'`` to allow tests to modify
361
- parameters if required without affecting other tests.
362
- """
363
- parameters = {
364
- 'Name': 'SunPower SPR-E20-327',
365
- 'BIPV': 'N',
366
- 'Date': '1/14/2013',
367
- 'T_NOCT': 46,
368
- 'A_c': 1.631,
369
- 'N_s': 96,
370
- 'I_sc_ref': 6.46,
371
- 'V_oc_ref': 65.1,
372
- 'I_mp_ref': 5.98,
373
- 'V_mp_ref': 54.7,
374
- 'alpha_sc': 0.004522,
375
- 'beta_oc': -0.23176,
376
- 'a_ref': 2.6868,
377
- 'I_L_ref': 6.468,
378
- 'I_o_ref': 1.88e-10,
379
- 'R_s': 0.37,
380
- 'R_sh_ref': 298.13,
381
- 'Adjust': -0.1862,
382
- 'gamma_r': -0.386,
383
- 'Version': 'NRELv1',
384
- 'PTC': 301.4,
385
- 'Technology': 'Mono-c-Si',
386
- }
387
- return parameters
388
-
389
-
390
- @pytest.fixture(scope='function')
391
- def cec_module_fs_495():
392
- """
393
- Define First Solar FS-495 module parameters for testing.
394
-
395
- The scope of the fixture is set to ``'function'`` to allow tests to modify
396
- parameters if required without affecting other tests.
397
- """
398
- parameters = {
399
- 'Name': 'First Solar FS-495',
400
- 'BIPV': 'N',
401
- 'Date': '9/18/2014',
402
- 'T_NOCT': 44.6,
403
- 'A_c': 0.72,
404
- 'N_s': 216,
405
- 'I_sc_ref': 1.55,
406
- 'V_oc_ref': 86.5,
407
- 'I_mp_ref': 1.4,
408
- 'V_mp_ref': 67.9,
409
- 'alpha_sc': 0.000924,
410
- 'beta_oc': -0.22741,
411
- 'a_ref': 2.9482,
412
- 'I_L_ref': 1.563,
413
- 'I_o_ref': 2.64e-13,
414
- 'R_s': 6.804,
415
- 'R_sh_ref': 806.27,
416
- 'Adjust': -10.65,
417
- 'gamma_r': -0.264,
418
- 'Version': 'NRELv1',
419
- 'PTC': 89.7,
420
- 'Technology': 'CdTe',
421
- }
422
- return parameters
423
-
424
-
425
- @pytest.fixture(scope='function')
426
- def sapm_temperature_cs5p_220m():
427
- # SAPM temperature model parameters for Canadian_Solar_CS5P_220M
428
- # (glass/polymer) in open rack
429
- return {'a': -3.40641, 'b': -0.0842075, 'deltaT': 3}
430
-
431
-
432
- @pytest.fixture(scope='function')
433
- def sapm_module_params():
434
- """
435
- Define SAPM model parameters for Canadian Solar CS5P 220M module.
436
-
437
- The scope of the fixture is set to ``'function'`` to allow tests to modify
438
- parameters if required without affecting other tests.
439
- """
440
- parameters = {'Material': 'c-Si',
441
- 'Cells_in_Series': 96,
442
- 'Parallel_Strings': 1,
443
- 'A0': 0.928385,
444
- 'A1': 0.068093,
445
- 'A2': -0.0157738,
446
- 'A3': 0.0016606,
447
- 'A4': -6.93E-05,
448
- 'B0': 1,
449
- 'B1': -0.002438,
450
- 'B2': 0.0003103,
451
- 'B3': -0.00001246,
452
- 'B4': 2.11E-07,
453
- 'B5': -1.36E-09,
454
- 'C0': 1.01284,
455
- 'C1': -0.0128398,
456
- 'C2': 0.279317,
457
- 'C3': -7.24463,
458
- 'C4': 0.996446,
459
- 'C5': 0.003554,
460
- 'C6': 1.15535,
461
- 'C7': -0.155353,
462
- 'Isco': 5.09115,
463
- 'Impo': 4.54629,
464
- 'Voco': 59.2608,
465
- 'Vmpo': 48.3156,
466
- 'Aisc': 0.000397,
467
- 'Aimp': 0.000181,
468
- 'Bvoco': -0.21696,
469
- 'Mbvoc': 0.0,
470
- 'Bvmpo': -0.235488,
471
- 'Mbvmp': 0.0,
472
- 'N': 1.4032,
473
- 'IXO': 4.97599,
474
- 'IXXO': 3.18803,
475
- 'FD': 1}
476
- return parameters
File without changes