Skip to content

Fix inconsistencies #1268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
Aug 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d7deb80
Add cams.get_cams_radiation function
Feb 22, 2021
510f08e
Revert "Add cams.get_cams_radiation function"
Feb 22, 2021
8132943
Fix inconsistencies
AdamRJensen Jul 30, 2021
a93f38a
Merge branch 'master' into pvlib_inconsistencies
AdamRJensen Jul 30, 2021
95c029e
Merge remote-tracking branch 'upstream/master' into pvlib_inconsisten…
AdamRJensen Jul 30, 2021
1a10c67
Merge remote-tracking branch 'upstream/master' into pvlib_inconsisten…
AdamRJensen Jul 30, 2021
95efd76
Have station arg precede start/end in get_bsrn
AdamRJensen Jul 30, 2021
f4c2576
Update get_bsrn doc string
AdamRJensen Jul 30, 2021
082c3f8
Change output order in psm3
AdamRJensen Jul 30, 2021
b8bdd62
Add variable map to pvgis_tmy with depreciating warning
AdamRJensen Aug 2, 2021
b659af2
Add variable_map to pvgis_tmy
AdamRJensen Aug 2, 2021
146a8b5
Coverage for variable_map for read_pvigs_tmy
AdamRJensen Aug 2, 2021
2ac6185
Add "versionchanged" to psm3 docs
AdamRJensen Aug 2, 2021
5303e08
Update psm3 docs
AdamRJensen Aug 2, 2021
941eb30
Update versionchanged
AdamRJensen Aug 2, 2021
ab4ac23
Update versionchange message
AdamRJensen Aug 3, 2021
b4a5228
Correct ouput for get_pvgis_tmy with epw format
AdamRJensen Aug 4, 2021
dbee07e
Update pvgis_tmy map test
AdamRJensen Aug 4, 2021
42db488
Update v0.9.0.rst
AdamRJensen Aug 4, 2021
58242b5
Implement comments from review by kanderso-nrel
AdamRJensen Aug 5, 2021
7f3b32c
Remove 'empty' columns when an empty dataframe is returned by bsrn
AdamRJensen Aug 5, 2021
d67a1e9
Remove admonition about pvgis renaming in introtutorial.rst
AdamRJensen Aug 5, 2021
d9bc9cb
Fix typo in pvigs_tmy documentation
AdamRJensen Aug 5, 2021
162cd2f
Fix references in whatsnew
AdamRJensen Aug 5, 2021
ecc549a
Refactor pvigs_tmy
AdamRJensen Aug 6, 2021
9cb3602
Fix stickler
AdamRJensen Aug 6, 2021
0b6ccb5
Fix issue references in whatsnew
AdamRJensen Aug 6, 2021
aedc064
Coverage for get_pvgis_tmy map_variables
AdamRJensen Aug 6, 2021
7dd2c3c
Fix errors in whatsnew
AdamRJensen Aug 6, 2021
6d1045c
Add double backticks in whatsnew
AdamRJensen Aug 9, 2021
01f5d3c
Add double backticks in whatsnew
AdamRJensen Aug 9, 2021
381870f
Add double backticks in whatsnew
AdamRJensen Aug 9, 2021
17f9138
Add double backticks in whatsnew
AdamRJensen Aug 9, 2021
c8e5a6a
Change fail version to 0.10 in test_modelchain
AdamRJensen Aug 9, 2021
8c77b65
Coverage for deprecation warnings
AdamRJensen Aug 9, 2021
351f549
Fix doublebackticks in whatsnew
AdamRJensen Aug 9, 2021
0aee6a8
Fix stickler
AdamRJensen Aug 9, 2021
6276ccc
Replace tab with spaces in introtutorial
AdamRJensen Aug 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 2 additions & 13 deletions docs/sphinx/source/introtutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,13 @@ the :ref:`iotools` module. In this example we will be using PVGIS, one of the
data sources available, to retrieve a Typical Meteorological Year (TMY) which
includes irradiation, temperature and wind speed.

.. note:: PVGIS uses different naming conventions, so it is required to rename
the weather data variables before using them. Data is already UTC-localized,
so conversion to local timezone is optional.

.. ipython:: python

