Skip to content

Commit a5888e4

Browse files
committed
add ability to open tmy3 files via a url. required more flexible renaming
1 parent 78724f5 commit a5888e4

File tree

1 file changed

+72
-45
lines changed

1 file changed

+72
-45
lines changed

pvlib/tmy.py

Lines changed: 72 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
import logging
66
pvl_logger = logging.getLogger('pvlib')
77

8-
import pdb
98
import re
109
import datetime
1110
import dateutil
12-
import csv
11+
import io
12+
try:
13+
from urllib2 import urlopen
14+
except ImportError:
15+
from urllib.request import urlopen
1316

1417
import pandas as pd
1518
import numpy as np
@@ -18,53 +21,57 @@
1821

1922

2023

21-
def readtmy3(filename=None):
24+
def readtmy3(filename=None, coerce_year=None, recolumn=True):
2225
'''
23-
Read a TMY3 file in to a pandas dataframe
26+
Read a TMY3 file in to a pandas dataframe.
2427
2528
Read a TMY3 file and make a pandas dataframe of the data. Note that values
26-
contained in the struct are unchanged from the TMY3 file (i.e. units
29+
contained in the metadata dictionary are unchanged from the TMY3 file (i.e. units
2730
are retained). In the case of any discrepencies between this
2831
documentation and the TMY3 User's Manual ([1]), the TMY3 User's Manual
2932
takes precedence.
3033
31-
If a filename is not provided, the user will be prompted to browse to
32-
an appropriate TMY3 file.
33-
3434
Parameters
3535
----------
3636
37-
filename : string
38-
An optional argument which allows the user to select which
39-
TMY3 format file should be read. A file path may also be necessary if
40-
the desired TMY3 file is not in the MATLAB working path.
37+
filename : None or string
38+
If None, attempts to use an interactive file browser.
39+
A string can be a relative file path, absolute file path,
40+
or url.
41+
42+
coerce_year : None or int
43+
If supplied, the year of the data will be coerced to this input.
44+
45+
recolumn : bool
46+
If True, apply standard names to TMY3 columns.
47+
Typically this resulsts in stripping the units from the column name.
48+
4149
4250
Returns
4351
-------
4452
45-
TMYDATA : DataFrame
53+
data : DataFrame
4654
47-
A pandas dataframe, is provided with the components in the table below. Note
48-
that for more detailed descriptions of each component, please consult
49-
the TMY3 User's Manual ([1]), especially tables 1-1 through 1-6.
55+
A pandas dataframe with the columns described in the table below.
56+
For more detailed descriptions of each component, please consult
57+
the TMY3 User's Manual ([1]), especially tables 1-1 through 1-6.
5058
51-
meta : struct
52-
struct of meta data is created, which contains all
53-
site metadata available in the file
59+
metadata : dict
60+
The site metadata available in the file.
5461
5562
Notes
5663
-----
5764
5865
=============== ====== ===================
59-
meta field format description
66+
key format description
6067
=============== ====== ===================
61-
meta.altitude Float site elevation
62-
meta.latitude Float site latitudeitude
63-
meta.longitude Float site longitudeitude
64-
meta.Name String site name
65-
meta.State String state
66-
meta.TZ Float timezone
67-
meta.USAF Int USAF identifier
68+
altitude Float site elevation
69+
latitude Float site latitudeitude
70+
longitude Float site longitudeitude
71+
Name String site name
72+
State String state
73+
TZ Float UTC offset
74+
USAF Int USAF identifier
6875
=============== ====== ===================
6976
7077
============================= ======================================================================================================================================================
@@ -147,24 +154,26 @@ def readtmy3(filename=None):
147154
148155
[2] Wilcox, S. (2007). National Solar Radiation Database 1991 2005
149156
Update: Users Manual. 472 pp.; NREL Report No. TP-581-41364.
150-
151-
See also
152-
---------
153-
154-
pvl_makelocationstruct
155-
pvl_readtmy2
156-
157157
'''
158158

159-
if filename is None: #If no filename is input
159+
if filename is None:
160160
try:
161161
filename = interactive_load()
162162
except:
163163
raise Exception('Interactive load failed. Tkinter not supported on this system. Try installing X-Quartz and reloading')
164164

