pvlib 0.11.1__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/_deprecation.py +73 -0
- pvlib/atmosphere.py +77 -7
- pvlib/bifacial/infinite_sheds.py +4 -3
- pvlib/bifacial/utils.py +2 -1
- pvlib/clearsky.py +35 -22
- pvlib/iam.py +4 -4
- pvlib/iotools/midc.py +1 -1
- pvlib/iotools/psm3.py +1 -1
- pvlib/iotools/pvgis.py +10 -12
- pvlib/iotools/tmy.py +3 -69
- pvlib/irradiance.py +112 -55
- pvlib/ivtools/sdm.py +75 -52
- pvlib/location.py +73 -33
- pvlib/modelchain.py +18 -35
- pvlib/pvsystem.py +139 -94
- pvlib/snow.py +64 -28
- pvlib/solarposition.py +46 -30
- pvlib/spa.py +4 -2
- pvlib/spectrum/__init__.py +0 -1
- pvlib/spectrum/irradiance.py +2 -64
- pvlib/spectrum/mismatch.py +3 -3
- pvlib/spectrum/spectrl2.py +2 -1
- pvlib/temperature.py +49 -3
- pvlib/tools.py +6 -5
- {pvlib-0.11.1.dist-info → pvlib-0.12.0.dist-info}/METADATA +14 -11
- pvlib-0.12.0.dist-info/RECORD +75 -0
- {pvlib-0.11.1.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/aod550_tcwv_20121101_test.nc +0 -0
- 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.dat +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_2020.csv +0 -8789
- pvlib/data/tmy_45.000_8.000_2005_2020.epw +0 -8768
- pvlib/data/tmy_45.000_8.000_2005_2020.json +0 -1
- pvlib/data/tmy_45.000_8.000_2005_2020.txt +0 -8761
- pvlib/data/tmy_45.000_8.000_userhorizon.json +0 -1
- pvlib/data/variables_style_rules.csv +0 -56
- 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 -407
- 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_albedo.py +0 -84
- pvlib/tests/test_atmosphere.py +0 -204
- pvlib/tests/test_clearsky.py +0 -878
- pvlib/tests/test_conftest.py +0 -81
- pvlib/tests/test_iam.py +0 -555
- pvlib/tests/test_inverter.py +0 -213
- pvlib/tests/test_irradiance.py +0 -1441
- 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 -2495
- 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 -933
- pvlib/tests/test_spa.py +0 -425
- 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.1.dist-info/RECORD +0 -192
- {pvlib-0.11.1.dist-info → pvlib-0.12.0.dist-info/licenses}/AUTHORS.md +0 -0
- {pvlib-0.11.1.dist-info → pvlib-0.12.0.dist-info/licenses}/LICENSE +0 -0
- {pvlib-0.11.1.dist-info → pvlib-0.12.0.dist-info}/top_level.txt +0 -0
|
@@ -1,644 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
test the pvgis IO tools
|
|
3
|
-
"""
|
|
4
|
-
import json
|
|
5
|
-
import numpy as np
|
|
6
|
-
import pandas as pd
|
|
7
|
-
import io
|
|
8
|
-
import pytest
|
|
9
|
-
import requests
|
|
10
|
-
from pvlib.iotools import get_pvgis_tmy, read_pvgis_tmy
|
|
11
|
-
from pvlib.iotools import get_pvgis_hourly, read_pvgis_hourly
|
|
12
|
-
from pvlib.iotools import get_pvgis_horizon
|
|
13
|
-
from ..conftest import (DATA_DIR, RERUNS, RERUNS_DELAY, assert_frame_equal,
|
|
14
|
-
assert_series_equal)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
# PVGIS Hourly tests
|
|
18
|
-
# The test files are actual files from PVGIS where the data section have been
|
|
19
|
-
# reduced to only a few lines
|
|
20
|
-
testfile_radiation_csv = DATA_DIR / \
|
|
21
|
-
'pvgis_hourly_Timeseries_45.000_8.000_SA_30deg_0deg_2016_2016.csv'
|
|
22
|
-
testfile_pv_json = DATA_DIR / \
|
|
23
|
-
'pvgis_hourly_Timeseries_45.000_8.000_SA2_10kWp_CIS_5_2a_2013_2014.json'
|
|
24
|
-
|
|
25
|
-
index_radiation_csv = \
|
|
26
|
-
pd.date_range('20160101 00:10', freq='1h', periods=14, tz='UTC')
|
|
27
|
-
index_pv_json = \
|
|
28
|
-
pd.date_range('2013-01-01 00:10', freq='1h', periods=10, tz='UTC')
|
|
29
|
-
|
|
30
|
-
columns_radiation_csv = [
|
|
31
|
-
'Gb(i)', 'Gd(i)', 'Gr(i)', 'H_sun', 'T2m', 'WS10m', 'Int']
|
|
32
|
-
columns_radiation_csv_mapped = [
|
|
33
|
-
'poa_direct', 'poa_sky_diffuse', 'poa_ground_diffuse', 'solar_elevation',
|
|
34
|
-
'temp_air', 'wind_speed', 'Int']
|
|
35
|
-
columns_pv_json = [
|
|
36
|
-
'P', 'G(i)', 'H_sun', 'T2m', 'WS10m', 'Int']
|
|
37
|
-
columns_pv_json_mapped = [
|
|
38
|
-
'P', 'poa_global', 'solar_elevation', 'temp_air', 'wind_speed', 'Int']
|
|
39
|
-
|
|
40
|
-
data_radiation_csv = [
|
|
41
|
-
[0.0, 0.0, 0.0, 0.0, 3.44, 1.43, 0.0],
|
|
42
|
-
[0.0, 0.0, 0.0, 0.0, 2.94, 1.47, 0.0],
|
|
43
|
-
[0.0, 0.0, 0.0, 0.0, 2.43, 1.51, 0.0],
|
|
44
|
-
[0.0, 0.0, 0.0, 0.0, 1.93, 1.54, 0.0],
|
|
45
|
-
[0.0, 0.0, 0.0, 0.0, 2.03, 1.62, 0.0],
|
|
46
|
-
[0.0, 0.0, 0.0, 0.0, 2.14, 1.69, 0.0],
|
|
47
|
-
[0.0, 0.0, 0.0, 0.0, 2.25, 1.77, 0.0],
|
|
48
|
-
[0.0, 0.0, 0.0, 0.0, 3.06, 1.49, 0.0],
|
|
49
|
-
[26.71, 8.28, 0.21, 8.06, 3.87, 1.22, 1.0],
|
|
50
|
-
[14.69, 5.76, 0.16, 14.8, 4.67, 0.95, 1.0],
|
|
51
|
-
[2.19, 0.94, 0.03, 19.54, 5.73, 0.77, 1.0],
|
|
52
|
-
[2.11, 0.94, 0.03, 21.82, 6.79, 0.58, 1.0],
|
|
53
|
-
[4.25, 1.88, 0.05, 21.41, 7.84, 0.4, 1.0],
|
|
54
|
-
[0.0, 0.0, 0.0, 0.0, 7.43, 0.72, 0.0]]
|
|
55
|
-
data_pv_json = [
|
|
56
|
-
[0.0, 0.0, 0.0, -0.97, 1.52, 0.0],
|
|
57
|
-
[0.0, 0.0, 0.0, -1.06, 1.45, 0.0],
|
|
58
|
-
[0.0, 0.0, 0.0, -1.03, 1.45, 0.0],
|
|
59
|
-
[0.0, 0.0, 0.0, -0.48, 1.31, 0.0],
|
|
60
|
-
[0.0, 0.0, 0.0, -0.09, 1.24, 0.0],
|
|
61
|
-
[0.0, 0.0, 0.0, -0.38, 1.17, 0.0],
|
|
62
|
-
[0.0, 0.0, 0.0, 0.29, 1.03, 0.0],
|
|
63
|
-
[0.0, 0.0, 0.0, 1.0, 0.62, 0.0],
|
|
64
|
-
[1187.2, 129.59, 8.06, 0.97, 0.97, 0.0],
|
|
65
|
-
[3950.1, 423.28, 14.8, 1.89, 0.69, 0.0]]
|
|
66
|
-
|
|
67
|
-
inputs_radiation_csv = {'latitude': 45.0, 'longitude': 8.0, 'elevation': 250.0,
|
|
68
|
-
'radiation_database': 'PVGIS-SARAH',
|
|
69
|
-
'Slope': '30 deg.', 'Azimuth': '0 deg.'}
|
|
70
|
-
|
|
71
|
-
metadata_radiation_csv = {
|
|
72
|
-
'Gb(i)': 'Beam (direct) irradiance on the inclined plane (plane of the array) (W/m2)', # noqa: E501
|
|
73
|
-
'Gd(i)': 'Diffuse irradiance on the inclined plane (plane of the array) (W/m2)', # noqa: E501
|
|
74
|
-
'Gr(i)': 'Reflected irradiance on the inclined plane (plane of the array) (W/m2)', # noqa: E501
|
|
75
|
-
'H_sun': 'Sun height (degree)',
|
|
76
|
-
'T2m': '2-m air temperature (degree Celsius)',
|
|
77
|
-
'WS10m': '10-m total wind speed (m/s)',
|
|
78
|
-
'Int': '1 means solar radiation values are reconstructed'}
|
|
79
|
-
|
|
80
|
-
inputs_pv_json = {
|
|
81
|
-
'location': {'latitude': 45.0, 'longitude': 8.0, 'elevation': 250.0},
|
|
82
|
-
'meteo_data': {'radiation_db': 'PVGIS-SARAH2', 'meteo_db': 'ERA-Interim',
|
|
83
|
-
'year_min': 2013, 'year_max': 2014, 'use_horizon': True,
|
|
84
|
-
'horizon_db': None, 'horizon_data': 'DEM-calculated'},
|
|
85
|
-
'mounting_system': {'two_axis': {
|
|
86
|
-
'slope': {'value': '-', 'optimal': '-'},
|
|
87
|
-
'azimuth': {'value': '-', 'optimal': '-'}}},
|
|
88
|
-
'pv_module': {'technology': 'CIS', 'peak_power': 10.0, 'system_loss': 5.0}}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
metadata_pv_json = {
|
|
92
|
-
'inputs': {
|
|
93
|
-
'location':
|
|
94
|
-
{'description': 'Selected location', 'variables': {
|
|
95
|
-
'latitude': {'description': 'Latitude', 'units': 'decimal degree'}, # noqa: E501
|
|
96
|
-
'longitude': {'description': 'Longitude', 'units': 'decimal degree'}, # noqa: E501
|
|
97
|
-
'elevation': {'description': 'Elevation', 'units': 'm'}}},
|
|
98
|
-
'meteo_data': {
|
|
99
|
-
'description': 'Sources of meteorological data',
|
|
100
|
-
'variables': {
|
|
101
|
-
'radiation_db': {'description': 'Solar radiation database'}, # noqa: E501
|
|
102
|
-
'meteo_db': {'description': 'Database used for meteorological variables other than solar radiation'}, # noqa: E501
|
|
103
|
-
'year_min': {'description': 'First year of the calculations'}, # noqa: E501
|
|
104
|
-
'year_max': {'description': 'Last year of the calculations'}, # noqa: E501
|
|
105
|
-
'use_horizon': {'description': 'Include horizon shadows'},
|
|
106
|
-
'horizon_db': {'description': 'Source of horizon data'}}},
|
|
107
|
-
'mounting_system': {
|
|
108
|
-
'description': 'Mounting system',
|
|
109
|
-
'choices': 'fixed, vertical_axis, inclined_axis, two_axis',
|
|
110
|
-
'fields': {
|
|
111
|
-
'slope': {'description': 'Inclination angle from the horizontal plane', 'units': 'degree'}, # noqa: E501
|
|
112
|
-
'azimuth': {'description': 'Orientation (azimuth) angle of the (fixed) PV system (0 = S, 90 = W, -90 = E)', 'units': 'degree'}}}, # noqa: E501
|
|
113
|
-
'pv_module': {
|
|
114
|
-
'description': 'PV module parameters',
|
|
115
|
-
'variables': {
|
|
116
|
-
'technology': {'description': 'PV technology'},
|
|
117
|
-
'peak_power': {'description': 'Nominal (peak) power of the PV module', 'units': 'kW'}, # noqa: E501
|
|
118
|
-
'system_loss': {'description': 'Sum of system losses', 'units': '%'}}}}, # noqa: E501
|
|
119
|
-
'outputs': {
|
|
120
|
-
'hourly': {
|
|
121
|
-
'type': 'time series', 'timestamp': 'hourly averages',
|
|
122
|
-
'variables': {
|
|
123
|
-
'P': {'description': 'PV system power', 'units': 'W'},
|
|
124
|
-
'G(i)': {'description': 'Global irradiance on the inclined plane (plane of the array)', 'units': 'W/m2'}, # noqa: E501
|
|
125
|
-
'H_sun': {'description': 'Sun height', 'units': 'degree'},
|
|
126
|
-
'T2m': {'description': '2-m air temperature', 'units': 'degree Celsius'}, # noqa: E501
|
|
127
|
-
'WS10m': {'description': '10-m total wind speed', 'units': 'm/s'}, # noqa: E501
|
|
128
|
-
'Int': {'description': '1 means solar radiation values are reconstructed'}}}}} # noqa: E501
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
def generate_expected_dataframe(values, columns, index):
|
|
132
|
-
"""Create dataframe from arrays of values, columns and index, in order to
|
|
133
|
-
use this dataframe to compare to.
|
|
134
|
-
"""
|
|
135
|
-
expected = pd.DataFrame(index=index, data=values, columns=columns)
|
|
136
|
-
expected['Int'] = expected['Int'].astype(int)
|
|
137
|
-
expected.index.name = 'time'
|
|
138
|
-
expected.index.freq = None
|
|
139
|
-
return expected
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
@pytest.fixture
|
|
143
|
-
def expected_radiation_csv():
|
|
144
|
-
expected = generate_expected_dataframe(
|
|
145
|
-
data_radiation_csv, columns_radiation_csv, index_radiation_csv)
|
|
146
|
-
return expected
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
@pytest.fixture
|
|
150
|
-
def expected_radiation_csv_mapped():
|
|
151
|
-
expected = generate_expected_dataframe(
|
|
152
|
-
data_radiation_csv, columns_radiation_csv_mapped, index_radiation_csv)
|
|
153
|
-
return expected
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
@pytest.fixture
|
|
157
|
-
def expected_pv_json():
|
|
158
|
-
expected = generate_expected_dataframe(
|
|
159
|
-
data_pv_json, columns_pv_json, index_pv_json)
|
|
160
|
-
return expected
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
@pytest.fixture
|
|
164
|
-
def expected_pv_json_mapped():
|
|
165
|
-
expected = generate_expected_dataframe(
|
|
166
|
-
data_pv_json, columns_pv_json_mapped, index_pv_json)
|
|
167
|
-
return expected
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
# Test read_pvgis_hourly function using two different files with different
|
|
171
|
-
# input arguments (to test variable mapping and pvgis_format)
|
|
172
|
-
# pytest request.getfixturevalue is used to simplify the input arguments
|
|
173
|
-
@pytest.mark.parametrize('testfile,expected_name,metadata_exp,inputs_exp,map_variables,pvgis_format', [ # noqa: E501
|
|
174
|
-
(testfile_radiation_csv, 'expected_radiation_csv', metadata_radiation_csv,
|
|
175
|
-
inputs_radiation_csv, False, None),
|
|
176
|
-
(testfile_radiation_csv, 'expected_radiation_csv_mapped',
|
|
177
|
-
metadata_radiation_csv, inputs_radiation_csv, True, 'csv'),
|
|
178
|
-
(testfile_pv_json, 'expected_pv_json', metadata_pv_json, inputs_pv_json,
|
|
179
|
-
False, None),
|
|
180
|
-
(testfile_pv_json, 'expected_pv_json_mapped', metadata_pv_json,
|
|
181
|
-
inputs_pv_json, True, 'json')])
|
|
182
|
-
def test_read_pvgis_hourly(testfile, expected_name, metadata_exp,
|
|
183
|
-
inputs_exp, map_variables, pvgis_format, request):
|
|
184
|
-
# Get expected dataframe from fixture
|
|
185
|
-
expected = request.getfixturevalue(expected_name)
|
|
186
|
-
# Read data from file
|
|
187
|
-
out, inputs, metadata = read_pvgis_hourly(
|
|
188
|
-
testfile, map_variables=map_variables, pvgis_format=pvgis_format)
|
|
189
|
-
# Assert whether dataframe, metadata, and inputs are as expected
|
|
190
|
-
assert_frame_equal(out, expected)
|
|
191
|
-
assert inputs == inputs_exp
|
|
192
|
-
assert metadata == metadata_exp
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
def test_read_pvgis_hourly_bad_extension():
|
|
196
|
-
# Test if ValueError is raised if file extension cannot be recognized and
|
|
197
|
-
# pvgis_format is not specified
|
|
198
|
-
with pytest.raises(ValueError, match="pvgis format 'txt' was unknown"):
|
|
199
|
-
read_pvgis_hourly('filename.txt')
|
|
200
|
-
# Test if ValueError is raised if an unkonwn pvgis_format is specified
|
|
201
|
-
with pytest.raises(ValueError, match="pvgis format 'txt' was unknown"):
|
|
202
|
-
read_pvgis_hourly(testfile_pv_json, pvgis_format='txt')
|
|
203
|
-
# Test if TypeError is raised if input is a buffer and pvgis_format=None.
|
|
204
|
-
# The error text changed in python 3.12. This regex matches both versions:
|
|
205
|
-
with pytest.raises(TypeError, match="str.*os.PathLike"):
|
|
206
|
-
read_pvgis_hourly(io.StringIO())
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
args_radiation_csv = {
|
|
210
|
-
'surface_tilt': 30, 'surface_azimuth': 180, 'outputformat': 'csv',
|
|
211
|
-
'usehorizon': False, 'userhorizon': None, 'raddatabase': 'PVGIS-SARAH',
|
|
212
|
-
'start': 2016, 'end': 2016, 'pvcalculation': False, 'components': True}
|
|
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
|
|
215
|
-
|
|
216
|
-
args_pv_json = {
|
|
217
|
-
'surface_tilt': 30, 'surface_azimuth': 180, 'outputformat': 'json',
|
|
218
|
-
'usehorizon': True, 'userhorizon': None, 'raddatabase': 'PVGIS-SARAH2',
|
|
219
|
-
'start': pd.Timestamp(2013, 1, 1), 'end': pd.Timestamp(2014, 5, 1),
|
|
220
|
-
'pvcalculation': True, 'peakpower': 10, 'pvtechchoice': 'CIS', 'loss': 5,
|
|
221
|
-
'trackingtype': 2, 'optimalangles': True, 'components': False,
|
|
222
|
-
'url': 'https://re.jrc.ec.europa.eu/api/v5_2/'}
|
|
223
|
-
|
|
224
|
-
url_pv_json = 'https://re.jrc.ec.europa.eu/api/v5_2/seriescalc?lat=45&lon=8&outputformat=json&angle=30&aspect=0&pvtechchoice=CIS&mountingplace=free&trackingtype=2&components=0&usehorizon=1&raddatabase=PVGIS-SARAH2&startyear=2013&endyear=2014&pvcalculation=1&peakpower=10&loss=5&optimalangles=1' # noqa: E501
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
@pytest.mark.parametrize('testfile,expected_name,args,map_variables,url_test', [ # noqa: E501
|
|
228
|
-
(testfile_radiation_csv, 'expected_radiation_csv',
|
|
229
|
-
args_radiation_csv, False, url_hourly_radiation_csv),
|
|
230
|
-
(testfile_radiation_csv, 'expected_radiation_csv_mapped',
|
|
231
|
-
args_radiation_csv, True, url_hourly_radiation_csv),
|
|
232
|
-
(testfile_pv_json, 'expected_pv_json', args_pv_json, False, url_pv_json),
|
|
233
|
-
(testfile_pv_json, 'expected_pv_json_mapped', args_pv_json, True,
|
|
234
|
-
url_pv_json)])
|
|
235
|
-
def test_get_pvgis_hourly(requests_mock, testfile, expected_name, args,
|
|
236
|
-
map_variables, url_test, request):
|
|
237
|
-
"""Test that get_pvgis_hourly generates the correct URI request and that
|
|
238
|
-
_parse_pvgis_hourly_json and _parse_pvgis_hourly_csv is called correctly"""
|
|
239
|
-
# Open local test file containing McClear monthly data
|
|
240
|
-
with open(testfile, 'r') as test_file:
|
|
241
|
-
mock_response = test_file.read()
|
|
242
|
-
# Specify the full URI of a specific example, this ensures that all of the
|
|
243
|
-
# inputs are passing on correctly
|
|
244
|
-
requests_mock.get(url_test, text=mock_response)
|
|
245
|
-
# Make API call - an error is raised if requested URI does not match
|
|
246
|
-
out, inputs, metadata = get_pvgis_hourly(
|
|
247
|
-
latitude=45, longitude=8, map_variables=map_variables, **args)
|
|
248
|
-
# Get expected dataframe from fixture
|
|
249
|
-
expected = request.getfixturevalue(expected_name)
|
|
250
|
-
# Compare out and expected dataframes
|
|
251
|
-
assert_frame_equal(out, expected)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
def test_get_pvgis_hourly_bad_status_code(requests_mock):
|
|
255
|
-
# Test if a HTTPError is raised if a bad request is returned
|
|
256
|
-
requests_mock.get(url_pv_json, status_code=400)
|
|
257
|
-
with pytest.raises(requests.HTTPError):
|
|
258
|
-
get_pvgis_hourly(latitude=45, longitude=8, **args_pv_json)
|
|
259
|
-
# Test if HTTPError is raised and error message is returned if avaiable
|
|
260
|
-
requests_mock.get(url_pv_json, status_code=400,
|
|
261
|
-
json={'message': 'peakpower Mandatory'})
|
|
262
|
-
with pytest.raises(requests.HTTPError):
|
|
263
|
-
get_pvgis_hourly(latitude=45, longitude=8, **args_pv_json)
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
url_bad_outputformat = 'https://re.jrc.ec.europa.eu/api/seriescalc?lat=45&lon=8&outputformat=basic&angle=0&aspect=0&pvcalculation=0&pvtechchoice=crystSi&mountingplace=free&trackingtype=0&components=1&usehorizon=1&optimalangles=0&optimalinclination=0&loss=0' # noqa: E501
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
def test_get_pvgis_hourly_bad_outputformat(requests_mock):
|
|
270
|
-
# Test if a ValueError is raised if an unsupported outputformat is used
|
|
271
|
-
# E.g. 'basic' is a valid PVGIS format, but is not supported by pvlib
|
|
272
|
-
requests_mock.get(url_bad_outputformat)
|
|
273
|
-
with pytest.raises(ValueError):
|
|
274
|
-
get_pvgis_hourly(latitude=45, longitude=8, outputformat='basic')
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
url_additional_inputs = 'https://re.jrc.ec.europa.eu/api/seriescalc?lat=55.6814&lon=12.5758&outputformat=csv&angle=0&aspect=0&pvcalculation=1&pvtechchoice=crystSi&mountingplace=free&trackingtype=0&components=1&usehorizon=1&optimalangles=1&optimalinclination=0&loss=2&userhorizon=10%2C15%2C20%2C10&peakpower=5' # noqa: E501
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
def test_get_pvgis_hourly_additional_inputs(requests_mock):
|
|
281
|
-
# Test additional inputs, including userhorizons
|
|
282
|
-
# Necessary to pass a test file in order for the parser not to fail
|
|
283
|
-
with open(testfile_radiation_csv, 'r') as test_file:
|
|
284
|
-
mock_response = test_file.read()
|
|
285
|
-
requests_mock.get(url_additional_inputs, text=mock_response)
|
|
286
|
-
# Make request with userhorizon specified
|
|
287
|
-
# Test passes if the request made by get_pvgis_hourly matches exactly the
|
|
288
|
-
# url passed to the mock request (url_additional_inputs)
|
|
289
|
-
get_pvgis_hourly(
|
|
290
|
-
latitude=55.6814, longitude=12.5758, outputformat='csv',
|
|
291
|
-
usehorizon=True, userhorizon=[10, 15, 20, 10], pvcalculation=True,
|
|
292
|
-
peakpower=5, loss=2, trackingtype=0, components=True,
|
|
293
|
-
optimalangles=True)
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
def test_read_pvgis_hourly_empty_file():
|
|
297
|
-
# Check if a IOError is raised if file does not contain a data section
|
|
298
|
-
with pytest.raises(ValueError, match='No data section'):
|
|
299
|
-
read_pvgis_hourly(
|
|
300
|
-
io.StringIO('1:1\n2:2\n3:3\n4:4\n5:5\n'),
|
|
301
|
-
pvgis_format='csv')
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
# PVGIS TMY tests
|
|
305
|
-
@pytest.fixture
|
|
306
|
-
def expected():
|
|
307
|
-
return pd.read_csv(DATA_DIR / 'pvgis_tmy_test.dat', index_col='time(UTC)')
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
@pytest.fixture
|
|
311
|
-
def userhorizon_expected():
|
|
312
|
-
return pd.read_json(DATA_DIR / 'tmy_45.000_8.000_userhorizon.json')
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
@pytest.fixture
|
|
316
|
-
def month_year_expected():
|
|
317
|
-
return [
|
|
318
|
-
2014, 2011, 2008, 2011, 2009, 2011, 2020, 2006, 2006, 2013, 2007, 2018]
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
@pytest.fixture
|
|
322
|
-
def inputs_expected():
|
|
323
|
-
return {
|
|
324
|
-
'location': {'latitude': 45.0, 'longitude': 8.0, 'elevation': 250.0},
|
|
325
|
-
'meteo_data': {
|
|
326
|
-
'radiation_db': 'PVGIS-SARAH2',
|
|
327
|
-
'meteo_db': 'ERA5',
|
|
328
|
-
'year_min': 2005,
|
|
329
|
-
'year_max': 2020,
|
|
330
|
-
'use_horizon': True,
|
|
331
|
-
'horizon_db': 'DEM-calculated'}}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
@pytest.fixture
|
|
335
|
-
def epw_meta():
|
|
336
|
-
return {
|
|
337
|
-
'loc': 'LOCATION',
|
|
338
|
-
'city': 'unknown',
|
|
339
|
-
'state-prov': '-',
|
|
340
|
-
'country': 'unknown',
|
|
341
|
-
'data_type': 'ECMWF/ERA',
|
|
342
|
-
'WMO_code': 'unknown',
|
|
343
|
-
'latitude': 45.0,
|
|
344
|
-
'longitude': 8.0,
|
|
345
|
-
'TZ': 1.0,
|
|
346
|
-
'altitude': 250.0}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
@pytest.fixture
|
|
350
|
-
def meta_expected():
|
|
351
|
-
with (DATA_DIR / 'pvgis_tmy_meta.json').open() as f:
|
|
352
|
-
return json.load(f)
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
@pytest.fixture
|
|
356
|
-
def csv_meta(meta_expected):
|
|
357
|
-
return [
|
|
358
|
-
f"{k}: {v['description']} ({v['units']})" for k, v
|
|
359
|
-
in meta_expected['outputs']['tmy_hourly']['variables'].items()]
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
@pytest.fixture
|
|
363
|
-
def pvgis_tmy_mapped_columns():
|
|
364
|
-
return ['temp_air', 'relative_humidity', 'ghi', 'dni', 'dhi', 'IR(h)',
|
|
365
|
-
'wind_speed', 'wind_direction', 'pressure']
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
@pytest.mark.remote_data
|
|
369
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
370
|
-
def test_get_pvgis_tmy(expected, month_year_expected, inputs_expected,
|
|
371
|
-
meta_expected):
|
|
372
|
-
pvgis_data = get_pvgis_tmy(45, 8, map_variables=False)
|
|
373
|
-
_compare_pvgis_tmy_json(expected, month_year_expected, inputs_expected,
|
|
374
|
-
meta_expected, pvgis_data)
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
def _compare_pvgis_tmy_json(expected, month_year_expected, inputs_expected,
|
|
378
|
-
meta_expected, pvgis_data):
|
|
379
|
-
data, months_selected, inputs, meta = pvgis_data
|
|
380
|
-
# check each column of output separately
|
|
381
|
-
for outvar in meta_expected['outputs']['tmy_hourly']['variables'].keys():
|
|
382
|
-
assert np.allclose(data[outvar], expected[outvar])
|
|
383
|
-
assert np.allclose(
|
|
384
|
-
[_['month'] for _ in months_selected], np.arange(1, 13, 1))
|
|
385
|
-
assert np.allclose(
|
|
386
|
-
[_['year'] for _ in months_selected], month_year_expected)
|
|
387
|
-
inputs_loc = inputs['location']
|
|
388
|
-
assert inputs_loc['latitude'] == inputs_expected['location']['latitude']
|
|
389
|
-
assert inputs_loc['longitude'] == inputs_expected['location']['longitude']
|
|
390
|
-
assert inputs_loc['elevation'] == inputs_expected['location']['elevation']
|
|
391
|
-
inputs_met_data = inputs['meteo_data']
|
|
392
|
-
expected_met_data = inputs_expected['meteo_data']
|
|
393
|
-
assert (
|
|
394
|
-
inputs_met_data['radiation_db'] == expected_met_data['radiation_db'])
|
|
395
|
-
assert inputs_met_data['year_min'] == expected_met_data['year_min']
|
|
396
|
-
assert inputs_met_data['year_max'] == expected_met_data['year_max']
|
|
397
|
-
assert inputs_met_data['use_horizon'] == expected_met_data['use_horizon']
|
|
398
|
-
assert inputs_met_data['horizon_db'] == expected_met_data['horizon_db']
|
|
399
|
-
assert meta == meta_expected
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
@pytest.mark.remote_data
|
|
403
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
404
|
-
def test_get_pvgis_tmy_kwargs(userhorizon_expected):
|
|
405
|
-
_, _, inputs, _ = get_pvgis_tmy(45, 8, usehorizon=False,
|
|
406
|
-
map_variables=False)
|
|
407
|
-
assert inputs['meteo_data']['use_horizon'] is False
|
|
408
|
-
data, _, _, _ = get_pvgis_tmy(
|
|
409
|
-
45, 8, userhorizon=[0, 10, 20, 30, 40, 15, 25, 5], map_variables=False)
|
|
410
|
-
assert np.allclose(
|
|
411
|
-
data['G(h)'], userhorizon_expected['G(h)'].values)
|
|
412
|
-
assert np.allclose(
|
|
413
|
-
data['Gb(n)'], userhorizon_expected['Gb(n)'].values)
|
|
414
|
-
assert np.allclose(
|
|
415
|
-
data['Gd(h)'], userhorizon_expected['Gd(h)'].values)
|
|
416
|
-
_, _, inputs, _ = get_pvgis_tmy(45, 8, startyear=2005, map_variables=False)
|
|
417
|
-
assert inputs['meteo_data']['year_min'] == 2005
|
|
418
|
-
_, _, inputs, _ = get_pvgis_tmy(45, 8, endyear=2016, map_variables=False)
|
|
419
|
-
assert inputs['meteo_data']['year_max'] == 2016
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
@pytest.mark.remote_data
|
|
423
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
424
|
-
def test_get_pvgis_tmy_basic(expected, meta_expected):
|
|
425
|
-
pvgis_data = get_pvgis_tmy(45, 8, outputformat='basic',
|
|
426
|
-
map_variables=False)
|
|
427
|
-
_compare_pvgis_tmy_basic(expected, meta_expected, pvgis_data)
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
def _compare_pvgis_tmy_basic(expected, meta_expected, pvgis_data):
|
|
431
|
-
data, _, _, _ = pvgis_data
|
|
432
|
-
# check each column of output separately
|
|
433
|
-
for outvar in meta_expected['outputs']['tmy_hourly']['variables'].keys():
|
|
434
|
-
assert np.allclose(data[outvar], expected[outvar])
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
@pytest.mark.remote_data
|
|
438
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
439
|
-
def test_get_pvgis_tmy_coerce_year():
|
|
440
|
-
"""test utc_offset and coerce_year work as expected"""
|
|
441
|
-
base_case, _, _, _ = get_pvgis_tmy(45, 8) # Turin
|
|
442
|
-
assert str(base_case.index.tz) == 'UTC'
|
|
443
|
-
assert base_case.index.name == 'time(UTC)'
|
|
444
|
-
noon_test_data = [
|
|
445
|
-
base_case[base_case.index.month == m].iloc[12]
|
|
446
|
-
for m in range(1, 13)]
|
|
447
|
-
cet_tz = 1 # Turin time is CET
|
|
448
|
-
cet_name = 'Etc/GMT-1'
|
|
449
|
-
# check indices of rolled data after converting timezone
|
|
450
|
-
pvgis_data, _, _, _ = get_pvgis_tmy(45, 8, roll_utc_offset=cet_tz)
|
|
451
|
-
jan1_midnight = pd.Timestamp('1990-01-01 00:00:00', tz=cet_name)
|
|
452
|
-
dec31_midnight = pd.Timestamp('1990-12-31 23:00:00', tz=cet_name)
|
|
453
|
-
assert pvgis_data.index[0] == jan1_midnight
|
|
454
|
-
assert pvgis_data.index[-1] == dec31_midnight
|
|
455
|
-
assert pvgis_data.index.name == f'time({cet_name})'
|
|
456
|
-
# spot check rolled data matches original
|
|
457
|
-
for m, test_case in enumerate(noon_test_data):
|
|
458
|
-
expected = pvgis_data[pvgis_data.index.month == m+1].iloc[12+cet_tz]
|
|
459
|
-
assert all(test_case == expected)
|
|
460
|
-
# repeat tests with year coerced
|
|
461
|
-
test_yr = 2021
|
|
462
|
-
pvgis_data, _, _, _ = get_pvgis_tmy(
|
|
463
|
-
45, 8, roll_utc_offset=cet_tz, coerce_year=test_yr)
|
|
464
|
-
jan1_midnight = pd.Timestamp(f'{test_yr}-01-01 00:00:00', tz=cet_name)
|
|
465
|
-
dec31_midnight = pd.Timestamp(f'{test_yr}-12-31 23:00:00', tz=cet_name)
|
|
466
|
-
assert pvgis_data.index[0] == jan1_midnight
|
|
467
|
-
assert pvgis_data.index[-1] == dec31_midnight
|
|
468
|
-
assert pvgis_data.index.name == f'time({cet_name})'
|
|
469
|
-
for m, test_case in enumerate(noon_test_data):
|
|
470
|
-
expected = pvgis_data[pvgis_data.index.month == m+1].iloc[12+cet_tz]
|
|
471
|
-
assert all(test_case == expected)
|
|
472
|
-
# repeat tests with year coerced but utc offset none or zero
|
|
473
|
-
pvgis_data, _, _, _ = get_pvgis_tmy(45, 8, coerce_year=test_yr)
|
|
474
|
-
jan1_midnight = pd.Timestamp(f'{test_yr}-01-01 00:00:00', tz='UTC')
|
|
475
|
-
dec31_midnight = pd.Timestamp(f'{test_yr}-12-31 23:00:00', tz='UTC')
|
|
476
|
-
assert pvgis_data.index[0] == jan1_midnight
|
|
477
|
-
assert pvgis_data.index[-1] == dec31_midnight
|
|
478
|
-
assert pvgis_data.index.name == 'time(UTC)'
|
|
479
|
-
for m, test_case in enumerate(noon_test_data):
|
|
480
|
-
expected = pvgis_data[pvgis_data.index.month == m+1].iloc[12]
|
|
481
|
-
assert all(test_case == expected)
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
@pytest.mark.remote_data
|
|
485
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
486
|
-
def test_get_pvgis_tmy_csv(expected, month_year_expected, inputs_expected,
|
|
487
|
-
meta_expected, csv_meta):
|
|
488
|
-
pvgis_data = get_pvgis_tmy(45, 8, outputformat='csv', map_variables=False)
|
|
489
|
-
_compare_pvgis_tmy_csv(expected, month_year_expected, inputs_expected,
|
|
490
|
-
meta_expected, csv_meta, pvgis_data)
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
def _compare_pvgis_tmy_csv(expected, month_year_expected, inputs_expected,
|
|
494
|
-
meta_expected, csv_meta, pvgis_data):
|
|
495
|
-
data, months_selected, inputs, meta = pvgis_data
|
|
496
|
-
# check each column of output separately
|
|
497
|
-
for outvar in meta_expected['outputs']['tmy_hourly']['variables'].keys():
|
|
498
|
-
assert np.allclose(data[outvar], expected[outvar])
|
|
499
|
-
assert np.allclose(
|
|
500
|
-
[_['month'] for _ in months_selected], np.arange(1, 13, 1))
|
|
501
|
-
assert np.allclose(
|
|
502
|
-
[_['year'] for _ in months_selected], month_year_expected)
|
|
503
|
-
assert inputs['latitude'] == inputs_expected['location']['latitude']
|
|
504
|
-
assert inputs['longitude'] == inputs_expected['location']['longitude']
|
|
505
|
-
assert inputs['elevation'] == inputs_expected['location']['elevation']
|
|
506
|
-
for meta_value in meta:
|
|
507
|
-
if not meta_value:
|
|
508
|
-
continue
|
|
509
|
-
# this copyright text tends to change (copyright year range increments
|
|
510
|
-
# annually, e.g.), so just check the beginning of it:
|
|
511
|
-
if meta_value.startswith('PVGIS (c) European'):
|
|
512
|
-
continue
|
|
513
|
-
assert meta_value in csv_meta
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
@pytest.mark.remote_data
|
|
517
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
518
|
-
def test_get_pvgis_tmy_epw(expected, epw_meta):
|
|
519
|
-
pvgis_data = get_pvgis_tmy(45, 8, outputformat='epw', map_variables=False)
|
|
520
|
-
_compare_pvgis_tmy_epw(expected, epw_meta, pvgis_data)
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
def _compare_pvgis_tmy_epw(expected, epw_meta, pvgis_data):
|
|
524
|
-
data, _, _, meta = pvgis_data
|
|
525
|
-
assert np.allclose(data.ghi, expected['G(h)'])
|
|
526
|
-
assert np.allclose(data.dni, expected['Gb(n)'])
|
|
527
|
-
assert np.allclose(data.dhi, expected['Gd(h)'])
|
|
528
|
-
assert np.allclose(data.temp_air, expected['T2m'])
|
|
529
|
-
assert meta == epw_meta
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
@pytest.mark.remote_data
|
|
533
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
534
|
-
def test_get_pvgis_tmy_error():
|
|
535
|
-
err_msg = 'outputformat: Incorrect value.'
|
|
536
|
-
with pytest.raises(requests.HTTPError, match=err_msg):
|
|
537
|
-
get_pvgis_tmy(45, 8, outputformat='bad')
|
|
538
|
-
with pytest.raises(requests.HTTPError, match='404 Client Error'):
|
|
539
|
-
get_pvgis_tmy(45, 8, url='https://re.jrc.ec.europa.eu/')
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
@pytest.mark.remote_data
|
|
543
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
544
|
-
def test_get_pvgis_map_variables(pvgis_tmy_mapped_columns):
|
|
545
|
-
actual, _, _, _ = get_pvgis_tmy(45, 8, map_variables=True)
|
|
546
|
-
assert all(c in pvgis_tmy_mapped_columns for c in actual.columns)
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
@pytest.mark.remote_data
|
|
550
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
551
|
-
def test_read_pvgis_horizon():
|
|
552
|
-
pvgis_data, _ = get_pvgis_horizon(35.171051, -106.465158)
|
|
553
|
-
horizon_data = pd.read_csv(DATA_DIR / 'test_read_pvgis_horizon.csv',
|
|
554
|
-
index_col=0)
|
|
555
|
-
horizon_data = horizon_data['horizon_elevation']
|
|
556
|
-
assert_series_equal(pvgis_data, horizon_data)
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
@pytest.mark.remote_data
|
|
560
|
-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
|
|
561
|
-
def test_read_pvgis_horizon_invalid_coords():
|
|
562
|
-
with pytest.raises(requests.HTTPError, match='lat: Incorrect value'):
|
|
563
|
-
_, _ = get_pvgis_horizon(100, 50) # unfeasible latitude
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
def test_read_pvgis_tmy_map_variables(pvgis_tmy_mapped_columns):
|
|
567
|
-
fn = DATA_DIR / 'tmy_45.000_8.000_2005_2020.json'
|
|
568
|
-
actual, _, _, _ = read_pvgis_tmy(fn, map_variables=True)
|
|
569
|
-
assert all(c in pvgis_tmy_mapped_columns for c in actual.columns)
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
def test_read_pvgis_tmy_json(expected, month_year_expected, inputs_expected,
|
|
573
|
-
meta_expected):
|
|
574
|
-
fn = DATA_DIR / 'tmy_45.000_8.000_2005_2020.json'
|
|
575
|
-
# infer outputformat from file extensions
|
|
576
|
-
pvgis_data = read_pvgis_tmy(fn, map_variables=False)
|
|
577
|
-
_compare_pvgis_tmy_json(expected, month_year_expected, inputs_expected,
|
|
578
|
-
meta_expected, pvgis_data)
|
|
579
|
-
# explicit pvgis outputformat
|
|
580
|
-
pvgis_data = read_pvgis_tmy(fn, pvgis_format='json', map_variables=False)
|
|
581
|
-
_compare_pvgis_tmy_json(expected, month_year_expected, inputs_expected,
|
|
582
|
-
meta_expected, pvgis_data)
|
|
583
|
-
with fn.open('r') as fbuf:
|
|
584
|
-
pvgis_data = read_pvgis_tmy(fbuf, pvgis_format='json',
|
|
585
|
-
map_variables=False)
|
|
586
|
-
_compare_pvgis_tmy_json(expected, month_year_expected, inputs_expected,
|
|
587
|
-
meta_expected, pvgis_data)
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
def test_read_pvgis_tmy_epw(expected, epw_meta):
|
|
591
|
-
fn = DATA_DIR / 'tmy_45.000_8.000_2005_2020.epw'
|
|
592
|
-
# infer outputformat from file extensions
|
|
593
|
-
pvgis_data = read_pvgis_tmy(fn, map_variables=False)
|
|
594
|
-
_compare_pvgis_tmy_epw(expected, epw_meta, pvgis_data)
|
|
595
|
-
# explicit pvgis outputformat
|
|
596
|
-
pvgis_data = read_pvgis_tmy(fn, pvgis_format='epw', map_variables=False)
|
|
597
|
-
_compare_pvgis_tmy_epw(expected, epw_meta, pvgis_data)
|
|
598
|
-
with fn.open('r') as fbuf:
|
|
599
|
-
pvgis_data = read_pvgis_tmy(fbuf, pvgis_format='epw',
|
|
600
|
-
map_variables=False)
|
|
601
|
-
_compare_pvgis_tmy_epw(expected, epw_meta, pvgis_data)
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
def test_read_pvgis_tmy_csv(expected, month_year_expected, inputs_expected,
|
|
605
|
-
meta_expected, csv_meta):
|
|
606
|
-
fn = DATA_DIR / 'tmy_45.000_8.000_2005_2020.csv'
|
|
607
|
-
# infer outputformat from file extensions
|
|
608
|
-
pvgis_data = read_pvgis_tmy(fn, map_variables=False)
|
|
609
|
-
_compare_pvgis_tmy_csv(expected, month_year_expected, inputs_expected,
|
|
610
|
-
meta_expected, csv_meta, pvgis_data)
|
|
611
|
-
# explicit pvgis outputformat
|
|
612
|
-
pvgis_data = read_pvgis_tmy(fn, pvgis_format='csv', map_variables=False)
|
|
613
|
-
_compare_pvgis_tmy_csv(expected, month_year_expected, inputs_expected,
|
|
614
|
-
meta_expected, csv_meta, pvgis_data)
|
|
615
|
-
with fn.open('rb') as fbuf:
|
|
616
|
-
pvgis_data = read_pvgis_tmy(fbuf, pvgis_format='csv',
|
|
617
|
-
map_variables=False)
|
|
618
|
-
_compare_pvgis_tmy_csv(expected, month_year_expected, inputs_expected,
|
|
619
|
-
meta_expected, csv_meta, pvgis_data)
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
def test_read_pvgis_tmy_basic(expected, meta_expected):
|
|
623
|
-
fn = DATA_DIR / 'tmy_45.000_8.000_2005_2020.txt'
|
|
624
|
-
# XXX: can't infer outputformat from file extensions for basic
|
|
625
|
-
with pytest.raises(ValueError, match="pvgis format 'txt' was unknown"):
|
|
626
|
-
read_pvgis_tmy(fn, map_variables=False)
|
|
627
|
-
# explicit pvgis outputformat
|
|
628
|
-
pvgis_data = read_pvgis_tmy(fn, pvgis_format='basic', map_variables=False)
|
|
629
|
-
_compare_pvgis_tmy_basic(expected, meta_expected, pvgis_data)
|
|
630
|
-
with fn.open('rb') as fbuf:
|
|
631
|
-
pvgis_data = read_pvgis_tmy(fbuf, pvgis_format='basic',
|
|
632
|
-
map_variables=False)
|
|
633
|
-
_compare_pvgis_tmy_basic(expected, meta_expected, pvgis_data)
|
|
634
|
-
# file buffer raises TypeError if passed to pathlib.Path()
|
|
635
|
-
with pytest.raises(TypeError):
|
|
636
|
-
read_pvgis_tmy(fbuf, map_variables=False)
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
def test_read_pvgis_tmy_exception():
|
|
640
|
-
bad_outputformat = 'bad'
|
|
641
|
-
err_msg = f"pvgis format '{bad_outputformat:s}' was unknown"
|
|
642
|
-
with pytest.raises(ValueError, match=err_msg):
|
|
643
|
-
read_pvgis_tmy('filename', pvgis_format=bad_outputformat,
|
|
644
|
-
map_variables=False)
|