variables_translation = {
"Gb(n)": "dni",
"G(h)": "ghi",
"Gd(h)": "dhi",
"T2m": "temp_air",
"WS10m": "wind_speed",
}
tmys = []
for location in coordinates:
latitude, longitude, name, altitude, timezone = location
weather = pvlib.iotools.get_pvgis_tmy(latitude, longitude)[0]
weather = weather.rename(columns=variables_translation)
weather = pvlib.iotools.get_pvgis_tmy(latitude, longitude,
map_variables=True)[0]
weather.index.name = "utc_time"
tmys.append(weather)

Expand Down
12 changes: 12 additions & 0 deletions docs/sphinx/source/whatsnew/v0.9.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ Breaking changes
:py:meth:`~pvlib.pvsystem.PVSystem.calcparams_desoto` and
:py:meth:`~pvlib.pvsystem.PVSystem.calcparams_cec` (:issue:`1118`, :pull:`1222`)

* Switched the order of the outputs from the PSM3 iotools, notably
:py:func:`~pvlib.iotools.get_psm3` and :py:func:`~pvlib.iotools.read_psm3`
(:issue:`1245`, :pull:`1268`)

* Changed the naming of the inputs ``startdate``/``enddate`` to ``start``/``end`` in
:py:func:`~pvlib.iotools.get_ecmwf_macc`
(:issue:`1245`, :pull:`1268`)

* Change the naming of the inputs ``lat``/``lon`` to ``latitude``/``longitude`` in
:py:func:`~pvlib.iotools.get_pvgis_tmy` (:issue:`1245`, :pull:`1268`)

Deprecations
~~~~~~~~~~~~
Expand Down Expand Up @@ -111,6 +121,8 @@ Enhancements
:func:`~pvlib.iotools.get_pvgis_hourly` for reading and retrieving hourly
solar radiation data and PV power output from PVGIS. (:pull:`1186`,
:issue:`849`)
* Added ``map_variables`` option to :func:`~pvlib.iotools.get_pvgis_tmy` and
:func:`~pvlib.iotools.read_pvgis_tmy` (:issue:`1250`, :pull:`1268`)
* Add :func:`~pvlib.iotools.get_bsrn` and :func:`~pvlib.iotools.read_bsrn`
for retrieving and reading BSRN solar radiation data files.
(:pull:`1254`, :pull:`1145`, :issue:`1015`)
Expand Down
7 changes: 4 additions & 3 deletions pvlib/iotools/bsrn.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ def _empty_dataframe_from_logical_records(logical_records):
columns = []
for lr in logical_records:
columns += BSRN_COLUMNS[lr][2:]
columns = [c for c in columns if c != 'empty']
return pd.DataFrame(columns=columns)