165-
head = ['USAF','Name','State','TZ','latitude','longitude','altitude']
166-
headerfile = open(filename,'r')
167-
meta = dict(zip(head,headerfile.readline().rstrip('\n').split(","))) #Read in file metadata
165+
head = ['USAF', 'Name', 'State', 'TZ', 'latitude', 'longitude', 'altitude']
166+
167+
try:
168+
csvdata = open(filename, 'r')
169+
except IOError:
170+
response = urlopen(filename)
171+
csvdata = io.StringIO(response.read().decode(errors='ignore'))
172+
173+
# read in file metadata
174+
meta = dict(zip(head, csvdata.readline().rstrip('\n').split(",")))
175+
176+
# convert metadata strings to numeric types
168177
meta['altitude'] = float(meta['altitude'])
169178
meta['latitude'] = float(meta['latitude'])
170179
meta['longitude'] = float(meta['longitude'])
@@ -174,8 +183,9 @@ def readtmy3(filename=None):
174183
TMYData = pd.read_csv(filename, header=1,
175184
parse_dates={'datetime':['Date (MM/DD/YYYY)','Time (HH:MM)']},
176185
date_parser=parsedate, index_col='datetime')
177-
178-
TMYData = recolumn(TMYData) #rename to standard column names
186+
187+
if recolumn:
188+
_recolumn(TMYData) #rename to standard column names
179189

180190
TMYData = TMYData.tz_localize(int(meta['TZ']*3600))
181191

@@ -214,8 +224,23 @@ def parsetz(UTC):
214224

215225

216226

217-
def recolumn(TMY3):
218-
TMY3.columns = ('ETR','ETRN','GHI','GHISource','GHIUncertainty',
227+
def _recolumn(tmy3_dataframe, inplace=True):
228+
"""
229+
Rename the columns of the TMY3 DataFrame.
230+
231+
Parameters
232+
----------
233+
tmy3_dataframe : DataFrame
234+
inplace : bool
235+
passed to DataFrame.rename()
236+
237+
Returns
238+
-------
239+
Recolumned DataFrame.
240+
"""
241+
raw_columns = 'ETR (W/m^2),ETRN (W/m^2),GHI (W/m^2),GHI source,GHI uncert (%),DNI (W/m^2),DNI source,DNI uncert (%),DHI (W/m^2),DHI source,DHI uncert (%),GH illum (lx),GH illum source,Global illum uncert (%),DN illum (lx),DN illum source,DN illum uncert (%),DH illum (lx),DH illum source,DH illum uncert (%),Zenith lum (cd/m^2),Zenith lum source,Zenith lum uncert (%),TotCld (tenths),TotCld source,TotCld uncert (code),OpqCld (tenths),OpqCld source,OpqCld uncert (code),Dry-bulb (C),Dry-bulb source,Dry-bulb uncert (code),Dew-point (C),Dew-point source,Dew-point uncert (code),RHum (%),RHum source,RHum uncert (code),Pressure (mbar),Pressure source,Pressure uncert (code),Wdir (degrees),Wdir source,Wdir uncert (code),Wspd (m/s),Wspd source,Wspd uncert (code),Hvis (m),Hvis source,Hvis uncert (code),CeilHgt (m),CeilHgt source,CeilHgt uncert (code),Pwat (cm),Pwat source,Pwat uncert (code),AOD (unitless),AOD source,AOD uncert (code),Alb (unitless),Alb source,Alb uncert (code),Lprecip depth (mm),Lprecip quantity (hr),Lprecip source,Lprecip uncert (code),PresWth (METAR code),PresWth source,PresWth uncert (code)'
242+
243+
new_columns = ['ETR','ETRN','GHI','GHISource','GHIUncertainty',
219244
'DNI','DNISource','DNIUncertainty','DHI','DHISource','DHIUncertainty',
220245
'GHillum','GHillumSource','GHillumUncertainty','DNillum','DNillumSource',
221246
'DNillumUncertainty','DHillum','DHillumSource','DHillumUncertainty',
@@ -228,9 +253,11 @@ def recolumn(TMY3):
228253
'CeilHgt','CeilHgtSource','CeilHgtUncertainty','Pwat','PwatSource',
229254
'PwatUncertainty','AOD','AODSource','AODUncertainty','Alb','AlbSource',
230255
'AlbUncertainty','Lprecipdepth','Lprecipquantity','LprecipSource',
231-
'LprecipUncertainty')
232-
233-
return TMY3
256+
'LprecipUncertainty','PresWth','PresWth source','PresWth uncert']
257+
258+
mapping = dict(zip(raw_columns.split(','), new_columns))
259+
260+
return tmy3_dataframe.rename(columns=mapping, inplace=True)
234261

235262

236263

0 commit comments

Comments
 (0)