Skip to content

Commit f318c1c

Browse files
AdamRJensenAdamRJensenwholmgren
authored
Fix inconsistencies (#1268)
* Add cams.get_cams_radiation function * Revert "Add cams.get_cams_radiation function" This reverts commit d7deb80. * Fix inconsistencies Enforce the usage of the following terminology in the iotools inputs: start/end, latitude/longitude, and metadata. Also, latitude/longitude should come before start/end * Have station arg precede start/end in get_bsrn * Update get_bsrn doc string * Change output order in psm3 * Add variable map to pvgis_tmy with depreciating warning * Add variable_map to pvgis_tmy * Coverage for variable_map for read_pvigs_tmy * Add "versionchanged" to psm3 docs * Update psm3 docs * Update versionchanged * Update versionchange message * Correct ouput for get_pvgis_tmy with epw format * Update pvgis_tmy map test * Update v0.9.0.rst * Implement comments from review by kanderso-nrel * Remove 'empty' columns when an empty dataframe is returned by bsrn * Remove admonition about pvgis renaming in introtutorial.rst * Fix typo in pvigs_tmy documentation * Fix references in whatsnew * Refactor pvigs_tmy * Fix stickler * Fix issue references in whatsnew * Coverage for get_pvgis_tmy map_variables * Fix errors in whatsnew * Add double backticks in whatsnew Co-authored-by: Will Holmgren <[email protected]> * Add double backticks in whatsnew Co-authored-by: Will Holmgren <[email protected]> * Add double backticks in whatsnew Co-authored-by: Will Holmgren <[email protected]> * Add double backticks in whatsnew * Change fail version to 0.10 in test_modelchain * Coverage for deprecation warnings * Fix doublebackticks in whatsnew * Fix stickler * Replace tab with spaces in introtutorial Co-authored-by: AdamRJensen <[email protected]> Co-authored-by: Will Holmgren <[email protected]>
1 parent 0fd5c43 commit f318c1c

File tree

10 files changed

+226
-135
lines changed

10 files changed

+226
-135
lines changed

docs/sphinx/source/introtutorial.rst

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,13 @@ the :ref:`iotools` module. In this example we will be using PVGIS, one of the
5252
data sources available, to retrieve a Typical Meteorological Year (TMY) which
5353
includes irradiation, temperature and wind speed.
5454

55-
.. note:: PVGIS uses different naming conventions, so it is required to rename
56-
the weather data variables before using them. Data is already UTC-localized,
57-
so conversion to local timezone is optional.
58-
5955
.. ipython:: python
6056
61-
variables_translation = {
62-
"Gb(n)": "dni",
63-
"G(h)": "ghi",
64-
"Gd(h)": "dhi",
65-
"T2m": "temp_air",
66-
"WS10m": "wind_speed",
67-
}
6857
tmys = []
6958
for location in coordinates:
7059
latitude, longitude, name, altitude, timezone = location
71-
weather = pvlib.iotools.get_pvgis_tmy(latitude, longitude)[0]
72-
weather = weather.rename(columns=variables_translation)
60+
weather = pvlib.iotools.get_pvgis_tmy(latitude, longitude,
61+
map_variables=True)[0]
7362
weather.index.name = "utc_time"
7463
tmys.append(weather)
7564

docs/sphinx/source/whatsnew/v0.9.0.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ Breaking changes
4949
:py:meth:`~pvlib.pvsystem.PVSystem.calcparams_desoto` and
5050
:py:meth:`~pvlib.pvsystem.PVSystem.calcparams_cec` (:issue:`1118`, :pull:`1222`)
5151

52+
* Switched the order of the outputs from the PSM3 iotools, notably
53+
:py:func:`~pvlib.iotools.get_psm3` and :py:func:`~pvlib.iotools.read_psm3`
54+
(:issue:`1245`, :pull:`1268`)
55+
56+
* Changed the naming of the inputs ``startdate``/``enddate`` to ``start``/``end`` in
57+
:py:func:`~pvlib.iotools.get_ecmwf_macc`
58+
(:issue:`1245`, :pull:`1268`)
59+
60+
* Change the naming of the inputs ``lat``/``lon`` to ``latitude``/``longitude`` in
61+
:py:func:`~pvlib.iotools.get_pvgis_tmy` (:issue:`1245`, :pull:`1268`)
5262

5363
Deprecations
5464
~~~~~~~~~~~~
@@ -111,6 +121,8 @@ Enhancements
111121
:func:`~pvlib.iotools.get_pvgis_hourly` for reading and retrieving hourly
112122
solar radiation data and PV power output from PVGIS. (:pull:`1186`,
113123
:issue:`849`)
124+
* Added ``map_variables`` option to :func:`~pvlib.iotools.get_pvgis_tmy` and
125+
:func:`~pvlib.iotools.read_pvgis_tmy` (:issue:`1250`, :pull:`1268`)
114126
* Add :func:`~pvlib.iotools.get_bsrn` and :func:`~pvlib.iotools.read_bsrn`
115127
for retrieving and reading BSRN solar radiation data files.
116128
(:pull:`1254`, :pull:`1145`, :issue:`1015`)

pvlib/iotools/bsrn.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,11 @@ def _empty_dataframe_from_logical_records(logical_records):
5757
columns = []
5858
for lr in logical_records:
5959
columns += BSRN_COLUMNS[lr][2:]
60+
columns = [c for c in columns if c != 'empty']
6061
return pd.DataFrame(columns=columns)
6162

6263

63-
def get_bsrn(start, end, station, username, password,
64+
def get_bsrn(station, start, end, username, password,
6465
logical_records=('0100',), local_path=None):
6566
"""
6667
Retrieve ground measured irradiance data from the BSRN FTP server.
@@ -73,12 +74,12 @@ def get_bsrn(start, end, station, username, password,
7374
7475
Parameters
7576
----------
77+
station: str
78+
3-letter BSRN station abbreviation
7679
start: datetime-like
7780
First day of the requested period
7881
end: datetime-like
7982
Last day of the requested period
80-
station: str
81-
3-letter BSRN station abbreviation
8283
username: str
8384
username for accessing the BSRN FTP server
8485
password: str

pvlib/iotools/ecmwf_macc.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ def ECMWFDataServer(*a, **kw):
3434
}
3535

3636

37-
def _ecmwf(server, startdate, stopdate, params, targetname):
37+
def _ecmwf(server, startdate, enddate, params, targetname):
3838
# see http://apps.ecmwf.int/datasets/data/macc-reanalysis/levtype=sfc/
3939
server.retrieve({
4040
"class": "mc",
4141
"dataset": "macc",
42-
"date": "%s/to/%s" % (startdate, stopdate),
42+
"date": "%s/to/%s" % (startdate, enddate),
4343
"expver": "rean",
4444
"grid": "0.75/0.75",
4545
"levtype": "sfc",
@@ -53,7 +53,7 @@ def _ecmwf(server, startdate, stopdate, params, targetname):
5353
})
5454

5555

56-
def get_ecmwf_macc(filename, params, startdate, stopdate, lookup_params=True,
56+
def get_ecmwf_macc(filename, params, start, end, lookup_params=True,
5757
server=None, target=_ecmwf):
5858
"""
5959
Download data from ECMWF MACC Reanalysis API.
@@ -64,9 +64,9 @@ def get_ecmwf_macc(filename, params, startdate, stopdate, lookup_params=True,
6464
full path of file where to save data, ``.nc`` appended if not given
6565
params : str or sequence of str
6666
keynames of parameter[s] to download
67-
startdate : datetime.datetime or datetime.date
67+
start : datetime.datetime or datetime.date
6868
UTC date
69-
stopdate : datetime.datetime or datetime.date
69+
end : datetime.datetime or datetime.date
7070
UTC date
7171
lookup_params : bool, default True
7272
optional flag, if ``False``, then codes are already formatted
@@ -137,7 +137,7 @@ def get_ecmwf_macc(filename, params, startdate, stopdate, lookup_params=True,
137137
:func:`pvlib.iotools.get_ecmwf_macc`. ::
138138
139139
140-
target(server, startdate, stopdate, params, filename) -> None
140+
target(server, startdate, enddate, params, filename) -> None
141141
142142
Examples
143143
--------
@@ -161,12 +161,12 @@ def get_ecmwf_macc(filename, params, startdate, stopdate, lookup_params=True,
161161
params = '/'.join(PARAMS.get(p) for p in params)
162162
except TypeError:
163163
params = PARAMS.get(params)
164-
startdate = startdate.strftime('%Y-%m-%d')
165-
stopdate = stopdate.strftime('%Y-%m-%d')
164+
startdate = start.strftime('%Y-%m-%d')
165+
enddate = end.strftime('%Y-%m-%d')
166166
if not server:
167167
server = ECMWFDataServer()
168168
t = threading.Thread(target=target, daemon=True,
169-
args=(server, startdate, stopdate, params, filename))
169+
args=(server, startdate, enddate, params, filename))
170170
t.start()
171171
return t
172172

@@ -191,8 +191,8 @@ def __init__(self, filename):
191191
# time resolution in hours
192192
self.time_size = self.data.dimensions['time'].size
193193
self.start_time = self.data['time'][0]
194-
self.stop_time = self.data['time'][-1]
195-
self.time_range = self.stop_time - self.start_time
194+
self.end_time = self.data['time'][-1]
195+
self.time_range = self.end_time - self.start_time
196196
self.delta_time = self.time_range / (self.time_size - 1)
197197

198198
def get_nearest_indices(self, latitude, longitude):
@@ -281,7 +281,7 @@ def read_ecmwf_macc(filename, latitude, longitude, utc_time_range=None):
281281
longitude : float
282282
longitude in degrees
283283
utc_time_range : sequence of datetime.datetime
284-
pair of start and stop naive or UTC date-times
284+
pair of start and end naive or UTC date-times
285285
286286
Returns
287287
-------
@@ -295,9 +295,9 @@ def read_ecmwf_macc(filename, latitude, longitude, utc_time_range=None):
295295
if utc_time_range:
296296
start_idx = netCDF4.date2index(
297297
utc_time_range[0], nctime, select='before')
298-
stop_idx = netCDF4.date2index(
298+
end_idx = netCDF4.date2index(
299299
utc_time_range[-1], nctime, select='after')
300-
time_slice = slice(start_idx, stop_idx + 1)
300+
time_slice = slice(start_idx, end_idx + 1)
301301
else:
302302
time_slice = slice(0, ecmwf_macc.time_size)
303303
times = netCDF4.num2date(nctime[time_slice], nctime.units)

pvlib/iotools/psm3.py

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
2828
Retrieve NSRDB PSM3 timeseries weather data from the PSM3 API. The NSRDB
2929
is described in [1]_ and the PSM3 API is described in [2]_, [3]_, and [4]_.
3030
31+
.. versionchanged:: 0.9.0
32+
The function now returns a tuple where the first element is a dataframe
33+
and the second element is a dictionary containing metadata. Previous
34+
versions of this function had the return values switched.
35+
3136
Parameters
3237
----------
3338
latitude : float or int
@@ -61,11 +66,11 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
6166
6267
Returns
6368
-------
64-
headers : dict
65-
metadata from NREL PSM3 about the record, see
66-
:func:`pvlib.iotools.parse_psm3` for fields
6769
data : pandas.DataFrame
6870
timeseries data from NREL PSM3
71+
metadata : dict
72+
metadata from NREL PSM3 about the record, see
73+
:func:`pvlib.iotools.parse_psm3` for fields
6974
7075
Raises
7176
------
@@ -170,22 +175,30 @@ def parse_psm3(fbuf):
170175
Parse an NSRDB PSM3 weather file (formatted as SAM CSV). The NSRDB
171176
is described in [1]_ and the SAM CSV format is described in [2]_.
172177
178+
.. versionchanged:: 0.9.0
179+
The function now returns a tuple where the first element is a dataframe
180+
and the second element is a dictionary containing metadata. Previous
181+
versions of this function had the return values switched.
182+
173183
Parameters
174184
----------
175185
fbuf: file-like object
176186
File-like object containing data to read.
177187
178188
Returns
179189
-------
180-
headers : dict
181-
metadata from NREL PSM3 about the record, see notes for fields
182190
data : pandas.DataFrame
183191
timeseries data from NREL PSM3
192+
metadata : dict
193+
metadata from NREL PSM3 about the record, see notes for fields
184194
185195
Notes
186196
-----
187-
The return is a tuple with two items. The first item is a header with
188-
metadata from NREL PSM3 about the record containing the following fields:
197+
The return is a tuple with two items. The first item is a dataframe with
198+
the PSM3 timeseries data.
199+
200+
The second item is a dictionary with metadata from NREL PSM3 about the
201+
record containing the following fields:
189202
190203
* Source
191204
* Location ID
@@ -234,13 +247,11 @@ def parse_psm3(fbuf):
234247
* Surface Albedo Units
235248
* Version
236249
237-
The second item is a dataframe with the PSM3 timeseries data.
238-
239250
Examples
240251
--------
241252
>>> # Read a local PSM3 file:
242253
>>> with open(filename, 'r') as f: # doctest: +SKIP
243-
... metadata, df = iotools.parse_psm3(f) # doctest: +SKIP
254+
... df, metadata = iotools.parse_psm3(f) # doctest: +SKIP
244255
245256
See Also
246257
--------
@@ -254,17 +265,17 @@ def parse_psm3(fbuf):
254265
<https://rredc.nrel.gov/solar/old_data/nsrdb/2005-2012/wfcsv.pdf>`_
255266
"""
256267
# The first 2 lines of the response are headers with metadata
257-
header_fields = fbuf.readline().split(',')
258-
header_fields[-1] = header_fields[-1].strip() # strip trailing newline
259-
header_values = fbuf.readline().split(',')
260-
header_values[-1] = header_values[-1].strip() # strip trailing newline
261-
header = dict(zip(header_fields, header_values))
262-
# the response is all strings, so set some header types to numbers
263-
header['Local Time Zone'] = int(header['Local Time Zone'])
264-
header['Time Zone'] = int(header['Time Zone'])
265-
header['Latitude'] = float(header['Latitude'])
266-
header['Longitude'] = float(header['Longitude'])
267-
header['Elevation'] = int(header['Elevation'])
268+
metadata_fields = fbuf.readline().split(',')
269+
metadata_fields[-1] = metadata_fields[-1].strip() # strip trailing newline
270+
metadata_values = fbuf.readline().split(',')
271+
metadata_values[-1] = metadata_values[-1].strip() # strip trailing newline
272+
metadata = dict(zip(metadata_fields, metadata_values))
273+
# the response is all strings, so set some metadata types to numbers
274+
metadata['Local Time Zone'] = int(metadata['Local Time Zone'])
275+
metadata['Time Zone'] = int(metadata['Time Zone'])
276+
metadata['Latitude'] = float(metadata['Latitude'])
277+
metadata['Longitude'] = float(metadata['Longitude'])
278+
metadata['Elevation'] = int(metadata['Elevation'])
268279
# get the column names so we can set the dtypes
269280
columns = fbuf.readline().split(',')
270281
columns[-1] = columns[-1].strip() # strip trailing newline
@@ -282,29 +293,34 @@ def parse_psm3(fbuf):
282293
dtidx = pd.to_datetime(
283294
data[['Year', 'Month', 'Day', 'Hour', 'Minute']])
284295
# in USA all timezones are integers
285-
tz = 'Etc/GMT%+d' % -header['Time Zone']
296+
tz = 'Etc/GMT%+d' % -metadata['Time Zone']
286297
data.index = pd.DatetimeIndex(dtidx).tz_localize(tz)
287298

288-
return header, data
299+
return data, metadata
289300

290301

291302
def read_psm3(filename):
292303
"""
293304
Read an NSRDB PSM3 weather file (formatted as SAM CSV). The NSRDB
294305
is described in [1]_ and the SAM CSV format is described in [2]_.
295306
307+
.. versionchanged:: 0.9.0
308+
The function now returns a tuple where the first element is a dataframe
309+
and the second element is a dictionary containing metadata. Previous
310+
versions of this function had the return values switched.
311+
296312
Parameters
297313
----------
298314
filename: str
299315
Filename of a file containing data to read.
300316
301317
Returns
302318
-------
303-
headers : dict
304-
metadata from NREL PSM3 about the record, see
305-
:func:`pvlib.iotools.parse_psm3` for fields
306319
data : pandas.DataFrame
307320
timeseries data from NREL PSM3
321+
metadata : dict
322+
metadata from NREL PSM3 about the record, see
323+
:func:`pvlib.iotools.parse_psm3` for fields
308324
309325
See Also
310326
--------

0 commit comments

Comments
 (0)