def get_bsrn(start, end, station, username, password,
def get_bsrn(station, start, end, username, password,
logical_records=('0100',), local_path=None):
"""
Retrieve ground measured irradiance data from the BSRN FTP server.
Expand All @@ -73,12 +74,12 @@ def get_bsrn(start, end, station, username, password,

Parameters
----------
station: str
3-letter BSRN station abbreviation
start: datetime-like
First day of the requested period
end: datetime-like
Last day of the requested period
station: str
3-letter BSRN station abbreviation
username: str
username for accessing the BSRN FTP server
password: str
Expand Down
28 changes: 14 additions & 14 deletions pvlib/iotools/ecmwf_macc.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ def ECMWFDataServer(*a, **kw):
}


def _ecmwf(server, startdate, stopdate, params, targetname):
def _ecmwf(server, startdate, enddate, params, targetname):
# see http://apps.ecmwf.int/datasets/data/macc-reanalysis/levtype=sfc/
server.retrieve({
"class": "mc",
"dataset": "macc",
"date": "%s/to/%s" % (startdate, stopdate),
"date": "%s/to/%s" % (startdate, enddate),
"expver": "rean",
"grid": "0.75/0.75",
"levtype": "sfc",
Expand All @@ -53,7 +53,7 @@ def _ecmwf(server, startdate, stopdate, params, targetname):
})


def get_ecmwf_macc(filename, params, startdate, stopdate, lookup_params=True,
def get_ecmwf_macc(filename, params, start, end, lookup_params=True,
server=None, target=_ecmwf):
"""
Download data from ECMWF MACC Reanalysis API.
Expand All @@ -64,9 +64,9 @@ def get_ecmwf_macc(filename, params, startdate, stopdate, lookup_params=True,
full path of file where to save data, ``.nc`` appended if not given
params : str or sequence of str
keynames of parameter[s] to download
startdate : datetime.datetime or datetime.date
start : datetime.datetime or datetime.date
UTC date
stopdate : datetime.datetime or datetime.date
end : datetime.datetime or datetime.date
UTC date
lookup_params : bool, default True
optional flag, if ``False``, then codes are already formatted
Expand Down Expand Up @@ -137,7 +137,7 @@ def get_ecmwf_macc(filename, params, startdate, stopdate, lookup_params=True,
:func:`pvlib.iotools.get_ecmwf_macc`. ::


target(server, startdate, stopdate, params, filename) -> None
target(server, startdate, enddate, params, filename) -> None

Examples
--------
Expand All @@ -161,12 +161,12 @@ def get_ecmwf_macc(filename, params, startdate, stopdate, lookup_params=True,
params = '/'.join(PARAMS.get(p) for p in params)
except TypeError:
params = PARAMS.get(params)
startdate = startdate.strftime('%Y-%m-%d')
stopdate = stopdate.strftime('%Y-%m-%d')
startdate = start.strftime('%Y-%m-%d')
enddate = end.strftime('%Y-%m-%d')
if not server:
server = ECMWFDataServer()
t = threading.Thread(target=target, daemon=True,
args=(server, startdate, stopdate, params, filename))
args=(server, startdate, enddate, params, filename))
t.start()
return t

Expand All @@ -191,8 +191,8 @@ def __init__(self, filename):
# time resolution in hours
self.time_size = self.data.dimensions['time'].size
self.start_time = self.data['time'][0]
self.stop_time = self.data['time'][-1]
self.time_range = self.stop_time - self.start_time
self.end_time = self.data['time'][-1]
self.time_range = self.end_time - self.start_time
self.delta_time = self.time_range / (self.time_size - 1)

def get_nearest_indices(self, latitude, longitude):
Expand Down Expand Up @@ -281,7 +281,7 @@ def read_ecmwf_macc(filename, latitude, longitude, utc_time_range=None):
longitude : float
longitude in degrees
utc_time_range : sequence of datetime.datetime
pair of start and stop naive or UTC date-times
pair of start and end naive or UTC date-times

Returns
-------
Expand All @@ -295,9 +295,9 @@ def read_ecmwf_macc(filename, latitude, longitude, utc_time_range=None):
if utc_time_range:
start_idx = netCDF4.date2index(
utc_time_range[0], nctime, select='before')
stop_idx = netCDF4.date2index(
end_idx = netCDF4.date2index(
utc_time_range[-1], nctime, select='after')
time_slice = slice(start_idx, stop_idx + 1)
time_slice = slice(start_idx, end_idx + 1)
else:
time_slice = slice(0, ecmwf_macc.time_size)
times = netCDF4.num2date(nctime[time_slice], nctime.units)
Expand Down
68 changes: 42 additions & 26 deletions pvlib/iotools/psm3.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,
Retrieve NSRDB PSM3 timeseries weather data from the PSM3 API. The NSRDB
is described in [1]_ and the PSM3 API is described in [2]_, [3]_, and [4]_.

.. versionchanged:: 0.9.0
The function now returns a tuple where the first element is a dataframe
and the second element is a dictionary containing metadata. Previous
versions of this function had the return values switched.

Parameters
----------
latitude : float or int
Expand Down Expand Up @@ -61,11 +66,11 @@ def get_psm3(latitude, longitude, api_key, email, names='tmy', interval=60,

Returns
-------
headers : dict
metadata from NREL PSM3 about the record, see
:func:`pvlib.iotools.parse_psm3` for fields
data : pandas.DataFrame
timeseries data from NREL PSM3
metadata : dict
metadata from NREL PSM3 about the record, see
:func:`pvlib.iotools.parse_psm3` for fields

Raises
------
Expand Down Expand Up @@ -170,22 +175,30 @@ def parse_psm3(fbuf):
Parse an NSRDB PSM3 weather file (formatted as SAM CSV). The NSRDB
is described in [1]_ and the SAM CSV format is described in [2]_.

.. versionchanged:: 0.9.0
The function now returns a tuple where the first element is a dataframe
and the second element is a dictionary containing metadata. Previous
versions of this function had the return values switched.

Parameters
----------
fbuf: file-like object
File-like object containing data to read.

Returns
-------
headers : dict
metadata from NREL PSM3 about the record, see notes for fields
data : pandas.DataFrame
timeseries data from NREL PSM3
metadata : dict
metadata from NREL PSM3 about the record, see notes for fields

Notes
-----
The return is a tuple with two items. The first item is a header with
metadata from NREL PSM3 about the record containing the following fields:
The return is a tuple with two items. The first item is a dataframe with
the PSM3 timeseries data.

The second item is a dictionary with metadata from NREL PSM3 about the
record containing the following fields:

* Source
* Location ID
Expand Down Expand Up @@ -234,13 +247,11 @@ def parse_psm3(fbuf):
* Surface Albedo Units
* Version

The second item is a dataframe with the PSM3 timeseries data.

Examples
--------
>>> # Read a local PSM3 file:
>>> with open(filename, 'r') as f: # doctest: +SKIP
... metadata, df = iotools.parse_psm3(f) # doctest: +SKIP
... df, metadata = iotools.parse_psm3(f) # doctest: +SKIP

See Also
--------
Expand All @@ -254,17 +265,17 @@ def parse_psm3(fbuf):
<https://rredc.nrel.gov/solar/old_data/nsrdb/2005-2012/wfcsv.pdf>`_
"""
# The first 2 lines of the response are headers with metadata
header_fields = fbuf.readline().split(',')
header_fields[-1] = header_fields[-1].strip() # strip trailing newline
header_values = fbuf.readline().split(',')
header_values[-1] = header_values[-1].strip() # strip trailing newline
header = dict(zip(header_fields, header_values))
# the response is all strings, so set some header types to numbers
header['Local Time Zone'] = int(header['Local Time Zone'])
header['Time Zone'] = int(header['Time Zone'])
header['Latitude'] = float(header['Latitude'])
header['Longitude'] = float(header['Longitude'])
header['Elevation'] = int(header['Elevation'])
metadata_fields = fbuf.readline().split(',')
metadata_fields[-1] = metadata_fields[-1].strip() # strip trailing newline
metadata_values = fbuf.readline().split(',')
metadata_values[-1] = metadata_values[-1].strip() # strip trailing newline
metadata = dict(zip(metadata_fields, metadata_values))
# the response is all strings, so set some metadata types to numbers
metadata['Local Time Zone'] = int(metadata['Local Time Zone'])
metadata['Time Zone'] = int(metadata['Time Zone'])
metadata['Latitude'] = float(metadata['Latitude'])
metadata['Longitude'] = float(metadata['Longitude'])
metadata['Elevation'] = int(metadata['Elevation'])
# get the column names so we can set the dtypes
columns = fbuf.readline().split(',')
columns[-1] = columns[-1].strip() # strip trailing newline
Expand All @@ -282,29 +293,34 @@ def parse_psm3(fbuf):
dtidx = pd.to_datetime(
data[['Year', 'Month', 'Day', 'Hour', 'Minute']])
# in USA all timezones are integers
tz = 'Etc/GMT%+d' % -header['Time Zone']
tz = 'Etc/GMT%+d' % -metadata['Time Zone']
data.index = pd.DatetimeIndex(dtidx).tz_localize(tz)

return header, data
return data, metadata


def read_psm3(filename):
"""
Read an NSRDB PSM3 weather file (formatted as SAM CSV). The NSRDB
is described in [1]_ and the SAM CSV format is described in [2]_.

.. versionchanged:: 0.9.0
The function now returns a tuple where the first element is a dataframe
and the second element is a dictionary containing metadata. Previous
versions of this function had the return values switched.

Parameters
----------
filename: str
Filename of a file containing data to read.

Returns
-------
headers : dict
metadata from NREL PSM3 about the record, see
:func:`pvlib.iotools.parse_psm3` for fields
data : pandas.DataFrame
timeseries data from NREL PSM3
metadata : dict
metadata from NREL PSM3 about the record, see
:func:`pvlib.iotools.parse_psm3` for fields

See Also
--------
Expand Down
Loading