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.
- pvlib/__init__.py +1 -0
- pvlib/atmosphere.py +0 -9
- pvlib/bifacial/infinite_sheds.py +4 -3
- pvlib/bifacial/utils.py +2 -1
- pvlib/iotools/psm3.py +1 -1
- pvlib/iotools/pvgis.py +10 -2
- pvlib/iotools/tmy.py +3 -69
- pvlib/irradiance.py +14 -0
- pvlib/location.py +73 -33
- pvlib/modelchain.py +18 -35
- pvlib/pvsystem.py +7 -10
- pvlib/snow.py +64 -28
- pvlib/spectrum/__init__.py +0 -1
- pvlib/spectrum/irradiance.py +0 -63
- pvlib/spectrum/mismatch.py +3 -3
- pvlib/tools.py +6 -5
- {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info}/METADATA +5 -3
- pvlib-0.12.0.dist-info/RECORD +75 -0
- {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info}/WHEEL +1 -1
- pvlib/data/BIRD_08_16_2012.csv +0 -8761
- pvlib/data/BIRD_08_16_2012_patm.csv +0 -8761
- pvlib/data/Burlington, United States SolarAnywhere Time Series 2021 Lat_44_465 Lon_-73_205 TMY3 format.csv +0 -8762
- pvlib/data/Burlington, United States SolarAnywhere Time Series 20210101 to 20210103 Lat_44_4675 Lon_-73_2075 SA format.csv +0 -578
- pvlib/data/Burlington, United States SolarAnywhere Typical GHI Year Lat_44_465 Lon_-73_205 SA format.csv +0 -74
- pvlib/data/CPS SCH275KTL-DO-US-800-250kW_275kVA_1.OND +0 -146
- pvlib/data/CRNS0101-05-2019-AZ_Tucson_11_W.txt +0 -4
- pvlib/data/CRN_with_problems.txt +0 -3
- pvlib/data/ET-M772BH550GL.PAN +0 -75
- pvlib/data/NLD_Amsterdam062400_IWEC.epw +0 -8768
- pvlib/data/PVsyst_demo.csv +0 -10757
- pvlib/data/PVsyst_demo_model.csv +0 -3588
- pvlib/data/SRML-day-EUPO1801.txt +0 -1441
- pvlib/data/abq19056.dat +0 -6
- pvlib/data/bishop88_numerical_precision.csv +0 -101
- pvlib/data/bsrn-lr0100-pay0616.dat +0 -86901
- pvlib/data/bsrn-pay0616.dat.gz +0 -0
- pvlib/data/cams_mcclear_1min_verbose.csv +0 -60
- pvlib/data/cams_mcclear_monthly.csv +0 -42
- pvlib/data/cams_radiation_1min_verbose.csv +0 -72
- pvlib/data/cams_radiation_monthly.csv +0 -47
- pvlib/data/detect_clearsky_data.csv +0 -35
- pvlib/data/detect_clearsky_threshold_data.csv +0 -126
- pvlib/data/greensboro_kimber_soil_manwash.dat +0 -8761
- pvlib/data/greensboro_kimber_soil_nowash.dat +0 -8761
- pvlib/data/inverter_fit_snl_meas.csv +0 -127
- pvlib/data/inverter_fit_snl_sim.csv +0 -19
- pvlib/data/ivtools_numdiff.csv +0 -52
- pvlib/data/midc_20181014.txt +0 -1441
- pvlib/data/midc_raw_20181018.txt +0 -1441
- pvlib/data/midc_raw_short_header_20191115.txt +0 -1441
- pvlib/data/msn19056.dat +0 -6
- pvlib/data/precise_iv_curves1.json +0 -10251
- pvlib/data/precise_iv_curves2.json +0 -10251
- pvlib/data/precise_iv_curves_parameter_sets1.csv +0 -33
- pvlib/data/precise_iv_curves_parameter_sets2.csv +0 -33
- pvlib/data/pvgis_hourly_Timeseries_45.000_8.000_SA2_10kWp_CIS_5_2a_2013_2014.json +0 -1
- pvlib/data/pvgis_hourly_Timeseries_45.000_8.000_SA_30deg_0deg_2016_2016.csv +0 -35
- pvlib/data/pvgis_tmy_meta.json +0 -32
- pvlib/data/pvgis_tmy_test.csv +0 -8761
- pvlib/data/pvwatts_8760_rackmount.csv +0 -8779
- pvlib/data/pvwatts_8760_roofmount.csv +0 -8779
- pvlib/data/singleaxis_tracker_wslope.csv +0 -8761
- pvlib/data/spectrl2_example_spectra.csv +0 -123
- pvlib/data/surfrad-slv16001.dat +0 -1442
- pvlib/data/test_psm3_2017.csv +0 -17521
- pvlib/data/test_psm3_2019_5min.csv +0 -289
- pvlib/data/test_psm3_tmy-2017.csv +0 -8761
- pvlib/data/test_read_psm3.csv +0 -17523
- pvlib/data/test_read_pvgis_horizon.csv +0 -49
- pvlib/data/tmy_45.000_8.000_2005_2023.csv +0 -8789
- pvlib/data/tmy_45.000_8.000_2005_2023.epw +0 -8768
- pvlib/data/tmy_45.000_8.000_2005_2023.json +0 -1
- pvlib/data/tmy_45.000_8.000_2005_2023.txt +0 -8761
- pvlib/data/tmy_45.000_8.000_userhorizon.json +0 -1
- pvlib/spa_c_files/README.md +0 -81
- pvlib/spa_c_files/cspa_py.pxd +0 -43
- pvlib/spa_c_files/spa_py.pyx +0 -30
- pvlib/tests/__init__.py +0 -0
- pvlib/tests/bifacial/__init__.py +0 -0
- pvlib/tests/bifacial/test_infinite_sheds.py +0 -317
- pvlib/tests/bifacial/test_losses_models.py +0 -54
- pvlib/tests/bifacial/test_pvfactors.py +0 -82
- pvlib/tests/bifacial/test_utils.py +0 -192
- pvlib/tests/conftest.py +0 -476
- pvlib/tests/iotools/__init__.py +0 -0
- pvlib/tests/iotools/test_acis.py +0 -213
- pvlib/tests/iotools/test_bsrn.py +0 -131
- pvlib/tests/iotools/test_crn.py +0 -95
- pvlib/tests/iotools/test_epw.py +0 -23
- pvlib/tests/iotools/test_midc.py +0 -89
- pvlib/tests/iotools/test_panond.py +0 -32
- pvlib/tests/iotools/test_psm3.py +0 -198
- pvlib/tests/iotools/test_pvgis.py +0 -644
- pvlib/tests/iotools/test_sodapro.py +0 -298
- pvlib/tests/iotools/test_solaranywhere.py +0 -287
- pvlib/tests/iotools/test_solargis.py +0 -68
- pvlib/tests/iotools/test_solcast.py +0 -324
- pvlib/tests/iotools/test_solrad.py +0 -152
- pvlib/tests/iotools/test_srml.py +0 -124
- pvlib/tests/iotools/test_surfrad.py +0 -75
- pvlib/tests/iotools/test_tmy.py +0 -133
- pvlib/tests/ivtools/__init__.py +0 -0
- pvlib/tests/ivtools/test_sde.py +0 -230
- pvlib/tests/ivtools/test_sdm.py +0 -429
- pvlib/tests/ivtools/test_utils.py +0 -173
- pvlib/tests/spectrum/__init__.py +0 -0
- pvlib/tests/spectrum/conftest.py +0 -40
- pvlib/tests/spectrum/test_irradiance.py +0 -138
- pvlib/tests/spectrum/test_mismatch.py +0 -304
- pvlib/tests/spectrum/test_response.py +0 -124
- pvlib/tests/spectrum/test_spectrl2.py +0 -72
- pvlib/tests/test__deprecation.py +0 -97
- pvlib/tests/test_albedo.py +0 -84
- pvlib/tests/test_atmosphere.py +0 -351
- pvlib/tests/test_clearsky.py +0 -884
- pvlib/tests/test_conftest.py +0 -37
- pvlib/tests/test_iam.py +0 -555
- pvlib/tests/test_inverter.py +0 -213
- pvlib/tests/test_irradiance.py +0 -1487
- pvlib/tests/test_location.py +0 -356
- pvlib/tests/test_modelchain.py +0 -2020
- pvlib/tests/test_numerical_precision.py +0 -124
- pvlib/tests/test_pvarray.py +0 -71
- pvlib/tests/test_pvsystem.py +0 -2511
- pvlib/tests/test_scaling.py +0 -207
- pvlib/tests/test_shading.py +0 -391
- pvlib/tests/test_singlediode.py +0 -608
- pvlib/tests/test_snow.py +0 -212
- pvlib/tests/test_soiling.py +0 -230
- pvlib/tests/test_solarposition.py +0 -966
- pvlib/tests/test_spa.py +0 -454
- pvlib/tests/test_temperature.py +0 -470
- pvlib/tests/test_tools.py +0 -146
- pvlib/tests/test_tracking.py +0 -474
- pvlib/tests/test_transformer.py +0 -60
- pvlib-0.11.2.dist-info/RECORD +0 -191
- {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info/licenses}/AUTHORS.md +0 -0
- {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info/licenses}/LICENSE +0 -0
- {pvlib-0.11.2.dist-info → pvlib-0.12.0.dist-info}/top_level.txt +0 -0
pvlib/tests/test_clearsky.py
DELETED
|
@@ -1,884 +0,0 @@
|
|
|
1
|
-
from collections import OrderedDict
|
|
2
|
-
|
|
3
|
-
import numpy as np
|
|
4
|
-
from numpy import nan
|
|
5
|
-
import pandas as pd
|
|
6
|
-
import pytz
|
|
7
|
-
from scipy.linalg import hankel
|
|
8
|
-
|
|
9
|
-
import pytest
|
|
10
|
-
from numpy.testing import assert_allclose
|
|
11
|
-
from .conftest import assert_frame_equal, assert_series_equal
|
|
12
|
-
|
|
13
|
-
from pvlib.location import Location
|
|
14
|
-
from pvlib import clearsky
|
|
15
|
-
from pvlib import solarposition
|
|
16
|
-
from pvlib import atmosphere
|
|
17
|
-
from pvlib import irradiance
|
|
18
|
-
|
|
19
|
-
from .conftest import DATA_DIR
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def test_ineichen_series():
|
|
23
|
-
times = pd.date_range(start='2014-06-24', end='2014-06-25', freq='3h',
|
|
24
|
-
tz='America/Phoenix')
|
|
25
|
-
apparent_zenith = pd.Series(np.array(
|
|
26
|
-
[124.0390863, 113.38779941, 82.85457044, 46.0467599, 10.56413562,
|
|
27
|
-
34.86074109, 72.41687122, 105.69538659, 124.05614124]),
|
|
28
|
-
index=times)
|
|
29
|
-
am = pd.Series(np.array(
|
|
30
|
-
[nan, nan, 6.97935524, 1.32355476, 0.93527685,
|
|
31
|
-
1.12008114, 3.01614096, nan, nan]),
|
|
32
|
-
index=times)
|
|
33
|
-
expected = pd.DataFrame(np.
|
|
34
|
-
array([[ 0. , 0. , 0. ],
|
|
35
|
-
[ 0. , 0. , 0. ],
|
|
36
|
-
[ 65.49426624, 321.16092181, 25.54562017],
|
|
37
|
-
[ 704.6968125 , 888.90147035, 87.73601277],
|
|
38
|
-
[1044.1230677 , 953.24925854, 107.03109696],
|
|
39
|
-
[ 853.02065704, 922.06124712, 96.42909484],
|
|
40
|
-
[ 251.99427693, 655.44925241, 53.9901349 ],
|
|
41
|
-
[ 0. , 0. , 0. ],
|
|
42
|
-
[ 0. , 0. , 0. ]]),
|
|
43
|
-
columns=['ghi', 'dni', 'dhi'],
|
|
44
|
-
index=times)
|
|
45
|
-
|
|
46
|
-
out = clearsky.ineichen(apparent_zenith, am, 3)
|
|
47
|
-
assert_frame_equal(expected, out)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def test_ineichen_series_perez_enhancement():
|
|
51
|
-
times = pd.date_range(start='2014-06-24', end='2014-06-25', freq='3h',
|
|
52
|
-
tz='America/Phoenix')
|
|
53
|
-
apparent_zenith = pd.Series(np.array(
|
|
54
|
-
[124.0390863, 113.38779941, 82.85457044, 46.0467599, 10.56413562,
|
|
55
|
-
34.86074109, 72.41687122, 105.69538659, 124.05614124]),
|
|
56
|
-
index=times)
|
|
57
|
-
am = pd.Series(np.array(
|
|
58
|
-
[nan, nan, 6.97935524, 1.32355476, 0.93527685,
|
|
59
|
-
1.12008114, 3.01614096, nan, nan]),
|
|
60
|
-
index=times)
|
|
61
|
-
expected = pd.DataFrame(np.
|
|
62
|
-
array([[ 0. , 0. , 0. ],
|
|
63
|
-
[ 0. , 0. , 0. ],
|
|
64
|
-
[ 91.1249279 , 321.16092171, 51.17628184],
|
|
65
|
-
[ 716.46580547, 888.9014706 , 99.50500553],
|
|
66
|
-
[1053.42066073, 953.24925905, 116.3286895 ],
|
|
67
|
-
[ 863.54692748, 922.06124652, 106.9553658 ],
|
|
68
|
-
[ 271.06382275, 655.44925213, 73.05968076],
|
|
69
|
-
[ 0. , 0. , 0. ],
|
|
70
|
-
[ 0. , 0. , 0. ]]),
|
|
71
|
-
columns=['ghi', 'dni', 'dhi'],
|
|
72
|
-
index=times)
|
|
73
|
-
|
|
74
|
-
out = clearsky.ineichen(apparent_zenith, am, 3, perez_enhancement=True)
|
|
75
|
-
assert_frame_equal(expected, out)
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def test_ineichen_scalar_input():
|
|
79
|
-
expected = OrderedDict()
|
|
80
|
-
expected['ghi'] = 1038.159219
|
|
81
|
-
expected['dni'] = 942.2081860378344
|
|
82
|
-
expected['dhi'] = 110.26529293612793
|
|
83
|
-
|
|
84
|
-
out = clearsky.ineichen(10., 1., 3.)
|
|
85
|
-
for k, v in expected.items():
|
|
86
|
-
assert_allclose(expected[k], out[k])
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def test_ineichen_nans():
|
|
90
|
-
length = 4
|
|
91
|
-
|
|
92
|
-
apparent_zenith = np.full(length, 10.)
|
|
93
|
-
apparent_zenith[0] = np.nan
|
|
94
|
-
|
|
95
|
-
linke_turbidity = np.full(length, 3.)
|
|
96
|
-
linke_turbidity[1] = np.nan
|
|
97
|
-
|
|
98
|
-
dni_extra = np.full(length, 1370.)
|
|
99
|
-
dni_extra[2] = np.nan
|
|
100
|
-
|
|
101
|
-
airmass_absolute = np.full(length, 1.)
|
|
102
|
-
|
|
103
|
-
expected = OrderedDict()
|
|
104
|
-
expected['ghi'] = np.full(length, np.nan)
|
|
105
|
-
expected['dni'] = np.full(length, np.nan)
|
|
106
|
-
expected['dhi'] = np.full(length, np.nan)
|
|
107
|
-
|
|
108
|
-
expected['ghi'][length-1] = 1042.72590228
|
|
109
|
-
expected['dni'][length-1] = 946.35279683
|
|
110
|
-
expected['dhi'][length-1] = 110.75033088
|
|
111
|
-
|
|
112
|
-
out = clearsky.ineichen(apparent_zenith, airmass_absolute,
|
|
113
|
-
linke_turbidity, dni_extra=dni_extra)
|
|
114
|
-
|
|
115
|
-
for k, v in expected.items():
|
|
116
|
-
assert_allclose(expected[k], out[k])
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
def test_ineichen_arrays():
|
|
120
|
-
expected = OrderedDict()
|
|
121
|
-
|
|
122
|
-
expected['ghi'] = (np.
|
|
123
|
-
array([[[1095.77074798, 1054.17449885, 1014.15727338],
|
|
124
|
-
[ 839.40909243, 807.54451692, 776.88954373],
|
|
125
|
-
[ 190.27859353, 183.05548067, 176.10656239]],
|
|
126
|
-
|
|
127
|
-
[[ 773.49041181, 625.19479557, 505.33080493],
|
|
128
|
-
[ 592.52803177, 478.92699901, 387.10585505],
|
|
129
|
-
[ 134.31520045, 108.56393694, 87.74977339]],
|
|
130
|
-
|
|
131
|
-
[[ 545.9968869 , 370.78162375, 251.79449885],
|
|
132
|
-
[ 418.25788117, 284.03520249, 192.88577665],
|
|
133
|
-
[ 94.81136442, 64.38555328, 43.72365587]]]))
|
|
134
|
-
|
|
135
|
-
expected['dni'] = (np.
|
|
136
|
-
array([[[1014.38807396, 942.20818604, 861.11344424],
|
|
137
|
-
[1014.38807396, 942.20818604, 861.11344424],
|
|
138
|
-
[1014.38807396, 942.20818604, 861.11344424]],
|
|
139
|
-
|
|
140
|
-
[[ 687.61305142, 419.14891162, 255.50098235],
|
|
141
|
-
[ 687.61305142, 419.14891162, 255.50098235],
|
|
142
|
-
[ 687.61305142, 419.14891162, 255.50098235]],
|
|
143
|
-
|
|
144
|
-
[[ 458.62196014, 186.46177428, 75.80970012],
|
|
145
|
-
[ 458.62196014, 186.46177428, 75.80970012],
|
|
146
|
-
[ 458.62196014, 186.46177428, 75.80970012]]]))
|
|
147
|
-
|
|
148
|
-
expected['dhi'] = (np.
|
|
149
|
-
array([[[ 81.38267402, 111.96631281, 153.04382915],
|
|
150
|
-
[ 62.3427452 , 85.77117175, 117.23837487],
|
|
151
|
-
[ 14.13195304, 19.44274618, 26.57578203]],
|
|
152
|
-
|
|
153
|
-
[[ 85.87736039, 206.04588395, 249.82982258],
|
|
154
|
-
[ 65.78587472, 157.84030442, 191.38074731],
|
|
155
|
-
[ 14.91244713, 35.77949226, 43.38249342]],
|
|
156
|
-
|
|
157
|
-
[[ 87.37492676, 184.31984947, 175.98479873],
|
|
158
|
-
[ 66.93307711, 141.19719644, 134.81217714],
|
|
159
|
-
[ 15.17249681, 32.00680597, 30.5594396 ]]]))
|
|
160
|
-
|
|
161
|
-
apparent_zenith = np.linspace(0, 80, 3)
|
|
162
|
-
airmass_absolute = np.linspace(1, 10, 3)
|
|
163
|
-
linke_turbidity = np.linspace(2, 4, 3)
|
|
164
|
-
|
|
165
|
-
apparent_zenith, airmass_absolute, linke_turbidity = \
|
|
166
|
-
np.meshgrid(apparent_zenith, airmass_absolute, linke_turbidity)
|
|
167
|
-
|
|
168
|
-
out = clearsky.ineichen(apparent_zenith, airmass_absolute, linke_turbidity)
|
|
169
|
-
|
|
170
|
-
for k, v in expected.items():
|
|
171
|
-
assert_allclose(expected[k], out[k])
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
def test_ineichen_dni_extra():
|
|
175
|
-
expected = pd.DataFrame(
|
|
176
|
-
np.array([[1042.72590228, 946.35279683, 110.75033088]]),
|
|
177
|
-
columns=['ghi', 'dni', 'dhi'])
|
|
178
|
-
|
|
179
|
-
out = clearsky.ineichen(10, 1, 3, dni_extra=pd.Series(1370))
|
|
180
|
-
assert_frame_equal(expected, out)
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
def test_ineichen_altitude():
|
|
184
|
-
expected = pd.DataFrame(
|
|
185
|
-
np.array([[1134.24312405, 994.95377835, 154.40492924]]),
|
|
186
|
-
columns=['ghi', 'dni', 'dhi'])
|
|
187
|
-
|
|
188
|
-
out = clearsky.ineichen(10, 1, 3, altitude=pd.Series(2000))
|
|
189
|
-
assert_frame_equal(expected, out)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
def test_lookup_linke_turbidity():
|
|
193
|
-
times = pd.date_range(start='2014-06-24', end='2014-06-25',
|
|
194
|
-
freq='12h', tz='America/Phoenix')
|
|
195
|
-
# expect same value on 2014-06-24 0000 and 1200, and
|
|
196
|
-
# diff value on 2014-06-25
|
|
197
|
-
expected = pd.Series(
|
|
198
|
-
np.array([3.11803278689, 3.11803278689, 3.13114754098]), index=times
|
|
199
|
-
)
|
|
200
|
-
out = clearsky.lookup_linke_turbidity(times, 32.125, -110.875)
|
|
201
|
-
assert_series_equal(expected, out)
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
def test_lookup_linke_turbidity_leapyear():
|
|
205
|
-
times = pd.date_range(start='2016-06-24', end='2016-06-25',
|
|
206
|
-
freq='12h', tz='America/Phoenix')
|
|
207
|
-
# expect same value on 2016-06-24 0000 and 1200, and
|
|
208
|
-
# diff value on 2016-06-25
|
|
209
|
-
expected = pd.Series(
|
|
210
|
-
np.array([3.11803278689, 3.11803278689, 3.13114754098]), index=times
|
|
211
|
-
)
|
|
212
|
-
out = clearsky.lookup_linke_turbidity(times, 32.125, -110.875)
|
|
213
|
-
assert_series_equal(expected, out)
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
def test_lookup_linke_turbidity_nointerp():
|
|
217
|
-
times = pd.date_range(start='2014-06-24', end='2014-06-25',
|
|
218
|
-
freq='12h', tz='America/Phoenix')
|
|
219
|
-
# expect same value for all days
|
|
220
|
-
expected = pd.Series(np.array([3., 3., 3.]), index=times)
|
|
221
|
-
out = clearsky.lookup_linke_turbidity(times, 32.125, -110.875,
|
|
222
|
-
interp_turbidity=False)
|
|
223
|
-
assert_series_equal(expected, out)
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
def test_lookup_linke_turbidity_months():
|
|
227
|
-
times = pd.date_range(start='2014-04-01', end='2014-07-01',
|
|
228
|
-
freq='1M', tz='America/Phoenix')
|
|
229
|
-
expected = pd.Series(
|
|
230
|
-
np.array([2.89918032787, 2.97540983607, 3.19672131148]), index=times
|
|
231
|
-
)
|
|
232
|
-
out = clearsky.lookup_linke_turbidity(times, 32.125, -110.875)
|
|
233
|
-
assert_series_equal(expected, out)
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
def test_lookup_linke_turbidity_months_leapyear():
|
|
237
|
-
times = pd.date_range(start='2016-04-01', end='2016-07-01',
|
|
238
|
-
freq='1M', tz='America/Phoenix')
|
|
239
|
-
expected = pd.Series(
|
|
240
|
-
np.array([2.89918032787, 2.97540983607, 3.19672131148]), index=times
|
|
241
|
-
)
|
|
242
|
-
out = clearsky.lookup_linke_turbidity(times, 32.125, -110.875)
|
|
243
|
-
assert_series_equal(expected, out)
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
def test_lookup_linke_turbidity_nointerp_months():
|
|
247
|
-
times = pd.date_range(start='2014-04-10', end='2014-07-10',
|
|
248
|
-
freq='1M', tz='America/Phoenix')
|
|
249
|
-
expected = pd.Series(np.array([2.85, 2.95, 3.]), index=times)
|
|
250
|
-
out = clearsky.lookup_linke_turbidity(times, 32.125, -110.875,
|
|
251
|
-
interp_turbidity=False)
|
|
252
|
-
assert_series_equal(expected, out)
|
|
253
|
-
# changing the dates shouldn't matter if interp=False
|
|
254
|
-
times = pd.date_range(start='2014-04-05', end='2014-07-05',
|
|
255
|
-
freq='1M', tz='America/Phoenix')
|
|
256
|
-
out = clearsky.lookup_linke_turbidity(times, 32.125, -110.875,
|
|
257
|
-
interp_turbidity=False)
|
|
258
|
-
assert_series_equal(expected, out)
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
def test_haurwitz():
|
|
262
|
-
apparent_solar_elevation = np.array([-20, -0.05, -0.001, 5, 10, 30, 50, 90])
|
|
263
|
-
apparent_solar_zenith = 90 - apparent_solar_elevation
|
|
264
|
-
data_in = pd.DataFrame(data=apparent_solar_zenith,
|
|
265
|
-
index=apparent_solar_zenith,
|
|
266
|
-
columns=['apparent_zenith'])
|
|
267
|
-
expected = pd.DataFrame(np.array([0.,
|
|
268
|
-
0.,
|
|
269
|
-
0.,
|
|
270
|
-
48.6298687941956,
|
|
271
|
-
135.741748091813,
|
|
272
|
-
487.894132885425,
|
|
273
|
-
778.766689344363,
|
|
274
|
-
1035.09203253450]),
|
|
275
|
-
columns=['ghi'],
|
|
276
|
-
index=apparent_solar_zenith)
|
|
277
|
-
out = clearsky.haurwitz(data_in['apparent_zenith'])
|
|
278
|
-
assert_frame_equal(expected, out)
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
def test_simplified_solis_scalar_elevation():
|
|
282
|
-
expected = OrderedDict()
|
|
283
|
-
expected['ghi'] = 1064.653145
|
|
284
|
-
expected['dni'] = 959.335463
|
|
285
|
-
expected['dhi'] = 129.125602
|
|
286
|
-
|
|
287
|
-
out = clearsky.simplified_solis(80)
|
|
288
|
-
for k, v in expected.items():
|
|
289
|
-
assert_allclose(expected[k], out[k])
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
def test_simplified_solis_scalar_neg_elevation():
|
|
293
|
-
expected = OrderedDict()
|
|
294
|
-
expected['ghi'] = 0
|
|
295
|
-
expected['dni'] = 0
|
|
296
|
-
expected['dhi'] = 0
|
|
297
|
-
|
|
298
|
-
out = clearsky.simplified_solis(-10)
|
|
299
|
-
for k, v in expected.items():
|
|
300
|
-
assert_allclose(expected[k], out[k])
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
def test_simplified_solis_series_elevation():
|
|
304
|
-
expected = pd.DataFrame(
|
|
305
|
-
np.array([[959.335463, 1064.653145, 129.125602]]),
|
|
306
|
-
columns=['dni', 'ghi', 'dhi'])
|
|
307
|
-
expected = expected[['ghi', 'dni', 'dhi']]
|
|
308
|
-
|
|
309
|
-
out = clearsky.simplified_solis(pd.Series(80))
|
|
310
|
-
assert_frame_equal(expected, out)
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
def test_simplified_solis_dni_extra():
|
|
314
|
-
expected = pd.DataFrame(np.array([[963.555414, 1069.33637, 129.693603]]),
|
|
315
|
-
columns=['dni', 'ghi', 'dhi'])
|
|
316
|
-
expected = expected[['ghi', 'dni', 'dhi']]
|
|
317
|
-
|
|
318
|
-
out = clearsky.simplified_solis(80, dni_extra=pd.Series(1370))
|
|
319
|
-
assert_frame_equal(expected, out)
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
def test_simplified_solis_pressure():
|
|
323
|
-
expected = pd.DataFrame(np.
|
|
324
|
-
array([[ 964.26930718, 1067.96543669, 127.22841797],
|
|
325
|
-
[ 961.88811874, 1066.36847963, 128.1402539 ],
|
|
326
|
-
[ 959.58112234, 1064.81837558, 129.0304193 ]]),
|
|
327
|
-
columns=['dni', 'ghi', 'dhi'])
|
|
328
|
-
expected = expected[['ghi', 'dni', 'dhi']]
|
|
329
|
-
|
|
330
|
-
out = clearsky.simplified_solis(
|
|
331
|
-
80, pressure=pd.Series([95000, 98000, 101000]))
|
|
332
|
-
assert_frame_equal(expected, out)
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
def test_simplified_solis_aod700():
|
|
336
|
-
expected = pd.DataFrame(np.
|
|
337
|
-
array([[ 1056.61710493, 1105.7229086 , 64.41747323],
|
|
338
|
-
[ 1007.50558875, 1085.74139063, 102.96233698],
|
|
339
|
-
[ 959.3354628 , 1064.65314509, 129.12560167],
|
|
340
|
-
[ 342.45810926, 638.63409683, 77.71786575],
|
|
341
|
-
[ 55.24140911, 7.5413313 , 0. ]]),
|
|
342
|
-
columns=['dni', 'ghi', 'dhi'])
|
|
343
|
-
expected = expected[['ghi', 'dni', 'dhi']]
|
|
344
|
-
|
|
345
|
-
aod700 = pd.Series([0.0, 0.05, 0.1, 1, 10])
|
|
346
|
-
out = clearsky.simplified_solis(80, aod700=aod700)
|
|
347
|
-
assert_frame_equal(expected, out)
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
def test_simplified_solis_precipitable_water():
|
|
351
|
-
expected = pd.DataFrame(np.
|
|
352
|
-
array([[ 1001.15353307, 1107.84678941, 128.58887606],
|
|
353
|
-
[ 1001.15353307, 1107.84678941, 128.58887606],
|
|
354
|
-
[ 983.51027357, 1089.62306672, 129.08755996],
|
|
355
|
-
[ 959.3354628 , 1064.65314509, 129.12560167],
|
|
356
|
-
[ 872.02335029, 974.18046717, 125.63581346]]),
|
|
357
|
-
columns=['dni', 'ghi', 'dhi'])
|
|
358
|
-
expected = expected[['ghi', 'dni', 'dhi']]
|
|
359
|
-
|
|
360
|
-
out = clearsky.simplified_solis(
|
|
361
|
-
80, precipitable_water=pd.Series([0.0, 0.2, 0.5, 1.0, 5.0]))
|
|
362
|
-
assert_frame_equal(expected, out)
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
def test_simplified_solis_small_scalar_pw():
|
|
366
|
-
|
|
367
|
-
expected = OrderedDict()
|
|
368
|
-
expected['ghi'] = 1107.84678941
|
|
369
|
-
expected['dni'] = 1001.15353307
|
|
370
|
-
expected['dhi'] = 128.58887606
|
|
371
|
-
|
|
372
|
-
out = clearsky.simplified_solis(80, precipitable_water=0.1)
|
|
373
|
-
for k, v in expected.items():
|
|
374
|
-
assert_allclose(expected[k], out[k])
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
def test_simplified_solis_return_arrays():
|
|
378
|
-
expected = OrderedDict()
|
|
379
|
-
|
|
380
|
-
expected['ghi'] = np.array([[ 1148.40081325, 913.42330823],
|
|
381
|
-
[ 965.48550828, 760.04527609]])
|
|
382
|
-
|
|
383
|
-
expected['dni'] = np.array([[ 1099.25706525, 656.24601381],
|
|
384
|
-
[ 915.31689149, 530.31697378]])
|
|
385
|
-
|
|
386
|
-
expected['dhi'] = np.array([[ 64.1063074 , 254.6186615 ],
|
|
387
|
-
[ 62.75642216, 232.21931597]])
|
|
388
|
-
|
|
389
|
-
aod700 = np.linspace(0, 0.5, 2)
|
|
390
|
-
precipitable_water = np.linspace(0, 10, 2)
|
|
391
|
-
|
|
392
|
-
aod700, precipitable_water = np.meshgrid(aod700, precipitable_water)
|
|
393
|
-
|
|
394
|
-
out = clearsky.simplified_solis(80, aod700, precipitable_water)
|
|
395
|
-
|
|
396
|
-
for k, v in expected.items():
|
|
397
|
-
assert_allclose(expected[k], out[k])
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
def test_simplified_solis_nans_arrays():
|
|
401
|
-
|
|
402
|
-
# construct input arrays that each have 1 nan offset from each other,
|
|
403
|
-
# the last point is valid for all arrays
|
|
404
|
-
|
|
405
|
-
length = 6
|
|
406
|
-
|
|
407
|
-
apparent_elevation = np.full(length, 80.)
|
|
408
|
-
apparent_elevation[0] = np.nan
|
|
409
|
-
|
|
410
|
-
aod700 = np.full(length, 0.1)
|
|
411
|
-
aod700[1] = np.nan
|
|
412
|
-
|
|
413
|
-
precipitable_water = np.full(length, 0.5)
|
|
414
|
-
precipitable_water[2] = np.nan
|
|
415
|
-
|
|
416
|
-
pressure = np.full(length, 98000.)
|
|
417
|
-
pressure[3] = np.nan
|
|
418
|
-
|
|
419
|
-
dni_extra = np.full(length, 1370.)
|
|
420
|
-
dni_extra[4] = np.nan
|
|
421
|
-
|
|
422
|
-
expected = OrderedDict()
|
|
423
|
-
expected['ghi'] = np.full(length, np.nan)
|
|
424
|
-
expected['dni'] = np.full(length, np.nan)
|
|
425
|
-
expected['dhi'] = np.full(length, np.nan)
|
|
426
|
-
|
|
427
|
-
expected['ghi'][length-1] = 1096.022736
|
|
428
|
-
expected['dni'][length-1] = 990.306854
|
|
429
|
-
expected['dhi'][length-1] = 128.664594
|
|
430
|
-
|
|
431
|
-
out = clearsky.simplified_solis(apparent_elevation, aod700,
|
|
432
|
-
precipitable_water, pressure, dni_extra)
|
|
433
|
-
|
|
434
|
-
for k, v in expected.items():
|
|
435
|
-
assert_allclose(expected[k], out[k])
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
def test_simplified_solis_nans_series():
|
|
439
|
-
|
|
440
|
-
# construct input arrays that each have 1 nan offset from each other,
|
|
441
|
-
# the last point is valid for all arrays
|
|
442
|
-
|
|
443
|
-
length = 6
|
|
444
|
-
|
|
445
|
-
apparent_elevation = pd.Series(np.full(length, 80.))
|
|
446
|
-
apparent_elevation[0] = np.nan
|
|
447
|
-
|
|
448
|
-
aod700 = np.full(length, 0.1)
|
|
449
|
-
aod700[1] = np.nan
|
|
450
|
-
|
|
451
|
-
precipitable_water = np.full(length, 0.5)
|
|
452
|
-
precipitable_water[2] = np.nan
|
|
453
|
-
|
|
454
|
-
pressure = np.full(length, 98000.)
|
|
455
|
-
pressure[3] = np.nan
|
|
456
|
-
|
|
457
|
-
dni_extra = np.full(length, 1370.)
|
|
458
|
-
dni_extra[4] = np.nan
|
|
459
|
-
|
|
460
|
-
expected = OrderedDict()
|
|
461
|
-
expected['ghi'] = np.full(length, np.nan)
|
|
462
|
-
expected['dni'] = np.full(length, np.nan)
|
|
463
|
-
expected['dhi'] = np.full(length, np.nan)
|
|
464
|
-
|
|
465
|
-
expected['ghi'][length-1] = 1096.022736
|
|
466
|
-
expected['dni'][length-1] = 990.306854
|
|
467
|
-
expected['dhi'][length-1] = 128.664594
|
|
468
|
-
|
|
469
|
-
expected = pd.DataFrame.from_dict(expected)
|
|
470
|
-
|
|
471
|
-
out = clearsky.simplified_solis(apparent_elevation, aod700,
|
|
472
|
-
precipitable_water, pressure, dni_extra)
|
|
473
|
-
|
|
474
|
-
assert_frame_equal(expected, out)
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
def test_linke_turbidity_corners():
|
|
478
|
-
"""Test Linke turbidity corners out of bounds."""
|
|
479
|
-
months = pd.DatetimeIndex('%d/1/2016' % (m + 1) for m in range(12))
|
|
480
|
-
|
|
481
|
-
def monthly_lt_nointerp(lat, lon, time=months):
|
|
482
|
-
"""monthly Linke turbidity factor without time interpolation"""
|
|
483
|
-
return clearsky.lookup_linke_turbidity(
|
|
484
|
-
time, lat, lon, interp_turbidity=False
|
|
485
|
-
)
|
|
486
|
-
|
|
487
|
-
# Northwest
|
|
488
|
-
assert np.allclose(
|
|
489
|
-
monthly_lt_nointerp(90, -180),
|
|
490
|
-
[1.9, 1.9, 1.9, 2.0, 2.05, 2.05, 2.1, 2.1, 2.0, 1.95, 1.9, 1.9])
|
|
491
|
-
# Southwest
|
|
492
|
-
assert np.allclose(
|
|
493
|
-
monthly_lt_nointerp(-90, -180),
|
|
494
|
-
[1.35, 1.3, 1.45, 1.35, 1.35, 1.35, 1.35, 1.35, 1.35, 1.4, 1.4, 1.3])
|
|
495
|
-
# Northeast
|
|
496
|
-
assert np.allclose(
|
|
497
|
-
monthly_lt_nointerp(90, 180),
|
|
498
|
-
[1.9, 1.9, 1.9, 2.0, 2.05, 2.05, 2.1, 2.1, 2.0, 1.95, 1.9, 1.9])
|
|
499
|
-
# Southeast
|
|
500
|
-
assert np.allclose(
|
|
501
|
-
monthly_lt_nointerp(-90, 180),
|
|
502
|
-
[1.35, 1.7, 1.35, 1.35, 1.35, 1.35, 1.35, 1.35, 1.35, 1.35, 1.35, 1.7])
|
|
503
|
-
# test out of range exceptions at corners
|
|
504
|
-
with pytest.raises(IndexError):
|
|
505
|
-
monthly_lt_nointerp(91, -122) # exceeds max latitude
|
|
506
|
-
with pytest.raises(IndexError):
|
|
507
|
-
monthly_lt_nointerp(38.2, 181) # exceeds max longitude
|
|
508
|
-
with pytest.raises(IndexError):
|
|
509
|
-
monthly_lt_nointerp(-91, -122) # exceeds min latitude
|
|
510
|
-
with pytest.raises(IndexError):
|
|
511
|
-
monthly_lt_nointerp(38.2, -181) # exceeds min longitude
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
@pytest.fixture
|
|
515
|
-
def detect_clearsky_data():
|
|
516
|
-
data_file = DATA_DIR / 'detect_clearsky_data.csv'
|
|
517
|
-
expected = pd.read_csv(
|
|
518
|
-
data_file, index_col=0, parse_dates=True, comment='#')
|
|
519
|
-
expected = expected.tz_localize('UTC').tz_convert('Etc/GMT+7')
|
|
520
|
-
metadata = {}
|
|
521
|
-
with data_file.open() as f:
|
|
522
|
-
for line in f:
|
|
523
|
-
if line.startswith('#'):
|
|
524
|
-
key, value = line.strip('# \n').split(':')
|
|
525
|
-
metadata[key] = float(value)
|
|
526
|
-
else:
|
|
527
|
-
break
|
|
528
|
-
metadata['window_length'] = int(metadata['window_length'])
|
|
529
|
-
loc = Location(metadata['latitude'], metadata['longitude'],
|
|
530
|
-
altitude=metadata['elevation'])
|
|
531
|
-
# specify turbidity to guard against future lookup changes
|
|
532
|
-
cs = loc.get_clearsky(expected.index, linke_turbidity=2.658197)
|
|
533
|
-
return expected, cs
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
@pytest.fixture
|
|
537
|
-
def detect_clearsky_threshold_data():
|
|
538
|
-
# this is (roughly) just a 2 hour period of the same data in
|
|
539
|
-
# detect_clearsky_data (which only spans 30 minutes)
|
|
540
|
-
data_file = DATA_DIR / 'detect_clearsky_threshold_data.csv'
|
|
541
|
-
expected = pd.read_csv(
|
|
542
|
-
data_file, index_col=0, parse_dates=True, comment='#')
|
|
543
|
-
expected = expected.tz_localize('UTC').tz_convert('Etc/GMT+7')
|
|
544
|
-
metadata = {}
|
|
545
|
-
with data_file.open() as f:
|
|
546
|
-
for line in f:
|
|
547
|
-
if line.startswith('#'):
|
|
548
|
-
key, value = line.strip('# \n').split(':')
|
|
549
|
-
metadata[key] = float(value)
|
|
550
|
-
else:
|
|
551
|
-
break
|
|
552
|
-
metadata['window_length'] = int(metadata['window_length'])
|
|
553
|
-
loc = Location(metadata['latitude'], metadata['longitude'],
|
|
554
|
-
altitude=metadata['elevation'])
|
|
555
|
-
# specify turbidity to guard against future lookup changes
|
|
556
|
-
cs = loc.get_clearsky(expected.index, linke_turbidity=2.658197)
|
|
557
|
-
return expected, cs
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
def test_clearsky_get_threshold():
|
|
561
|
-
out = clearsky._clearsky_get_threshold(4.5)
|
|
562
|
-
expected = (58.75, 75, 64.375, -45, 80.0, 0.009375, 58.75)
|
|
563
|
-
assert np.allclose(out, expected)
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
def test_clearsky_get_threshold_raises_error():
|
|
567
|
-
with pytest.raises(ValueError, match='can only be used for inputs'):
|
|
568
|
-
clearsky._clearsky_get_threshold(0.5)
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
def test_detect_clearsky_calls_threshold(mocker, detect_clearsky_threshold_data):
|
|
572
|
-
threshold_spy = mocker.spy(clearsky, '_clearsky_get_threshold')
|
|
573
|
-
expected, cs = detect_clearsky_threshold_data
|
|
574
|
-
threshold_actual = clearsky.detect_clearsky(expected['GHI'], cs['ghi'],
|
|
575
|
-
infer_limits=True)
|
|
576
|
-
assert threshold_spy.call_count == 1
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
def test_detect_clearsky(detect_clearsky_data):
|
|
580
|
-
expected, cs = detect_clearsky_data
|
|
581
|
-
clear_samples = clearsky.detect_clearsky(
|
|
582
|
-
expected['GHI'], cs['ghi'], times=cs.index, window_length=10)
|
|
583
|
-
assert_series_equal(expected['Clear or not'], clear_samples,
|
|
584
|
-
check_dtype=False, check_names=False)
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
def test_detect_clearsky_defaults(detect_clearsky_data):
|
|
588
|
-
expected, cs = detect_clearsky_data
|
|
589
|
-
clear_samples = clearsky.detect_clearsky(
|
|
590
|
-
expected['GHI'], cs['ghi'])
|
|
591
|
-
assert_series_equal(expected['Clear or not'], clear_samples,
|
|
592
|
-
check_dtype=False, check_names=False)
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
def test_detect_clearsky_components(detect_clearsky_data):
|
|
596
|
-
expected, cs = detect_clearsky_data
|
|
597
|
-
clear_samples, components, alpha = clearsky.detect_clearsky(
|
|
598
|
-
expected['GHI'], cs['ghi'], times=cs.index, window_length=10,
|
|
599
|
-
return_components=True)
|
|
600
|
-
assert_series_equal(expected['Clear or not'], clear_samples,
|
|
601
|
-
check_dtype=False, check_names=False)
|
|
602
|
-
assert isinstance(components, OrderedDict)
|
|
603
|
-
assert np.allclose(alpha, 0.9633903181941296)
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
def test_detect_clearsky_iterations(detect_clearsky_data):
|
|
607
|
-
expected, cs = detect_clearsky_data
|
|
608
|
-
alpha = 1.0448
|
|
609
|
-
with pytest.warns(RuntimeWarning):
|
|
610
|
-
clear_samples = clearsky.detect_clearsky(
|
|
611
|
-
expected['GHI'], cs['ghi']*alpha, max_iterations=1)
|
|
612
|
-
assert clear_samples[:'2012-04-01 10:41:00'].all()
|
|
613
|
-
assert not clear_samples['2012-04-01 10:42:00':].any() # expected False
|
|
614
|
-
clear_samples = clearsky.detect_clearsky(
|
|
615
|
-
expected['GHI'], cs['ghi']*alpha, max_iterations=20)
|
|
616
|
-
assert_series_equal(expected['Clear or not'], clear_samples,
|
|
617
|
-
check_dtype=False, check_names=False)
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
def test_detect_clearsky_kwargs(detect_clearsky_data):
|
|
621
|
-
expected, cs = detect_clearsky_data
|
|
622
|
-
clear_samples = clearsky.detect_clearsky(
|
|
623
|
-
expected['GHI'], cs['ghi'], times=cs.index, window_length=10,
|
|
624
|
-
mean_diff=1000, max_diff=1000, lower_line_length=-1000,
|
|
625
|
-
upper_line_length=1000, var_diff=10, slope_dev=1000)
|
|
626
|
-
assert clear_samples.all()
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
def test_detect_clearsky_window(detect_clearsky_data):
|
|
630
|
-
expected, cs = detect_clearsky_data
|
|
631
|
-
clear_samples = clearsky.detect_clearsky(
|
|
632
|
-
expected['GHI'], cs['ghi'], window_length=3)
|
|
633
|
-
expected = expected['Clear or not'].copy()
|
|
634
|
-
expected.iloc[-3:] = 1
|
|
635
|
-
assert_series_equal(expected, clear_samples,
|
|
636
|
-
check_dtype=False, check_names=False)
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
def test_detect_clearsky_time_interval(detect_clearsky_data):
|
|
640
|
-
expected, cs = detect_clearsky_data
|
|
641
|
-
u = np.arange(0, len(cs), 2)
|
|
642
|
-
cs2 = cs.iloc[u]
|
|
643
|
-
expected2 = expected.iloc[u]
|
|
644
|
-
clear_samples = clearsky.detect_clearsky(
|
|
645
|
-
expected2['GHI'], cs2['ghi'], window_length=6)
|
|
646
|
-
assert_series_equal(expected2['Clear or not'], clear_samples,
|
|
647
|
-
check_dtype=False, check_names=False)
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
def test_detect_clearsky_arrays(detect_clearsky_data):
|
|
651
|
-
expected, cs = detect_clearsky_data
|
|
652
|
-
clear_samples = clearsky.detect_clearsky(
|
|
653
|
-
expected['GHI'].values, cs['ghi'].values, times=cs.index,
|
|
654
|
-
window_length=10)
|
|
655
|
-
assert isinstance(clear_samples, np.ndarray)
|
|
656
|
-
assert (clear_samples == expected['Clear or not'].values).all()
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
def test_detect_clearsky_irregular_times(detect_clearsky_data):
|
|
660
|
-
expected, cs = detect_clearsky_data
|
|
661
|
-
times = cs.index.values.copy()
|
|
662
|
-
times[0] += 10**9
|
|
663
|
-
times = pd.DatetimeIndex(times)
|
|
664
|
-
with pytest.raises(NotImplementedError):
|
|
665
|
-
clearsky.detect_clearsky(expected['GHI'].values, cs['ghi'].values,
|
|
666
|
-
times, 10)
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
def test_detect_clearsky_missing_index(detect_clearsky_data):
|
|
670
|
-
expected, cs = detect_clearsky_data
|
|
671
|
-
with pytest.raises(ValueError):
|
|
672
|
-
clearsky.detect_clearsky(expected['GHI'].values, cs['ghi'].values)
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
def test_detect_clearsky_not_enough_data(detect_clearsky_data):
|
|
676
|
-
expected, cs = detect_clearsky_data
|
|
677
|
-
with pytest.raises(ValueError, match='times has only'):
|
|
678
|
-
clearsky.detect_clearsky(expected['GHI'], cs['ghi'], window_length=60)
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
def test_detect_clearsky_window_too_short(detect_clearsky_data):
|
|
682
|
-
expected, cs = detect_clearsky_data
|
|
683
|
-
with pytest.raises(ValueError, match="Samples per window of "):
|
|
684
|
-
clearsky.detect_clearsky(expected['GHI'], cs['ghi'], window_length=2)
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
@pytest.mark.parametrize("window_length", [5, 10, 15, 20, 25])
|
|
688
|
-
def test_detect_clearsky_optimizer_not_failed(
|
|
689
|
-
detect_clearsky_data, window_length
|
|
690
|
-
):
|
|
691
|
-
expected, cs = detect_clearsky_data
|
|
692
|
-
clear_samples = clearsky.detect_clearsky(
|
|
693
|
-
expected["GHI"], cs["ghi"], window_length=window_length
|
|
694
|
-
)
|
|
695
|
-
assert isinstance(clear_samples, pd.Series)
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
@pytest.fixture
|
|
699
|
-
def detect_clearsky_helper_data():
|
|
700
|
-
samples_per_window = 3
|
|
701
|
-
sample_interval = 1
|
|
702
|
-
x = pd.Series(np.arange(0, 7)**2.)
|
|
703
|
-
# line length between adjacent points
|
|
704
|
-
sqt = pd.Series(np.sqrt(np.array([np.nan, 2., 10., 26., 50., 82, 122.])))
|
|
705
|
-
H = hankel(np.arange(samples_per_window),
|
|
706
|
-
np.arange(samples_per_window-1, len(sqt)))
|
|
707
|
-
return x, samples_per_window, sample_interval, H
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
def test__line_length_windowed(detect_clearsky_helper_data):
|
|
711
|
-
x, samples_per_window, sample_interval, H = detect_clearsky_helper_data
|
|
712
|
-
# sqt is hand-calculated assuming window=3
|
|
713
|
-
# line length between adjacent points
|
|
714
|
-
sqt = pd.Series(np.sqrt(np.array([np.nan, 2., 10., 26., 50., 82, 122.])))
|
|
715
|
-
expected = {}
|
|
716
|
-
expected['line_length'] = sqt + sqt.shift(-1)
|
|
717
|
-
result = clearsky._line_length_windowed(
|
|
718
|
-
x, H, samples_per_window, sample_interval)
|
|
719
|
-
assert_series_equal(result, expected['line_length'])
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
def test__max_diff_windowed(detect_clearsky_helper_data):
|
|
723
|
-
x, samples_per_window, sample_interval, H = detect_clearsky_helper_data
|
|
724
|
-
expected = {}
|
|
725
|
-
expected['max_diff'] = pd.Series(
|
|
726
|
-
data=[np.nan, 3., 5., 7., 9., 11., np.nan], index=x.index)
|
|
727
|
-
result = clearsky._max_diff_windowed(x, H, samples_per_window)
|
|
728
|
-
assert_series_equal(result, expected['max_diff'])
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
def test__calc_stats(detect_clearsky_helper_data):
|
|
732
|
-
x, samples_per_window, sample_interval, H = detect_clearsky_helper_data
|
|
733
|
-
# stats are hand-computed assuming window = 3, sample_interval = 1,
|
|
734
|
-
# and right-aligned labels
|
|
735
|
-
mean_x = pd.Series(np.array([np.nan, np.nan, 5, 14, 29, 50, 77]) / 3.)
|
|
736
|
-
max_x = pd.Series(np.array([np.nan, np.nan, 4, 9, 16, 25, 36]))
|
|
737
|
-
diff_std = np.array([np.nan, np.nan, np.sqrt(2), np.sqrt(2), np.sqrt(2),
|
|
738
|
-
np.sqrt(2), np.sqrt(2)])
|
|
739
|
-
slope_nstd = diff_std / mean_x
|
|
740
|
-
slope = x.diff().shift(-1)
|
|
741
|
-
expected = {}
|
|
742
|
-
expected['mean'] = mean_x.shift(-1) # shift to align to center
|
|
743
|
-
expected['max'] = max_x.shift(-1)
|
|
744
|
-
# slope between adjacent points
|
|
745
|
-
expected['slope'] = slope
|
|
746
|
-
expected['slope_nstd'] = slope_nstd.shift(-1)
|
|
747
|
-
result = clearsky._calc_stats(
|
|
748
|
-
x, samples_per_window, sample_interval, H)
|
|
749
|
-
res_mean, res_max, res_slope_nstd, res_slope = result
|
|
750
|
-
assert_series_equal(res_mean, expected['mean'])
|
|
751
|
-
assert_series_equal(res_max, expected['max'])
|
|
752
|
-
assert_series_equal(res_slope_nstd, expected['slope_nstd'])
|
|
753
|
-
assert_series_equal(res_slope, expected['slope'])
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
def test_bird():
|
|
757
|
-
"""Test Bird/Hulstrom Clearsky Model"""
|
|
758
|
-
times = pd.date_range(start='1/1/2015 0:00', end='12/31/2015 23:00',
|
|
759
|
-
freq='h')
|
|
760
|
-
tz = -7 # test timezone
|
|
761
|
-
gmt_tz = pytz.timezone('Etc/GMT%+d' % -(tz))
|
|
762
|
-
times = times.tz_localize(gmt_tz) # set timezone
|
|
763
|
-
times_utc = times.tz_convert('UTC')
|
|
764
|
-
# match test data from BIRD_08_16_2012.xls
|
|
765
|
-
latitude = 40.
|
|
766
|
-
longitude = -105.
|
|
767
|
-
press_mB = 840.
|
|
768
|
-
o3_cm = 0.3
|
|
769
|
-
h2o_cm = 1.5
|
|
770
|
-
aod_500nm = 0.1
|
|
771
|
-
aod_380nm = 0.15
|
|
772
|
-
b_a = 0.85
|
|
773
|
-
alb = 0.2
|
|
774
|
-
eot = solarposition.equation_of_time_spencer71(times_utc.dayofyear)
|
|
775
|
-
hour_angle = solarposition.hour_angle(times, longitude, eot) - 0.5 * 15.
|
|
776
|
-
declination = solarposition.declination_spencer71(times_utc.dayofyear)
|
|
777
|
-
zenith = solarposition.solar_zenith_analytical(
|
|
778
|
-
np.deg2rad(latitude), np.deg2rad(hour_angle), declination
|
|
779
|
-
)
|
|
780
|
-
zenith = np.rad2deg(zenith)
|
|
781
|
-
airmass = atmosphere.get_relative_airmass(zenith, model='kasten1966')
|
|
782
|
-
etr = irradiance.get_extra_radiation(times)
|
|
783
|
-
# test Bird with time series data
|
|
784
|
-
field_names = ('dni', 'direct_horizontal', 'ghi', 'dhi')
|
|
785
|
-
irrads = clearsky.bird(
|
|
786
|
-
zenith, airmass, aod_380nm, aod_500nm, h2o_cm, o3_cm, press_mB * 100.,
|
|
787
|
-
etr, b_a, alb
|
|
788
|
-
)
|
|
789
|
-
Eb, Ebh, Gh, Dh = (irrads[_] for _ in field_names)
|
|
790
|
-
data_path = DATA_DIR / 'BIRD_08_16_2012.csv'
|
|
791
|
-
testdata = pd.read_csv(data_path, usecols=range(1, 26), header=1).dropna()
|
|
792
|
-
testdata[['DEC', 'EQT']] = testdata[['DEC', 'EQT']].shift(tz)
|
|
793
|
-
testdata = testdata[:tz]
|
|
794
|
-
end = 48 + tz
|
|
795
|
-
testdata.index = times[1:end]
|
|
796
|
-
assert np.allclose(testdata['DEC'], np.rad2deg(declination[1:end]))
|
|
797
|
-
assert np.allclose(testdata['EQT'], eot[1:end], rtol=1e-4)
|
|
798
|
-
assert np.allclose(testdata['Hour Angle'], hour_angle[1:end], rtol=1e-2)
|
|
799
|
-
assert np.allclose(testdata['Zenith Ang'], zenith[1:end], rtol=1e-2)
|
|
800
|
-
dawn = zenith < 88.
|
|
801
|
-
dusk = testdata['Zenith Ang'] < 88.
|
|
802
|
-
am = pd.Series(np.where(dawn, airmass, 0.), index=times).fillna(0.0)
|
|
803
|
-
assert np.allclose(
|
|
804
|
-
testdata['Air Mass'].where(dusk, 0.), am[1:end], rtol=1e-3
|
|
805
|
-
)
|
|
806
|
-
direct_beam = pd.Series(np.where(dawn, Eb, 0.), index=times).fillna(0.)
|
|
807
|
-
assert np.allclose(
|
|
808
|
-
testdata['Direct Beam'].where(dusk, 0.), direct_beam[1:end], rtol=1e-3
|
|
809
|
-
)
|
|
810
|
-
direct_horz = pd.Series(np.where(dawn, Ebh, 0.), index=times).fillna(0.)
|
|
811
|
-
assert np.allclose(
|
|
812
|
-
testdata['Direct Hz'].where(dusk, 0.), direct_horz[1:end], rtol=1e-3
|
|
813
|
-
)
|
|
814
|
-
global_horz = pd.Series(np.where(dawn, Gh, 0.), index=times).fillna(0.)
|
|
815
|
-
assert np.allclose(
|
|
816
|
-
testdata['Global Hz'].where(dusk, 0.), global_horz[1:end], rtol=1e-3
|
|
817
|
-
)
|
|
818
|
-
diffuse_horz = pd.Series(np.where(dawn, Dh, 0.), index=times).fillna(0.)
|
|
819
|
-
assert np.allclose(
|
|
820
|
-
testdata['Dif Hz'].where(dusk, 0.), diffuse_horz[1:end], rtol=1e-3
|
|
821
|
-
)
|
|
822
|
-
# repeat test with albedo as a Series
|
|
823
|
-
alb_series = pd.Series(0.2, index=times)
|
|
824
|
-
irrads = clearsky.bird(
|
|
825
|
-
zenith, airmass, aod_380nm, aod_500nm, h2o_cm, o3_cm, press_mB * 100.,
|
|
826
|
-
etr, b_a, alb_series
|
|
827
|
-
)
|
|
828
|
-
Eb, Ebh, Gh, Dh = (irrads[_] for _ in field_names)
|
|
829
|
-
direct_beam = pd.Series(np.where(dawn, Eb, 0.), index=times).fillna(0.)
|
|
830
|
-
assert np.allclose(
|
|
831
|
-
testdata['Direct Beam'].where(dusk, 0.), direct_beam[1:end], rtol=1e-3
|
|
832
|
-
)
|
|
833
|
-
direct_horz = pd.Series(np.where(dawn, Ebh, 0.), index=times).fillna(0.)
|
|
834
|
-
assert np.allclose(
|
|
835
|
-
testdata['Direct Hz'].where(dusk, 0.), direct_horz[1:end], rtol=1e-3
|
|
836
|
-
)
|
|
837
|
-
global_horz = pd.Series(np.where(dawn, Gh, 0.), index=times).fillna(0.)
|
|
838
|
-
assert np.allclose(
|
|
839
|
-
testdata['Global Hz'].where(dusk, 0.), global_horz[1:end], rtol=1e-3
|
|
840
|
-
)
|
|
841
|
-
diffuse_horz = pd.Series(np.where(dawn, Dh, 0.), index=times).fillna(0.)
|
|
842
|
-
assert np.allclose(
|
|
843
|
-
testdata['Dif Hz'].where(dusk, 0.), diffuse_horz[1:end], rtol=1e-3
|
|
844
|
-
)
|
|
845
|
-
|
|
846
|
-
# test keyword parameters
|
|
847
|
-
irrads2 = clearsky.bird(
|
|
848
|
-
zenith, airmass, aod_380nm, aod_500nm, h2o_cm, dni_extra=etr
|
|
849
|
-
)
|
|
850
|
-
Eb2, Ebh2, Gh2, Dh2 = (irrads2[_] for _ in field_names)
|
|
851
|
-
data_path = DATA_DIR / 'BIRD_08_16_2012_patm.csv'
|
|
852
|
-
testdata2 = pd.read_csv(data_path, usecols=range(1, 26), header=1).dropna()
|
|
853
|
-
testdata2[['DEC', 'EQT']] = testdata2[['DEC', 'EQT']].shift(tz)
|
|
854
|
-
testdata2 = testdata2[:tz]
|
|
855
|
-
testdata2.index = times[1:end]
|
|
856
|
-
direct_beam2 = pd.Series(np.where(dawn, Eb2, 0.), index=times).fillna(0.)
|
|
857
|
-
assert np.allclose(
|
|
858
|
-
testdata2['Direct Beam'].where(dusk, 0.), direct_beam2[1:end],
|
|
859
|
-
rtol=1e-3
|
|
860
|
-
)
|
|
861
|
-
direct_horz2 = pd.Series(np.where(dawn, Ebh2, 0.), index=times).fillna(0.)
|
|
862
|
-
assert np.allclose(
|
|
863
|
-
testdata2['Direct Hz'].where(dusk, 0.), direct_horz2[1:end], rtol=1e-3
|
|
864
|
-
)
|
|
865
|
-
global_horz2 = pd.Series(np.where(dawn, Gh2, 0.), index=times).fillna(0.)
|
|
866
|
-
assert np.allclose(
|
|
867
|
-
testdata2['Global Hz'].where(dusk, 0.), global_horz2[1:end], rtol=1e-3
|
|
868
|
-
)
|
|
869
|
-
diffuse_horz2 = pd.Series(np.where(dawn, Dh2, 0.), index=times).fillna(0.)
|
|
870
|
-
assert np.allclose(
|
|
871
|
-
testdata2['Dif Hz'].where(dusk, 0.), diffuse_horz2[1:end], rtol=1e-3
|
|
872
|
-
)
|
|
873
|
-
# test scalars just at noon
|
|
874
|
-
# XXX: calculations start at 12am so noon is at index = 12
|
|
875
|
-
irrads3 = clearsky.bird(
|
|
876
|
-
zenith[12], airmass[12], aod_380nm, aod_500nm, h2o_cm,
|
|
877
|
-
dni_extra=etr.iloc[12]
|
|
878
|
-
)
|
|
879
|
-
Eb3, Ebh3, Gh3, Dh3 = (irrads3[_] for _ in field_names)
|
|
880
|
-
# XXX: testdata starts at 1am so noon is at index = 11
|
|
881
|
-
np.allclose(
|
|
882
|
-
[Eb3, Ebh3, Gh3, Dh3],
|
|
883
|
-
testdata2[['Direct Beam', 'Direct Hz', 'Global Hz', 'Dif Hz']].iloc[11],
|
|
884
|
-
rtol=1e-3)
|