pvlib 0.10.3__py3-none-any.whl → 0.10.5__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.
- pvlib/__init__.py +1 -0
- pvlib/bifacial/utils.py +2 -1
- pvlib/clearsky.py +7 -8
- pvlib/iam.py +3 -3
- pvlib/inverter.py +3 -3
- pvlib/iotools/__init__.py +2 -0
- pvlib/iotools/solargis.py +214 -0
- pvlib/iotools/solcast.py +2 -7
- pvlib/iotools/solrad.py +121 -23
- pvlib/iotools/srml.py +12 -12
- pvlib/iotools/surfrad.py +2 -2
- pvlib/irradiance.py +28 -22
- pvlib/location.py +3 -1
- pvlib/modelchain.py +10 -9
- pvlib/pvarray.py +127 -0
- pvlib/pvsystem.py +52 -43
- pvlib/scaling.py +4 -2
- pvlib/shading.py +110 -0
- pvlib/singlediode.py +37 -9
- pvlib/snow.py +3 -1
- pvlib/solarposition.py +38 -30
- pvlib/spa.py +3 -11
- pvlib/spectrum/mismatch.py +2 -1
- pvlib/temperature.py +3 -2
- pvlib/tests/bifacial/test_utils.py +6 -5
- pvlib/tests/conftest.py +13 -14
- pvlib/tests/iotools/test_sodapro.py +2 -1
- pvlib/tests/iotools/test_solargis.py +68 -0
- pvlib/tests/iotools/test_solcast.py +2 -2
- pvlib/tests/iotools/test_solrad.py +58 -7
- pvlib/tests/iotools/test_srml.py +7 -14
- pvlib/tests/test_clearsky.py +1 -1
- pvlib/tests/test_irradiance.py +24 -8
- pvlib/tests/test_location.py +1 -1
- pvlib/tests/test_modelchain.py +37 -26
- pvlib/tests/test_pvarray.py +25 -0
- pvlib/tests/test_pvsystem.py +76 -104
- pvlib/tests/test_shading.py +130 -11
- pvlib/tests/test_singlediode.py +68 -10
- pvlib/tests/test_snow.py +1 -1
- pvlib/tests/test_solarposition.py +121 -7
- pvlib/tests/test_spa.py +5 -15
- pvlib/tests/test_temperature.py +4 -4
- pvlib/tests/test_tracking.py +2 -2
- pvlib/tracking.py +8 -38
- pvlib/version.py +1 -5
- {pvlib-0.10.3.dist-info → pvlib-0.10.5.dist-info}/METADATA +9 -33
- {pvlib-0.10.3.dist-info → pvlib-0.10.5.dist-info}/RECORD +52 -51
- {pvlib-0.10.3.dist-info → pvlib-0.10.5.dist-info}/WHEEL +1 -1
- pvlib/spa_c_files/SPA_NOTICE.md +0 -39
- {pvlib-0.10.3.dist-info → pvlib-0.10.5.dist-info}/AUTHORS.md +0 -0
- {pvlib-0.10.3.dist-info → pvlib-0.10.5.dist-info}/LICENSE +0 -0
- {pvlib-0.10.3.dist-info → pvlib-0.10.5.dist-info}/top_level.txt +0 -0
pvlib/tests/iotools/test_srml.py
CHANGED
|
@@ -14,11 +14,12 @@ def test_read_srml():
|
|
|
14
14
|
srml.read_srml(srml_testfile)
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
@pytest.mark.skip(reason="SRML server is undergoing maintenance as of 12-2023")
|
|
18
17
|
@pytest.mark.remote_data
|
|
19
18
|
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
20
19
|
def test_read_srml_remote():
|
|
21
|
-
srml.read_srml(
|
|
20
|
+
srml.read_srml(
|
|
21
|
+
'http://solardata.uoregon.edu/download/Archive/EUPO1801.txt'
|
|
22
|
+
)
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
def test_read_srml_columns_exist():
|
|
@@ -47,11 +48,10 @@ def test_read_srml_nans_exist():
|
|
|
47
48
|
assert data['dni_0_flag'].iloc[1119] == 99
|
|
48
49
|
|
|
49
50
|
|
|
50
|
-
@pytest.mark.skip(reason="SRML server is undergoing maintenance as of 12-2023")
|
|
51
51
|
@pytest.mark.parametrize('url,year,month', [
|
|
52
|
-
('http://
|
|
52
|
+
('http://solardata.uoregon.edu/download/Archive/EUPO1801.txt',
|
|
53
53
|
2018, 1),
|
|
54
|
-
('http://
|
|
54
|
+
('http://solardata.uoregon.edu/download/Archive/EUPO1612.txt',
|
|
55
55
|
2016, 12),
|
|
56
56
|
])
|
|
57
57
|
@pytest.mark.remote_data
|
|
@@ -78,30 +78,27 @@ def test__map_columns(column, expected):
|
|
|
78
78
|
assert srml._map_columns(column) == expected
|
|
79
79
|
|
|
80
80
|
|
|
81
|
-
@pytest.mark.skip(reason="SRML server is undergoing maintenance as of 12-2023")
|
|
82
81
|
@pytest.mark.remote_data
|
|
83
82
|
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
84
83
|
def test_get_srml():
|
|
85
|
-
url = 'http://
|
|
84
|
+
url = 'http://solardata.uoregon.edu/download/Archive/EUPO1801.txt'
|
|
86
85
|
file_data = srml.read_srml(url)
|
|
87
86
|
requested, _ = srml.get_srml(station='EU', start='2018-01-01',
|
|
88
87
|
end='2018-01-31')
|
|
89
88
|
assert_frame_equal(file_data, requested)
|
|
90
89
|
|
|
91
90
|
|
|
92
|
-
@pytest.mark.skip(reason="SRML server is undergoing maintenance as of 12-2023")
|
|
93
91
|
@fail_on_pvlib_version('0.11')
|
|
94
92
|
@pytest.mark.remote_data
|
|
95
93
|
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
96
94
|
def test_read_srml_month_from_solardat():
|
|
97
|
-
url = 'http://
|
|
95
|
+
url = 'http://solardata.uoregon.edu/download/Archive/EUPO1801.txt'
|
|
98
96
|
file_data = srml.read_srml(url)
|
|
99
97
|
with pytest.warns(pvlibDeprecationWarning, match='get_srml instead'):
|
|
100
98
|
requested = srml.read_srml_month_from_solardat('EU', 2018, 1)
|
|
101
99
|
assert file_data.equals(requested)
|
|
102
100
|
|
|
103
101
|
|
|
104
|
-
@pytest.mark.skip(reason="SRML server is undergoing maintenance as of 12-2023")
|
|
105
102
|
@fail_on_pvlib_version('0.11')
|
|
106
103
|
@pytest.mark.remote_data
|
|
107
104
|
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
@@ -117,7 +114,6 @@ def test_15_minute_dt_index():
|
|
|
117
114
|
assert (data.index[3::4].minute == 45).all()
|
|
118
115
|
|
|
119
116
|
|
|
120
|
-
@pytest.mark.skip(reason="SRML server is undergoing maintenance as of 12-2023")
|
|
121
117
|
@fail_on_pvlib_version('0.11')
|
|
122
118
|
@pytest.mark.remote_data
|
|
123
119
|
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
@@ -133,7 +129,6 @@ def test_hourly_dt_index():
|
|
|
133
129
|
assert (data.index.minute == 0).all()
|
|
134
130
|
|
|
135
131
|
|
|
136
|
-
@pytest.mark.skip(reason="SRML server is undergoing maintenance as of 12-2023")
|
|
137
132
|
@pytest.mark.remote_data
|
|
138
133
|
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
139
134
|
def test_get_srml_hourly():
|
|
@@ -144,7 +139,6 @@ def test_get_srml_hourly():
|
|
|
144
139
|
assert_index_equal(data.index, expected_index)
|
|
145
140
|
|
|
146
141
|
|
|
147
|
-
@pytest.mark.skip(reason="SRML server is undergoing maintenance as of 12-2023")
|
|
148
142
|
@pytest.mark.remote_data
|
|
149
143
|
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
150
144
|
def test_get_srml_minute():
|
|
@@ -162,7 +156,6 @@ def test_get_srml_minute():
|
|
|
162
156
|
assert meta['filenames'] == ['EUPO1801.txt']
|
|
163
157
|
|
|
164
158
|
|
|
165
|
-
@pytest.mark.skip(reason="SRML server is undergoing maintenance as of 12-2023")
|
|
166
159
|
@pytest.mark.remote_data
|
|
167
160
|
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
168
161
|
def test_get_srml_nonexisting_month_warning():
|
pvlib/tests/test_clearsky.py
CHANGED
|
@@ -745,7 +745,7 @@ def test__calc_stats(detect_clearsky_helper_data):
|
|
|
745
745
|
def test_bird():
|
|
746
746
|
"""Test Bird/Hulstrom Clearsky Model"""
|
|
747
747
|
times = pd.date_range(start='1/1/2015 0:00', end='12/31/2015 23:00',
|
|
748
|
-
freq='
|
|
748
|
+
freq='h')
|
|
749
749
|
tz = -7 # test timezone
|
|
750
750
|
gmt_tz = pytz.timezone('Etc/GMT%+d' % -(tz))
|
|
751
751
|
times = times.tz_localize(gmt_tz) # set timezone
|
pvlib/tests/test_irradiance.py
CHANGED
|
@@ -27,7 +27,7 @@ from .conftest import (
|
|
|
27
27
|
@pytest.fixture
|
|
28
28
|
def times():
|
|
29
29
|
# must include night values
|
|
30
|
-
return pd.date_range(start='20140624', freq='
|
|
30
|
+
return pd.date_range(start='20140624', freq='6h', periods=4,
|
|
31
31
|
tz='US/Arizona')
|
|
32
32
|
|
|
33
33
|
|
|
@@ -349,7 +349,7 @@ def test_perez_driesse_components(irrad_data, ephem_data, dni_et,
|
|
|
349
349
|
|
|
350
350
|
|
|
351
351
|
def test_perez_negative_horizon():
|
|
352
|
-
times = pd.date_range(start='20190101 11:30:00', freq='
|
|
352
|
+
times = pd.date_range(start='20190101 11:30:00', freq='1h',
|
|
353
353
|
periods=5, tz='US/Central')
|
|
354
354
|
|
|
355
355
|
# Avoid test dependencies on functionality not being tested by hard-coding
|
|
@@ -711,7 +711,7 @@ def test_dirint_value():
|
|
|
711
711
|
|
|
712
712
|
|
|
713
713
|
def test_dirint_nans():
|
|
714
|
-
times = pd.date_range(start='2014-06-24T12-0700', periods=5, freq='
|
|
714
|
+
times = pd.date_range(start='2014-06-24T12-0700', periods=5, freq='6h')
|
|
715
715
|
ghi = pd.Series([np.nan, 1038.62, 1038.62, 1038.62, 1038.62], index=times)
|
|
716
716
|
zenith = pd.Series([10.567, np.nan, 10.567, 10.567, 10.567], index=times)
|
|
717
717
|
pressure = pd.Series([93193., 93193., np.nan, 93193., 93193.], index=times)
|
|
@@ -782,7 +782,7 @@ def test_dirint_min_cos_zenith_max_zenith():
|
|
|
782
782
|
assert_series_equal(out, expected, check_less_precise=True)
|
|
783
783
|
|
|
784
784
|
|
|
785
|
-
def test_ghi_from_poa_driesse():
|
|
785
|
+
def test_ghi_from_poa_driesse(mocker):
|
|
786
786
|
# inputs copied from test_gti_dirint
|
|
787
787
|
times = pd.DatetimeIndex(
|
|
788
788
|
['2014-06-24T06-0700', '2014-06-24T09-0700', '2014-06-24T12-0700'])
|
|
@@ -825,6 +825,22 @@ def test_ghi_from_poa_driesse():
|
|
|
825
825
|
expected = [0, -1, 0]
|
|
826
826
|
assert_allclose(expected, niter)
|
|
827
827
|
|
|
828
|
+
# test xtol argument
|
|
829
|
+
poa_global = pd.Series([20, 300, 1000], index=times)
|
|
830
|
+
# test exception
|
|
831
|
+
xtol = -3.14159 # negative value raises exception in scipy.optimize.bisect
|
|
832
|
+
with pytest.raises(ValueError, match=rf"xtol too small \({xtol:g} <= 0\)"):
|
|
833
|
+
output = irradiance.ghi_from_poa_driesse_2023(
|
|
834
|
+
surface_tilt, surface_azimuth, zenith, azimuth,
|
|
835
|
+
poa_global, dni_extra=1366.1, xtol=xtol)
|
|
836
|
+
# test propagation
|
|
837
|
+
xtol = 3.141592
|
|
838
|
+
bisect_spy = mocker.spy(irradiance, "bisect")
|
|
839
|
+
output = irradiance.ghi_from_poa_driesse_2023(
|
|
840
|
+
surface_tilt, surface_azimuth, zenith, azimuth,
|
|
841
|
+
poa_global, dni_extra=1366.1, xtol=xtol)
|
|
842
|
+
assert bisect_spy.call_args[1]["xtol"] == xtol
|
|
843
|
+
|
|
828
844
|
|
|
829
845
|
def test_gti_dirint():
|
|
830
846
|
times = pd.DatetimeIndex(
|
|
@@ -1210,7 +1226,7 @@ def test_clearsky_index():
|
|
|
1210
1226
|
expected = 0.01
|
|
1211
1227
|
assert_allclose(out, expected, atol=0.001)
|
|
1212
1228
|
# series
|
|
1213
|
-
times = pd.date_range(start='20180601', periods=2, freq='
|
|
1229
|
+
times = pd.date_range(start='20180601', periods=2, freq='12h')
|
|
1214
1230
|
ghi_measured = pd.Series([100, 500], index=times)
|
|
1215
1231
|
ghi_modeled = pd.Series([500, 1000], index=times)
|
|
1216
1232
|
out = irradiance.clearsky_index(ghi_measured, ghi_modeled)
|
|
@@ -1266,7 +1282,7 @@ def test_clearness_index():
|
|
|
1266
1282
|
expected = 0.725
|
|
1267
1283
|
assert_allclose(out, expected, atol=0.001)
|
|
1268
1284
|
# series
|
|
1269
|
-
times = pd.date_range(start='20180601', periods=2, freq='
|
|
1285
|
+
times = pd.date_range(start='20180601', periods=2, freq='12h')
|
|
1270
1286
|
ghi = pd.Series([0, 1000], index=times)
|
|
1271
1287
|
solar_zenith = pd.Series([90, 0], index=times)
|
|
1272
1288
|
extra_radiation = pd.Series([1360, 1400], index=times)
|
|
@@ -1300,7 +1316,7 @@ def test_clearness_index_zenith_independent(airmass_kt):
|
|
|
1300
1316
|
expected = 0.443
|
|
1301
1317
|
assert_allclose(out, expected, atol=0.001)
|
|
1302
1318
|
# series
|
|
1303
|
-
times = pd.date_range(start='20180601', periods=2, freq='
|
|
1319
|
+
times = pd.date_range(start='20180601', periods=2, freq='12h')
|
|
1304
1320
|
clearness_index = pd.Series([0, .5], index=times)
|
|
1305
1321
|
airmass = pd.Series([np.nan, 2], index=times)
|
|
1306
1322
|
out = irradiance.clearness_index_zenith_independent(clearness_index,
|
|
@@ -1311,7 +1327,7 @@ def test_clearness_index_zenith_independent(airmass_kt):
|
|
|
1311
1327
|
|
|
1312
1328
|
def test_complete_irradiance():
|
|
1313
1329
|
# Generate dataframe to test on
|
|
1314
|
-
times = pd.date_range('2010-07-05 7:00:00-0700', periods=2, freq='
|
|
1330
|
+
times = pd.date_range('2010-07-05 7:00:00-0700', periods=2, freq='h')
|
|
1315
1331
|
i = pd.DataFrame({'ghi': [372.103976116, 497.087579068],
|
|
1316
1332
|
'dhi': [356.543700, 465.44400],
|
|
1317
1333
|
'dni': [49.63565561689957, 62.10624908037814]},
|
pvlib/tests/test_location.py
CHANGED
pvlib/tests/test_modelchain.py
CHANGED
|
@@ -268,7 +268,7 @@ def location():
|
|
|
268
268
|
|
|
269
269
|
@pytest.fixture
|
|
270
270
|
def weather():
|
|
271
|
-
times = pd.date_range('20160101 1200-0700', periods=2, freq='
|
|
271
|
+
times = pd.date_range('20160101 1200-0700', periods=2, freq='6h')
|
|
272
272
|
weather = pd.DataFrame({'ghi': [500, 0], 'dni': [800, 0], 'dhi': [100, 0]},
|
|
273
273
|
index=times)
|
|
274
274
|
return weather
|
|
@@ -350,7 +350,7 @@ def test_with_pvwatts(pvwatts_dc_pvwatts_ac_system, location, weather):
|
|
|
350
350
|
|
|
351
351
|
def test_run_model_with_irradiance(sapm_dc_snl_ac_system, location):
|
|
352
352
|
mc = ModelChain(sapm_dc_snl_ac_system, location)
|
|
353
|
-
times = pd.date_range('20160101 1200-0700', periods=2, freq='
|
|
353
|
+
times = pd.date_range('20160101 1200-0700', periods=2, freq='6h')
|
|
354
354
|
irradiance = pd.DataFrame({'dni': 900, 'ghi': 600, 'dhi': 150},
|
|
355
355
|
index=times)
|
|
356
356
|
ac = mc.run_model(irradiance).results.ac
|
|
@@ -417,7 +417,7 @@ def test_run_model_from_irradiance_arrays_no_loss(
|
|
|
417
417
|
spectral_model='no_loss',
|
|
418
418
|
losses_model='no_loss'
|
|
419
419
|
)
|
|
420
|
-
times = pd.date_range('20160101 1200-0700', periods=2, freq='
|
|
420
|
+
times = pd.date_range('20160101 1200-0700', periods=2, freq='6h')
|
|
421
421
|
irradiance = pd.DataFrame({'dni': 900, 'ghi': 600, 'dhi': 150},
|
|
422
422
|
index=times)
|
|
423
423
|
mc_one.run_model(irradiance)
|
|
@@ -457,7 +457,7 @@ def test_run_model_from_irradiance_arrays_no_loss_input_type(
|
|
|
457
457
|
spectral_model='no_loss',
|
|
458
458
|
losses_model='no_loss'
|
|
459
459
|
)
|
|
460
|
-
times = pd.date_range('20160101 1200-0700', periods=2, freq='
|
|
460
|
+
times = pd.date_range('20160101 1200-0700', periods=2, freq='6h')
|
|
461
461
|
irradiance = pd.DataFrame({'dni': 900, 'ghi': 600, 'dhi': 150},
|
|
462
462
|
index=times)
|
|
463
463
|
mc_one.run_model(irradiance)
|
|
@@ -487,7 +487,7 @@ def test_ModelChain_invalid_inverter_params_arrays(
|
|
|
487
487
|
def test_prepare_inputs_multi_weather(
|
|
488
488
|
sapm_dc_snl_ac_system_Array, location, input_type):
|
|
489
489
|
times = pd.date_range(start='20160101 1200-0700',
|
|
490
|
-
end='20160101 1800-0700', freq='
|
|
490
|
+
end='20160101 1800-0700', freq='6h')
|
|
491
491
|
mc = ModelChain(sapm_dc_snl_ac_system_Array, location)
|
|
492
492
|
weather = pd.DataFrame({'ghi': 1, 'dhi': 1, 'dni': 1},
|
|
493
493
|
index=times)
|
|
@@ -502,7 +502,7 @@ def test_prepare_inputs_multi_weather(
|
|
|
502
502
|
def test_prepare_inputs_albedo_in_weather(
|
|
503
503
|
sapm_dc_snl_ac_system_Array, location, input_type):
|
|
504
504
|
times = pd.date_range(start='20160101 1200-0700',
|
|
505
|
-
end='20160101 1800-0700', freq='
|
|
505
|
+
end='20160101 1800-0700', freq='6h')
|
|
506
506
|
mc = ModelChain(sapm_dc_snl_ac_system_Array, location)
|
|
507
507
|
weather = pd.DataFrame({'ghi': 1, 'dhi': 1, 'dni': 1, 'albedo': 0.5},
|
|
508
508
|
index=times)
|
|
@@ -564,14 +564,14 @@ def test_ModelChain_times_error_arrays(sapm_dc_snl_ac_system_Array, location):
|
|
|
564
564
|
error_str = r"Input DataFrames must have same index\."
|
|
565
565
|
mc = ModelChain(sapm_dc_snl_ac_system_Array, location)
|
|
566
566
|
irradiance = {'ghi': [1, 2], 'dhi': [1, 2], 'dni': [1, 2]}
|
|
567
|
-
times_one = pd.date_range(start='1/1/2020', freq='
|
|
568
|
-
times_two = pd.date_range(start='1/1/2020 00:15', freq='
|
|
567
|
+
times_one = pd.date_range(start='1/1/2020', freq='6h', periods=2)
|
|
568
|
+
times_two = pd.date_range(start='1/1/2020 00:15', freq='6h', periods=2)
|
|
569
569
|
weather_one = pd.DataFrame(irradiance, index=times_one)
|
|
570
570
|
weather_two = pd.DataFrame(irradiance, index=times_two)
|
|
571
571
|
with pytest.raises(ValueError, match=error_str):
|
|
572
572
|
mc.prepare_inputs((weather_one, weather_two))
|
|
573
573
|
# test with overlapping, but differently sized indices.
|
|
574
|
-
times_three = pd.date_range(start='1/1/2020', freq='
|
|
574
|
+
times_three = pd.date_range(start='1/1/2020', freq='6h', periods=3)
|
|
575
575
|
irradiance_three = irradiance
|
|
576
576
|
irradiance_three['ghi'].append(3)
|
|
577
577
|
irradiance_three['dhi'].append(3)
|
|
@@ -588,7 +588,7 @@ def test_ModelChain_times_arrays(sapm_dc_snl_ac_system_Array, location):
|
|
|
588
588
|
mc = ModelChain(sapm_dc_snl_ac_system_Array, location)
|
|
589
589
|
irradiance_one = {'ghi': [1, 2], 'dhi': [1, 2], 'dni': [1, 2]}
|
|
590
590
|
irradiance_two = {'ghi': [2, 1], 'dhi': [2, 1], 'dni': [2, 1]}
|
|
591
|
-
times = pd.date_range(start='1/1/2020', freq='
|
|
591
|
+
times = pd.date_range(start='1/1/2020', freq='6h', periods=2)
|
|
592
592
|
weather_one = pd.DataFrame(irradiance_one, index=times)
|
|
593
593
|
weather_two = pd.DataFrame(irradiance_two, index=times)
|
|
594
594
|
mc.prepare_inputs((weather_one, weather_two))
|
|
@@ -617,7 +617,7 @@ def test_run_model_arrays_weather(sapm_dc_snl_ac_system_same_arrays,
|
|
|
617
617
|
'pvwatts': pvwatts_dc_pvwatts_ac_system_arrays}
|
|
618
618
|
mc = ModelChain(system[ac_model], location, aoi_model='no_loss',
|
|
619
619
|
spectral_model='no_loss')
|
|
620
|
-
times = pd.date_range('20200101 1200-0700', periods=2, freq='
|
|
620
|
+
times = pd.date_range('20200101 1200-0700', periods=2, freq='2h')
|
|
621
621
|
weather_one = pd.DataFrame({'dni': [900, 800],
|
|
622
622
|
'ghi': [600, 500],
|
|
623
623
|
'dhi': [150, 100]},
|
|
@@ -634,7 +634,7 @@ def test_run_model_arrays_weather(sapm_dc_snl_ac_system_same_arrays,
|
|
|
634
634
|
def test_run_model_perez(sapm_dc_snl_ac_system, location):
|
|
635
635
|
mc = ModelChain(sapm_dc_snl_ac_system, location,
|
|
636
636
|
transposition_model='perez')
|
|
637
|
-
times = pd.date_range('20160101 1200-0700', periods=2, freq='
|
|
637
|
+
times = pd.date_range('20160101 1200-0700', periods=2, freq='6h')
|
|
638
638
|
irradiance = pd.DataFrame({'dni': 900, 'ghi': 600, 'dhi': 150},
|
|
639
639
|
index=times)
|
|
640
640
|
ac = mc.run_model(irradiance).results.ac
|
|
@@ -648,7 +648,7 @@ def test_run_model_gueymard_perez(sapm_dc_snl_ac_system, location):
|
|
|
648
648
|
mc = ModelChain(sapm_dc_snl_ac_system, location,
|
|
649
649
|
airmass_model='gueymard1993',
|
|
650
650
|
transposition_model='perez')
|
|
651
|
-
times = pd.date_range('20160101 1200-0700', periods=2, freq='
|
|
651
|
+
times = pd.date_range('20160101 1200-0700', periods=2, freq='6h')
|
|
652
652
|
irradiance = pd.DataFrame({'dni': 900, 'ghi': 600, 'dhi': 150},
|
|
653
653
|
index=times)
|
|
654
654
|
ac = mc.run_model(irradiance).results.ac
|
|
@@ -812,7 +812,7 @@ def test_prepare_inputs_from_poa_arrays_different_indices(
|
|
|
812
812
|
mc = ModelChain(sapm_dc_snl_ac_system_Array, location)
|
|
813
813
|
poa = pd.concat([weather, total_irrad], axis=1)
|
|
814
814
|
with pytest.raises(ValueError, match=error_str):
|
|
815
|
-
mc.prepare_inputs_from_poa((poa, poa.shift(periods=1, freq='
|
|
815
|
+
mc.prepare_inputs_from_poa((poa, poa.shift(periods=1, freq='6h')))
|
|
816
816
|
|
|
817
817
|
|
|
818
818
|
def test_prepare_inputs_from_poa_arrays_missing_column(
|
|
@@ -1078,7 +1078,7 @@ def test_run_model_from_effective_irradiance_arrays_error(
|
|
|
1078
1078
|
with pytest.raises(ValueError,
|
|
1079
1079
|
match=r"Input DataFrames must have same index\."):
|
|
1080
1080
|
mc.run_model_from_effective_irradiance(
|
|
1081
|
-
(data, data.shift(periods=1, freq='
|
|
1081
|
+
(data, data.shift(periods=1, freq='6h'))
|
|
1082
1082
|
)
|
|
1083
1083
|
|
|
1084
1084
|
|
|
@@ -1305,6 +1305,20 @@ def test_temperature_model_inconsistent(location, sapm_dc_snl_ac_system):
|
|
|
1305
1305
|
spectral_model='no_loss', temperature_model='pvsyst')
|
|
1306
1306
|
|
|
1307
1307
|
|
|
1308
|
+
def test_temperature_model_not_specified():
|
|
1309
|
+
location = Location(latitude=32.2, longitude=-110.9)
|
|
1310
|
+
arrays = [pvsystem.Array(pvsystem.FixedMount(),
|
|
1311
|
+
module_parameters={'pdc0': 1, 'gamma_pdc': 0})]
|
|
1312
|
+
system = pvsystem.PVSystem(arrays,
|
|
1313
|
+
temperature_model_parameters={'u0': 1, 'u1': 1},
|
|
1314
|
+
inverter_parameters={'pdc0': 1})
|
|
1315
|
+
with pytest.raises(ValueError,
|
|
1316
|
+
match='Could not infer temperature model from '
|
|
1317
|
+
'ModelChain.system.'):
|
|
1318
|
+
_ = ModelChain(system, location,
|
|
1319
|
+
aoi_model='no_loss', spectral_model='no_loss')
|
|
1320
|
+
|
|
1321
|
+
|
|
1308
1322
|
def test_dc_model_user_func(pvwatts_dc_pvwatts_ac_system, location, weather,
|
|
1309
1323
|
mocker):
|
|
1310
1324
|
m = mocker.spy(sys.modules[__name__], 'poadc')
|
|
@@ -1776,7 +1790,7 @@ def test_ModelChain_no_extra_kwargs(sapm_dc_snl_ac_system, location):
|
|
|
1776
1790
|
def test_basic_chain_alt_az(sam_data, cec_inverter_parameters,
|
|
1777
1791
|
sapm_temperature_cs5p_220m):
|
|
1778
1792
|
times = pd.date_range(start='20160101 1200-0700',
|
|
1779
|
-
end='20160101 1800-0700', freq='
|
|
1793
|
+
end='20160101 1800-0700', freq='6h')
|
|
1780
1794
|
latitude = 32.2
|
|
1781
1795
|
longitude = -111
|
|
1782
1796
|
surface_tilt = 0
|
|
@@ -1798,7 +1812,7 @@ def test_basic_chain_alt_az(sam_data, cec_inverter_parameters,
|
|
|
1798
1812
|
def test_basic_chain_altitude_pressure(sam_data, cec_inverter_parameters,
|
|
1799
1813
|
sapm_temperature_cs5p_220m):
|
|
1800
1814
|
times = pd.date_range(start='20160101 1200-0700',
|
|
1801
|
-
end='20160101 1800-0700', freq='
|
|
1815
|
+
end='20160101 1800-0700', freq='6h')
|
|
1802
1816
|
latitude = 32.2
|
|
1803
1817
|
longitude = -111
|
|
1804
1818
|
altitude = 700
|
|
@@ -1833,7 +1847,7 @@ def test_basic_chain_altitude_pressure(sam_data, cec_inverter_parameters,
|
|
|
1833
1847
|
def test_complete_irradiance_clean_run(sapm_dc_snl_ac_system, location):
|
|
1834
1848
|
"""The DataFrame should not change if all columns are passed"""
|
|
1835
1849
|
mc = ModelChain(sapm_dc_snl_ac_system, location)
|
|
1836
|
-
times = pd.date_range('2010-07-05 9:00:00', periods=2, freq='
|
|
1850
|
+
times = pd.date_range('2010-07-05 9:00:00', periods=2, freq='h')
|
|
1837
1851
|
i = pd.DataFrame(
|
|
1838
1852
|
{'dni': [2, 3], 'dhi': [4, 6], 'ghi': [9, 5]}, index=times)
|
|
1839
1853
|
|
|
@@ -1850,7 +1864,7 @@ def test_complete_irradiance_clean_run(sapm_dc_snl_ac_system, location):
|
|
|
1850
1864
|
def test_complete_irradiance(sapm_dc_snl_ac_system, location, mocker):
|
|
1851
1865
|
"""Check calculations"""
|
|
1852
1866
|
mc = ModelChain(sapm_dc_snl_ac_system, location)
|
|
1853
|
-
times = pd.date_range('2010-07-05 7:00:00-0700', periods=2, freq='
|
|
1867
|
+
times = pd.date_range('2010-07-05 7:00:00-0700', periods=2, freq='h')
|
|
1854
1868
|
i = pd.DataFrame({'dni': [49.756966, 62.153947],
|
|
1855
1869
|
'ghi': [372.103976116, 497.087579068],
|
|
1856
1870
|
'dhi': [356.543700, 465.44400]}, index=times)
|
|
@@ -1883,7 +1897,7 @@ def test_complete_irradiance_arrays(
|
|
|
1883
1897
|
sapm_dc_snl_ac_system_same_arrays, location, input_type):
|
|
1884
1898
|
"""ModelChain.complete_irradiance can accept a tuple of weather
|
|
1885
1899
|
DataFrames."""
|
|
1886
|
-
times = pd.date_range(start='2020-01-01 0700-0700', periods=2, freq='
|
|
1900
|
+
times = pd.date_range(start='2020-01-01 0700-0700', periods=2, freq='h')
|
|
1887
1901
|
weather = pd.DataFrame({'dni': [2, 3],
|
|
1888
1902
|
'dhi': [4, 6],
|
|
1889
1903
|
'ghi': [9, 5]}, index=times)
|
|
@@ -1918,7 +1932,7 @@ def test_complete_irradiance_arrays(
|
|
|
1918
1932
|
def test_complete_irradiance_arrays_wrong_length(
|
|
1919
1933
|
sapm_dc_snl_ac_system_same_arrays, location, input_type):
|
|
1920
1934
|
mc = ModelChain(sapm_dc_snl_ac_system_same_arrays, location)
|
|
1921
|
-
times = pd.date_range(start='2020-01-01 0700-0700', periods=2, freq='
|
|
1935
|
+
times = pd.date_range(start='2020-01-01 0700-0700', periods=2, freq='h')
|
|
1922
1936
|
weather = pd.DataFrame({'dni': [2, 3],
|
|
1923
1937
|
'dhi': [4, 6],
|
|
1924
1938
|
'ghi': [9, 5]}, index=times)
|
|
@@ -1941,11 +1955,8 @@ def test_inconsistent_array_params(location,
|
|
|
1941
1955
|
cec_module_params):
|
|
1942
1956
|
module_error = ".* selected for the DC model but one or more Arrays are " \
|
|
1943
1957
|
"missing one or more required parameters"
|
|
1944
|
-
temperature_error =
|
|
1945
|
-
|
|
1946
|
-
r"that all Arrays in system\.arrays have " \
|
|
1947
|
-
r"parameters for the same temperature model\. " \
|
|
1948
|
-
r"Common temperature model parameters: .*"
|
|
1958
|
+
temperature_error = 'Could not infer temperature model from ' \
|
|
1959
|
+
'ModelChain.system. '
|
|
1949
1960
|
different_module_system = pvsystem.PVSystem(
|
|
1950
1961
|
arrays=[
|
|
1951
1962
|
pvsystem.Array(
|
pvlib/tests/test_pvarray.py
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import numpy as np
|
|
2
|
+
import pandas as pd
|
|
2
3
|
from numpy.testing import assert_allclose
|
|
4
|
+
from .conftest import assert_series_equal
|
|
5
|
+
import pytest
|
|
3
6
|
|
|
4
7
|
from pvlib import pvarray
|
|
5
8
|
|
|
@@ -44,3 +47,25 @@ def test_pvefficiency_adr_round_trip():
|
|
|
44
47
|
params = pvarray.fit_pvefficiency_adr(g, t, eta, dict_output=False)
|
|
45
48
|
result = pvarray.pvefficiency_adr(g, t, *params)
|
|
46
49
|
assert_allclose(result, eta, atol=1e-6)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_huld():
|
|
53
|
+
pdc0 = 100
|
|
54
|
+
res = pvarray.huld(1000, 25, pdc0, cell_type='cSi')
|
|
55
|
+
assert np.isclose(res, pdc0)
|
|
56
|
+
exp_sum = np.exp(1) * (np.sum(pvarray._infer_k_huld('cSi', pdc0)) + pdc0)
|
|
57
|
+
res = pvarray.huld(1000*np.exp(1), 26, pdc0, cell_type='cSi')
|
|
58
|
+
assert np.isclose(res, exp_sum)
|
|
59
|
+
res = pvarray.huld(100, 30, pdc0, k=(1, 1, 1, 1, 1, 1))
|
|
60
|
+
exp_100 = 0.1 * (pdc0 + np.log(0.1) + np.log(0.1)**2 + 5 + 5*np.log(0.1)
|
|
61
|
+
+ 5*np.log(0.1)**2 + 25)
|
|
62
|
+
assert np.isclose(res, exp_100)
|
|
63
|
+
# Series input, and irradiance = 0
|
|
64
|
+
eff_irr = pd.Series([1000, 100, 0])
|
|
65
|
+
tm = pd.Series([25, 30, 30])
|
|
66
|
+
expected = pd.Series([pdc0, exp_100, 0])
|
|
67
|
+
res = pvarray.huld(eff_irr, tm, pdc0, k=(1, 1, 1, 1, 1, 1))
|
|
68
|
+
assert_series_equal(res, expected)
|
|
69
|
+
with pytest.raises(ValueError,
|
|
70
|
+
match='Either k or cell_type must be specified'):
|
|
71
|
+
res = pvarray.huld(1000, 25, 100)
|