Skip to content

Commit 8480af3

Browse files
authored
Remove networking code from iotools.read_tmy3, tkinter from read_tmy2/3 (#1004)
* remove networking code from tmy.read_tmy3 * whatsnew * whats even newer * improvements from review * forgot open(pathlib.Path) doesn't work on python 3.5 * move line outside with block * whatsnew entry for tkinter removal
1 parent 39b3607 commit 8480af3

File tree

3 files changed

+25
-64
lines changed

3 files changed

+25
-64
lines changed

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,15 @@ API Changes with Deprecations
1616
API Changes
1717
~~~~~~~~~~~
1818
* Removed ``run_parallel_calculations`` and ``n_workers_for_parallel_calcs``
19-
from :py:func:`pvlib.bifacial.pvfactors_timeseries` inputs (:issue:`902`)(:pull:`934`)
19+
from :py:func:`pvlib.bifacial.pvfactors_timeseries` inputs (:issue:`902`) (:pull:`934`)
20+
* :py:func:`pvlib.iotools.read_tmy3` can now only read local data files because
21+
the NREL RREDC server hosting the TMY3 dataset has been retired. For
22+
fetching TMY data from NREL servers, :py:func:`pvlib.iotools.get_psm3` is
23+
now recommended to retrieve newer PSM3 data over the older TMY3 data.
24+
(:issue:`996`) (:pull:`1004`)
25+
* The tkinter-based file selection dialog has been removed from
26+
:py:func:`pvlib.iotools.read_tmy2` and :py:func:`pvlib.iotools.read_tmy3`;
27+
the filepath is now a required parameter. (:pull:`1004`)
2028

2129
Enhancements
2230
~~~~~~~~~~~~

pvlib/iotools/tmy.py

Lines changed: 14 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,26 @@
33
"""
44

55
import datetime
6-
import io
76
import re
8-
from urllib.request import urlopen, Request
97
import pandas as pd
108

119

12-
def read_tmy3(filename=None, coerce_year=None, recolumn=True):
10+
def read_tmy3(filename, coerce_year=None, recolumn=True):
1311
'''
1412
Read a TMY3 file in to a pandas dataframe.
1513
1614
Note that values contained in the metadata dictionary are unchanged
1715
from the TMY3 file (i.e. units are retained). In the case of any
18-
discrepencies between this documentation and the TMY3 User's Manual
16+
discrepancies between this documentation and the TMY3 User's Manual
1917
[1]_, the TMY3 User's Manual takes precedence.
2018
2119
The TMY3 files were updated in Jan. 2015. This function requires the
2220
use of the updated files.
2321
2422
Parameters
2523
----------
26-
filename : None or string, default None
27-
If None, attempts to use a Tkinter file browser. A string can be
28-
a relative file path, absolute file path, or url.
24+
filename : str
25+
A relative file path or absolute file path.
2926
3027
coerce_year : None or int, default None
3128
If supplied, the year of the index will be set to `coerce_year`, except
@@ -161,46 +158,25 @@ def read_tmy3(filename=None, coerce_year=None, recolumn=True):
161158
Update: Users Manual. 472 pp.; NREL Report No. TP-581-41364.
162159
'''
163160

164-
if filename is None:
165-
try:
166-
filename = _interactive_load()
167-
except ImportError:
168-
raise ImportError('Interactive load failed. tkinter not supported '
169-
'on this system. Try installing X-Quartz and '
170-
'reloading')
171-
172161
head = ['USAF', 'Name', 'State', 'TZ', 'latitude', 'longitude', 'altitude']
173162

174-
if str(filename).startswith('http'):
175-
request = Request(filename, headers={'User-Agent': (
176-
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) '
177-
'AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 '
178-
'Safari/537.36')})
179-
response = urlopen(request)
180-
csvdata = io.StringIO(response.read().decode(errors='ignore'))
181-
else:
182-
# assume it's accessible via the file system
183-
csvdata = open(str(filename), 'r')
184-
185-
# read in file metadata, advance buffer to second line
186-
firstline = csvdata.readline()
187-
if 'Request Rejected' in firstline:
188-
raise IOError('Remote server rejected TMY file request')
163+
with open(str(filename), 'r') as csvdata:
164+
# read in file metadata, advance buffer to second line
165+
firstline = csvdata.readline()
166+
# use pandas to read the csv file buffer
167+
# header is actually the second line, but tell pandas to look for
168+
# header information on the 1st line (0 indexing) because we've already
169+
# advanced past the true first line with the readline call above.
170+
data = pd.read_csv(csvdata, header=0)
189171

190172
meta = dict(zip(head, firstline.rstrip('\n').split(",")))
191-
192173
# convert metadata strings to numeric types
193174
meta['altitude'] = float(meta['altitude'])
194175
meta['latitude'] = float(meta['latitude'])
195176
meta['longitude'] = float(meta['longitude'])
196177
meta['TZ'] = float(meta['TZ'])
197178
meta['USAF'] = int(meta['USAF'])
198179

199-
# use pandas to read the csv file/stringio buffer
200-
# header is actually the second line in file, but tell pandas to look for
201-
# header information on the 1st line (0 indexing) because we've already
202-
# advanced past the true first line with the readline call above.
203-
data = pd.read_csv(csvdata, header=0)
204180
# get the date column as a pd.Series of numpy datetime64
205181
data_ymd = pd.to_datetime(data['Date (MM/DD/YYYY)'], format='%m/%d/%Y')
206182
# shift the time column so that midnite is 00:00 instead of 24:00
@@ -231,13 +207,6 @@ def read_tmy3(filename=None, coerce_year=None, recolumn=True):
231207
return data, meta
232208

233209

234-
def _interactive_load():
235-
import tkinter
236-
from tkinter.filedialog import askopenfilename
237-
tkinter.Tk().withdraw() # Start interactive file input
238-
return askopenfilename()
239-
240-
241210
def _recolumn(tmy3_dataframe):
242211
"""
243212
Rename the columns of the TMY3 DataFrame.
@@ -295,9 +264,8 @@ def read_tmy2(filename):
295264
296265
Parameters
297266
----------
298-
filename : None or string
299-
If None, attempts to use a Tkinter file browser. A string can be
300-
a relative file path, absolute file path, or url.
267+
filename : str
268+
A relative or absolute file path.
301269
302270
Returns
303271
-------
@@ -412,14 +380,6 @@ def read_tmy2(filename):
412380
for TMY2s". NREL 1995.
413381
'''
414382

415-
if filename is None:
416-
try:
417-
filename = _interactive_load()
418-
except ImportError:
419-
raise ImportError('Interactive load failed. tkinter not supported '
420-
'on this system. Try installing X-Quartz and '
421-
'reloading')
422-
423383
# paste in the column info as one long line
424384
string = '%2d%2d%2d%2d%4d%4d%4d%1s%1d%4d%1s%1d%4d%1s%1d%4d%1s%1d%4d%1s%1d%4d%1s%1d%4d%1s%1d%2d%1s%1d%2d%1s%1d%4d%1s%1d%4d%1s%1d%3d%1s%1d%4d%1s%1d%3d%1s%1d%3d%1s%1d%4d%1s%1d%5d%1s%1d%10d%3d%1s%1d%3d%1s%1d%3d%1s%1d%2d%1s%1d' # noqa: E501
425385
columns = 'year,month,day,hour,ETR,ETRN,GHI,GHISource,GHIUncertainty,DNI,DNISource,DNIUncertainty,DHI,DHISource,DHIUncertainty,GHillum,GHillumSource,GHillumUncertainty,DNillum,DNillumSource,DNillumUncertainty,DHillum,DHillumSource,DHillumUncertainty,Zenithlum,ZenithlumSource,ZenithlumUncertainty,TotCld,TotCldSource,TotCldUncertainty,OpqCld,OpqCldSource,OpqCldUncertainty,DryBulb,DryBulbSource,DryBulbUncertainty,DewPoint,DewPointSource,DewPointUncertainty,RHum,RHumSource,RHumUncertainty,Pressure,PressureSource,PressureUncertainty,Wdir,WdirSource,WdirUncertainty,Wspd,WspdSource,WspdUncertainty,Hvis,HvisSource,HvisUncertainty,CeilHgt,CeilHgtSource,CeilHgtUncertainty,PresentWeather,Pwat,PwatSource,PwatUncertainty,AOD,AODSource,AODUncertainty,SnowDepth,SnowDepthSource,SnowDepthUncertainty,LastSnowfall,LastSnowfallSource,LastSnowfallUncertaint' # noqa: E501

pvlib/tests/iotools/test_tmy.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import numpy as np
22
import pandas as pd
3-
import pytest
43
from pvlib.iotools import tmy
5-
from conftest import DATA_DIR, RERUNS, RERUNS_DELAY
4+
from conftest import DATA_DIR
65

76
# test the API works
87
from pvlib.iotools import read_tmy3
@@ -16,13 +15,6 @@ def test_read_tmy3():
1615
tmy.read_tmy3(TMY3_TESTFILE)
1716

1817

19-
@pytest.mark.remote_data
20-
@pytest.mark.flaky(reruns=RERUNS, reruns_delay=RERUNS_DELAY)
21-
def test_read_tmy3_remote():
22-
url = 'http://rredc.nrel.gov/solar/old_data/nsrdb/1991-2005/data/tmy3/703165TYA.CSV'
23-
tmy.read_tmy3(url)
24-
25-
2618
def test_read_tmy3_recolumn():
2719
data, meta = tmy.read_tmy3(TMY3_TESTFILE)
2820
assert 'GHISource' in data.columns
@@ -47,6 +39,7 @@ def test_read_tmy3_no_coerce_year():
4739
assert data.index[-2] == pd.Timestamp('1998-12-31 23:00:00-09:00')
4840
assert data.index[-1] == pd.Timestamp('1999-01-01 00:00:00-09:00')
4941

42+
5043
def test_read_tmy2():
5144
tmy.read_tmy2(TMY2_TESTFILE)
5245

0 commit comments

Comments
 (0)