Skip to content

Commit a8fb121

Browse files
committed
Update variable map and documentation
1 parent 35f3b24 commit a8fb121

File tree

1 file changed

+70
-28
lines changed

1 file changed

+70
-28
lines changed

pvlib/iotools/pvgis.py

Lines changed: 70 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,33 @@
2323

2424
URL = 'https://re.jrc.ec.europa.eu/api/'
2525

26-
27-
def get_pvgis_hourly(lat, lon, angle=0, aspect=0,
28-
outputformat='json', usehorizon=True,
29-
userhorizon=None, raddatabase=None,
30-
startyear=None, endyear=None,
31-
pvcalculation=False, peakpower=None,
32-
pvtechchoice='crystSi', mountingplace='free', loss=None,
33-
trackingtype=0,
26+
# Dictionary mapping PVGIS names to pvlib names
27+
VARIABLE_MAP = {
28+
'G(h)': 'ghi',
29+
'Gb(n)': 'dni',
30+
'Gd(h)': 'dhi',
31+
'G(i)': 'poa_global',
32+
'Gb(i)': 'poa_direct',
33+
'Gd(i)': 'poa_diffuse',
34+
'Gr(i)': 'poa_ground_diffuse',
35+
'H_sun': 'solar_elevation',
36+
'T2m': 'temp_air',
37+
'RH': 'relative_humidity',
38+
'SP': 'pressure',
39+
'WS10m': 'wind_speed',
40+
'WD10m': 'wind_direction',
41+
}
42+
43+
44+
def get_pvgis_hourly(lat, lon, angle=0, aspect=0, outputformat='json',
45+
usehorizon=True, userhorizon=None, raddatabase=None,
46+
startyear=None, endyear=None, pvcalculation=False,
47+
peakpower=None, pvtechchoice='crystSi',
48+
mountingplace='free', loss=None, trackingtype=0,
3449
optimal_inclination=False, optimalangles=False,
35-
components=True, url=URL, timeout=30):
50+
components=True, url=URL, map_variables=True, timeout=30):
3651
"""
37-
Get hourly solar radiation data and modeled PV power output from PVGIS
38-
[1]_.
52+
Get hourly solar irradiation and modeled PV power output from PVGIS [1]_.
3953
4054
Parameters
4155
----------
@@ -49,8 +63,8 @@ def get_pvgis_hourly(lat, lon, angle=0, aspect=0,
4963
Orientation (azimuth angle) of the (fixed) plane. 0=south, 90=west,
5064
-90: east. Not relevant for tracking systems.
5165
outputformat: str, default: 'json'
52-
Must be in ``['csv', 'json']``. See PVGIS hourly data documentation
53-
[2]_ for more info.
66+
Must be in ``['json', 'csv', 'basic']``. See PVGIS hourly data
67+
documentation [2]_ for more info. Note basic does not include a header.
5468
usehorizon: bool, default: True
5569
Include effects of horizon
5670
userhorizon: list of float, default: None
@@ -92,17 +106,45 @@ def get_pvgis_hourly(lat, lon, angle=0, aspect=0,
92106
url: str, default:const:`pvlib.iotools.pvgis.URL`
93107
Base url of PVGIS API, append ``seriescalc`` to get hourly data
94108
endpoint
109+
map_variables: bool, default True
110+
When true, renames columns of the Dataframe to pvlib variable names
111+
where applicable. See variable VARIABLE_MAP.
95112
timeout: int, default: 30
96113
Time in seconds to wait for server response before timeout
97114
98115
Returns
99116
-------
100117
data : pandas.DataFrame
101-
Time-series of hourly data
118+
Time-series of hourly data, see Notes for fields
102119
inputs : dict
103-
Dictionary of the request input parameters
120+
Dictionary of the request input parameters, ``None`` for basic
104121
meta : list or dict
105-
meta data
122+
meta data, ``None`` for basic
123+
124+
Notes
125+
-----
126+
data includes the following fields:
127+
128+
======================= ====== ==========================================
129+
raw, mapped Format Description
130+
======================= ====== ==========================================
131+
**Mapped field names are returned when the map_variables argument is True**
132+
---------------------------------------------------------------------------
133+
P* float PV system power (W)
134+
G(i)** float Global irradiance on inclined plane (W/m^2)
135+
Gb(i)** float Beam (direct) irradiance on inclined plane (W/m^2)
136+
Gd(i)** float Diffuse irradiance on inclined plane (W/m^2)
137+
Gr(i)** float Reflected irradiance on inclined plane (W/m^2)
138+
H_sun, solar_elevation float Sun height/elevation (degrees)
139+
T2m, temp_air float Air temperature at 2 (degrees Celsius)
140+
WS10m, wind_speed float Wind speed at 10 m (m/s)
141+
Int int Solar radiation reconstructed (1/0)
142+
======================= ====== ==========================================
143+
144+
*P (PV system power) is only returned when pvcalculation=True.
145+
146+
**Gb(i), Gd(i), and Gr(i) are returned when components=True, whereas
147+
otherwise the sum of the three components, G(i), is returned.
106148
107149
Raises
108150
------
@@ -113,7 +155,7 @@ def get_pvgis_hourly(lat, lon, angle=0, aspect=0,
113155
114156
See also
115157
--------
116-
pvlib.iotools.read_pvgis_hourly
158+
pvlib.iotools.read_pvgis_hourly, pvlib.iotools.get_pvgis_tmy
117159
118160
References
119161
----------
@@ -173,10 +215,10 @@ def get_pvgis_hourly(lat, lon, angle=0, aspect=0,
173215
data = None, None, None, None
174216
if outputformat == 'json':
175217
src = res.json()
176-
return _parse_pvgis_hourly_json(src)
218+
return _parse_pvgis_hourly_json(src, map_variables=map_variables)
177219
elif outputformat == 'csv':
178220
with io.StringIO(res.content.decode('utf-8')) as src:
179-
return _parse_pvgis_hourly_csv(src)
221+
return _parse_pvgis_hourly_csv(src, map_variables=map_variables)
180222
elif outputformat == 'basic':
181223
with io.BytesIO(res.content) as src:
182224
return _parse_pvgis_hourly_basic(src)
@@ -187,13 +229,15 @@ def get_pvgis_hourly(lat, lon, angle=0, aspect=0,
187229
return data
188230

189231

190-
def _parse_pvgis_hourly_json(src):
232+
def _parse_pvgis_hourly_json(src, map_variables=True):
191233
inputs = src['inputs']
192234
meta = src['meta']
193235
data = pd.DataFrame(src['outputs']['hourly'])
194236
data.index = pd.to_datetime(data['time'], format='%Y%m%d:%H%M', utc=True)
195237
data = data.drop('time', axis=1)
196238
data = data.astype(dtype={'Int': 'int'}) # The 'Int' column to be integer
239+
if map_variables:
240+
data.rename(columns=VARIABLE_MAP, inplace=True)
197241
return data, inputs, meta
198242

199243

@@ -203,7 +247,7 @@ def _parse_pvgis_hourly_basic(src):
203247
return data, None, None
204248

205249

206-
def _parse_pvgis_hourly_csv(src):
250+
def _parse_pvgis_hourly_csv(src, map_variables=True):
207251
# The first 4 rows are latitude, longitude, elevation, radiation database
208252
inputs = {}
209253
# 'Latitude (decimal degrees): 45.000\r\n'
@@ -215,7 +259,6 @@ def _parse_pvgis_hourly_csv(src):
215259
# 'Radiation database: \tPVGIS-SARAH\r\n'
216260
inputs['radiation_database'] = str(src.readline().split(':')[1]
217261
.replace('\t', '').replace('\n', ''))
218-
219262
# Parse through the remaining metadata section (the number of lines for
220263
# this section depends on the requested parameters)
221264
while True:
@@ -229,9 +272,8 @@ def _parse_pvgis_hourly_csv(src):
229272
inputs[line.split(':')[0]] = str(line.split(':')[1]
230273
.replace('\n', '')
231274
.replace('\r', '').strip())
232-
233-
# The data section covers a variable number of lines (depends on requested
234-
# years) and ends with a blank line
275+
# Save the entries from the data section to a list, until an empty line is
276+
# reached an empty line. The length of the section depends on the request
235277
data_lines = []
236278
while True:
237279
line = src.readline()
@@ -240,22 +282,22 @@ def _parse_pvgis_hourly_csv(src):
240282
else:
241283
data_lines.append(line.replace('\n', '').replace('\r', '')
242284
.split(','))
243-
244285
data = pd.DataFrame(data_lines, columns=names)
245286
data.index = pd.to_datetime(data['time'], format='%Y%m%d:%H%M', utc=True)
246287
data = data.drop('time', axis=1)
288+
if map_variables:
289+
data.rename(columns=VARIABLE_MAP, inplace=True)
247290
# All columns should have the dtype=float, except 'Int' which should be
248291
# integer. It is necessary to convert to float, before converting to int
249292
data = data.astype(float).astype(dtype={'Int': 'int'})
250-
251293
# Generate metadata dictionary containing description of parameters
252294
meta = {}
253295
for line in src.readlines():
254296
if ':' in line:
255297
meta[line.split(':')[0]] = line.split(':')[1].strip()
256-
257298
return data, inputs, meta
258299

300+
259301
def get_pvgis_tmy(lat, lon, outputformat='json', usehorizon=True,
260302
userhorizon=None, startyear=None, endyear=None, url=URL,
261303
timeout=30):

0 commit comments

Comments
 (0)