pvlib 0.9.4a1__py3-none-any.whl → 0.10.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.
- pvlib/__init__.py +3 -2
- pvlib/atmosphere.py +23 -173
- pvlib/bifacial/infinite_sheds.py +88 -277
- pvlib/bifacial/utils.py +270 -28
- pvlib/data/adr-library-cec-inverters-2019-03-05.csv +5009 -0
- pvlib/data/precise_iv_curves1.json +10251 -0
- pvlib/data/precise_iv_curves2.json +10251 -0
- pvlib/data/precise_iv_curves_parameter_sets1.csv +33 -0
- pvlib/data/precise_iv_curves_parameter_sets2.csv +33 -0
- pvlib/data/test_psm3_2017.csv +17521 -17521
- pvlib/data/test_psm3_2019_5min.csv +288 -288
- pvlib/data/test_read_psm3.csv +17522 -17522
- pvlib/data/test_read_pvgis_horizon.csv +49 -0
- pvlib/data/variables_style_rules.csv +3 -0
- pvlib/iam.py +207 -51
- pvlib/inverter.py +6 -1
- pvlib/iotools/__init__.py +7 -2
- pvlib/iotools/acis.py +516 -0
- pvlib/iotools/midc.py +4 -4
- pvlib/iotools/psm3.py +59 -42
- pvlib/iotools/pvgis.py +84 -28
- pvlib/iotools/sodapro.py +8 -6
- pvlib/iotools/srml.py +121 -18
- pvlib/iotools/surfrad.py +2 -2
- pvlib/iotools/tmy.py +146 -102
- pvlib/irradiance.py +270 -15
- pvlib/ivtools/sde.py +14 -20
- pvlib/ivtools/sdm.py +31 -20
- pvlib/ivtools/utils.py +127 -6
- pvlib/location.py +3 -2
- pvlib/modelchain.py +67 -70
- pvlib/pvarray.py +225 -0
- pvlib/pvsystem.py +169 -539
- pvlib/shading.py +43 -2
- pvlib/singlediode.py +216 -66
- pvlib/snow.py +36 -15
- pvlib/soiling.py +3 -3
- pvlib/spa.py +327 -368
- pvlib/spectrum/__init__.py +8 -2
- pvlib/spectrum/mismatch.py +335 -0
- pvlib/temperature.py +124 -13
- pvlib/tests/bifacial/test_infinite_sheds.py +44 -106
- pvlib/tests/bifacial/test_utils.py +102 -5
- pvlib/tests/conftest.py +0 -31
- pvlib/tests/iotools/test_acis.py +213 -0
- pvlib/tests/iotools/test_midc.py +6 -6
- pvlib/tests/iotools/test_psm3.py +7 -5
- pvlib/tests/iotools/test_pvgis.py +21 -14
- pvlib/tests/iotools/test_sodapro.py +1 -1
- pvlib/tests/iotools/test_srml.py +71 -6
- pvlib/tests/iotools/test_tmy.py +43 -8
- pvlib/tests/ivtools/test_sde.py +19 -17
- pvlib/tests/ivtools/test_sdm.py +9 -4
- pvlib/tests/ivtools/test_utils.py +96 -1
- pvlib/tests/test_atmosphere.py +8 -64
- pvlib/tests/test_clearsky.py +0 -1
- pvlib/tests/test_iam.py +74 -1
- pvlib/tests/test_irradiance.py +56 -2
- pvlib/tests/test_location.py +1 -1
- pvlib/tests/test_modelchain.py +33 -76
- pvlib/tests/test_pvarray.py +46 -0
- pvlib/tests/test_pvsystem.py +366 -201
- pvlib/tests/test_shading.py +35 -0
- pvlib/tests/test_singlediode.py +306 -29
- pvlib/tests/test_snow.py +84 -1
- pvlib/tests/test_soiling.py +8 -7
- pvlib/tests/test_solarposition.py +7 -7
- pvlib/tests/test_spa.py +6 -7
- pvlib/tests/test_spectrum.py +145 -1
- pvlib/tests/test_temperature.py +29 -11
- pvlib/tests/test_tools.py +41 -0
- pvlib/tests/test_tracking.py +0 -149
- pvlib/tools.py +49 -25
- pvlib/tracking.py +1 -269
- pvlib-0.10.0.dist-info/AUTHORS.md +35 -0
- {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/LICENSE +5 -2
- {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/METADATA +3 -13
- {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/RECORD +80 -75
- {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/WHEEL +1 -1
- pvlib/data/adr-library-2013-10-01.csv +0 -1762
- pvlib/forecast.py +0 -1211
- pvlib/iotools/ecmwf_macc.py +0 -312
- pvlib/tests/iotools/test_ecmwf_macc.py +0 -162
- pvlib/tests/test_forecast.py +0 -228
- pvlib-0.9.4a1.dist-info/AUTHORS.md +0 -32
- {pvlib-0.9.4a1.dist-info → pvlib-0.10.0.dist-info}/top_level.txt +0 -0
|
@@ -9,8 +9,9 @@ import pytest
|
|
|
9
9
|
import requests
|
|
10
10
|
from pvlib.iotools import get_pvgis_tmy, read_pvgis_tmy
|
|
11
11
|
from pvlib.iotools import get_pvgis_hourly, read_pvgis_hourly
|
|
12
|
+
from pvlib.iotools import get_pvgis_horizon
|
|
12
13
|
from ..conftest import (DATA_DIR, RERUNS, RERUNS_DELAY, assert_frame_equal,
|
|
13
|
-
fail_on_pvlib_version)
|
|
14
|
+
fail_on_pvlib_version, assert_series_equal)
|
|
14
15
|
from pvlib._deprecation import pvlibDeprecationWarning
|
|
15
16
|
|
|
16
17
|
|
|
@@ -206,14 +207,14 @@ def test_read_pvgis_hourly_bad_extension():
|
|
|
206
207
|
|
|
207
208
|
|
|
208
209
|
args_radiation_csv = {
|
|
209
|
-
'surface_tilt': 30, 'surface_azimuth':
|
|
210
|
+
'surface_tilt': 30, 'surface_azimuth': 180, 'outputformat': 'csv',
|
|
210
211
|
'usehorizon': False, 'userhorizon': None, 'raddatabase': 'PVGIS-SARAH',
|
|
211
212
|
'start': 2016, 'end': 2016, 'pvcalculation': False, 'components': True}
|
|
212
213
|
|
|
213
214
|
url_hourly_radiation_csv = 'https://re.jrc.ec.europa.eu/api/seriescalc?lat=45&lon=8&outputformat=csv&angle=30&aspect=0&usehorizon=0&pvtechchoice=crystSi&mountingplace=free&trackingtype=0&components=1&raddatabase=PVGIS-SARAH&startyear=2016&endyear=2016' # noqa: E501
|
|
214
215
|
|
|
215
216
|
args_pv_json = {
|
|
216
|
-
'surface_tilt': 30, 'surface_azimuth':
|
|
217
|
+
'surface_tilt': 30, 'surface_azimuth': 180, 'outputformat': 'json',
|
|
217
218
|
'usehorizon': True, 'userhorizon': None, 'raddatabase': 'PVGIS-SARAH2',
|
|
218
219
|
'start': pd.Timestamp(2013, 1, 1), 'end': pd.Timestamp(2014, 5, 1),
|
|
219
220
|
'pvcalculation': True, 'peakpower': 10, 'pvtechchoice': 'CIS', 'loss': 5,
|
|
@@ -364,17 +365,6 @@ def pvgis_tmy_mapped_columns():
|
|
|
364
365
|
'wind_speed', 'wind_direction', 'pressure']
|
|
365
366
|
|
|
366
367
|
|
|
367
|
-
@fail_on_pvlib_version('0.10')
|
|
368
|
-
@pytest.mark.remote_data
|
|
369
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
370
|
-
def test_pvgis_tmy_variable_map_deprecating_warning_0_10():
|
|
371
|
-
with pytest.warns(pvlibDeprecationWarning, match='names will be renamed'):
|
|
372
|
-
_ = get_pvgis_tmy(45, 8)
|
|
373
|
-
with pytest.warns(pvlibDeprecationWarning, match='names will be renamed'):
|
|
374
|
-
fn = DATA_DIR / 'tmy_45.000_8.000_2005_2016.epw'
|
|
375
|
-
_ = read_pvgis_tmy(fn)
|
|
376
|
-
|
|
377
|
-
|
|
378
368
|
@pytest.mark.remote_data
|
|
379
369
|
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
380
370
|
def test_get_pvgis_tmy(expected, month_year_expected, inputs_expected,
|
|
@@ -509,6 +499,23 @@ def test_get_pvgis_map_variables(pvgis_tmy_mapped_columns):
|
|
|
509
499
|
assert all([c in pvgis_tmy_mapped_columns for c in actual.columns])
|
|
510
500
|
|
|
511
501
|
|
|
502
|
+
@pytest.mark.remote_data
|
|
503
|
+
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
504
|
+
def test_read_pvgis_horizon():
|
|
505
|
+
pvgis_data, _ = get_pvgis_horizon(35.171051, -106.465158)
|
|
506
|
+
horizon_data = pd.read_csv(DATA_DIR / 'test_read_pvgis_horizon.csv',
|
|
507
|
+
index_col=0)
|
|
508
|
+
horizon_data = horizon_data['horizon_elevation']
|
|
509
|
+
assert_series_equal(pvgis_data, horizon_data)
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
@pytest.mark.remote_data
|
|
513
|
+
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
514
|
+
def test_read_pvgis_horizon_invalid_coords():
|
|
515
|
+
with pytest.raises(requests.HTTPError, match='lat: Incorrect value'):
|
|
516
|
+
_, _ = get_pvgis_horizon(100, 50) # unfeasible latitude
|
|
517
|
+
|
|
518
|
+
|
|
512
519
|
def test_read_pvgis_tmy_map_variables(pvgis_tmy_mapped_columns):
|
|
513
520
|
fn = DATA_DIR / 'tmy_45.000_8.000_2005_2016.json'
|
|
514
521
|
actual, _, _, _ = read_pvgis_tmy(fn, map_variables=True)
|
|
@@ -209,7 +209,7 @@ def test_get_cams(requests_mock, testfile, index, columns, values, dtypes,
|
|
|
209
209
|
mock_response = test_file.read()
|
|
210
210
|
# Specify the full URI of a specific example, this ensures that all of the
|
|
211
211
|
# inputs are passing on correctly
|
|
212
|
-
url_test_cams = f'https://
|
|
212
|
+
url_test_cams = f'https://api.soda-solardata.com/service/wps?DataInputs=latitude=55.7906;longitude=12.5251;altitude=80;date_begin=2020-01-01;date_end=2020-05-04;time_ref=UT;summarization=P01M;username=pvlib-admin%2540googlegroups.com;verbose=false&Service=WPS&Request=Execute&Identifier=get_{identifier}&version=1.0.0&RawDataOutput=irradiation' # noqa: E501
|
|
213
213
|
|
|
214
214
|
requests_mock.get(url_test_cams, text=mock_response,
|
|
215
215
|
headers={'Content-Type': 'application/csv'})
|
pvlib/tests/iotools/test_srml.py
CHANGED
|
@@ -3,7 +3,9 @@ import pandas as pd
|
|
|
3
3
|
import pytest
|
|
4
4
|
|
|
5
5
|
from pvlib.iotools import srml
|
|
6
|
-
from ..conftest import DATA_DIR, RERUNS, RERUNS_DELAY
|
|
6
|
+
from ..conftest import (DATA_DIR, RERUNS, RERUNS_DELAY, assert_index_equal,
|
|
7
|
+
assert_frame_equal, fail_on_pvlib_version)
|
|
8
|
+
from pvlib._deprecation import pvlibDeprecationWarning
|
|
7
9
|
|
|
8
10
|
srml_testfile = DATA_DIR / 'SRML-day-EUPO1801.txt'
|
|
9
11
|
|
|
@@ -28,6 +30,16 @@ def test_read_srml_columns_exist():
|
|
|
28
30
|
assert '7008_flag' in data.columns
|
|
29
31
|
|
|
30
32
|
|
|
33
|
+
def test_read_srml_map_variables_false():
|
|
34
|
+
data = srml.read_srml(srml_testfile, map_variables=False)
|
|
35
|
+
assert '1000' in data.columns
|
|
36
|
+
assert '1000_flag' in data.columns
|
|
37
|
+
assert '2010' in data.columns
|
|
38
|
+
assert '2010_flag' in data.columns
|
|
39
|
+
assert '7008' in data.columns
|
|
40
|
+
assert '7008_flag' in data.columns
|
|
41
|
+
|
|
42
|
+
|
|
31
43
|
def test_read_srml_nans_exist():
|
|
32
44
|
data = srml.read_srml(srml_testfile)
|
|
33
45
|
assert isnan(data['dni_0'][1119])
|
|
@@ -60,23 +72,37 @@ def test_read_srml_dt_index(url, year, month):
|
|
|
60
72
|
('2001', '2001'),
|
|
61
73
|
('2017', 'dni_7')
|
|
62
74
|
])
|
|
63
|
-
def
|
|
64
|
-
assert srml.
|
|
75
|
+
def test__map_columns(column, expected):
|
|
76
|
+
assert srml._map_columns(column) == expected
|
|
65
77
|
|
|
66
78
|
|
|
79
|
+
@pytest.mark.remote_data
|
|
80
|
+
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
81
|
+
def test_get_srml():
|
|
82
|
+
url = 'http://solardat.uoregon.edu/download/Archive/EUPO1801.txt'
|
|
83
|
+
file_data = srml.read_srml(url)
|
|
84
|
+
requested, _ = srml.get_srml(station='EU', start='2018-01-01',
|
|
85
|
+
end='2018-01-31')
|
|
86
|
+
assert_frame_equal(file_data, requested)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@fail_on_pvlib_version('0.11')
|
|
67
90
|
@pytest.mark.remote_data
|
|
68
91
|
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
69
92
|
def test_read_srml_month_from_solardat():
|
|
70
93
|
url = 'http://solardat.uoregon.edu/download/Archive/EUPO1801.txt'
|
|
71
94
|
file_data = srml.read_srml(url)
|
|
72
|
-
|
|
95
|
+
with pytest.warns(pvlibDeprecationWarning, match='get_srml instead'):
|
|
96
|
+
requested = srml.read_srml_month_from_solardat('EU', 2018, 1)
|
|
73
97
|
assert file_data.equals(requested)
|
|
74
98
|
|
|
75
99
|
|
|
100
|
+
@fail_on_pvlib_version('0.11')
|
|
76
101
|
@pytest.mark.remote_data
|
|
77
102
|
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
78
103
|
def test_15_minute_dt_index():
|
|
79
|
-
|
|
104
|
+
with pytest.warns(pvlibDeprecationWarning, match='get_srml instead'):
|
|
105
|
+
data = srml.read_srml_month_from_solardat('TW', 2019, 4, 'RQ')
|
|
80
106
|
start = pd.Timestamp('20190401 00:00')
|
|
81
107
|
start = start.tz_localize('Etc/GMT+8')
|
|
82
108
|
end = pd.Timestamp('20190430 23:45')
|
|
@@ -86,10 +112,12 @@ def test_15_minute_dt_index():
|
|
|
86
112
|
assert (data.index[3::4].minute == 45).all()
|
|
87
113
|
|
|
88
114
|
|
|
115
|
+
@fail_on_pvlib_version('0.11')
|
|
89
116
|
@pytest.mark.remote_data
|
|
90
117
|
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
91
118
|
def test_hourly_dt_index():
|
|
92
|
-
|
|
119
|
+
with pytest.warns(pvlibDeprecationWarning, match='get_srml instead'):
|
|
120
|
+
data = srml.read_srml_month_from_solardat('CD', 1986, 4, 'PH')
|
|
93
121
|
start = pd.Timestamp('19860401 00:00')
|
|
94
122
|
start = start.tz_localize('Etc/GMT+8')
|
|
95
123
|
end = pd.Timestamp('19860430 23:00')
|
|
@@ -97,3 +125,40 @@ def test_hourly_dt_index():
|
|
|
97
125
|
assert data.index[0] == start
|
|
98
126
|
assert data.index[-1] == end
|
|
99
127
|
assert (data.index.minute == 0).all()
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@pytest.mark.remote_data
|
|
131
|
+
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
132
|
+
def test_get_srml_hourly():
|
|
133
|
+
data, meta = data, meta = srml.get_srml(station='CD', start='1986-04-01',
|
|
134
|
+
end='1986-05-31', filetype='PH')
|
|
135
|
+
expected_index = pd.date_range(start='1986-04-01', end='1986-05-31 23:59',
|
|
136
|
+
freq='1h', tz='Etc/GMT+8')
|
|
137
|
+
assert_index_equal(data.index, expected_index)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@pytest.mark.remote_data
|
|
141
|
+
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
142
|
+
def test_get_srml_minute():
|
|
143
|
+
data_read = srml.read_srml(srml_testfile)
|
|
144
|
+
data_get, meta = srml.get_srml(station='EU', start='2018-01-01',
|
|
145
|
+
end='2018-01-31', filetype='PO')
|
|
146
|
+
expected_index = pd.date_range(start='2018-01-01', end='2018-01-31 23:59',
|
|
147
|
+
freq='1min', tz='Etc/GMT+8')
|
|
148
|
+
assert_index_equal(data_get.index, expected_index)
|
|
149
|
+
assert all([c in data_get.columns for c in data_read.columns])
|
|
150
|
+
# Check that all indices in example file are present in remote file
|
|
151
|
+
assert data_read.index.isin(data_get.index).all()
|
|
152
|
+
assert meta['station'] == 'EU'
|
|
153
|
+
assert meta['filetype'] == 'PO'
|
|
154
|
+
assert meta['filenames'] == ['EUPO1801.txt']
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
@pytest.mark.remote_data
|
|
158
|
+
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
159
|
+
def test_get_srml_nonexisting_month_warning():
|
|
160
|
+
with pytest.warns(UserWarning, match='file was not found: EUPO0912.txt'):
|
|
161
|
+
# Request data for a period where not all files exist
|
|
162
|
+
# Eugene (EU) station started reporting 1-minute data in January 2010
|
|
163
|
+
data, meta = data, meta = srml.get_srml(
|
|
164
|
+
station='EU', start='2009-12-01', end='2010-01-31', filetype='PO')
|
pvlib/tests/iotools/test_tmy.py
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
import pandas as pd
|
|
3
3
|
from pvlib.iotools import tmy
|
|
4
|
+
from pvlib._deprecation import pvlibDeprecationWarning
|
|
4
5
|
from ..conftest import DATA_DIR
|
|
5
6
|
import pytest
|
|
7
|
+
import warnings
|
|
6
8
|
|
|
7
9
|
# test the API works
|
|
8
10
|
from pvlib.iotools import read_tmy3
|
|
@@ -16,29 +18,60 @@ TMY3_SOLARANYWHERE = DATA_DIR / 'Burlington, United States SolarAnywhere Time Se
|
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
def test_read_tmy3():
|
|
19
|
-
tmy.read_tmy3(TMY3_TESTFILE)
|
|
21
|
+
tmy.read_tmy3(TMY3_TESTFILE, map_variables=False)
|
|
20
22
|
|
|
21
23
|
|
|
22
24
|
def test_read_tmy3_recolumn():
|
|
23
|
-
|
|
25
|
+
with warnings.catch_warnings():
|
|
26
|
+
warnings.simplefilter("ignore")
|
|
27
|
+
data, meta = tmy.read_tmy3(TMY3_TESTFILE, recolumn=True)
|
|
24
28
|
assert 'GHISource' in data.columns
|
|
25
29
|
|
|
26
30
|
|
|
27
31
|
def test_read_tmy3_norecolumn():
|
|
28
|
-
data, _ = tmy.read_tmy3(TMY3_TESTFILE,
|
|
32
|
+
data, _ = tmy.read_tmy3(TMY3_TESTFILE, map_variables=False)
|
|
29
33
|
assert 'GHI source' in data.columns
|
|
30
34
|
|
|
31
35
|
|
|
36
|
+
def test_read_tmy3_raise_valueerror():
|
|
37
|
+
with pytest.raises(ValueError, match='`map_variables` and `recolumn`'):
|
|
38
|
+
_ = tmy.read_tmy3(TMY3_TESTFILE, recolumn=True, map_variables=True)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_read_tmy3_map_variables():
|
|
42
|
+
data, meta = tmy.read_tmy3(TMY3_TESTFILE, map_variables=True)
|
|
43
|
+
assert 'ghi' in data.columns
|
|
44
|
+
assert 'dni' in data.columns
|
|
45
|
+
assert 'dhi' in data.columns
|
|
46
|
+
assert 'pressure' in data.columns
|
|
47
|
+
assert 'wind_direction' in data.columns
|
|
48
|
+
assert 'wind_speed' in data.columns
|
|
49
|
+
assert 'temp_air' in data.columns
|
|
50
|
+
assert 'temp_dew' in data.columns
|
|
51
|
+
assert 'relative_humidity' in data.columns
|
|
52
|
+
assert 'albedo' in data.columns
|
|
53
|
+
assert 'ghi_extra' in data.columns
|
|
54
|
+
assert 'dni_extra' in data.columns
|
|
55
|
+
assert 'precipitable_water' in data.columns
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_read_tmy3_map_variables_deprecating_warning():
|
|
59
|
+
with pytest.warns(pvlibDeprecationWarning, match='names will be renamed'):
|
|
60
|
+
data, meta = tmy.read_tmy3(TMY3_TESTFILE)
|
|
61
|
+
|
|
62
|
+
|
|
32
63
|
def test_read_tmy3_coerce_year():
|
|
33
64
|
coerce_year = 1987
|
|
34
|
-
data, _ = tmy.read_tmy3(TMY3_TESTFILE, coerce_year=coerce_year
|
|
65
|
+
data, _ = tmy.read_tmy3(TMY3_TESTFILE, coerce_year=coerce_year,
|
|
66
|
+
map_variables=False)
|
|
35
67
|
assert (data.index[:-1].year == 1987).all()
|
|
36
68
|
assert data.index[-1].year == 1988
|
|
37
69
|
|
|
38
70
|
|
|
39
71
|
def test_read_tmy3_no_coerce_year():
|
|
40
72
|
coerce_year = None
|
|
41
|
-
data, _ = tmy.read_tmy3(TMY3_TESTFILE, coerce_year=coerce_year
|
|
73
|
+
data, _ = tmy.read_tmy3(TMY3_TESTFILE, coerce_year=coerce_year,
|
|
74
|
+
map_variables=False)
|
|
42
75
|
assert 1997 and 1999 in data.index.year
|
|
43
76
|
assert data.index[-2] == pd.Timestamp('1998-12-31 23:00:00-09:00')
|
|
44
77
|
assert data.index[-1] == pd.Timestamp('1999-01-01 00:00:00-09:00')
|
|
@@ -50,7 +83,7 @@ def test_read_tmy2():
|
|
|
50
83
|
|
|
51
84
|
def test_gh865_read_tmy3_feb_leapyear_hr24():
|
|
52
85
|
"""correctly parse the 24th hour if the tmy3 file has a leap year in feb"""
|
|
53
|
-
data, meta = read_tmy3(TMY3_FEB_LEAPYEAR)
|
|
86
|
+
data, meta = read_tmy3(TMY3_FEB_LEAPYEAR, map_variables=False)
|
|
54
87
|
# just to be safe, make sure this _IS_ the Greensboro file
|
|
55
88
|
greensboro = {
|
|
56
89
|
'USAF': 723170,
|
|
@@ -66,7 +99,8 @@ def test_gh865_read_tmy3_feb_leapyear_hr24():
|
|
|
66
99
|
assert data.index[1414] == pd.Timestamp('1996-02-28 23:00:00-0500')
|
|
67
100
|
assert data.index[1415] == pd.Timestamp('1996-03-01 00:00:00-0500')
|
|
68
101
|
# now check if it parses correctly when we try to coerce the year
|
|
69
|
-
data, _ = read_tmy3(TMY3_FEB_LEAPYEAR, coerce_year=1990
|
|
102
|
+
data, _ = read_tmy3(TMY3_FEB_LEAPYEAR, coerce_year=1990,
|
|
103
|
+
map_variables=False)
|
|
70
104
|
# if get's here w/o an error, then gh865 is fixed, but let's check anyway
|
|
71
105
|
assert all(data.index[:-1].year == 1990)
|
|
72
106
|
assert data.index[-1].year == 1991
|
|
@@ -87,7 +121,8 @@ def test_solaranywhere_tmy3(solaranywhere_index):
|
|
|
87
121
|
# The SolarAnywhere TMY3 format specifies midnight as 00:00 whereas the
|
|
88
122
|
# NREL TMY3 format utilizes 24:00. The SolarAnywhere file is therefore
|
|
89
123
|
# included to test files with 00:00 timestamps are parsed correctly
|
|
90
|
-
data, meta = tmy.read_tmy3(TMY3_SOLARANYWHERE
|
|
124
|
+
data, meta = tmy.read_tmy3(TMY3_SOLARANYWHERE, encoding='iso-8859-1',
|
|
125
|
+
map_variables=False)
|
|
91
126
|
pd.testing.assert_index_equal(data.index, solaranywhere_index)
|
|
92
127
|
assert meta['USAF'] == 0
|
|
93
128
|
assert meta['Name'] == 'Burlington United States'
|
pvlib/tests/ivtools/test_sde.py
CHANGED
|
@@ -2,6 +2,7 @@ import numpy as np
|
|
|
2
2
|
import pytest
|
|
3
3
|
from pvlib import pvsystem
|
|
4
4
|
from pvlib.ivtools import sde
|
|
5
|
+
from pvlib._deprecation import pvlibDeprecationWarning
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
@pytest.fixture
|
|
@@ -11,31 +12,32 @@ def get_test_iv_params():
|
|
|
11
12
|
|
|
12
13
|
def test_fit_sandia_simple(get_test_iv_params, get_bad_iv_curves):
|
|
13
14
|
test_params = get_test_iv_params
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
test_params = dict(photocurrent=test_params['IL'],
|
|
16
|
+
saturation_current=test_params['I0'],
|
|
17
|
+
resistance_series=test_params['Rs'],
|
|
18
|
+
resistance_shunt=test_params['Rsh'],
|
|
19
|
+
nNsVth=test_params['nNsVth'])
|
|
20
|
+
testcurve = pvsystem.singlediode(**test_params)
|
|
21
|
+
v = np.linspace(0., testcurve['v_oc'], 300)
|
|
22
|
+
i = pvsystem.i_from_v(voltage=v, **test_params)
|
|
23
|
+
expected = tuple(test_params.values())
|
|
24
|
+
|
|
25
|
+
result = sde.fit_sandia_simple(voltage=v, current=i)
|
|
24
26
|
assert np.allclose(result, expected, rtol=5e-5)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
|
|
28
|
+
result = sde.fit_sandia_simple(voltage=v, current=i,
|
|
27
29
|
v_oc=testcurve['v_oc'],
|
|
28
30
|
i_sc=testcurve['i_sc'])
|
|
29
31
|
assert np.allclose(result, expected, rtol=5e-5)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
|
|
33
|
+
result = sde.fit_sandia_simple(voltage=v, current=i,
|
|
32
34
|
v_oc=testcurve['v_oc'],
|
|
33
35
|
i_sc=testcurve['i_sc'],
|
|
34
36
|
v_mp_i_mp=(testcurve['v_mp'],
|
|
35
|
-
|
|
37
|
+
testcurve['i_mp']))
|
|
36
38
|
assert np.allclose(result, expected, rtol=5e-5)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
|
|
40
|
+
result = sde.fit_sandia_simple(voltage=v, current=i, vlim=0.1)
|
|
39
41
|
assert np.allclose(result, expected, rtol=5e-5)
|
|
40
42
|
|
|
41
43
|
|
pvlib/tests/ivtools/test_sdm.py
CHANGED
|
@@ -6,6 +6,7 @@ from numpy.testing import assert_allclose
|
|
|
6
6
|
|
|
7
7
|
from pvlib.ivtools import sdm
|
|
8
8
|
from pvlib import pvsystem
|
|
9
|
+
from pvlib._deprecation import pvlibDeprecationWarning
|
|
9
10
|
|
|
10
11
|
from pvlib.tests.conftest import requires_pysam, requires_statsmodels
|
|
11
12
|
|
|
@@ -100,11 +101,15 @@ def test_fit_desoto_sandia(cec_params_cansol_cs5p_220p):
|
|
|
100
101
|
temp_cell = np.array([15., 25., 35., 45.])
|
|
101
102
|
ee = np.tile(effective_irradiance, len(temp_cell))
|
|
102
103
|
tc = np.repeat(temp_cell, len(effective_irradiance))
|
|
103
|
-
|
|
104
|
+
IL, I0, Rs, Rsh, nNsVth = pvsystem.calcparams_desoto(
|
|
104
105
|
ee, tc, alpha_sc=specs['alpha_sc'], **params)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
ivcurve_params = dict(photocurrent=IL, saturation_current=I0,
|
|
107
|
+
resistance_series=Rs, resistance_shunt=Rsh,
|
|
108
|
+
nNsVth=nNsVth)
|
|
109
|
+
sim_ivcurves = pvsystem.singlediode(**ivcurve_params).to_dict('series')
|
|
110
|
+
v = np.linspace(0., sim_ivcurves['v_oc'], 300)
|
|
111
|
+
i = pvsystem.i_from_v(voltage=v, **ivcurve_params)
|
|
112
|
+
sim_ivcurves.update(v=v.T, i=i.T, ee=ee, tc=tc)
|
|
108
113
|
|
|
109
114
|
result = sdm.fit_desoto_sandia(sim_ivcurves, specs)
|
|
110
115
|
modeled = pd.Series(index=params.keys(), data=np.nan)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
import pandas as pd
|
|
3
3
|
import pytest
|
|
4
|
-
from pvlib.ivtools.utils import _numdiff, rectify_iv_curve
|
|
4
|
+
from pvlib.ivtools.utils import _numdiff, rectify_iv_curve, astm_e1036
|
|
5
5
|
from pvlib.ivtools.utils import _schumaker_qspline
|
|
6
6
|
|
|
7
7
|
from ..conftest import DATA_DIR
|
|
@@ -76,3 +76,98 @@ def test__schmumaker_qspline(x, y, expected):
|
|
|
76
76
|
np.testing.assert_allclose(t, expected[1], atol=0.0001)
|
|
77
77
|
np.testing.assert_allclose(yhat, expected[2], atol=0.0001)
|
|
78
78
|
np.testing.assert_allclose(kflag, expected[3], atol=0.0001)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@pytest.fixture
|
|
82
|
+
def i_array():
|
|
83
|
+
i = np.array([8.09403993, 8.09382549, 8.09361103, 8.09339656, 8.09318205,
|
|
84
|
+
8.09296748, 8.09275275, 8.09253771, 8.09232204, 8.09210506,
|
|
85
|
+
8.09188538, 8.09166014, 8.09142342, 8.09116305, 8.09085392,
|
|
86
|
+
8.09044425, 8.08982734, 8.08878333, 8.08685945, 8.08312463,
|
|
87
|
+
8.07566926, 8.06059856, 8.03005836, 7.96856869, 7.8469714,
|
|
88
|
+
7.61489584, 7.19789314, 6.51138396, 5.49373476, 4.13267172,
|
|
89
|
+
2.46021487, 0.52838624, -1.61055289])
|
|
90
|
+
return i
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@pytest.fixture
|
|
94
|
+
def v_array():
|
|
95
|
+
v = np.array([-0.005, 0.015, 0.035, 0.055, 0.075, 0.095, 0.115, 0.135,
|
|
96
|
+
0.155, 0.175, 0.195, 0.215, 0.235, 0.255, 0.275, 0.295,
|
|
97
|
+
0.315, 0.335, 0.355, 0.375, 0.395, 0.415, 0.435, 0.455,
|
|
98
|
+
0.475, 0.495, 0.515, 0.535, 0.555, 0.575, 0.595, 0.615,
|
|
99
|
+
0.635])
|
|
100
|
+
return v
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# astm_e1036 tests
|
|
104
|
+
def test_astm_e1036(v_array, i_array):
|
|
105
|
+
result = astm_e1036(v_array, i_array)
|
|
106
|
+
expected = {'voc': 0.6195097477985162,
|
|
107
|
+
'isc': 8.093986320386227,
|
|
108
|
+
'vmp': 0.494283417170082,
|
|
109
|
+
'imp': 7.626088301548568,
|
|
110
|
+
'pmp': 3.7694489853302127,
|
|
111
|
+
'ff': 0.7517393078504361}
|
|
112
|
+
fit = result.pop('mp_fit')
|
|
113
|
+
expected_fit = np.array(
|
|
114
|
+
[3.6260726, 0.49124176, -0.24644747, -0.26442383, -0.1223237])
|
|
115
|
+
assert fit.coef == pytest.approx(expected_fit)
|
|
116
|
+
assert result == pytest.approx(expected)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def test_astm_e1036_fit_order(v_array, i_array):
|
|
120
|
+
result = astm_e1036(v_array, i_array, mp_fit_order=3)
|
|
121
|
+
fit = result.pop('mp_fit')
|
|
122
|
+
expected_fit = np.array(
|
|
123
|
+
[3.64081697, 0.49124176, -0.3720477, -0.26442383])
|
|
124
|
+
assert fit.coef == pytest.approx(expected_fit)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def test_astm_e1036_est_isc_voc(v_array, i_array):
|
|
128
|
+
'''
|
|
129
|
+
Test the case in which Isc and Voc estimates are
|
|
130
|
+
valid without a linear fit
|
|
131
|
+
'''
|
|
132
|
+
v = v_array
|
|
133
|
+
i = i_array
|
|
134
|
+
v = np.append(v, [0.001, 0.6201])
|
|
135
|
+
i = np.append(i, [8.09397560e+00, 7.10653445e-04])
|
|
136
|
+
result = astm_e1036(v, i)
|
|
137
|
+
expected = {'voc': 0.6201,
|
|
138
|
+
'isc': 8.093975598317805,
|
|
139
|
+
'vmp': 0.494283417170082,
|
|
140
|
+
'imp': 7.626088301548568,
|
|
141
|
+
'pmp': 3.7694489853302127,
|
|
142
|
+
'ff': 0.751024747526615}
|
|
143
|
+
result.pop('mp_fit')
|
|
144
|
+
assert result == pytest.approx(expected)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def test_astm_e1036_mpfit_limits(v_array, i_array):
|
|
148
|
+
result = astm_e1036(v_array,
|
|
149
|
+
i_array,
|
|
150
|
+
imax_limits=(0.85, 1.1),
|
|
151
|
+
vmax_limits=(0.85, 1.1))
|
|
152
|
+
expected = {'voc': 0.6195097477985162,
|
|
153
|
+
'isc': 8.093986320386227,
|
|
154
|
+
'vmp': 0.49464214190725303,
|
|
155
|
+
'imp': 7.620032530519718,
|
|
156
|
+
'pmp': 3.769189212299219,
|
|
157
|
+
'ff': 0.7516875014460312}
|
|
158
|
+
result.pop('mp_fit')
|
|
159
|
+
assert result == pytest.approx(expected)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def test_astm_e1036_fit_points(v_array, i_array):
|
|
163
|
+
i = i_array
|
|
164
|
+
i[3] = 8.1 # ensure an interesting change happens
|
|
165
|
+
result = astm_e1036(v_array, i, voc_points=4, isc_points=4)
|
|
166
|
+
expected = {'voc': 0.619337073271274,
|
|
167
|
+
'isc': 8.093160893325297,
|
|
168
|
+
'vmp': 0.494283417170082,
|
|
169
|
+
'imp': 7.626088301548568,
|
|
170
|
+
'pmp': 3.7694489853302127,
|
|
171
|
+
'ff': 0.7520255886236707}
|
|
172
|
+
result.pop('mp_fit')
|
|
173
|
+
assert result == pytest.approx(expected)
|
pvlib/tests/test_atmosphere.py
CHANGED
|
@@ -9,6 +9,8 @@ import pytest
|
|
|
9
9
|
|
|
10
10
|
from pvlib import atmosphere
|
|
11
11
|
|
|
12
|
+
from pvlib._deprecation import pvlibDeprecationWarning
|
|
13
|
+
|
|
12
14
|
|
|
13
15
|
def test_pres2alt():
|
|
14
16
|
out = atmosphere.pres2alt(np.array([10000, 90000, 101325]))
|
|
@@ -35,7 +37,8 @@ def zeniths():
|
|
|
35
37
|
['kastenyoung1989', [nan, 36.467, 5.586, 1.000]],
|
|
36
38
|
['gueymard1993', [nan, 36.431, 5.581, 1.000]],
|
|
37
39
|
['young1994', [nan, 30.733, 5.541, 1.000]],
|
|
38
|
-
['pickering2002', [nan, 37.064, 5.581, 1.000]]
|
|
40
|
+
['pickering2002', [nan, 37.064, 5.581, 1.000]],
|
|
41
|
+
['gueymard2003', [nan, 36.676, 5.590, 1.000]]])
|
|
39
42
|
def test_airmass(model, expected, zeniths):
|
|
40
43
|
out = atmosphere.get_relative_airmass(zeniths, model)
|
|
41
44
|
expected = np.array(expected)
|
|
@@ -85,68 +88,10 @@ def test_gueymard94_pw():
|
|
|
85
88
|
assert_allclose(pws, expected, atol=0.01)
|
|
86
89
|
|
|
87
90
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
[ 1.04750335, 1.03814456, 1.00623986]])),
|
|
93
|
-
('monosi', np.array(
|
|
94
|
-
[[ 0.9776977 , 1.02043409, 1.03574032],
|
|
95
|
-
[ 0.98630905, 1.03055092, 1.04736262],
|
|
96
|
-
[ 0.98828494, 1.03299036, 1.05026561]])),
|
|
97
|
-
('polysi', np.array(
|
|
98
|
-
[[ 0.9770408 , 1.01705849, 1.02613202],
|
|
99
|
-
[ 0.98992828, 1.03173953, 1.04260662],
|
|
100
|
-
[ 0.99352435, 1.03588785, 1.04730718]])),
|
|
101
|
-
('cigs', np.array(
|
|
102
|
-
[[ 0.9745919 , 1.02821696, 1.05067895],
|
|
103
|
-
[ 0.97529378, 1.02967497, 1.05289307],
|
|
104
|
-
[ 0.97269159, 1.02730558, 1.05075651]])),
|
|
105
|
-
('asi', np.array(
|
|
106
|
-
[[ 1.0555275 , 0.87707583, 0.72243772],
|
|
107
|
-
[ 1.11225204, 0.93665901, 0.78487953],
|
|
108
|
-
[ 1.14555295, 0.97084011, 0.81994083]]))
|
|
109
|
-
])
|
|
110
|
-
def test_first_solar_spectral_correction(module_type, expect):
|
|
111
|
-
ams = np.array([1, 3, 5])
|
|
112
|
-
pws = np.array([1, 3, 5])
|
|
113
|
-
ams, pws = np.meshgrid(ams, pws)
|
|
114
|
-
out = atmosphere.first_solar_spectral_correction(pws, ams, module_type)
|
|
115
|
-
assert_allclose(out, expect, atol=0.001)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
def test_first_solar_spectral_correction_supplied():
|
|
119
|
-
# use the cdte coeffs
|
|
120
|
-
coeffs = (0.87102, -0.040543, -0.00929202, 0.10052, 0.073062, -0.0034187)
|
|
121
|
-
out = atmosphere.first_solar_spectral_correction(1, 1, coefficients=coeffs)
|
|
122
|
-
expected = 0.99134828
|
|
123
|
-
assert_allclose(out, expected, atol=1e-3)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
def test_first_solar_spectral_correction_ambiguous():
|
|
127
|
-
with pytest.raises(TypeError):
|
|
128
|
-
atmosphere.first_solar_spectral_correction(1, 1)
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
def test_first_solar_spectral_correction_range():
|
|
132
|
-
with pytest.warns(UserWarning, match='Exceptionally high pw values'):
|
|
133
|
-
out = atmosphere.first_solar_spectral_correction(np.array([.1, 3, 10]),
|
|
134
|
-
np.array([1, 3, 5]),
|
|
135
|
-
module_type='monosi')
|
|
136
|
-
expected = np.array([0.96080878, 1.03055092, nan])
|
|
137
|
-
assert_allclose(out, expected, atol=1e-3)
|
|
138
|
-
with pytest.warns(UserWarning, match='Exceptionally high pw values'):
|
|
139
|
-
out = atmosphere.first_solar_spectral_correction(6, 1.5, max_pw=5,
|
|
140
|
-
module_type='monosi')
|
|
141
|
-
with pytest.warns(UserWarning, match='Exceptionally low pw values'):
|
|
142
|
-
out = atmosphere.first_solar_spectral_correction(np.array([0, 3, 8]),
|
|
143
|
-
np.array([1, 3, 5]),
|
|
144
|
-
module_type='monosi')
|
|
145
|
-
expected = np.array([0.96080878, 1.03055092, 1.04932727])
|
|
146
|
-
assert_allclose(out, expected, atol=1e-3)
|
|
147
|
-
with pytest.warns(UserWarning, match='Exceptionally low pw values'):
|
|
148
|
-
out = atmosphere.first_solar_spectral_correction(0.2, 1.5, min_pw=1,
|
|
149
|
-
module_type='monosi')
|
|
91
|
+
def test_first_solar_spectral_correction_deprecated():
|
|
92
|
+
with pytest.warns(pvlibDeprecationWarning,
|
|
93
|
+
match='Use pvlib.spectrum.spectral_factor_firstsolar'):
|
|
94
|
+
atmosphere.first_solar_spectral_correction(1, 1, 'cdte')
|
|
150
95
|
|
|
151
96
|
|
|
152
97
|
def test_kasten96_lt():
|
|
@@ -169,7 +114,6 @@ def test_kasten96_lt():
|
|
|
169
114
|
)
|
|
170
115
|
lt = atmosphere.kasten96_lt(*np.meshgrid(amp, pwat, aod_bb))
|
|
171
116
|
assert np.allclose(lt, lt_expected, 1e-3)
|
|
172
|
-
return lt
|
|
173
117
|
|
|
174
118
|
|
|
175
119
|
def test_angstrom_aod():
|
pvlib/tests/test_clearsky.py
CHANGED